ctf sow web入门112

这是一道典型的 PHP 代码审计与绕过题(通常出现在 CTF 比赛中)。核心目标是利用 highlight_file() 函数来读取服务器上的敏感文件(比如 flag.php 或 /flag),但代码中做了一些非常严格的限制。

  1. 代码核心逻辑分析
    首先,我们把图片中的关键代码拆解一下:
php 复制代码
function filter($file){
    if(preg_match('/\. \. \/|http|https|data|input|rot13|base64|string/i', $file)){
        die("hacker!");
    }else{
        return $file;
    }
}

$file = $_GET['file'];
if(! is_file($file)){
    highlight_file(filter($file));
}else{
    echo "hacker!";
}

码的执行流程和限制如下:

输入源:通过 GET 请求接收参数 ?file=...。

第一道关卡 (is_file):必须满足 !is_file($file)。也就是说,你传入的字符串绝对不能被 PHP 直接识别为一个"客观存在的本地普通文件"。如果满足,则直接拦截并输出 "hacker!"。

第二道关卡 (filter):不能包含以下敏感关键字(忽略大小写 /i):

.../(即 .../ 目录遍历,注意图片中正则匹配了带空格或转义的路径,这里阻止了常规的相对路径跳转)

协议伪协议:http, https, data, input

常用过滤器:rot13, base64, string

  1. 核心矛盾点(破局关键)
    矛盾 1:我们需要读取一个文件(比如 flag.php),但 is_file('flag.php') 会返回 true,导致直接被 else { echo "hacker!"; } 拦截。

矛盾 2:为了绕过 is_file(),我们通常会使用 PHP 伪协议(Wrapper)。但是最常用的 php://filter/read=convert.base64-encode/resource=flag.php 中包含的 string、base64 等关键字全部被 filter() 函数拉黑了。

总结:我们需要找到一个既能让 is_file() 返回 false,又能让 highlight_file() 正常解析并读取到目标文件的路径或伪协议,且不包含黑名单关键字。

  1. 解题思路与绕过技巧
    思路一:利用其他未被过滤的 PHP 过滤器
    虽然 base64、rot13、string 被过滤了,但 PHP 支持的过滤器远不止这些。
    我们可以利用 php://filter 配合其他的编码转换过滤器。例如:

Iconv 编码转换:convert.iconv.*

解压/压缩过滤器(如果适用):zlib.deflate / zlib.inflate

构造 Payload 示例:

php 复制代码
?file=php://filter/read=convert.iconv.UCS-2.UCS-4/resource=flag.php

为什么能绕过 is_file? 因为 php://filter/... 是一个伪协议流,is_file() 无法将其直接识别为本地物理文件,返回 false,顺利通过第一关。

为什么能绕过 filter()?

因为里面没有包含 base64、string 等黑名单词汇。

还有其他payload可以读取flag

  1. php://filter/resource=flag.php
    为什么能绕过正则:它的字符串里只有 php、filter、resource、flag.php。对照题目黑名单(http|https|data|input|rot13|base64|string),没有任何一个词被命中。

读取原理:php://filter 是 PHP 专门用来处理流的通道。当你没有指定任何 read(过滤器)时,它默认就是直接读取原文件。

结果:直接在页面上高亮显示 flag.php 的源码。

  1. php://filter/convert.iconv.UCS-2LE.UCS-2BE/resource=flag.php
    为什么能绕过正则:使用了 convert.iconv(编码转换),避开了被过滤的 convert.base64 和 convert.string。

读取原理:它在读取 flag.php 时,强行把文件的编码从 UCS-2LE 转换成 UCS-2BE(一种字节序转换)。

结果:由于字节序被颠倒了,页面上会输出一堆表面上看起来是乱码、但实际上包含了 flag 信息的文本。你在浏览器查看网页源码,把它逆向转换回来就能看到明文。

  1. php://filter/read=convert.quoted-printable-encode/resource=flag.php
    为什么能绕过正则:虽然包含了 read=,但后面使用的是 convert.quoted-printable-encode(可打印字符引用编码,常用于邮件传输),这个过滤器同样不在黑名单里。

读取原理:它在读取文件时,会将文件内容进行 Quoted-printable 编码。

结果:高亮输出编码后的文本(通常表现为很多 =3D、=0D 之类的字符),代码中的特殊字符会被保护起来,同样能借此拿到数据。

  1. compress.zlib://flag.php
    为什么能绕过正则:compress.zlib:// 是 PHP 的压缩流包装器,完全不在黑名单的任何一个字眼里。

读取原理:这个伪协议本意是用来打开并解压 .gz 压缩文件的。但是如果后面跟的是一个普通的未压缩文本文件(如 flag.php),zlib 流在读取时发现它不是压缩包,会直接降级作为普通文件流读取输出。

结果:直接原汁原味地高亮输出 flag.php 的源码

相关推荐
自进化Agent智能体13 分钟前
Hermes GitHub PR 审查 —— 自动化代码评审
前端
涛涛ing2 小时前
OpenAI Astra 泄露:零样本生成 3D 网页,前端开发者慌了吗?
前端
ssshooter2 小时前
现在网页都能提供 MCP 了?!
前端·人工智能·程序员
杉氧2 小时前
状态管理变迁史:为什么我们放弃了 Redux 选择 Zustand?
android·前端·react native
cidy_983 小时前
OpenCode 手动配置火山方舟 Agent Plan 教程
前端
鹏多多3 小时前
PC 网站接入微信登录,这 10 个坑我替你踩完了!
前端·javascript·vue.js
律宏阔3 小时前
微信小程序使用 Orval + OpenAPI 自动生成接口:Axios 兼容踩坑记录
前端·微信小程序
律宏阔3 小时前
微信小程序集成 TDesign 完整记录:解决 NPM packages not found
前端·微信小程序
律宏阔3 小时前
微信小程序 ECharts 瘦身实战:分包异步化 + componentPlaceholder 避开主包 2MB 限制
前端·微信小程序
夏天要喝冰可乐3 小时前
从 Idea 到开源插件:我用 Vibe Coding 做了「文章摆渡」
前端·ai编程·vibecoding