靶场地址:天狩CTF竞赛平台
进入靶场
没看到什么信息,先分析源代码
// 为登录按钮绑定点击事件处理函数
document.getElementById('loginBtn').addEventListener('click', async () => {
// 获取用户输入的用户名和密码
const username = document.getElementById('username').value;
const password = document.getElementById('password').value;
try {
// 发送异步POST请求到/login接口
const response = await fetch('/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json' // 设置请求内容类型为JSON
},
body: JSON.stringify({ username, password }) // 将凭证序列化为JSON
});
// 解析响应数据为JSON格式
const data = await response.json();
if (response.ok) { // HTTP状态码2xx表示成功
token = data.token; // 存储认证令牌到全局变量
// 更新页面显示登录成功状态
document.getElementById('loginResult').textContent = `登录成功: ${data.message}`;
document.getElementById('loginResult').classList.remove('hidden'); // 显示结果区域
// 切换界面显示
document.getElementById('loginSection').classList.add('hidden'); // 隐藏登录表单
document.getElementById('secretSection').classList.remove('hidden'); // 显示敏感操作区
} else { // 登录失败处理
document.getElementById('loginResult').textContent = `错误: ${data.error}`;
document.getElementById('loginResult').classList.remove('hidden');
}
} catch (error) { // 网络错误或响应解析异常
document.getElementById('loginResult').textContent = `发生错误: ${error.message}`;
document.getElementById('loginResult').classList.remove('hidden');
}
});
// 为获取敏感信息按钮绑定点击事件处理函数
document.getElementById('getSecretBtn').addEventListener('click', async () => {
try {
// 发送携带令牌的GET请求到/get_secret接口
const response = await fetch('/get_secret', {
method: 'GET',
headers: {
'Authorization': token // 在请求头注入认证令牌
}
});
// 解析敏感数据响应
const data = await response.json();
// 此处可添加数据显示逻辑,例如:
// document.getElementById('secretContent').textContent = data.secret;
} catch (error) { // 错误处理
console.error('获取秘密失败:', error);
// 可添加错误提示逻辑
}
});
document.getElementById('getSecretBtn').addEventListener('click', async () => {
try {
// 发送携带认证令牌的 GET 请求到 /get_secret 端点
const response = await fetch('/get_secret', {
method: 'GET',
headers: {
'Authorization': token // 使用登录时获取的 JWT 令牌进行认证
}
});
// 解析 JSON 格式的响应数据
const data = await response.json();
if (response.ok) { // HTTP 状态码 2xx 表示成功
let resultText = `${data.message}\n\n`; // 基础消息
// 分层级显示不同敏感等级的信息
if (data.public) { // 公开信息
resultText += `${data.public}\n\n`;
}
if (data.confidential) { // 机密信息(猫猫信息)
resultText += `猫猫信息: ${data.confidential}\n\n`; // 可能是伪装的敏感数据
}
if (data.flag) { // CTF 的 flag 信息
resultText += `Flag: ${data.flag}`; // 最终目标数据
}
代码意思是登录成功后获得一个token,然后携带此token访问url/get_secret,即可获得flag,那么现在主要是登录成功,没有其他信息,爆破应该不行。再看一下源代码,发现了一个认证,Authorization认证,认证类型有Inherit auth from parent , No Auth, Bearer Token (安全令牌),API Key,JWT, Basic Auth (基本身份认证),Digest Auth (摘要认证)等,而在CTF中,考的应该是JWT认证,在我另一篇文章中,也说了关于CTF中WEB的考点,这里就是算法篡改了,
-
JWT(JSON Web Token)安全问题
-
算法篡改:将算法改为
none
(alg: none
) -
密钥爆破(弱密钥如
secret
) -
未验证签名(直接解析 Header/Payload)
-
进行抓包,确实是算法篡改
那么接下来就是获得token,构造payload
payload:
hearder:{"alg":"none"},
payload{ "username": "admin", "role": "admin"}
如图所示,进行JWT 加密
然后使用burpsuite拦截url/get_secret页面,在请求包加上
Authorization:eyJhbGciOiJub25lIn0.eyJ1c2VybmFtZSI6ImFkbWluIiwicm9sZSI6ImFkbWluIn0.w08J73Fde6pww7N54oV9HNsCwOfFhqzaZIrRYiyfDl8
ok,得到flag.