picoCTF 2014: “Steve’s List – 200 (Master Challenge)” WriteUp

Section Chief Steve was super proud of the website he was writing, but he’s pretty new to programming. When Daedalus Corp caught wind of this, they hacked his site. Steve still has an old backup, but they changed the secrets! They sent us a cryptic message saying they bet we couldn’t read  /home/daedalus/flag.txt. Can you go get it for us?

Steve’s list was in my opinion the easiest of the master challenges.

Steve’s defaced site looks pretty bad. Let’s find out how Daedalus hacked it!

Since we have access to the old source code, we’ll have a look at that. There are 4 interesting files:  cookies.php ,   classes.php ,   root_data.php  and   index.php .
Let’s see what these files do:

  • index.php : This file prints all the blog posts in  posts/*
  • root_data.php : Some unnecessary junk and the value of AUTH_SECRET , in the source backup it’s  AAAAAAAA .
  • classes.php : Classes  Filter and Post are used to display blog posts. Filter replaces BB tags with actual HTML markup using regular expressions.
  • cookies.php : Cookie checks and generation
    • If the cookie  custom_settings exists
      • Check if  sha1(AUTH_SECRET . urldecode($_COOKIE['custom_settings'])) == $_COOKIE['custom_settings_hash']
        • Split the cookie value and unserialize every line of the value
    • If the cookie  custom_settings does not exists
      • Create the cookie and set it to  urlencode(serialize(true))

Let’s ignore the hash check for now.

As every line in the cookie is unserialized and no checks are done, we could create arbitrary objects by putting a serialized object into the cookie (a so-called “Object Injection Vulnerability”).
As we only have two objects available (Filter and Post), we don’t have a lot of options of objects to generate. Let’s have a closer look at these classes:

So, using the cookie unserialization, we can create our own Post and Filter objects. Does that help? Yes!
Luckily, PHP’s preg_replace offers an eval functionality with /e .

This code would execute  print("foo") . To read and print the flag in this challenge, simply use this snippet:   print(file_get_contents("/home/daedalus/flag.txt")).

To craft our serialized object string, we can create our own script with the same classes and property names:

This prints the following string:

When this string is unserialized, it will create a Post object with our own filter. At the end of the execution, the object’s __destruct() function will be called, which will execute our injected code (aka print the flag).

The only thing missing is the hash check at the beginning of cookies.php. The  custom_settings_hash  cookie needs to contain  sha1(AUTH_SECRET . urldecode($_COOKIE['custom_settings'])) , but we don’t know  AUTH_SECRET . All we know is that “b:1;” hashes to “2141b332222df459fd212440824a35e63d37ef69” and that the secret is 8 characters long.

With a hash length extension attack, we are able to craft a valid hash! I am going to use the tool “hash_extender” for that.

Will return our payload and a valid sha1 hash:

Put the string into the custom_settings cookie and the signature into the custom_settings_hash cookie and we are done. Refresh the page and it will give us the flag:

D43d4lu5_w45_h3r3_w1th_s3rialization_chief_steve

Read more:

Leave a Reply

Your email address will not be published. Required fields are marked *

Time limit is exhausted. Please reload the CAPTCHA.