PicoCTF - Super Serial
Description: Try to recover the flag stored on this website
http://mercury.picoctf.net:2148/.
The homepage looks like this:
When visiting
robots.txtwe get the following:Strangely enough, if we visit
/admin.phpswe get an error:After searching what exactly
.phpsfiles are, we find [this] article:…PHP files will get interpreted by the Web server and PHP executable, and you will never see the code behind the PHP file. If you make the file extension
.PHPS, a properly-configured server will output a color-formated version of the source instead of the HTML that would normally be generated.Based on that, we can infer that our server is configured to have
.phpsfiles, since there is a/admin.phpsdirectory, so we can try see if that works on the/index.phpby visiting/index.phps:- We have 3 things of interest on the above code:
- A new script:
cookie.php. - Another script:
authentication.php. - A
setcookiemethod which includes serialization.
- A new script:
After visiting the source code for each page, i.e.,
/cookie.phpsand/authentication.phps, we see that the latter has an object of the classaccess_logwhich has thelog_fileattribute and uses the__toStringmethod to read that log and get its content:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
class access_log { public $log_file; function __construct($lf) { $this->log_file = $lf; } function __toString() { return $this->read_log(); } function append_to_log($data) { file_put_contents($this->log_file, $data, FILE_APPEND); } function read_log() { return file_get_contents($this->log_file); }
We know that our flag is under
../flag, therefore, if we have anaccess_logobject equal to that would be really handy.On the
cookie.phpscode we have the following code:1 2 3 4 5 6 7 8 9 10
if(isset($_COOKIE["login"])){ try{ $perm = unserialize(base64_decode(urldecode($_COOKIE["login"]))); $g = $perm->is_guest(); $a = $perm->is_admin(); } catch(Error $e){ die("Deserialization error. ".$perm); } }
The
.$permvariable represents our flag and it is shown when a deserialization error occurs. Thus, our goal is to trigger such an error.If we go to the
/authenticationdirectory and manually add thelogincookie giving it a random value we get the following:So we managed to invoke a deserialization error. The next step is to find a way to properly serializes the cookie with its value as
../flag. We can replicate the serialization process based onindex.phpscode:setcookie("login", urlencode(base64_encode(serialize($perm_res))). We can try serializing a simple string and check it gets deserialized when we pass it as a cookie:It successfully deserialized our cookie. Instead of just a string, we need an object of class
access_logwhoselog_fileattribute will be equal to../flag:If we now pass that string as the value of the cookie
login, we will get the flag back:












