尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

CTF文件包含漏洞实战:从LFI到RCE的完整攻击链解析

CTF文件包含漏洞实战:从LFI到RCE的完整攻击链解析 1. 项目概述从“包含”到“掌控”的漏洞艺术在Web安全的学习与实战中文件包含漏洞File Inclusion Vulnerability是一个既基础又充满变数的核心议题。它不像SQL注入那样有明确的“”或“union”作为攻击信号也不像XSS那样直观地在页面上弹出弹窗。文件包含更像是一扇“后门”攻击者通过它可以诱使服务器执行本不该被执行的代码或者读取敏感的系统文件。而“ctfshow文件包含-超详解”这个标题指向的正是CTFCapture The Flag竞赛中特别是ctfshow平台系列题目里对这一漏洞从浅入深、从理论到实战的全面剖析。我接触过大量相关题目也指导过不少新手发现很多人卡壳不是因为不知道漏洞原理而是面对题目中五花八门的限制过滤、伪协议、目录跳转时思维不够开阔缺少一套系统的“武器库”和“解题流”。本文将结合ctfshow的经典题目场景为你拆解文件包含的每一种攻击姿势、绕过技巧和深层利用目标不仅是让你解出题目更是让你建立起面对真实环境文件包含漏洞时的审计与利用能力。2. 文件包含漏洞核心原理与分类解析2.1 漏洞产生的根本原因信任与控制的失衡文件包含漏洞的本质是应用程序在动态包含文件时对用户输入的文件路径或参数缺乏充分的安全校验。开发人员为了代码的复用和模块化常使用诸如PHP中的include、require、include_once、require_once等函数。这些函数的本意是好的例如根据用户选择的语言包含不同的语言包文件include($_GET[lang] . .php);。设想中$_GET[lang]的值可能是en或zh最终包含en.php或zh.php。然而问题就出在这个“设想”上。如果攻击者将lang参数设置为../../../etc/passwd呢拼接后可能变成../../../etc/passwd.php但如果服务器配置允许包含非PHP文件或者存在空字节截断等特性攻击者就可能读取到系统的/etc/passwd文件。这就是信任了用户输入却未对其施加有效控制如白名单校验、路径过滤导致的恶果。注意现代PHP版本5.3.4默认情况下include和require对于远程文件HTTP/URL包含是关闭的allow_url_includeOff但这并不影响本地文件包含LFI的利用而LFI往往能衍生出更严重的后果。2.2 两大类型LFI与RFI根据包含文件的来源文件包含漏洞主要分为两类本地文件包含Local File Inclusion, LFI包含的是服务器本地的文件。这是最常见的形式也是ctfshow题目中的主力。利用LFI攻击者可以读取敏感文件如/etc/passwdLinux用户信息、/proc/self/environ环境变量、Web配置文件、数据库配置文件config.php、日志文件等。配合文件上传获取Webshell如果网站存在文件上传功能但上传的文件不被直接执行如图片马我们可以通过LFI去包含这个上传的文件从而执行其中的PHP代码。利用PHP封装协议php://进行数据流操作例如读取PHP文件源码php://filter/convert.base64-encode/resourceindex.php或者直接执行输入流中的代码。远程文件包含Remote File Inclusion, RFI包含的是远程服务器上的文件。这需要allow_url_fopen和allow_url_include均设置为On条件较为苛刻在实战中较少见但CTF中仍可能作为考点。利用RFI攻击者可以直接包含一个托管在远程服务器上的恶意脚本从而完全控制Web应用。在ctfshow的题目体系中LFI及其各种绕过技巧是绝对的重点RFI通常作为特定场景下的进阶考点。2.3 PHP封装协议LFI的“瑞士军刀”当直接包含.php文件时服务器会执行它我们看不到源码。当包含非.php文件如.txt,.jpg时如果其中包含PHP代码且被成功包含这些代码也会被执行。但如果我们想读取一个.php文件的源代码呢这时PHP封装协议就登场了。最常用的是php://filter协议。它允许我们对数据流进行过滤处理。一个经典的利用payload是?filephp://filter/convert.base64-encode/resourceindex.php这个payload做了以下几件事php://filter/指定使用过滤器。convert.base64-encode是一个过滤器它会对目标资源进行base64编码。resourceindex.php指定要读取的资源是index.php。服务器会读取index.php的内容经过base64编码后输出。攻击者拿到这段base64字符串解码即可获得完整的PHP源代码。这是文件包含漏洞审计中至关重要的一步通过读取源码我们可以分析其他参数、隐藏的逻辑、过滤函数从而找到进一步的利用路径。3. ctfshow文件包含题目常见考点与绕过技巧ctfshow的题目设计非常贴近实战且层层递进。下面我们梳理几个核心考点和对应的绕过方法。3.1 基础绕过后缀拼接与目录遍历这是最简单的关卡旨在让你理解最基本的LFI。题目特征代码类似include($_GET[file] . .php);。它强制给输入添加了.php后缀。绕过方法空字节截断%00在PHP版本 5.3.4 且 magic_quotes_gpcOff 时可以在路径后添加%00URL编码的空字节来截断后面的后缀。例如?file../../../etc/passwd%00。这样拼接后变成../../../etc/passwd%00.php%00告诉PHP字符串到此结束实际包含的就是/etc/passwd。路径长度截断在Windows下路径长度超过256字节或Linux下超过4096字节时可能会发生截断。但此法通常不实用。利用PHP伪协议php://input允许我们直接POST数据作为输入流被执行或者用php://filter读取源码这本身就不受后缀限制。例如?filephp://input然后POST body里写?php system(ls);?。目录遍历../如果题目没有过滤../可以直接跳转目录。例如?file../../../../etc/passwd。需要根据Web目录深度尝试。实操心得遇到后缀拼接第一反应就是尝试%00截断和php://filter读源码。如果%00无效高版本PHP那么伪协议通常是突破口。3.2 关键词过滤与编码绕过题目开始增加防御常见过滤../、php、data、input等关键词。题目特征代码中使用str_replace()、preg_match()等函数过滤特定字符串。绕过方法双写绕过如果过滤是简单的str_replace(“../”, “”, $file)可以使用..././或....//。过滤一次后剩余的字符又组合成了../。例如?file....//....//etc/passwd。编码绕过URL编码../可以编码为%2e%2e%2f或..%2f。有时过滤逻辑在解码前进行编码即可绕过。二次URL编码../-%2e%2e%2f-%252e%252e%252f%被编码为%25。服务器可能会进行两次解码。Unicode编码、UTF-7编码等取决于服务器解析方式。超长路径绕过使用大量的./。例如./././././././etc/passwd或者/etc/./passwd。某些简单的正则可能无法匹配这种形式。利用协议嵌套php://filter被过滤可以尝试PhP://FilTer大小写混淆或者使用zip://、phar://等协议。3.3 伪协议的综合利用这是文件包含的精髓也是ctfshow中高阶题目的核心。php://filter的链式过滤器除了convert.base64-encode还有string.rot13、string.toupper、string.strip_tags等。有时题目会过滤base64关键词我们可以用readconvert.base64-encode或者换用string.rot13编码虽然ROT13不是安全编码但有时能绕过简单的检查。例如?filephp://filter/readstring.rot13/resourceflag.php。php://input执行代码需要allow_url_includeOn。用法?filephp://input然后在POST Body中直接写入PHP代码。这是获取Webshell的直接方式之一。data://协议同样需要allow_url_includeOn。它允许直接包含数据流。例如?filedata://text/plain,?php phpinfo();?或?filedata://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8base64编码后的php代码。zip://与phar://协议这两个协议常用于绕过文件上传限制。你可以将一个包含恶意代码的PHP文件如shell.php压缩成shell.zip然后上传。接着通过文件包含去包含这个zip文件中的PHP文件?filezip://./uploads/shell.zip%23shell.php注意#需要URL编码为%23。phar://类似但它是PHP归档格式更常用于反序列化利用但在文件包含里用法相似?filephar://./uploads/shell.phar/shell.php。3.4 日志文件包含与Session文件包含这是LFI通向RCE远程代码执行的经典路径。日志文件包含Web服务器如Apache、Nginx会记录访问日志access.log和错误日志error.log。这些日志文件通常Web用户可读。攻击者可以故意访问一个包含PHP代码的URL例如/?php system($_GET[‘c’]);?。这段代码会被原封不动地记录在访问日志中。然后利用LFI漏洞去包含这个日志文件例如?file/var/log/apache2/access.log一旦包含成功日志文件中的PHP代码就会被执行从而在URL中传递?cls即可执行命令。关键点需要知道日志文件的绝对路径常见路径如/var/log/apache2/access.log,/var/log/nginx/access.log并且日志文件有读取权限。Session文件包含PHP会将Session数据存储在服务器上的临时文件中如/tmp/sess_[sessionid]。Session文件的内容我们可以部分控制通过$_SESSION变量。如果Session文件的存储路径已知通过phpinfo()或默认路径且文件名可预测通常与PHPSESSID相关那么就可以先写入一个包含PHP代码的Session再通过LFI包含这个Session文件来执行代码。利用条件Session存储路径已知、文件名可预测或可爆破、有文件包含点。在ctfshow题目中日志包含是常客因为它巧妙地连接了“信息获取”和“代码执行”。4. ctfshow典型题目实战流程拆解下面我们模拟一个综合性的ctfshow文件包含题目解题流程将上述技巧串联起来。4.1 第一步信息收集与初步测试假设题目URL为http://target.com/index.php?filehello基础LFI测试尝试?file../../../../etc/passwd看是否回显用户列表。PHP伪协议读源码无论有无回显直接上?filephp://filter/convert.base64-encode/resourceindex.php。解码获取首页源码。分析源码从解码得到的源码中寻找其他参数、包含file变量的代码逻辑、过滤函数。可能发现代码include($_GET[file] . .html);添加了.html后缀可能发现过滤$file str_replace( array( “../”, “..\”, “php://”, “data://” ), “”, $file );4.2 第二步绕过过滤与后缀根据源码分析结果场景A仅后缀限制。尝试%00截断高版本通常无效。尝试php://filter本身不受.html影响因为协议路径里不包含.html后缀。成功读到index.php源码。场景B过滤了../和php://。对于../尝试使用....//双写绕过。str_replace把../替换成空那么....//中间的../被删掉剩下的../又组合起来了。或者使用URL编码%2e%2e%2f。对于php://尝试大小写PhP://或者使用其他协议如zip://、phar://、data://如果没被过滤。如果data://也被过滤尝试DATA://或DaTa://。4.3 第三步扩大战果寻找Flag通过伪协议读到其他关键源码比如config.php、flag.php。?filephp://filter/convert.base64-encode/resourceconfig.php ?filephp://filter/convert.base64-encode/resource../flag.php如果flag.php直接包含会执行代码不显示内容就必须用php://filter来读取其源码。4.4 第四步尝试日志包含获取RCE如果题目设计更复杂直接读不到flag可能需要RCE。探测日志路径通过读取/proc/self/environ环境变量或/proc/self/fd/下的文件描述符有时能发现当前进程打开的文件其中可能包含日志路径。或者用常见的路径字典爆破。污染日志使用Burp Suite或curl发送一个包含PHP代码的请求。GET /?php system($_GET[‘cmd’]);? HTTP/1.1 Host: target.com包含日志假设日志路径是/var/log/nginx/access.log则构造?file/var/log/nginx/access.log。此时这个包含请求会执行日志中我们写入的PHP代码。执行命令在包含日志的请求中添加参数?cmdls /或?cmdcat /flag即可执行系统命令找到flag。4.5 第五步利用文件上传与zip/phar协议如果网站有上传点但上传后文件被重命名或移动到非Web目录。制作一个包含PHP代码的shell.php内容为?php eval($_POST[‘a’]);?。将其压缩为shell.zip注意压缩时选择仅存储不压缩确保代码不被破坏。上传shell.zip。通过文件包含漏洞包含这个zip文件?filezip://./uploads/shell.zip%23shell.php。成功则触发Webshell。使用蚁剑、冰蝎等工具连接或直接POST传参asystem(‘cat /flag’);。5. 高级技巧与疑难问题排查5.1 包含临时文件与竞争条件这是一种较难的利用方式。PHP在处理文件上传时会先在上传目录如/tmp创建一个临时文件处理完毕后再删除。这个窗口期极短。攻击者可以编写脚本在文件上传的同时疯狂地通过LFI漏洞尝试包含这个临时文件文件名通常是phpXXXXXX一旦在删除前包含成功其中的代码就会被执行。这需要编写自动化脚本利用时间竞争。5.2 PHP_SESSION_UPLOAD_PROGRESS 与 Session文件包含即使没有Session_start()在文件上传时如果POST一个PHP_SESSION_UPLOAD_PROGRESS变量并且Cookie中设置了PHPSESSIDPHP也会创建/写入Session文件。我们可以控制PHP_SESSION_UPLOAD_PROGRESS的值为PHP代码。然后通过LFI包含形如/tmp/sess_[PHPSESSID]的文件来执行代码。这需要知道Session存储路径默认/tmp和Session ID。5.3 编码与解码顺序导致的绕过有时过滤发生在URL解码之后。例如服务器代码先对$_GET[‘file’]进行urldecode()然后再进行str_replace(“../”, “”, $file)过滤。那么我们可以对../进行二次编码%252e%252e%252f。服务器第一次解码得到%2e%2e%2f过滤函数找不到../放过。随后在包含时可能还有一次解码过程将%2e%2e%2f解码为../最终成功包含。理解服务器端的处理流程是关键。5.4 常见错误与排查表问题现象可能原因排查思路包含php://filter后页面空白目标文件不存在或路径错误过滤器错误输出被关闭1. 检查resource后的路径是否正确。2. 尝试简单的resourceindex.php看是否报错。3. 尝试string.rot13过滤器看是否有不同输出。包含日志文件无反应日志路径错误Web权限无法读取日志日志格式导致PHP代码被破坏1. 尝试读取/proc/self/environ找路径线索。2. 尝试常见日志路径字典。3. 检查写入日志的PHP代码是否被转义或截断尝试最简单的??。zip://或phar://协议无效文件路径错误#未编码压缩包内文件路径错误PHP版本不支持1. 确保#被编码为%23。2. 使用绝对路径zip:///var/www/html/uploads/shell.zip%23shell.php。3. 确认PHP已启用对应协议包装器。过滤函数似乎无法绕过过滤逻辑比想象中复杂如递归过滤、正则匹配1. 用php://filter读取过滤函数的源码仔细分析。2. 尝试非常规编码UTF-7, UCS-2。3. 考虑是否可以利用其他漏洞如目录穿越到过滤文件本身进行修改通常不现实。6. 防御视角与安全开发建议理解了攻击才能更好地防御。作为开发者应杜绝文件包含漏洞避免动态包含如果可能使用静态包含或设计模式如自动加载类。白名单校验如果必须动态包含使用白名单机制。只允许包含预设的几个文件。$allowed_files [‘home.php’, ‘about.php’, ‘contact.php’]; if (in_array($_GET[‘page’], $allowed_files)) { include($_GET[‘page’]); } else { include(‘404.php’); }严格限制路径使用basename()函数获取文件名去除目录路径。或者将用户输入限制在特定子目录内。$file ‘./pages/’ . basename($_GET[‘file’]) . ‘.php’; if (file_exists($file)) { include($file); }关闭危险配置在生产环境中确保php.ini里allow_url_fopen Off和allow_url_include Off。更新与打补丁保持PHP版本更新旧版本的空字节截断等特性已被修复。文件包含漏洞的利用是一场关于“路径”和“协议”的想象力游戏。ctfshow的题目就像一个个精心设计的迷宫逼迫你去思考服务器是如何处理你的输入的过滤的边界在哪里系统还有哪些特性可以被利用。从简单的目录遍历到复杂的伪协议、日志污染组合拳每一步突破都需要对PHP特性、服务器配置和Web架构有深入的理解。解决这些问题后你收获的不仅是一个flag更是一种在黑白之间寻找通路的思维方式。在实际的渗透测试中这种对漏洞链的串联能力和对边界的探索精神价值远超工具本身。
返回列表