Day six in the Advent of Cyber 3 (2021). Yet another day in the Cyber Defences, and McSkidy had performed a routine security audit before all the incidents, where some recovery passwords in an old server was discovered. McSkidy created a ticket in the system, but hte Elf assigned to clean up the passwords, kept pushing off the task and it never got done.
Now, those recovery password could be used for saving some of the systems; Only problem is, access to the server is through an old web application.
WARNING: Spoilers and challenge-answers are provided in the following writeup.
Official walk-through video is as well available at Late-Twenties Boomer Performs LFI & Log Poisoning (elf hat) | TryHackMe Advent of Cyber Day 6!.
Day 6 - Patch Management Is Hard
Local File Inclusion is a type of vulnerability, where a website allows a threat actor to include a file, usually exploiting a "dynamic file inclusion" mechanisms implemented in the target application. This can lead to disclosure of sensitive information, Denial of Service, Cross-Site Scripting or even Remote Code Execution on the webserver.
Read further on LFI on OWASP.
After starting the challenge-machine, we open the website
https://MACHINE_IP.p.thmlaps.com, and we are greeted with "McSys Control System".
Looking at the URL:
We see that we are redirected to the
index.php site, telling us that PHP is running on the webserver. Furthermore, we see that there is a
GET-parameter set called
errand that it looks like a filename. Very interesting, as this could mean that the user-supplied value could be used in some
require() or similar statement in the PHP code. These statements includes the content of the specified file into the parsing of the current file - here
We can quickly check this by changing the value of the
err parameter to something that should not represent a file on the system.
As marked in the picture above, setting a random value gives us an PHP-error. Often these PHP-errors are disabled in hardended systems - but not here. This clearly shows us that the value of
erris indeed used in a
include()-statement. Also it shows us the file-location of
/var/www/html/ which is a common placement for website-files on Linux-based webservers.
To further verify that we indeed have found an LFI vulnerability with the ability to traverse the directory structure, we can try including the file
/etc/passwd - a file readable for every user on a Linux-system. As seen below - this was more than successful. And if it wasn't possible, we could have tried with path-traversal in Linux where
../ always gives you the parent directory, and using "too many" only ensures that you end up at the root - so using
../../../../../../../../../../../../should always ensure that you end up at the root and then you can traverse as you like - if not, just try with even more.
The first question for what entry point we have, we have established that the
errparameter of the
GET-request is working for us. Then we are questioned to find the flag provided in the file
/etc/flag - as we know we can get to
/etc/passwdin the same directory, we just swap the value of
errand bum - we have the flag served for us.
Question three is a bit funny. We are asked to receive the content of the
index.php-file it self and extract a flag from it. The only issue is, when the webserver is parsing a
.php-file, it will try running the PHP and then we are not receiving the source-content.
To mitigate this, we can use the "filter"-technique to convert the source-content to e.g. base64 encoding and then decode it our self afterwards.
Accessing this URL will give us the below base64 included on the site. This is happening as we are using the
err LFI-vulnerability from earlier but changing the scheme for the file-inclusion. On Linux it is possible to access "stuff" by defining the scheme/protocol like
http:// and so on. With
php://we are specifying that we want PHP to interpret the file for us before including it in the
err. But, before PHP just includes the file, we are using the
filter function to manipulate the file via the
convert.base64-encode function in PHP and use the data defined in
resource= to manipulate. So, we are instructing PHP to include the source-file manipulated to be base64 encoded.
Now just a quick decode, and we can find the flag for the question.
echo "<base64-encoded-text>" | base64 -d
McSkidy has forgotten the login credentials for the system, but remembers that
index.php has a reference to the file on the system. Looking at the source-file again from last question, and we see
include("./includes/creds.php"); - looking very promising.
Using the same "filter"-method as last, we are able to extract the source-file and decode the content, giving us the credentials for the next question.
With these credentials we can log on the system, and under "Password Recovery" we can see the flag for
flag.thm.aocwhich is the answer to the next question.
Lastly we are tasked with finding the name of the webserver via the log files. Being logged in, we have access to the "Log Access"-page on
logs.php. We are told that the log file is located in the
./includes/logs/app_access.logon the server. Using these information's we are going to perform a technique called "Log Poisoning". A technique used to gain RCE (Remote Code Execution) on the server by ingesting a malicious payload into the log file and then use a LFI vulnerability to execute it by requesting a page including the malicious payload/log file.
The logfile includes the username, ip, User-Agent and page for all successful accesses, thous allowing us to inject our payload into the User-Agent-field as we are in full control over that user-supplied data. Doing so is very easy with the commandline tool
curl and the flag
curl -A "This is a test McHackFace" http://10-10-25-17.p.thmlabs.com/login.php
Which is visible in the log:
So, now we want to inject something that can be interpreted by PHP and show us the webservers hostname. PHP has a function called
phpinfo(); that shows extremely many information's on the installation and setup - and as well our needed hostname. Let's try inject that enclosed in HTML-tags that instructs the server to treat the code as PHP and not just text.
curl -A "<?php phpinfo(); ?>" http://10-10-25-17.p.thmlabs.com/login.php
After this Log Poisoning where we ingested PHP-code, we need to execute the code by using the LFI vulnerability from earlier. So firstly, we logout as the
errvulnerability is for the
index.php when not being logged in. Then we create the
errvalue using the "filter"-method again - but this time not converting to base64 as we want the PHP rendering.
And with that, we see the page loaded with the log-file including the PHP info. The hostname is found under "Environment" and "HOSTNAME".