Now we get to level 1. We are presented with a simple web form with the PHP code powering it.
The PHP script checks if the input combination matches the combination in ‘secret-combination.txt’ file, and present the user with the password to the next level if the combinations match. Obviously, we’re not going to guess the combination.
There are a few ‘handy’ methods in PHP that are extremely dangerous.
extract is one of them. It will extract the content of the passed-in associative array, and import them into the global scope. e.g.,
extract(array('foo'=>'bar')); will make a global variable
$foo. What’s more dangerous is that if you already have a variable named
$foo, it will be overwritten with the new value in the associative array.
Because the secret combination’s location is stored in
$filename variable, we need to somehow manipulate the input to point
$filename to something else. Looking at line 27:
<form action="#" method="GET"> </form>
So the form is submitted using GET! So manipulating the variable is as easy as sending the endpoint with query param
Now, what will the
xyz be? The
$filename variable is passed into
file_get_contents() function. The parameter to the function is simply a string, and PHP defined a few ‘handy’ streams.
php://input caught my eyes. The doc says
php://input is a read-only stream that allows you to read raw data from the request body.. Hey, the form is submitted using GET, so there won’t be a request body. The input parameter is also sent using GET variable
attempt, so I just need to send an empty
attempt and point the filename to
…And indeed it works!
- Never, ever use
extract()in serious applications. Historically, PHP is used to build simple websites so it included many functions that puts “convenience” over security. Global variables are a bad idea, and having the ability to pollute the global space from any input is way worse.
file_get_contents()has the ability to take any string as parameter, including some named streams. They are handy but they pose potential threats.
- Again, don’t trust user input!