进入网页:
<?php
error_reporting(0);
require __DIR__ . '/vendor/autoload.php';
use GuzzleHttp\\Client;
highlight_file(__FILE__);
if(isset($_GET['flag'])) {
$client = new Client();
$response = $client->get('<http://127.0.0.1:5000/api/eligible>');
$content = $response->getBody();
$data = json_decode($content, TRUE);
if($data['success'] === true) {
echo system('/readflag');
}
}
if(isset($_GET['file'])) {
highlight_file($_GET['file']);
}
if(isset($_GET['phpinfo'])) {
phpinfo();
}
执行逻辑:
观察到代码中使用GuzzleHttp\Client组件,搜索GuzzleHttp\\Client 漏洞
,点击第一个链接。在CGI(RFC 3875)的模式的时候, 会把请求中的Header, 加上HTTP_ 前缀, 注册为环境变量, 所以如果你在Header中发送一个Proxy:xxxxxx, 那么PHP就会把他注册为HTTP_PROXY环境变量, 于是getenv("HTTP_PROXY")就变成可被控制的了. 那么如果你的所有类似的请求, 都会被代理到攻击者想要的地址,之后攻击者就可以伪造,监听,篡改你的请求了。
References
https://www.laruence.com/2016/07/19/3101.html
https://tools.ietf.org/html/rfc3875 RFC 3875
在Guzzle英文文档中,有这样一段话:
HTTP_PROXY Defines the proxy to use when sending requests using the "http" protocol. Note: because the HTTP_PROXY variable may contain arbitrary user input on some (CGI) environments, the variable is only used on the CLI SAPI. See https://httpoxy.org for more information.
References
https://docs.guzzlephp.org/en/stable/quickstart.html#environment-variables
但中文文档里面没有note之后的内容,所以我们知道我们要利用这个HTTP_PROXY漏洞,HTTP_PROXY可以使服务器发送请求到我们自己的服务器上。