实验环境:https://portswigger.net/web-security/request-smuggling
这里把原版翻译(机翻)一下,再附上解题过程
1.什么是HTTP请求走私?
HTTP请求走私是一种干扰网站处理从一个或多个用户接收的HTTP请求序列的方式的技术。请求走私漏洞在本质上通常是至关重要的,允许攻击者绕过安全控制,获得对敏感数据的未经授权的访问,并直接危害其他应用程序用户。
注
http请求走私最早记录在2005年,最近又由portswigger研究关于这个话题。
2.HTTP请求走私攻击会发生什么?
今天的Web应用程序经常在用户和最终应用程序逻辑之间使用HTTP服务器链。用户将请求发送到前端服务器(有时称为负载均衡器或反向代理),此服务器将请求转发给一个或多个后端服务器。这种架构在现代基于云的应用程序中越来越普遍,在某些情况下是不可避免的。
当前端服务器将HTTP请求转发到后端服务器时,通常会通过相同的后端网络连接发送多个请求,因为这样做的效率和性能要高得多。协议非常简单:一个接一个地发送HTTP请求,接收服务器解析HTTP请求头,以确定一个请求的结束位置和下一个请求开始的位置:
在这种情况下,前端和后端系统必须就请求之间的边界达成一致。否则,攻击者可能会发送由前端系统和后端系统不同解释的模糊请求:
在这里,攻击者将其前端请求的一部分由后端服务器解释为下一个请求的开始。它有效地优先于下一个请求,因此可能会干扰应用程序处理该请求的方式。这是一次请求走私攻击,可能会造成毁灭性的后果。
3.HTTP请求走私漏洞是如何产生的?
大多数HTTP请求走私漏洞的出现是因为HTTP规范提供了两种不同的方法来指定请求的结束位置:内容长度头和传输编码头球。
这个内容长度标头很简单:它指定消息体的长度(以字节为单位)。例如:
POST /search HTTP/1.1
Host: normal-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 11
q=smuggling
这个传输编码标头可用于指定消息主体使用分组编码。这意味着消息体包含一个或多个数据块。每个块包含以字节为单位的块大小(以十六进制表示),后面是换行符,后面是块内容。消息以0大小的块结束。例如:
POST /search HTTP/1.1
Host: normal-website.com
Content-Type: application/x-www-form-urlencoded
Transfer-Encoding: chunked
b
q=smuggling
0
注
许多安全测试人员不知道可以在HTTP请求中使用分组编码,原因有二:
- Burp Suite自动解压分组编码,使消息更易于查看和编辑。
- 浏览器通常不会在请求中使用分块编码,而且通常只在服务器响应中看到。
如果前端服务器和后端服务器的行为与传输编码标头,那么它们可能在连续请求之间的边界上存在分歧,从而导致请求走私漏洞。
4.如何执行HTTP请求走私攻击
请求走私攻击包括将内容长度头和传输编码报头进入单个HTTP请求并对这些请求进行操作,以便前端服务器和后端服务器处理请求的方式不同。具体的方式取决于这两个服务器的行为:
- CL.TE:前端服务器使用内容长度头和后端服务器使用传输编码头球。
- TE.CL:前端服务器使用传输编码头和后端服务器使用内容长度头球。
- TE.TE:前端和后端服务器都支持传输编码头,但其中一台服务器可以通过某种方式混淆报头,从而避免对其进行处理。
5.CL.TE漏洞
在这里,前端服务器使用内容长度头和后端服务器使用传输编码头球。我们可以执行以下简单的HTTP请求走私攻击:
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 13
Transfer-Encoding: chunked
0
SMUGGLED
前端服务器处理内容长度标头,并确定请求正文长度为13字节,直到走私...此请求被转发到后端服务器。
后端服务器处理传输编码标头,因此将消息体视为使用块编码。它处理第一个块,它声明为零长度,因此被视为终止请求。以下字节,走私,而后端服务器将将其视为序列中下一个请求的开始。
下面开始解题:
打开题目后:
然后点击Access the lab开启实验环境
用burp拦截一下访问主页的请求
直接发送到Reperter然后右键变更请求方法,把方法变成POST
因为是CL.TE的题目
所以前端服务器认CL,而后端服务器认TE那么把包体改一下
Content-Length的话burp会自动帮我们改的,Transfer-Encoding: chunked需要我们自己加上
然后当我们请求发送到前端服务器的时候,前端服务器人CL,认为这是一整个的包,直接发送给后端,后端服务器人TE,认为这是一个分块传输的包,读到包体中的0然后又读到两个空行,认为一个请求结束了,对请求做出响应,然后后端服务器的缓冲区里还留下了一个G,这个G就会留在缓冲区里(通常10s后会过期)和下一个请求拼接到一起
我们直接发包两次,第一次进行HTTP走私,第二次模拟正常用户
第一次发包后会得到正常的响应,但是第二次会得到
Unrecognized method GPOST
就是因为第一次请求留下的G和第二次请求头的POST拼接到了一起导致的
6.TE.CL漏洞
在这里,前端服务器使用传输编码头和后端服务器使用内容长度头球。我们可以执行以下简单的HTTP请求走私攻击:
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 3
Transfer-Encoding: chunked
8
SMUGGLED
0
注
要使用BurpRepeater发送此请求,首先需要转到Repeater菜单,并确保未选中“UpdateContent-Length”选项。
您需要包含尾随序列0后面的r\n\r\n.
前端服务器处理传输编码标头,因此将消息体视为使用块编码。它处理第一个块,它被声明为8个字节长,直到下面一行的开头走私...它处理第二个块,它声明为零长度,因此被视为终止请求。此请求被转发到后端服务器。
后端服务器处理内容长度标头,并确定请求体长度为3字节,直到下面一行的开头8...以下字节,以走私,而后端服务器将将其视为序列中下一个请求的开始。
点击Access the lab打开实验环境后,用burp抓一个访问首页的包,右键发送到Repeater,然后右键变更请求方法把GET变成POST方法
因为这次是TE.CL方式的题目
所以前端服务器认Transfer-Encoding,后端服务器人Content-Length
把包体改成这样
改成这样是方便测试是不是能成功测试这个漏洞
发送两次后
好的,这个形式是可以的利用漏洞的
这个包发送到前端服务器后,前端服务器认TE,认为这是一个分块传输的包,先识别1(十六进制)然后读取1个字符,再识别0和其后面的\r\n\r\n认为请求结束,就发送给后端了,后端收到包后认CL一看CL是3就读取了3个字符(1\r\n),然后认为包结束了,那G\r\n0\r\n\r\n就留在后端服务器的缓冲区里面了就会与下一次的请求拼接到一起了形成
Unrecognized method G0POST
但是题目要求我们实现GPOST
那就自己伪造请求头吧
这里55是十六进制的数,代表了55下面一行到0上面一行这之间的字符数量,我这里就是
GPOST / HTTP/1.1\r\nHost: ac531f741fc6086980080ac6000c004a.web-security-academy.net\r\n\r\n
这个数量可能不好计算,我写了个python3的代码,可以参考一下
# 专门用来计算chunked的长度
# 用在TE.CL模式的 第一个分块的长度计算
# 请把你的内容放在第三个双引号后面 a = """"""
a = """GPOST / HTTP/1.1
Host: ac531f741fc6086980080ac6000c004a.web-security-academy.net
"""
# a = """"""
n_num = 0
for i in a:
if i == '\n':
n_num += 1
print(hex(len(a) + n_num)[2:])
7. TE.TE行为:混淆TE头
在这里,前端服务器和后端服务器都支持传输编码头,但其中一台服务器可以通过某种方式混淆报头,从而避免对其进行处理。
有潜在的无穷尽的方法来混淆传输编码头球。例如:
1
Transfer-Encoding: xchunked
2
Transfer-Encoding : chunked
3
Transfer-Encoding: chunked
Transfer-Encoding: x
4
Transfer-Encoding:[tab]chunked
5
[space]Transfer-Encoding: chunked
6
X: X[\n]Transfer-Encoding: chunked
7
Transfer-Encoding
: chunked
据我测试6和7是不支持的,1、2、5对于本题是不能用的,4不能用来解题,3可以
这些技术中的每一种都涉及到与HTTP规范的微妙背离。实现协议规范的真实世界代码很少以绝对精确的方式依附它,而且不同的实现通常会容忍与规范不同的变化。要发现TEt.E漏洞,必须找到传输编码标头,使得只有一个前端或后端服务器处理它,而另一个服务器忽略它。
取决于可以诱导不处理模糊处理的是前端服务器还是后端服务器。传输编码标头时,其余的攻击将采取与前面描述的CL.TE或TE.CL漏洞相同的形式。
这个题目是前端会被混淆,后端不会被混淆
前端看到
Transfer-Encoding:chunked
Transfer-encoding:cow
认为这还是TE型的包,
但是后端服务器认为这不对劲,应该按照CL格式来看
连发两次,成功
下篇:Finding HTTP request smuggling vulnerabilities - 查找HTTP请求走私漏洞