当前位置: 首页 > news >正文

缓存投毒进阶 -- justctf 2025 Busy Traffic

题目核心逻辑如下

let browser; // 全局浏览器实例// 访问指定 URL 的异步函数
const visit = async (url) => {try {// 如果已有浏览器实例,先关闭并等待 2 秒if (browser) {await browser.close();await sleep(2000);console.log("Terminated ongoing job.");}// 启动 puppeteer,使用 chrome,无头模式browser = await puppeteer.launch({browser: 'chrome',headless: true,args: ["--disable-features=HttpsFirstBalancedModeAutoEnable","--no-sandbox"]});// 创建新的浏览器上下文const ctx = await browser.createBrowserContext();// 新建页面,访问 flag 页面并设置 localStoragepage = await ctx.newPage();await page.goto(`http://traefik/flag`, { timeout: 3000, waitUntil: 'domcontentloaded' });await page.evaluate((flag) => {localStorage.setItem('flag', flag); // 将 flag 存入 localStorage}, FLAG);await sleep(500); // 等待 0.5 秒await page.close(); // 关闭页面// 新建页面,访问用户提交的 URLpage = await ctx.newPage();await page.goto(url, { timeout: 3000, waitUntil: 'domcontentloaded' });await sleep(1000 * 60 * 2); // 停留 2 分钟await browser.close(); // 关闭浏览器browser = null;} catch (err) {// 捕获并打印异常console.log(err);} finally {// 最终关闭浏览器并打印日志console.log('close');if (browser) await browser.close();}
};
http:routers:bot:rule: 'PathPrefix(`/bot`)'service: botdashboard:rule: "PathPrefix(`/dashboard`) || PathPrefix(`/api`)"service: api@internalservices:bot:loadBalancer:servers:- url: "http://bot:3000"middlewares:cache-on-steroids:plugin:plugin-simplecache:path: /tmp/CacheQueryParams: Truemaxage:headers:customResponseHeaders:Cache-Control: "max-age=20"coop:headers:customResponseHeaders:Cross-Origin-Opener-Policy: "same-origin"
log:level: INFOaccessLog: {}entryPoints:web:address: ":80"http:middlewares:- maxage- coop- cache-on-steroidsproviders:file:filename: /config/dynamic.ymlapi:dashboard: trueexperimental:plugins:plugin-simplecache:moduleName: "github.com/scrazy77/plugin-simplecache-nocache"version: "v0.0.5"

服务器使用了此插件,插件存在默认不安全行为,忽略查询参数作为缓存判断的关键

// Config 配置中间件的结构体。
type Config struct {Path               string   `json:"path" yaml:"path" toml:"path"`                         // 缓存文件存储路径MaxExpiry          int      `json:"maxExpiry" yaml:"maxExpiry" toml:"maxExpiry"`          // 缓存最大过期时间(秒)Cleanup            int      `json:"cleanup" yaml:"cleanup" toml:"cleanup"`                // 清理周期(秒)AddStatusHeader    bool     `json:"addStatusHeader" yaml:"addStatusHeader" toml:"addStatusHeader"` // 是否添加缓存状态头CacheQueryParams   bool     `json:"cacheQueryParams" yaml:"cacheQueryParams" toml:"cacheQueryParams"` // 是否缓存查询参数ForceNoCacheHeader bool     `json:"forceNoCacheHeader" yaml:"forceNoCacheHeader" toml:"forceNoCacheHeader"` // 是否强制添加 no-cache 头BlacklistedHeaders []string `json:"blacklistedHeaders" yaml:"blacklistedHeaders" toml:"blacklistedHeaders"` // 黑名单头部,命中则不缓存
}// CreateConfig 返回一个默认配置实例。
func CreateConfig() *Config {return &Config{MaxExpiry:          int((5 * time.Minute).Seconds()), // 默认最大过期时间5分钟Cleanup:            int((5 * time.Minute).Seconds()), // 默认清理周期5分钟AddStatusHeader:    true,                             // 默认添加缓存状态头CacheQueryParams:   false,                            // 默认不缓存查询参数ForceNoCacheHeader: false,                            // 默认不强制 no-cacheBlacklistedHeaders: []string{},                       // 默认无黑名单头部}
}

可以通过使用 Host: traefik 标头发送请求来在 http://traefik 上执行缓存中毒。如果服务器后端没有正确处理host头,缓存中毒有可能使得攻击者凭空捏造出内部内部可访问的url(http://fake/)

可以通过使用 Host: traefik 标头发送请求来在 http://traefik 上执行缓存中毒。

缓存键仅由 HTTP 方法、主机名和路径组成,默认情况下甚至不包括查询参数缓存键完全忽略了 Range 请求头,这意味着具有不同/没有 Range 的请求会命中相同的缓存条目

// cacheKey 生成缓存键。
func (m *cache) cacheKey(r *http.Request) string {if m.cfg.CacheQueryParams {return r.Method + r.Host + r.URL.Path + r.URL.RawQuery // 包含查询参数}return r.Method + r.Host + r.URL.Path // 不包含查询参数
}

我们只需想办法配合题目不缓存参数的错误从服务器上凑齐如下“ROP”的方法即可

<iframe src="URL" name="XSS_payload">
Gadget 代码作用
e=this拿到全局对象
t=e.name读取 window.name
i=t复制变量
s=2设置延时
setTimeout(i,t,s)执行 XSS

我们还可以利用这一点使得不同的路径返回同一文件的不同部分

http://a/b/c.txt?/../d.txt -> http://a/d.txt

配合题目不缓存参数的错误,想办法凑出即可

Default-qPSf0Yui.js/..%2f..%2f/#/udp/a 加载 index-BH-fqmTU.js 和 api-DHmvWmr7.js,而 #/udp/routers 加载更多模块。

完整利用脚本

繁忙的交通 |justCTF 2025 — Busy Traffic | justCTF 2025

http://www.lryc.cn/news/614070.html

相关文章:

  • docker缓存目录转移设置和生效过程
  • 总结运行CRMEB标准版(uniapp)微信小程序的问题
  • 站在Vue的角度,对比鸿蒙开发中的数据渲染二
  • 【ESP32-menuconfig(1) -- Build Type及Bootloader config】
  • 跨平台音乐管理新方案:Melody如何实现一站式音源整合
  • 76 模块编程之高精度定时器
  • 数据仓库知识
  • PBootcms网站模板伪静态配置教程
  • C++信息学奥赛一本通-第一部分-基础一-第2章-第5节
  • linux信号量和日志
  • 户外广告牌识别准确率↑32%:陌讯多模态融合算法实战解析
  • 【JMeter】调试取样器的使用
  • 易美教育荣膺“腾讯年度影响力国际教育品牌”双奖加冕,见证中国国际教育力量的崛起
  • 《论文阅读》传统CoT方法和提出的CoT Prompting的区分
  • 有鹿机器人:如何用±2cm精度重塑行业标准?
  • 综合项目记录:自动化备份全网服务器数据平台
  • excel 导出
  • Linux Shell:Nano 编辑器备忘
  • 影刀 —— 练习 —— 读取Excel的AB两列组成字典
  • flink闲谈
  • 锂电池保护板测试仪:守护电池安全的核心工具|深圳鑫达能
  • 基于Vue.js和Golang构建高效在线客服系统:前端实现与后端交互详解
  • 碰一碰NFC开发写好评php语言源码
  • Track Any Anomalous Object: A Granular Video Anomaly Detection Pipeline
  • DigitalProductId解密算法php版
  • 基于 Modbus TCP 的飞升 FSH-CF计量泵多段速控制优化研究
  • 如何将视频转为GIF格式,3大视频转为GIF工具
  • 使用Python将中文语音翻译成英语音频
  • 【软考架构】计算机网络中的IP地址表示和子网划分
  • 数据结构(六):树与二叉树