PHP代码审计分段讲解(5)
原创
©著作权归作者所有:来自51CTO博客作者春告鳥Cl0udG0d的原创作品,请联系作者获取转载授权,否则将追究法律责任
11 sql闭合绕过
源代码为
<?php
if($_POST[user] && $_POST[pass]) {
$conn = mysql_connect("*******", "****", "****");
mysql_select_db("****") or die("Could not select database");
if ($conn->connect_error) {
die("Connection failed: " . mysql_error($conn));
}
$user = $_POST[user];
$pass = md5($_POST[pass]);
//select user from php where (user='admin')#
//exp:admin')#
$sql = "select user from php where (user='$user') and (pw='$pass')";
$query = mysql_query($sql);
if (!$query) {
printf("Error: %s\n", mysql_error($conn));
exit();
}
$row = mysql_fetch_array($query, MYSQL_ASSOC);
//echo $row["pw"];
if($row['user']=="admin") {
echo "<p>Logged in! Key: *********** </p>";
}
if($row['user'] != "admin") {
echo("<p>You are not admin!</p>");
}
}
?>
POST方式传入user和pass的值,同时连接数据库
if($_POST[user] && $_POST[pass]) {
$conn = mysql_connect("*******", "****", "****");
mysql_select_db("****") or die("Could not select database");
if ($conn->connect_error) {
die("Connection failed: " . mysql_error($conn));
}
$user = $_POST[user];
$pass = md5($_POST[pass]);
将pass的值使用md5处理重新赋值,接着使用sql语句进行查询
$sql = "select user from php where (user='$user') and (pw='$pass')";
查询成功后进入判断
if($row['user']=="admin") {
echo "<p>Logged in! Key: *********** </p>";
}
这里可以看到,登录的时候只对查询出结果里面的user进行了判断,当其的值为admin的时候,登录成功,并没有进行密码的校验
所以我们只需要闭合前面的SQL查询语句,令user=admin即可
所以payload为:
密码输入什么都无所谓
sql语句最后变成了这样:
$sql = "select user from php where (user='admin')#') and (pw='$pass')";
也就是
$sql = "select user from php where (user='admin')
登录即可获取flag
12 X-Forwarded-For绕过指定IP地址
源代码为:
<?php
function GetIP(){
if(!empty($_SERVER["HTTP_CLIENT_IP"]))
$cip = $_SERVER["HTTP_CLIENT_IP"];
else if(!empty($_SERVER["HTTP_X_FORWARDED_FOR"]))
$cip = $_SERVER["HTTP_X_FORWARDED_FOR"];
else if(!empty($_SERVER["REMOTE_ADDR"]))
$cip = $_SERVER["REMOTE_ADDR"];
else
$cip = "0.0.0.0";
return $cip;
}
$GetIPs = GetIP();
if ($GetIPs=="1.1.1.1"){
echo "Great! Key is *********";
}
else{
echo "错误!你的IP不在访问列表之内!";
}
?>
第一次遇到伪造IP的题目是在BugKu的做题平台上,这里的代码使用HTTP头里面的IP信息来进行IP访问列表的判断,而HTTP头的信息是可以通过我们抓包改变的。
这里我们跟题目一样,使用X_FORWARDED_FOR来进行IP的伪造
在请求头里面添加:X-Forwarded-For: 1.1.1.1
即可获取flag
13 md5加密相等绕过
<?php
$md51 = md5('QNKCDZO');
$a = @$_GET['a'];
$md52 = @md5($a);
if(isset($a)){
if ($a != 'QNKCDZO' && $md51 == $md52) {
echo "nctf{*****************}";
} else {
echo "false!!!";
}}
else{echo "please input a";}
?>
将 QNKCDZO MD5加密后,使用GET方式传入a的值,将a进行MD5加密,获取flag的条件为:
if ($a != 'QNKCDZO' && $md51 == $md52) {
传入的a不能为QNKCDZO,有需要令两者的md5加密后的值相等,这里需要用到MD5碰撞的知识
我们重新梳理一遍代码
获得的md51的值为
0e830400451993494058024219903391
有意思的地方在于,这串字符串转换成为数字的话,按照科学计数法,它是0的830400451993494058024219903391次方,虽然看上去很大,但是由于底数为0,所以结果也是0,而比较两个md5值的时候是
两个等号时会先进行类型转换,所以我们只需要找到一个md5值也是0e开头的字符串即可,这样它的md5加密结果科学计数法也会是0
当然这个也不需要找了,因为已经有大佬找好了:
我们选择其中的一个即可
获得flag