1. 首页只是一个登录框,f12没有有用信息,尝试用admin和password登录
2. 提示密码错误,说明账号也许是对的。
同时按f12有一段注释,注释为全大写字母与数字,猜测是base32加密:
base32解密后得到一串字符疑似为base64加密:
base64解密后得到一个提示:
3. 暂时不知道这串提示有什么用处,但是在经过几次尝试后确定了账号输入框为sql注入点。
4. 经过了很久的手动尝试,一直没能绕过题目的过滤,题目貌似是过滤了or,小括号,等号等,没有了小括号,似乎很多事情都做不了,做到这里我已经没有思路了。
5. 上网查找这题的源代码学习此题逻辑
1 <!--MMZFM422K5HDASKDN5TVU3SKOZRFGQRRMMZFM6KJJBSG6WSYJJWESSCWPJNFQSTVLFLTC3CJIQYGOSTZKJ2VSVZRNRFHOPJ5--> 2 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 3 <title>Do you know who am I?</title> 4 <?php 5 require "config.php"; 6 require "flag.php"; 7 8 // 去除转义 9 if (get_magic_quotes_gpc()) { 10 function stripslashes_deep($value) 11 { 12 $value = is_array($value) ? 13 array_map('stripslashes_deep', $value) : 14 stripslashes($value); 15 return $value; 16 } 17 18 $_POST = array_map('stripslashes_deep', $_POST); 19 $_GET = array_map('stripslashes_deep', $_GET); 20 $_COOKIE = array_map('stripslashes_deep', $_COOKIE); 21 $_REQUEST = array_map('stripslashes_deep', $_REQUEST); 22 } 23 24 mysqli_query($con,'SET NAMES UTF8'); 25 $name = $_POST['name']; 26 $password = $_POST['pw']; 27 $t_pw = md5($password); 28 $sql = "select * from user where username = '".$name."'"; 29 // echo $sql; 30 $result = mysqli_query($con, $sql); 31 32 33 if(preg_match("/(|)|=|or/", $name)){ 34 die("do not hack me!"); 35 } 36 else{ 37 if (!$result) { 38 printf("Error: %s ", mysqli_error($con)); 39 exit(); 40 } 41 else{ 42 // echo '<pre>'; 43 $arr = mysqli_fetch_row($result); 44 // print_r($arr); 45 if($arr[1] == "admin"){ 46 if(md5($password) == $arr[2]){ 47 echo $flag; 48 } 49 else{ 50 die("wrong pass!"); 51 } 52 } 53 else{ 54 die("wrong user!"); 55 } 56 } 57 } 58 59 ?>
经过审计看出,关键代码部分
if(preg_match("/(|)|=|or/", $name))//过滤了小括号,or,和等号。
$name = $_POST['name'];
$password = $_POST['pw'];
$sql = "select * from user where username = '".$name."'";
$result = mysqli_query($con, $sql);
后端接收了账号密码后,居然是直接用接收到的账号作为查询条件进行查询的,查询出来的第二项结果如果不为admin就会die,也就是说输入的账号必须为admin,随后对比admin这行的密码与输入密码是否相等
密码储存方式为md5加密后的密码。
利用联合查询临时插入数据:
select * from user where uname='zhangge' union select '1','2','3';
此时查询结果出了zhangge那一行,还会多出一行联合查询的字段,作为数据临时插入。
利用这个特性,首先随便选一个密码例如1,md5加密后用它作为临时密码插入。
构造payload:
name=zhangge'union select 1,'admin','c4ca4238a0b923820dcc509a6f75849b'#&pw=1