Hacking - The Art of Exploitation, 2nd Edition

(Romina) #1
Exploitation 149

signal(SIGINT, sigint);
signal(SIGQUIT, sigquit);
return(ret);
}


The important part of this function is shown in bold. The fork() function


starts a new process, and the execl() function is used to run the command


through /bin/sh with the appropriate command-line arguments.


The use of system() can sometimes cause problems. If a setuid program


uses system(), the privileges won’t be transferred, because /bin/sh has been


dropping privileges since version two. This isn’t the case with our exploit, but


the exploit doesn’t really need to be starting a new process, either. We can


ignore the fork() and just focus on the execl() function to run the command.


The execl() function belongs to a family of functions that execute com-


mands by replacing the current process with the new one. The arguments for


execl() start with the path to the target program and are followed by each of


the command-line arguments. The second function argument is actually the


zeroth command-line argument, which is the name of the program. The last


argument is a NULL to terminate the argument list, similar to how a null


byte terminates a string.


The execl() function has a sister function called execle(), which has one


additional argument to specify the environment under which the executing


process should run. This environment is presented in the form of an array of


pointers to null-terminated strings for each environment variable, and the


environment array itself is terminated with a NULL pointer.


With execl(), the existing environment is used, but if you use execle(),


the entire environment can be specified. If the environment array is just the


shellcode as the first string (with a NULL pointer to terminate the list), the


only environment variable will be the shellcode. This makes its address easy


to calculate. In Linux, the address will be 0xbffffffa, minus the length of the


shellcode in the environment, minus the length of the name of the executed


program. Since this address will be exact, there is no need for a NOP sled. All


that’s needed in the exploit buffer is the address, repeated enough times to


overflow the return address in the stack, as shown in exploit_nosearch_env.c.


exploit_notesearch_env.c


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


char shellcode[]=
"\x31\xc0\x31\xdb\x31\xc9\x99\xb0\xa4\xcd\x80\x6a\x0b\x58\x51\x68"
"\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x51\x89\xe2\x53\x89"
"\xe1\xcd\x80";


int main(int argc, char argv[]) {
char
env[2] = {shellcode, 0};
unsigned int i, ret;

Free download pdf