Day 6 – LFI Vuln. – Advent of Cyber 3 – TryHackMe Challenge

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.

The Challenge

After starting the challenge-machine, we open the website https://MACHINE_IP.p.thmlaps.com, and we are greeted with "McSys Control System".

McSys Control System

Looking at the URL:

https://10-10-25-17.p.thmlabs.com/index.php?err=error.txt

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 include(), 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 index.php.
We can quickly check this by changing the value of the err parameter to something that should not represent a file on the system.

McSys Control System LFI

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.

LFI vuln show /etc/passwd

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.

http://10-10-25-17.p.thmlabs.com/index.php?err=php://filter/convert.base64-encode/resource=./index.php

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 ssh://, php://, http:// and so on. With php://we are specifying that we want PHP to interpret the file for us before including it in the include()vulnerability from 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.

Received base64:

PD9waHAgc2Vzc2lvbl9zdGFydCgpOwokZmxhZyA9ICJUSE17NzkxZDQzZDQ2MDE4YTBkODkzNjFkYmY2MGQ1ZDllYjh9IjsKaW5jbHVkZSgiLi9pbmNsdWRlcy9jcmVkcy5waHAiKTsKaWYoJF9TRVNTSU9OWyd1c2VybmFtZSddID09PSAkVVNFUil7ICAgICAgICAgICAgICAgICAgICAgICAgCgloZWFkZXIoICdMb2NhdGlvbjogbWFuYWdlLnBocCcgKTsKCWRpZSgpOwp9IGVsc2UgewoJJGxhYk51bSA9ICIiOwogIHJlcXVpcmUgIi4vaW5jbHVkZXMvaGVhZGVyLnBocCI7Cj8+CjxkaXYgY2xhc3M9InJvdyI+CiAgPGRpdiBjbGFzcz0iY29sLWxnLTEyIj4KICA8L2Rpdj4KICA8ZGl2IGNsYXNzPSJjb2wtbGctOCBjb2wtb2Zmc2V0LTEiPgogICAgICA8P3BocCBpZiAoaXNzZXQoJGVycm9yKSkgeyA/PgogICAgICAgICAgPHNwYW4gY2xhc3M9InRleHQgdGV4dC1kYW5nZXIiPjxiPjw/cGhwIGVjaG8gJGVycm9yOyA/PjwvYj48L3NwYW4+CiAgICAgIDw/cGhwIH0KCj8+CiA8cD5XZWxjb21lIDw/cGhwIGVjaG8gZ2V0VXNlck5hbWUoKTsgPz48L3A+Cgk8ZGl2IGNsYXNzPSJhbGVydCBhbGVydC1kYW5nZXIiIHJvbGU9ImFsZXJ0Ij5UaGlzIHNlcnZlciBoYXMgc2Vuc2l0aXZlIGluZm9ybWF0aW9uLiBOb3RlIEFsbCBhY3Rpb25zIHRvIHRoaXMgc2VydmVyIGFyZSBsb2dnZWQgaW4hPC9kaXY+IAoJPC9kaXY+Cjw/cGhwIGlmKCRlcnJJbmNsdWRlKXsgaW5jbHVkZSgkX0dFVFsnZXJyJ10pO30gPz4KPC9kaXY+Cgo8P3BocAp9Cj8+

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 -A:

curl -A "This is a test McHackFace" http://10-10-25-17.p.thmlabs.com/login.php

Which is visible in the log:

Log Poisoning test

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.

https://10-10-25-17.p.thmlabs.com/index.php?err=php://filter/resource=./includes/logs/app_access.log

And with that, we see the page loaded with the log-file including the PHP info. The hostname is found under "Environment" and "HOSTNAME".

Leave a Reply

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