Networked
Reconnaissance: NMAP
┌──(kali💀kali)-[~]
└─$ sudo nmap -sC -sV -O 10.10.10.146
22/tcp open ssh OpenSSH 7.4 (protocol 2.0)
| ssh-hostkey:
| 2048 22:75:d7:a7:4f:81:a7:af:52:66:e5:27:44:b1:01:5b (RSA)
| 256 2d:63:28:fc:a2:99:c7:d4:35:b9:45:9a:4b:38:f9:c8 (ECDSA)
|_ 256 73:cd:a0:5b:84:10:7d:a7:1c:7c:61:1d:f5:54:cf:c4 (ED25519)
80/tcp open http Apache httpd 2.4.6 ((CentOS) PHP/5.4.16)
|_http-server-header: Apache/2.4.6 (CentOS) PHP/5.4.16
|_http-title: Site doesn't have a title (text/html; charset=UTF-8).
443/tcp closed https
Aggressive OS guesses: Linux 3.10 - 4.11 (92%), Linux 5.1 (90%), Linux 3.2 - 4.9 (89%), Linux 3.13 (88%), Linux 3.13 or 4.2 (88%), Linux 4.10 (88%), Linux 4.2 (88%), Linux 4.4 (88%), Linux 3.10 (88%), Linux 3.11 - 3.12 (88%)
No exact OS matches for host (test conditions non-ideal).
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .Before we move on to enumeration, let’s make some mental notes about the scan results. We have 2 open ports:
Port 22: running OpenSSH 7.4
Port 80: running Apache httpd 2.4.6
Running CVE scan on basic ports
HTTP Port 80/tcp
80: http://10.10.10.146/
Hello mate, we're building the new FaceMash! Help by funding us and be the new Tyler&Cameron! Join us at the pool party this Sat to get a glimpse
SOURCE CODE: view-source:http://10.10.10.146/
443: https://10.10.10.146/
Gobuster: Subdirectory Brute forcing
Nikto: Vuln Scanning
There’s a comment mentioning an upload and gallery pages that have not yet been linked to the index page. We found those pages during the gobuster scan.
http://10.10.10.146/upload.php
It gives you the option of uploading files. We’ll have to test what type of files can be uploaded. The web server can run php code, so we’ll have to check if it accepts .php files. Maybe we can upload a php shell on the server.
Next, visit the photos page. It contains a bunch of images. The images that get uploaded on the upload page, are presented on this page.
http://10.10.10.146/photos.php
journal.jpg file uploaded, refresh gallery
View page source to see the link to each image. http://10.10.10.146/uploads/10_10_16_4.jpg
So not only do we have a way of uploading files on the web server, but we can also execute those files. In most cases, restrictions are put in place preventing us from uploading any file. Therefore, we’ll need to first enumerate these restrictions and then figure out a way to bypass them.
Next, view the backup directory. It contains a compressed file.
upload.php: Let’s view the upload.php script. It takes in the uploaded file and performs two validation checks on it.
photos.php:
index.php:
lib.php:
It contains the source code of the php scripts running on the web server. This is great for us, because we can simply look at the php scripts in order to determine the validation that is put in place for uploading files.
Shell as apache
Let’s describe the second validation check first. It takes in an array of allowed file extensions and checks if the uploaded file contains that extension. The check is being performed using the substr_compare() function. This is a function that is used to compare two strings.
It requires at least three parameters:
$main_str: the main string being compared.
$str: the secondary string being compared.
$offset: the start position for the comparison. If negative, it starts counting from the end of the string.
The following is an example:
Since the offset in the above example is negative, it starts at the end of the string “test.png” and checks every character with the characters in the string “.png” (4 characters). In this case the test would pass and the function outputs a zero. This is exactly what the upload script is doing. Therefore, in order to bypass that, all we have to do is upload a file with a valid extension at the end. For example: test.php.png.
Let’s move on to the first validation check. The script calls the check_file_type() function from the lib.php file. This in turn calls the file_mime_type() function to determine the mime type of the file. Then the mime type is checked to see if it contains the string ‘image/’ in it.
This can be easily bypassed because we can simply include what is known as magic bytes in our file in order to trick the script into thinking the file is an image. This can be be done by adding the string “GIF87a” to the file.
Alright, we know how to bypass both validation checks, so we’re ready to run our exploit. Create a file called test.php.png and add the the following code to it.
The first line tricks the application into thinking it is an image and the second line adds a parameter to the get request called cmd. Upload the file and intercept the request in Burp.
We can see that our image has been uploaded. Right click and select View Image. This executes our code. Next, add the cmd parameter to the URL and run the whoami command.
We have code execution! Now, let’s get a reverse shell. First, set up a listener on the attack machine.
Then run the whoami request again and send it to Repeater. You will have to disable the “File extension” in Proxy > Options > Intercept Client Requests in order to intercept the request.
Next, visit pentestmonkey and add the bash reverse shell in the ‘cmd’ parameter https://pentestmonkey.net/cheat-sheet/shells/reverse-shell-cheat-sheet
We get a shell! Let’s upgrade it to a better shell.
Privesc to guly
The user.txt flag is in the home directory of the user guly. So we’ll either have to escalate our privileges to guly or root.
I ran the LinEnum.sh and pspy64 programs but didn’t find anything unusual. I did notice that in the home directory of guly there’s a php script and a crontab file. We have read permission on both of them.
View the content of crontab.guly.
It’s running the file check_attack.php script every 3 minutes. If you’re not familiar with the crontab format, refer to the following
Let’s view the check_attack.php file.
The script is taking in all the files in the /var/www/html/uploads directory and running the getnameCheck() and check_ip() functions on it from the lib.php file.
The getnameCheck() function simply separates the name of the file from the extension of the file. The check_ip() function checks if the filename is a valid IP address. If it is not, it will return false which will trigger the attack component in the check_attack.php file.
This passes the path of the file to the exec() function and deletes it. Of course, no validation is being done on the input of the exec() function and so we can abuse it to escalate privileges.
Change to the /var/www/html/uploads directory and create the following file.
The “;” will end the “rm” command in the exec() function and run the nc command, which will send a reverse shell back to our machine. Set up a listener to receive the reverse shell.
Wait for the cron job to run and we get a shell! Convert the shell to a fully interactive shell and grab the user.txt flag.
Privesc to root
We need to escalate our privileges to root. I downloaded the LinEnum script and ran it. It looks like we can run the following file as root without a password.
sudo -l (one of the first things I check on any Linux hosts) shows me that guly can run a shell script as root without a password:
We only have read and execute permissions on the file. Let’s view the content of the file.
It takes in the content of the file ifcfg-guly and does a simple regex check on the input. Let’s view the permissions on that file:
We can only read it. Let’s view the file:
The NAME is assigned a system command, so we can probably use this to escalate privileges. After a bit of googling, I found this bug report that states that incorrect whitespace filtering on the NAME attribute leads to code execution. Since we can run the changename.sh script with sudo privileges, it will prompt us to enter the NAME value and since it’s not properly validated, we can get a shell with root privileges!
Last updated
