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 的源码

相关推荐
稷下元歌2 小时前
系统学习plc 基础指令上篇,官方资料课程笔记整 理
笔记·学习
库拉大叔2 小时前
工具调用效率对比实测:GPT-5.5与Gemini 3.5 Flash性能评估
java·前端·人工智能
艾伦野鸽ggg2 小时前
CSS容器查询和悬浮间隙问题
前端·css
云水一下2 小时前
Vue.js从零到精通系列(一):初识Vue——背景、环境与第一个应用
前端·javascript·vue.js
朱涛的自习室2 小时前
Munk AI 正式开源:一个“自我进化”的 AI 测试引擎
android·人工智能·github
啦啦啦_99992 小时前
4. Transformer_3_解码器部分
android·深度学习·transformer
云水一下2 小时前
Vue.js从零到精通系列(二):响应式核心——ref、reactive、computed与watch
前端·javascript·vue.js
放下华子我只抽RuiKe52 小时前
FastAPI 全栈后端(二):路由与数据模型
前端·人工智能·react.js·前端框架·html·fastapi
超人不会飞_Jay3 小时前
26.6.8LangChain笔记
笔记