P4TH H1J4CKING CTF
PATH CTF
Problem:
In this CTF problem we are given an ELF file that creates a hash of the flag.txt file. If we run ./hasher we see the output of the hash as well as the output string “Computing the md5 hash of /root/flag.txt. Of course, I cat /root/flag.txt but we receive a “permission denied” log. I uploaded the file to Ghidra to take a look at what was happening inside!
I am going to point out the obvious and say that this program calls /bin/bash -c \md5sum /root/flag.txt\ with a system() call. We also know that this system() call is being called as root because of setuid(0). However, we can’t change the internal call that’s being called on system(command), where system opens a shell to execute a command.
Solution: $PATH Hijacking
As I stated, we can’t change the call inside but we can change which md5sum program it calls. How? \(PATH Hijacking. The md5sum algorithm is being called in /usr/bin/md5sum but the command doesn't specify where, it just assumes that our machine will find the program in our relative \)PATH. So if it looks in our \(PATH and executes the first program named md5sum with root privilages, then we can create our own md5sum program and set it at the beginning of \)PATH to make sure it is seen first.
echo '#!/bin/bash' > /tmp/md5sum
echo 'cat /root/flag.txt' >> /tmp/md5sum
chmod +x /tmp/md5sum
export PATH=/tmp:$PATH
once we run the ./hasher it runs ‘/bin/bash -c \md5sum /root/flag.txt\’ and it finds our md5sum in the beginning of the path and runs it as root, which prints out whatever is inside flag!
flag{You’ve_found_me}
What we should look out for when writing programs.
Always enforce absolute paths, that way you don’t let your machine implicitly call a program.
Be careful using setuid(0).
Be careful using system() as it opens a /bin/bash -c, which is often taken advantage of in a situation like this or even in a buffer-overflow for shell injection.
Use execve() where the programmer defines the PATH and not the user of the program.