Following on from my previous post this one is about level01 of Nebula on exploit-excercises.com. The information about this level says:
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 level01 account with the password level01 . Files for this level can be found in /home/flag01.
It also contains some source code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/types.h> #include <stdio.h> int main(int argc, char **argv, char **envp) { gid_t gid; uid_t uid; gid = getegid(); uid = geteuid(); setresgid(gid, gid, gid); setresuid(uid, uid, uid); system("/usr/bin/env echo and now what?"); } |
I’m not all that familiar with C (I’m more of a scripter), but I can understand enough; this appears to basically sets all uids for the process to the effective uid (presumably the setuid bit is present) and then calls a command line of:
/usr/bin/env echo and now what? |
I wasn’t familiar with the env command so used a bit of googling until I learned that env is used to launch programs in a different environment. It also also sometimes used because a script needs to start with a shebang and followed by an interpreter directive, which must be an absolute path. Because some interpreters are not always installed at the same location, env is sometimes used to launch the correct interpreter by file name rather than full path (e.g. #!/usr/bin/env/ python). To do this, env searches through the list of paths in in the environment variable $PATH in order until it finds a correctly named file that it can execute in one of them. Presumably (for some unknown reason) env is being used here to invoke echo, but it means we can make a different echo program run by creating a malicious script and changing $PATH to point to it first.
I changed the path to include /tmp at the beginning by running the follwing command:
PATH=/tmp:$PATH |
and then created a new symbolic link called echo to the getflag program:
ln -s /bin/getflag /tmp/echo |
Now when I ran the vulnerable program I got a success message, but I wanted to go one further. I wanted shell…
I tried creating a symbolic link to bash, but now running flag01 failed due to the invalid arguments (“and now what?” are valid arguments for echo, but not bash), so I removed the symbolic link and created an executable shell script that ignored all arguments, and saved it as echo in /tmp. It contained the following two lines of code:
1 2 | #!/bin/bash /bin/bash |
This, I hoped, would cause the vulnerable program to spawn a shell. I tested it and it worked. I then ran whoami to confirm that I was flag01 and then getflag to get a success message.