Skip to content
Kurisu
Go back

PHP 调试实战:Xdebug + VSCode 单步跟踪 ThinkPHP 反序列化链

看 PHP 漏洞代码光看源码很容易看晕——调用栈深、魔术方法乱跳。我的解法是把调试环境搭起来单步跟,变量怎么变、链子怎么走一目了然。这篇是我搭 Xdebug 环境和用它跟踪 ThinkPHP 反序列化链的记录。

环境清单

组件版本/说明
phpStudyPHP 7.3 + 自带 Xdebug 扩展
靶场ThinkPHP 5.1.29(tpdemo5129),跑在 8002 端口
编辑器VSCode + PHP Debug 扩展(xdebug.php-debug)
调试点127.0.0.1:8002/index/index/index?c=<payload>

Xdebug 配置

php.ini 里的关键几行(Xdebug 3.x 写法):

[Xdebug]
zend_extension=xdebug
xdebug.mode = debug
xdebug.client_host = 127.0.0.1
xdebug.client_port = 9000
xdebug.start_with_request = yes

start_with_request = yes 表示每个请求都尝试连调试器——调试期方便,平时记得关。

VSCode 侧

launch.json 只需要一个 Listen for Xdebug 配置,端口对到 9000。启动监听后,浏览器(或 curl)发请求,Xdebug 就会主动连过来。

验证连通性的土办法:抓包看 dbgp 握手——监听起来后第一个数据包是 Xdebug 发的 <init ...> XML,看到这个就说明链路通了。我第一次配的时候端口被别的进程占了,半天没反应,就是靠抓包定位的。

实战:单步跟踪 TP 5.1.29 反序列化链

入口 payload 触发 unserialize() 后,我在三个关键位置下断点:

Windows.php:163        __destruct() 里 removeFiles() 的调用点
Request.php:331        魔术方法跳板
Conversion.php:192     __toString() 最终拼接点

跟踪过程里真正值钱的观察:

  1. __destruct 不是起点而是引爆点:对象销毁时自动触发,POP 链的第一环从这里挂上。
  2. 变量在哪一步被污染:单步到 removeFiles() 时 watch 窗口能直接看到攻击者控制的属性值流进文件操作函数。
  3. 跳板方法的寻找思路:在调用处”步入”几次就能摸清这条链为什么选这几个类——每个跳板都只是”把可控属性传给下一个魔术方法”。

跟完一遍之后再看 POP 链的 payload 构造,就不是背链子,而是知道每一环为什么这么串

踩坑

小结

源码审计 + 动态调试是两条腿:审计帮你猜链子在哪儿,调试帮你验证链子怎么走。这套环境搭一次大概二十分钟,之后所有 PHP 漏洞分析都能复用。


Share this post:

Previous Post
SRC 信息收集自动化工具:从 2 小时到 30 分钟
Next Post
安全防御实战:我用雷池 WAF + 蜜罐 + 主机加固守住自己的服务器