Burp Web Academy HTTP 请求走私
0x01. PortSwigger Web Security Academy
PortSwigger Web Security Academy 是 Burp Suite 官方推出的免费 Web 安全学习靶场,在学习 Web 安全知识的同时,还可以练习 Burp Suite 的实战技能。
本篇文章讲解 Web Security Academy 之中的 HTTP 请求走私(HTTP Request Smuggling)章节。
0x02. HTTP 请求走私
2.1 Lab: HTTP request smuggling, confirming a CL.TE vulnerability via differential responses
This lab involves a front-end and back-end server, and the front-end server doesn’t support chunked encoding.
To solve the lab, smuggle a request to the back-end server, so that a subsequent request for
/
(the web root) triggers a 404 Not Found response.
第一次学习 HTTP 请求走私,直接看官方答案解题:尽管题目已经提示前端服务器不支持 Transfer-Encoding
,但我们还是按照常规思路测试一下。发送如下 POST 请求(注意,在 Burp Repeater 中,要在 Inspector 中把 HTTP 协议设置为 HTTP/1
):
1 | POST / |
注意这里的 BODY 内容为 2\r\nab
共 5
字节数据,对 Content-Length
而言是正确的,但是对于 Transfer-Encoding
而言是错误的。因此,可以根据服务器的返回状态来判断:
- 如果正常返回,表明是 CL-CL(发送
2\r\nab
共5
字节数据,和Content-Length
匹配) - 如果提示超时,表明是 CL-TE,前端服务器正常转发
2\r\nab
,后端服务器则没有等到Transfer-Encoding
的结束标志0\r\n\r\n
- 如果请求被拒绝,那么有两种可能(在前端服务器因为
Transfer-Encoding
不正确被拦截)- TE-TE
- TE-CL
测试下来,服务器返回 500
提示超时,因此是 CL-TE。
1 | 500 Internal Server Error |
先发送如下 POST 请求:
1 | POST / |
注意 BODY 内容为 0\r\n\r\nGET /404 HTTP/1.1\r\nX-Ignore: X
共 35
字节数据,因此前端服务器正常转发数据,而后端服务器则按照 Transfer-Encoding: chunked
来解析数据,因此 GET /404 HTTP/1.1\r\nX-Ignore: X
会被当做第二个请求的开头部分。注意,X-Ignore: X
末尾没有 \r\n
,这是为了屏蔽下一个正常请求的 GET
行,以便服务器认为请求行是 GET /404 HTTP/1.1
。
因此,接下来发送一个正常的 GET
请求,即可触发服务器返回 404
了,请求会拼接如下:
1 | GET /404 |
2.2 Lab: HTTP request smuggling, confirming a TE.CL vulnerability via differential responses
This lab involves a front-end and back-end server, and the back-end server doesn’t support chunked encoding.
To solve the lab, smuggle a request to the back-end server, so that a subsequent request for
/
(the web root) triggers a 404 Not Found response.
前面总结了一套测试方法,但是对于后端服务器使用哪个字段还无法确定,其实也是可以测试出来的:
- Payload:CL 正确 + TE 错误
- 正常返回,表明前端服务器、后端服务器均使用 CL
- 返回 5XX 提示超时,表明前端服务器使用 CL,后端服务器使用 TE
- 返回 4XX,表示请求被拒绝,表明前端服务器使用 TE,后端服务器需要进一步测试
- Payload:TE 正确 + CL 错误
- 正常返回,表明后端服务器使用 TE
- 提示超时,表明后端服务器使用 CL
- Payload:TE 正确 + CL 错误
因此,我们可以测试出来题目中提示的 TE-CL 场景。同时,Burp Repeater 默认会自动更新 Content-Length
字段,因此在测试时需要取消该设置。
发送如下 POST 请求:
1 | POST / |
首先,对 Transfer-Encoding: chunked
而言这个请求是合法的,因此前端服务器可以正常将请求转发给后端服务器。而对后端服务器而言,Content-Length: 4
导致第二个 POST
被当作下一个请求处理。需要注意的是,第二个 Content-Length
字段一定要设置的比实际的数据大,这样这个请求才是不完整的,需要等到用户真正发送第二个请求时,后端服务器才会在 Content-Length
指定的数据读取完毕时返回 404
。
2.3 Lab: Exploiting HTTP request smuggling to bypass front-end security controls, CL.TE vulnerability
This lab involves a front-end and back-end server, and the front-end server doesn’t support chunked encoding. There’s an admin panel at
/admin
, but the front-end server blocks access to it.To solve the lab, smuggle a request to the back-end server that accesses the admin panel and deletes the user
carlos
.
前端服务器对 URL 有权限检查,但是不支持 TE 字段。
直接访问 /admin
,会返回 403
并提示 "Path /admin is blocked"
。
1 | 403 Forbidden |
先发送 CL-TE Payload 请求:
1 | POST / |
然后发送正常的 GET /
请求,返回 401
并提示 Admin interface only available to local users
。看来还要模拟成本地用户来访问,需要改进 Payload:
- 尝试
X-Forwarded-For: 127.0.0.1
,不行 - 尝试
X-Forwarded-Host: localhost
,也不行 - 尝试
Host: localhost
,可以,但是为了屏蔽后续的 Host 字段,需要改成POST
请求发送
1 | POST / |
然后发送正常的 GET /
请求,即可看到页面的 HTML 代码:
1 | <section> |
删除 carlos
用户只需要请求 /admin/delete?username=carlos
即可,为了方便还是发送 POST
请求,新的 Payload 代码如下:
1 | POST / |
之后发送任意一个 HTTP 请求,即可删除 carlos
用户。
2.4 Lab: Exploiting HTTP request smuggling to bypass front-end security controls, TE.CL vulnerability
This lab involves a front-end and back-end server, and the back-end server doesn’t support chunked encoding. There’s an admin panel at
/admin
, but the front-end server blocks access to it.To solve the lab, smuggle a request to the back-end server that accesses the admin panel and deletes the user
carlos
.
跟前一个题目差不多,先构造如下请求访问 /admin
页面:
1 | POST / |
然后删除 carlos
用户:
1 | POST / |
2.5 Lab: Exploiting HTTP request smuggling to reveal front-end request rewriting
This lab involves a front-end and back-end server, and the front-end server doesn’t support chunked encoding.
There’s an admin panel at
/admin
, but it’s only accessible to people with the IP address 127.0.0.1. The front-end server adds an HTTP header to incoming requests containing their IP address. It’s similar to theX-Forwarded-For
header but has a different name.To solve the lab, smuggle a request to the back-end server that reveals the header that is added by the front-end server. Then smuggle a request to the back-end server that includes the added header, accesses the admin panel, and deletes the user
carlos
.
前端服务器不支持 Transfer-Encoding
,且前端服务器会增加一个类似 X-Forwarded-For
的字段,用来标识 IP 地址。
访问漏洞站点,发现存在一个搜索框,尝试搜索:
1 | POST / |
可以确认会有关键字回显,POST 请求发送给 /
,但是通过 search=
来指明关键字。我们可以借助这个接口来回显前端服务器增加的字段:
1 | POST / |
注意第二个 Content-Length
的大小设置,具体依赖于下一个请求的大小,只有合适的值才能既可回显字段,又不至于 Timeout。
1 | GET /111 |
之后,可以看到回显的内容(字段为 X-IUXfpE-Ip
):
1 | <h1> |
至此,解题思路和前面的题目就差不多了。
首先,构造如下请求访问 /admin
页面:
1 | POST / |
其次,构造如下请求删除 carlos
用户:
1 | POST / |
2.6 Lab: Exploiting HTTP request smuggling to capture other users’ requests
This lab involves a front-end and back-end server, and the front-end server doesn’t support chunked encoding.
To solve the lab, smuggle a request to the back-end server that causes the next user’s request to be stored in the application. Then retrieve the next user’s request and use the victim user’s cookies to access their account.
- The lab simulates the activity of a victim user. Every few POST requests that you make to the lab, the victim user will make their own request. You might need to repeat your attack a few times to ensure that the victim user’s request occurs as required.
前端服务器不支持 Transfer-Encoding
,需要通过 HTTP 请求走私来存储其他用户的 HTTP 请求,以窃取其 Cookie
- 有什么方法可以回显/存储其他用户的请求呢?初步推断是文章评论
- 每发送一定的 POST 请求,系统会自动模拟其他用户发送 HTTP 请求
不断间歇性尝试发送如下请求,直到在评论区看到 Victim 的 Cookie:
1 | POST / |
同样,需要注意第二个 Content-Length
的大小设置,只有合适的值才能既可回显 Cookie 字段,又不至于 Timeout。
最后发送如下 GET
请求完成解题:
1 | GET /my-account |
2.7 Lab: Exploiting HTTP request smuggling to deliver reflected XSS
This lab involves a front-end and back-end server, and the front-end server doesn’t support chunked encoding.
The application is also vulnerable to reflected XSS via the
User-Agent
header.To solve the lab, smuggle a request to the back-end server that causes the next user’s request to receive a response containing an XSS exploit that executes
alert(1)
.
- The lab simulates the activity of a victim user. Every few POST requests that you make to the lab, the victim user will make their own request. You might need to repeat your attack a few times to ensure that the victim user’s request occurs as required.
前端服务器不支持 Transfer-Encoding
,且 User-Agent
存在反射性 XSS 漏洞。随便打开一篇文章,查看评论区表单属性,发现存在 userAgent
隐藏字段:
1 | <input required="" type="hidden" name="userAgent" value="Mozilla/5.0 (Windows NT 10.0; Win64; x64)"> |
首先,需要测试 XSS Payload,发送如下请求:
1 | GET /post?postId=3 |
返回的 HTML 内容如下:
1 | <input required type="hidden" name="userAgent" value=""> |
成功注入了 JavaScript 代码,可以通过 Show response in browser
验证,成功弹出 JavaScript 对话框。
现在,需要通过 HTTP 请求走私漏洞,来改写下一个请求的 User-Agent 字段,发送如下 Payload:
1 | POST / |
注意,主要直接 POST /post?postId=3
,这样的请求会提示不允许,评论的请求是 POST /post/comment
。不过,评论本身还有隐藏的 userAgent
表单字段,这个需要先发送 GET 请求,就稍微有点复杂了。直接尝试发送 GET
请求,发现即使可能存在两个 User-Agent
字段,但还是可以进行 XSS 弹窗。
0x03. 小结
- HTTP Request Smuggling 只对 HTTP/1 有效,因此需要在 Burp Repeater 中设置好 HTTP 协议版本
- Burp Repeater 默认会自动更新
Content-Length
字段,在测试 HTTP Request Smuggling 漏洞时,需要取消 CL 的自动设置Content-Length
字段的值非常重要,既要能达到泄露数据的目的,又不能导致 Timeout
- 根据服务器的返回信息来判断 HTTP Request Smuggling 漏洞类型,全部四种类型都是可以确认的
- 基于 HTTP Request Smuggling 漏洞,可以绕过前端服务器的权限检查
- 注意
X-Forwarded-For
、X-Forwarded-Host
以及Host
- 注意
- 基于 HTTP Request Smuggling 漏洞,走私 GET、POST 请求的方法
- 仔细观察漏洞站点的特性,重复利用已有的功能特性来协助达成目标