CTFshow-Web-源码泄露与SQL注入
一、靶场:ctfshow web10
二、解题步骤:
步骤一:打开靶场,发现还是一个登陆页面,测试sql注入发现和web9一样没有任何回显或变化,但发现多了一个取消按钮,点击后发现下载了一个文件


里面貌似是登录页面的源码
步骤二:代码审计
<?php
$flag="";
function replaceSpecialChar($strParam){
$regex = "/(select|from|where|join|sleep|and|s|union|,)/i";
return preg_replace($regex,"",$strParam);
}
if (!$con){
die('Could not connect: ' . mysqli_error());
}
if(strlen($username)!=strlen(replaceSpecialChar($username))){
die("sql inject error");
}
if(strlen($password)!=strlen(replaceSpecialChar($password))){
die("sql inject error");
}
$sql="select * from user where username = '$username'";
$result=mysqli_query($con,$sql);
if(mysqli_num_rows($result)>0){
while($row=mysqli_fetch_assoc($result)){
if($password==$row['password']){
echo "登陆成功<br>";
echo $flag;
}
}
}
?>
分析上面的代码可以得知:
1、创建了一个过滤函数将一些常用sql注入语句被拉入了黑名单,将sql语句进行了正则替换,直接过滤了;
2、在执行sql语句前会将username和password的值放到过滤函数中,将黑名单中的语句进行过滤,并且过滤后的长度要与我们输入的内容一致;
3、用户名和密码没有要求长度;
4、过滤完成之后就直接执行了查询语句,使用mysqli_fetch_assoc() 函数从结果集中取得一行作为关联数组,即将查询结果中的密码与输入的密码进行校验
解题方法:此处只能用WITH ROLLUP的进行绕过,首先学习一下WITH ROLLUP:
with rollup 可以对 group by 分组结果再次进行分组,并在最后添加一行数据用于展示结果( 对group by未指定的字段进行求和汇总,而group by指定的分组字段则用null占位),使用 with rollup,此函数是对聚合函数进行求和,注意 with rollup是对 group by 后的第一个字段,进行分组求和。
例:
现在有这样一张学生表,里面的数据如下所示。

如果想对根据学生,对科目,分数求和,可以这样写。

如果想在这个的基础上,求出学生的总分数,应该这么做:

步骤三:构建payload:1'/**/or/**/true/**/group/**/by/**/password/**/with/**/rollup/**/#
注解:poc当作用户名输入后,而密码又没有要求一定要有内容,所以会通过前面的所有判断语句,然后到达sql查询语句,拼接替换后得到:
$sql="select * from user where username = '1'/**/or/**/true/**/group/**/by/**/password/**/with/**/rollup/**/#'";
可以看到拼接后的语句变了,username处由于or语句和后面的true直接通过,然后执行了group by分组语句,对密码进行分组,然后是with rollup对密码进行求和,然而由于with rollup语句的特殊性,返回结果的最后一行用null来填充password, 这样一来我们的返回结果 $result 中就有了一个值为null的password,而登录时并没有输入密码,那就是null,null==null成功登录,成功拿到flag


浙公网安备 33010602011771号