前言

HTTP Desync Attacks也就是HTTP走私攻击,是我见到的比较有趣的一种攻击方式,这里来对这种漏洞进行介绍。

TL;DR

HTTP走私攻击利用了HTTP协议本身的问题:HTTP中存在两种方式来指定请求的结束位置。因此,相同的HTTP请求,不同的服务器可能会产生不同的处理结果,这样就产生了了安全风险。

具体分析

HTTP/1.1

在HTTP协议中,存在两种Header来指定请求的结尾,分别是Content-Length以及Transfer-Encoding。Content-Length用来指明发送给接收方的消息主体的大小,后面的数字就代表了这个消息的大小;Transfer-Encoding指明了将实体安全传递给用户所采用的编码形式,常见的值有chunked,compress,deflate,gzip等,其中chunk表示消息体使用分块编码(Chunked Encode),也就是整个请求会分块发送,由多个消息组成,整个消息体以大小为0的块结束,也就是说解析遇到0数据块就结束,因此带来了一种新的判断结尾的方式。
这两个Header都源于RFC 7230也就是HTTP/1.1,在之前的版本中HTTP协议规定浏览器与服务器只保持短暂的连接,服务器完成请求即断开连接。显然,这种方式是有问题的,因此HTTP 1.1支持持久连接,在一个TCP连接上可以传送多个HTTP请求和响应。同时这个规范也带来了Content-Length以及Transfer-Encoding这两个Header,虽然协议明确说明以Transfer-Encoding为准,但是仍然存在很多服务器没有完全遵守规范,从而导致不同的服务器对结尾的判断不同,也就导致了这种漏洞。

CDN和代理

其实该漏洞早在2005年就有人提出,不过随着内容分发网络(CDN)的兴起,CDN本质上是一个反向代理,缓存了大量的静态网站数据,如果用户访问静态数据,直接从代理服务器中就可以获取到,不用再从源站所在服务器获取,从而提高访问速度并且降低网络拥塞,一个典型的CDN结构如下图:

可以看出,CDN的出现,使得大量用户会先访问CDN服务器,CDN服务器会判断是否有动态请求或者没有命中缓存的情况,如果存在,CDN会先代替用户请求,最后将封装好的请求返回给用户。可以看到,如果请求一个动态内容如查询等,CDN此时相当于一个代理,会讲用户的请求发送给服务器,如果这两者没有正确处理结尾,就会导致HTTP走私的出现。当下CDN的大量使用使得这种漏洞的重新兴起。

分类

我们可以将这种情况抽象为前端和后端两种服务器,根据前后服务器处理方式的差异,HTTP走私共分为三种:
– CLTE:前端服务器使用 Content-Length 头,后端服务器使用 Transfer-Encoding 头
– TECL:前端服务器使用 Transfer-Encoding 标头,后端服务器使用 Content-Length 标头。
– TETE:前端和后端服务器都支持 Transfer-Encoding 标头,但是可以通过以某种方式来诱导其中一个服务器不处理它。

CLTE

对于CLTE类型,如果构造如下请求,由于pipeline特性,会导致下一个请求的开头多了个PP

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
pp

前端由于是从Content-Length获取结尾,因此会讲全部作为一个包发送,但后端会在0处截断,从而导致认为pp是下一个包的开始,导致下一个请求的开头多了个pp

CL/CL

CLCL是构造一个包含两个Content-Length的包,根据规范此时应当返回400错误,但如果没有正确遵守规范,且前端按不同的CL进行处理,这可能会导致HTTP走私,例子如下:

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

该例子的过程和上一节类似

TE/TE

该种方式是前后端服务器都支持并且默认使用te来处理,使用某种方式导致一端不识别te块来达到,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
aPOST / 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,E的大小写不同,因此可能导致识别的不同。

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
aPOST / HTTP/1.1\r\n
\r\n
0\r\n
\r\n

前端全读,后端只读一部分

DEFCON CTF QUAL 2020 uploooadit

该题给了两个接口,一个是POST /文件/,该接口用于上传文件,会返回文件的id。另一个是GET /files/<guid>,该接口用于请求保存的文件。
同时我们可以看到前端服务器是一个haproxy 1.9.10,后端是Flask。
通过测试发现存在CL/TE类型的HTTP Desync,因此构造

这个的解析流程是,haproxy看到了187,便将整个请求发送给了后端,而后端只看TE,因此在0处截断,并将后面的内容看作第二个包,后面的部分只有CL,因此后端会继续读内容知道达到385长度为止,如果此时有别人传文件,文件内容会被我们的2aaaaa-aaaaa-aaaaa-aaaaaaaaaa读取到。
这个题目是存在一个不断上传flag的机器人,因此我们只要一直发送这样的包,读取我们上传的文件,就有可能获取到机器人上传的内容,最后我们GET /files/2aaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa,读取到了机器人上传的flag

总结

HTTP走私是源于服务端没有正确按照HTTP规范行事从而导致的漏洞,因此解决方案也很简单,按照HTTP/1.1规范正确处理请求,或者尽量避免服用连接就可以解决该漏洞。

