RSS Feed
更好更安全的互联网

Xdebug 攻击面在 PhpStorm 上的现实利用

2018-08-29

作者: dawu@知道创宇404实验室
日期:2018/08/16

0x00 前言

在调试 Drupal 远程命令执行漏洞(CVE-2018-7600 && CVE-2018-7602)时,存在一个超大的数组 $form 。在该数组中寻找到注入的变量,可以帮助调试人员确认攻击是否成功。

但是作为一个安全研究人员,在调试时也保持着一颗发现漏洞的心,所以知道 $form 中的每一个元素的内容就十分重要了。然而 PhpStorm 这款调试工具需要不断的点击才能看到数组中各元素的值,这显然非常低效。

笔者在官方手册中发现了一种解决方案:

但是 Evaluate in Console 看上去就具有一定的危险性,所以笔者深入研究了该功能的实现过程并成功通过 PhpStormXdebug 服务器上执行了命令。

0x01 准备工作

1.1 Xdebug的工作原理和潜在的攻击面

Xdebug 工作原理和潜在的攻击面前人已有部分文章总结:

综合上述参考链接,已知的攻击面有:

  1. eval 命令: 可以执行代码。
  2. property_set && property_get 命令: 可以执行代码
  3. source 命令: 可以阅读源码。
  4. 利用 DNS 重绑技术可能可以导致本地 Xdebug 服务器被攻击。

就本文而言 PhpStormXdebug 进行调试的工作流程如下:

  1. PhpStorm 开启调试监听,默认绑定 90001013720080 端口等待连接。
  2. 开发者使用 XDEBUG_SESSION=PHPSTORM (XDEBUG_SESSION的内容可以配置,笔者设置的是PHPSTORM) 访问 php 页面。
  3. Xdebug 服务器反连至 PhpStorm 监听的 9000 端口。
  4. 通过步骤3建立的连接,开发者可以进行阅读源码、设置断点、执行代码等操作。

如果我们可以控制 PhpStorm 在调试时使用的命令,那么在步骤4中攻击面 123 将会直接威胁到 Xdebug 服务器的安全。

1.2 实时嗅探脚本开发

工欲善其事,必先利其器。笔者开发了一个脚本用于实时显示 PhpStormXdebug 交互的流量(该脚本在下文截图中会多次出现):

0x02 通过 PhpStormXdebug 服务器上执行命令

2.1 通过 Evaluate in Console 执行命令

通过上文的脚本,可以很清晰的看到我们在执行 Evaluate in Console 命令时发生了什么(红色部分是 base64 解码后的结果):

如果我们可以控制 $q,那我们就可以控制 eval 的内容。但是在 PHP 官方手册中,明确规定了变量名称应该由 a-zA-Z_\x7f-\xff 组成:

Variable names follow the same rules as other labels in PHP. A valid variable name starts with a letter or underscore, followed by any number of letters, numbers, or underscores. As a regular expression, it would be expressed thus: '[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*'

所以通过控制 $q 来控制 eval 的内容并不现实。但是在 PhpStorm 获取数组中某个元素时,会将该元素的名称带入 eval 的语句中。

如图所示,定义数组如下: $a = ( "aaa'bbb"=>"ccc"),并在 PhpStorm 中使用 Evaluate in Console 功能。

可以看到单引号未做任何过滤,这也就意味着我可以控制 eval 的内容了。在下图中,我通过对 $a['aaa\'];#'] 变量使用 Evaluate in Console 功能获取到 $a['aaa'] 的值。

精心构造的请求和代码如下:

但在这个例子中存在一个明显的缺陷:可以看到恶意的元素名称。如果用于钓鱼攻击,会大大降低成功率,所以对上述的代码进行了一定的修改:

在元素名称足够长时,PhpStorm 会自动隐藏后面的部分:

2.2 通过 Copy Value As 执行命令

继续研究发现,COPY VALUE AS (print_r/var_export/json_encode) 同样也会使用 Xdebugeval 命令来实现相应的功能:

再次精心构造相应的请求和代码后,可以再次在 Xdebug 服务器上执行命令:

2.3 实际攻击探究

基于上述的研究,我认为可以通过 PhpStorm 实现钓鱼攻击。假设的攻击流程如下:

  1. 攻击者确保受害者可以发现恶意的 PHP 文件。例如安全研究人员之间交流 某大马 具体实现了哪些功能、运维人员发现服务器上出现了可疑的 PHP 文件。
  2. 如果受害者在大致浏览 PHP 文件内容后,决定使用 PhpStorm 分析该文件。
  3. 受害者使用 COPY VALUE AS (print_r/var_export/json_encode)Evaluate array in Console 等功能。命令将会执行。
  4. 攻击者可以收到受害者 Xdebug 服务器的 shell

精心构造的代码如下(其中的反连IP地址为临时开启的VPS):

直接执行该 PHP 代码,将只会多次运行 system("echo hello world;")。但是调试人员并不会执行 PHP 代码,他也许会取出 $n[$f] 的值,然后通过 echo XXXXXXXX|base64 -d 解码出具体的内容。

如果他使用 COPY VALUE BY print_r 拷贝对应的变量,他的 Xdebug 服务器上将会被执行命令。

在下面这个 gif 中,左边是攻击者的终端,右边是受害者的 debug 过程。

(GIF中存在一处笔误: decise 应为 decide

0x03 结语

在整个漏洞的发现过程中,存在一定的曲折,但这也正是安全研究的乐趣所在。PhpStorm 官方最终没有认可该漏洞,也是一点小小的遗憾。在此将该发现分享出来,一方面是为了跟大家分享思路,另一方面也请安全研究人员使用 PhpStorm 调试代码时慎用 COPY VALUE AS (print_r/var_export/json_encode)Evaluate array in Console 功能。

0x04 时间线

2018/06/08: 发现 Evaluate in Console 存在 在 Xdebug 服务器上 执行命令的风险。
2018/06/31 - 2018/07/01: 尝试分析 Evaluate in Console 的问题,发现新的利用点 Copy Value. 即使 evalXdebug 提供的功能,但是 PhpStorm 没有过滤单引号导致我们可以在 Xdebug 服务器上执行命令,所以整理文档联系 security@jetbrains.com
2018/07/04: 收到官方回复,认为这是 Xdebug 的问题,PhpStorm 在调试过程中不提供对服务器资源的额外访问权限。
2018/07/06: 再次联系官方,说明该攻击可以用于钓鱼攻击。
2018/07/06: 官方认为用户在服务器上运行不可信的代码会造成服务器被破坏,这与 PhpStorm 无关,这也是 PhpStorm 不影响服务器安全性的原因。官方同意我披露该问题。

2018/08/16: 披露该问题。


Paper 本文由 Seebug Paper 发布,如需转载请注明来源。本文地址:https://paper.seebug.org/668/

作者:Nanako | Categories:安全科普技术分享 | Tags:

发表评论