$cat authentication.mdWebHacknite 2.0
Authentication
A cookie holds a packed-up object that tells the server which file to read. Rebuild it to point at the flag file and the server hands it over.
$man authentication
What this one teaches:
- What base64 is, and how to read a cookie that's been encoded with it.
- What serialising an object means (packing it into text and rebuilding it later).
- PHP object injection, where a tampered cookie makes the server rebuild an object you control.
$hint --one-at-a-time
Stuck? Open one hint, then go back and try again before reading the next.
Hint 1 of 2show
The interesting cookie is base64. Decode it and see what it describes.
Hint 2 of 2show
You have the source. What does the server do with the object it rebuilds from the cookie?
Task description
While researching online, Ana found a novel way to log in as admin with no username or password. Pleased with it, she saved something interesting at /usr/local/flag.txt, but to read it you have to be signed in as admin.
The original was in Croatian; this is my translation.
The cookie
Like Hidden Admin Content, this turns on a cookie. In the developer tools (Inspect, then Application or Storage) there’s a cookie named message with a long scrambled value.
That value is base64. Base64 is a way of writing any data using only plain letters and digits, so it can travel safely in places like cookies. It isn’t encryption; anyone can decode it. Pasting it into a base64 decoder showed it wasn’t a word but a packed-up object.
Objects in a cookie
The task gives us the site’s source. In evenmoresecure.php, the key line is:
<p><?php print(unserialize(base64_decode($_COOKIE["message"]))->get_file()); ?></p>
Reading it from the inside out: take the message cookie, base64-decode it, then unserialize it. Serialising means packing an object (a bundle of data and the actions that go with it) into a line of text so it can be stored; unserialising rebuilds the object from that text. The rebuilt object here is a FileAccess with a filename, and the page calls its get_file(), which reads and prints that file.
The decoded cookie showed the filename set to /usr/local/default.txt. Since the server rebuilds the object straight from the cookie, we control the filename. This is PHP object injection: the server trusts a serialised object that the visitor can swap out.
Pointing it at the flag
We built the same object with the filename changed to the flag, then serialised and base64-encoded it, using a free online PHP sandbox:
<?php
class FileAccess {
private $filename;
function set_filename($f) { $this->filename = $f; }
function get_file() { return file_get_contents($this->filename); }
}
$a = new FileAccess();
$a->set_filename("/usr/local/flag.txt");
print(base64_encode(serialize($a)));
We pasted its output over the message cookie, reloaded, and the page read /usr/local/flag.txt and printed the flag.
The fix is to never rebuild objects from data the visitor controls. Keep the state on the server and give the cookie only a random session id.
$cat flag.txt reveal
CTF2021[254352283512]