这可能是最详细的解析HTTP走私攻击的文章的更多相关文章

  1. java连接mysql数据库详细步骤解析

    java连接mysql数据库详细步骤解析      第一步:下载一个JDBC驱动包,例如我用的是:mysql-connector-java-5.1.17-bin.jar      第二步:导入下载的J ...

  2. centos7安装zabbix3.0超详细步骤解析

    centos7安装zabbix3.0超详细步骤解析 很详细,感谢作者 以下是我操作的history 622 java -version 623 javac -version 624 grep SELI ...

  3. virsh的详细命令解析(一)

    virsh的详细命令解析 virsh 有命令模式和交互模式如果直接在vrish后面添加参数是命令模式,如果直接写virsh,就会进入交互模式 virsh list 列出所有的虚拟机,虚拟机的状态有(8 ...

  4. loam详细代码解析与公式推导

    loam详细代码解析与公式推导(基础理论知识) 一.基础坐标变换 loam中欧拉角解算都采用R P Y 的解算方式,即先左乘R, 再左乘P, 最后左乘Y,用矩阵表示为: R = Ry * Rp * R ...

  5. webpack详细配置解析

    阅读本文之前,先看下面这个webpack的配置文件,如果每一项你都懂,那本文能带给你的收获也许就比较有限,你可以快速浏览或直接跳过:如果你和十天前的我一样,对很多选项存在着疑惑,那花一段时间慢慢阅读本 ...

  6. 超详细JSON解析步骤

    JSON简介 JAVAScript Object Notation是一种轻量级的数据交换格式 具有良好的可读和便于快速编写的特性. 业内主流技术为其提供了完整的解决方案(有点类似于正则表达式 ,获得了 ...

  7. 超级详细通信协议解析webservice和dubbo通信协议区别

    简单说下接触webservice的背景吧,因为之前的接口对接更多的是成熟的接口品牌像是阿里巴巴.腾讯.聚合数据等,他们接口规范一般都是基于restful进行接口对接.什么是restful接口,可以通过 ...

  8. Swift 实现俄罗斯方块详细思路解析(附完整项目)

    一:写在开发前 俄罗斯方块,是一款我们小时候都玩过的小游戏,我自己也是看着书上的思路,学着用 Swift 来写这个小游戏,在写这个游戏的过程中,除了一些位置的计算,数据模型和理解 Swift 语言之外 ...

  9. ps 命令的详细功能解析

    转自:http://www.cnblogs.com/wangkangluo1/archive/2011/09/23/2185938.html 要对进程进行监测和控制,首先必须要了解当前进程的情况,也就 ...

随机推荐

  1. linux创建逻辑卷(lv)并挂载

    新加磁盘启动系统后,查看现有磁盘使用情况 命令 df -h 查看现有磁盘情况,我们发现系统已经有一个10G的磁盘sdb,这个磁盘共有1305个柱面,每个柱面大小是8225280 bytes (大约8M ...

  2. PHP array_replace_recursive() 函数

    实例 递归地使用第二个数组($a2)的值替换第一个数组($a1)的值: <?php$a1=array("a"=>array("red")," ...

  3. Skill 脚本演示 ycLayerExcel.il

    https://www.cnblogs.com/yeungchie/ ycLayerExcel.il 用于 Tape-out 流程,获取当前用到的所有 lpp 等信息,并按照自定格式输出为 Excel ...

  4. 电脑小知识:Windows 10是用什么语言写的?到底有多少行代码?

    这是微软的内核工程师 Axel Rietschin在Quora的一个回答. Windows 10 的code base 和Windows 8.x , 7 , Vista , XP , 2000 和Wi ...

  5. 5.21 省选模拟赛 luogu P4297 [NOI2006]网络收费 树形dp

    LINK:网络收费 还是自己没脑子. 早上思考的时候 发现树形dp不可做 然后放弃治疗了. 没有合理的转换问题的模型是我整个人最大的败笔. 暴力也值得一提 爆搜之后可以写成FFT的形式的计算贡献的方法 ...

  6. layui 父页面获取弹窗传递的值 和 父页面传值给子弹窗的方法

    1.父页面获取子页面(弹窗)的值: 现在父页面页面加载方法中定义方法,专门用来获取从子页面的值 $(document).ready(function() { //拿到子窗口中传回的数据 functio ...

  7. 删除数据-大表根据rowid来删除部分数据

    偶遇需求,大表中需要删除部分数据.分批删除. declare TYPE type_table_rowid IS TABLE OF ROWID INDEX BY BINARY_INTEGER;table ...

  8. LVS-DR:搭建HTTP和HTTPS负载均衡集群

    目录 LVS-DR实战:搭建HTTP和HTTPS负载均衡集群 1. 搭建lvs-dr模式的http负载集群 1.1 LVS上配置IP 1.2 RS上配置arp内核参数 1.3 RS上配置VIP 1.4 ...

  9. day10.函数基础及函数参数

    一.函数 功能:包裹一部分代码 实现某一个功能 达成某一个目的 特点: """ 特点:可以反复调用,提高代码的复用性,提高开发效率,便于维护管理 函数基本格式 函数的定义 ...

  10. 【BZOJ4398】福慧双修 题解(建图优化)

    题目链接 题目大意:给定一张$n$个点$m$条边的无向图,每条边两个方向的权值不一定相同.问从$1$出发不重复走一条边回到$1$的最短路径. ------------------- 暴力不太会.大概是 ...