ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

CTF Web安全实战:文件包含漏洞原理、绕过与利用链分析

CTF Web安全实战:文件包含漏洞原理、绕过与利用链分析 1. 项目概述一次典型的中职CTF赛题复盘最近在整理过去的竞赛资料翻到了2022年中职网络空间安全国赛的一道题目编号是试题7。这道题在当时赛场上给不少选手制造了麻烦但它的设计思路非常经典涵盖了Web安全中几个核心的知识点。今天我就以这道题为例和大家一起拆解一下CTFCapture The Flag竞赛中Web类题目的常见套路和解题逻辑。我的解析仅代表个人在实战中的理解和建议希望能给正在学习网络安全、准备竞赛的朋友们提供一个清晰的思考路径。CTF比赛尤其是中职、高职阶段的赛事题目往往不会追求最新的、最偏门的漏洞而是侧重于考察选手对基础知识的扎实掌握和灵活运用能力。这道2022年的国赛题就是一个很好的例子它没有用复杂的框架或生僻的CVE而是将信息泄露、代码审计、命令执行这几个基础环节串联起来构建了一个完整的攻击链。对于初学者而言吃透这类题目远比去追逐那些“炫技”的0day更有价值。接下来我们就一步步走进这道题看看如何从题目描述和给定的环境通常是一个Web地址中抽丝剥茧找到最终的flag。2. 赛题环境初探与信息收集2.1 题目描述分析与初始思路拿到任何CTF题目第一步永远是仔细阅读题目描述。虽然我们无法还原当时的完整题目文本但根据“试题7”的常见模式和后续解题过程反推这类题目通常会提供一个简单的网站地址例如http://target_ip:port并附上一句模糊的提示比如“找到隐藏的flag”或“获取服务器上的秘密信息”。题目本身可能没有任何前端交互就是一个静态页面也可能是一个存在功能缺陷的简单应用。我的建议是立即打开浏览器访问目标地址。首先用眼睛快速扫描页面内容包括前端HTML源码右键查看源代码。不要放过任何注释、隐藏的表单、不起眼的链接甚至是图片的alt属性。很多入门题喜欢把提示直接写在HTML注释里。接着使用浏览器开发者工具F12查看网络请求、检查JS文件。同时用dirsearch、gobuster这类目录扫描工具进行后台目录爆破寻找像/admin、/backup、/src、/.git这类可能泄露信息的路径。这是信息收集的“标准作业流程”必须形成肌肉记忆。注意在比赛环境中使用扫描工具要注意频率避免触发WAFWeb应用防火墙规则或被封IP。通常可以加上延迟参数例如dirsearch -u http://target -e php,html,bak --delay1。2.2 关键信息发现与源码泄露在对这道模拟题进行信息收集时我们假设发现了一个关键线索在网站根目录下存在一个名为robots.txt的文件。访问后其内容显示User-agent: * Disallow: /source.zip这是一个非常明显的提示它告诉我们有一个/source.zip文件被故意“隐藏”了起来。下载并解压这个ZIP文件我们得到了网站的源代码。这步操作在CTF中称为“源码泄露”是出题人降低难度、引导选手进入代码审计阶段常见的手法。解压后我们发现这是一个简单的PHP应用目录结构通常包含index.php、login.php、admin.php等文件。我们的主战场立刻从黑盒测试转向了白盒的代码审计。此时应该快速浏览所有PHP文件重点关注以下几个部分包含用户输入的函数如$_GET、$_POST、$_REQUEST、$_COOKIE。文件操作函数如include、require、file_get_contents、system、exec、passthru。数据库操作函数如mysqli_query 注意SQL语句的拼接方式。任何自定义的过滤函数或正则表达式。3. 核心漏洞审计从代码到利用链3.1 入口点分析与参数可控性判断通过快速审计我们锁定了一个关键文件——index.php。其核心代码简化后如下?php highlight_file(__FILE__); $file $_GET[file]; if(isset($file)){ if (strpos($file, “..”) ! false || strpos($file, “tp”) ! false || strpos($file, “input”) ! false || strpos($file, “data”) ! false){ die(“Hacker!”); } include($file); } else { include(“home.php”); } ?这是一段非常典型的、存在漏洞的代码。它通过GET参数file接收一个文件名然后使用include()函数将其包含进来。include()在PHP中不仅能够包含本地文件如果配置不当allow_url_includeOn还能包含远程文件从而导致严重的安全问题。代码中虽然有一个简单的黑名单过滤过滤了..(目录遍历)过滤了tp过滤了input过滤了data但这个过滤是极其脆弱和不完整的。它只使用了strpos()进行字符串匹配且是黑名单机制。我们的目标很明确绕过过滤让include()函数执行我们想要的代码。3.2 过滤绕过与伪协议利用首先过滤..是为了防止目录遍历攻击如../../../etc/passwd。过滤tp很可能是想防止php://伪协议过滤input和data则是为了防止php://input和data://伪协议。然而这里的绕过方式非常多。1. 大小写绕过strpos()是大小写敏感的。PHP://或PhP://就可以轻松绕过对tp的检查。2. 嵌套协议绕过PHP的流包装器支持嵌套。我们可以使用compress.zlib://php://input这样的形式。虽然php://被禁但外层的compress.zlib://没有被禁它内部依然可以封装一个php://input流。3. 编码绕过使用URL编码。例如php://编码后是%70%68%70%3a%2f%2fstrpos()在原始参数中找不到明文tp同样可以绕过。在这道题中经过测试最简单有效的方法是大小写绕过。我们尝试使用PHP://input作为file参数的值。php://input是一个只读流可以访问请求的原始数据。这意味着我们可以在POST请求体中直接发送PHP代码include()会将其当作PHP文件来执行。3.3 构造利用链实现命令执行现在我们有了执行任意PHP代码的能力。下一步的目标是在服务器上执行系统命令从而读取flag文件。flag在CTF中通常位于根目录/flag、当前目录./flag或一个具有固定名称的文件中。我们构造如下请求请求方法POSTURLhttp://target_ip:port/index.php?filePHP://input注意大写PHP请求体Body?php system(‘ls /’); ?这个请求的含义是告诉服务器我要包含PHP://input这个“文件”而这个“文件”的内容就是POST Body里的?php system(‘ls /’); ?。服务器端的include()会执行这段代码调用system(‘ls /’)命令列出根目录下的文件。如果请求成功我们会在页面返回中看到根目录的文件列表其中很可能包含一个名为flag、flag.txt或flag.php的文件。假设我们看到了/flag。接下来我们修改请求体读取这个文件请求体Body?php system(‘cat /flag’); ?或?php echo file_get_contents(‘/flag’); ?发送请求后页面应该会直接输出flag的内容。至此整个攻击链就完成了信息收集发现源码 - 代码审计发现文件包含漏洞 - 大小写绕过黑名单过滤 - 利用php://input伪协议执行任意代码 - 通过system函数执行命令读取flag。4. 深度拆解漏洞原理与加固方案4.1 文件包含漏洞详解与变种这道题的核心是“本地文件包含”LFI漏洞并通过伪协议升级为了“远程文件包含”RFI的效果。我们来深入拆解一下include()与require()的危险性这两个函数的本意是用于代码模块化。但当其参数完全或部分由用户控制时就极其危险。攻击者可以包含系统敏感文件如/etc/passwd包含日志文件可能写入Webshell或者如本题所示包含伪协议来执行代码。伪协议是“魔法开关”PHP内置的众多伪协议php://data://zip://phar://等极大地扩展了文件包含漏洞的利用面。php://filter可以用于读取文件源码例如php://filter/convert.base64-encode/resourceindex.phpphp://input和data://则可以直接执行代码。黑名单过滤的弊端本题的过滤是典型的“无效黑名单”。安全领域有一条铁律“黑名单永远会漏白名单才是王道”。试图过滤掉所有危险字符是不现实的总会存在绕过方法大小写、编码、嵌套、冷门协议。正确的做法是采用白名单机制只允许包含预定义的、安全的文件。例如$allowed_files [‘home.php’, ‘news.php’, ‘about.php’]; $file $_GET[‘file’]; if(in_array($file, $allowed_files)){ include($file); } else { include(‘home.php’); }4.2 从漏洞利用看安全开发要点通过这道题我们可以总结出几个对开发者至关重要的安全要点永远不要信任用户输入所有来自外部的参数GET, POST, COOKIE, Header都必须视为不可信的。在将其用于敏感操作包含文件、执行命令、查询数据库前必须进行严格的验证和过滤。使用白名单而非黑名单对于文件包含、文件上传、重定向等功能尽可能定义明确的、范围有限的允许值列表白名单。最小权限原则运行Web服务的进程如www-data用户应该只拥有完成其功能所必需的最小权限。这样即使被攻破攻击者能做的事情也非常有限。本题中如果能限制Web用户对/flag文件的读取权限攻击链也会中断。关闭危险配置在生产环境中务必在php.ini中关闭allow_url_fopen和allow_url_include。这能从根本上杜绝利用伪协议进行远程文件包含和代码执行。5. 实战演练与技巧延伸5.1 手工利用与工具辅助的平衡在CTF比赛中熟练掌握手工利用技巧至关重要它能帮助你理解漏洞的本质。就像这道题你需要手动构造HTTP请求。我推荐使用Burp Suite的Repeater模块或者命令行工具curl。使用curl完成本题利用的命令示例# 第一步探测是否可执行命令查看根目录 curl -X POST http://target_ip:port/index.php?filePHP://input --data “?php system(‘ls /’); ?” # 第二步读取flag文件 curl -X POST http://target_ip:port/index.php?filePHP://input --data “?php system(‘cat /flag’); ?”同时也要善用工具。例如在信息收集阶段dirsearch能帮你快速发现robots.txt和source.zip在代码审计时可以使用grep命令快速搜索危险函数grep -r “include\|require\|system\|exec” ./source_code/。5.2 常见变形与赛题预测这道题的模式非常常见出题人可能会在以下几个方面进行变形制造新的挑战过滤加强过滤了“php”字符串甚至使用正则表达式进行更严格的匹配。这时可能需要考虑使用其他伪协议如data://text/plain,?php system(‘ls’);?或利用zip://、phar://协议包含恶意压缩包。无源码泄露题目不提供source.zip需要你通过其他方式获取源码比如利用php://filter读取index.php本身的源码?filephp://filter/convert.base64-encode/resourceindex.php然后将返回的base64编码解码。组合漏洞文件包含漏洞可能需要结合其他漏洞才能利用。例如先通过一个SQL注入将PHP代码写入日志文件然后通过文件包含漏洞去包含这个日志文件。限制命令执行system、exec等函数被禁用。这时需要思考PHP中还有哪些可以执行代码或读写文件的函数如shell_exec()、passthru()、popen()、proc_open()或者使用反引号ls。如果全部禁用或许可以考虑用file_put_contents()写入一个Webshell。5.3 赛后复盘与技能提升路径解完一道题千万不要就此结束。有效的复盘能让你收获翻倍搭建复现环境在本地虚拟机如使用Docker快速搭建LAMP/LEMP环境中完全还原这道题的代码和环境。亲手触发漏洞观察每一步的结果。这是加深理解的最佳方式。尝试多种解法不要满足于一种payload。尝试用大小写、编码、嵌套协议等多种方式绕过过滤。思考如果过滤规则变化你的绕过方法是否依然有效。查阅官方文档去PHP官网仔细阅读include、require以及各个伪协议的文档。理解它们的设计初衷、参数和限制你会在字里行间发现更多利用可能性。关联知识体系将文件包含漏洞放入整个Web安全知识体系中。它与文件上传、代码执行、日志注入等漏洞有何关联如何形成组合拳推荐阅读《白帽子讲Web安全》等经典书籍并配合在HackTheBox、TryHackMe或国内的一些合法靶场平台进行持续性练习。这道2022年的国赛题像一块棱镜折射出Web安全基础中多个重要的知识点。它考察的不仅仅是某个漏洞的利用更是选手在面对一个黑盒系统时如何进行系统性的信息收集、逻辑推理和链条构建。对于中职乃至高职的网络安全学习者来说把这类基础题吃透、嚼烂建立起稳固的知识框架和实战思维远比盲目刷题更重要。安全之路始于足下重在基础。希望这次的解析能为你点亮一盏前行的灯。
返回列表