直接上题分析
确诊为单引号闭合
有报错回显
无回显,爆出字段为3,暂时猜测为 id,username,password
经过一系列测试下来发现过滤了,括号,or ,|,=
到这里有点束手无策,上网看了一下大6们的解题思路豁然开朗,以下是大佬提供的源代码
<!--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!");
}
}
}
?>
发现有一处逻辑漏洞在如下
可以看出php未对返回数据进行安全的处理,当我们对联合查询数据时未指明表名,select时数据库会返回一个虚拟的表与当前表拼接返回给php,实列如下:
也就是说如果我们如果进行以下payload:
1' union select 1,'admin','e10adc3949ba59abbe56e057f20f883e'#&pw=123456
e10adc3949ba59abbe56e057f20f883e为md5加密后的密码,原因是在开发过程中为了更好的保护密码。