elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.
 
Inicio Ayuda Buscar Ingresar Registrarse
25 Mayo 2012, 15:28  


Tema destacado: Entra al canal IRC oficial de #elhacker.net

+  Foro de elhacker.net
|-+  Seguridad Informática
| |-+  Bugs y Exploits (Moderador: berz3k)
| | |-+  Problema Format Strings: ¿pero qué $$! hay en la pila?
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Problema Format Strings: ¿pero qué $$! hay en la pila?  (Leído 1,592 veces)
wisehacks

Desconectado Desconectado

Mensajes: 21


Ver Perfil
Problema Format Strings: ¿pero qué $$! hay en la pila?
« en: 30 Marzo 2010, 14:52 »

Buenas a todos,

estaba intentando probar por mí mismo el clásico format strings y me he encontrado con contenido de la pila que no tengo claro qué es. El código que uso de ejemplo es este:

Código
#include <string.h>
#include <stdio.h>
 
int main(int argc, char* argv[]){
   printf(argv[1]);
   printf("\n");
   return 0;
}
 
Compilado en un sistema ubuntu 32 bits con -fno-stack-protector para tratar de evitarme temas de canary en la pila. El caso es que si uno se fija en los tutoriales de la red (y si se fía de cómo deberían estar las variables en la pila en teoría), la propia cadena que introduces al programa debe encontrarse cerca del SP, tal como muestran en set-ezine, por ejemplo:

Código
blackngel@linux:~$ ./fmt AAAA.%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x
AAAA.bffff727.000000d3.bffff450.bffff5e4.f63d4e2e.00000003.b7e78cbc.41414141
blackngel@linux:~$
 
 
Sin embargo, si uso mi código de ejemplo y utilizo la misma cadena de ejemplo, obtengo esto otro:

Código
wisehacks@wisebox:~$ ./fstrings AAAA.%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x
AAAA.00a3ed20.0804845b.00308ff4.08048450.00000000.bffff508.001deb56.00000002
 
Asumo que por ejemplo el 0x00000002 es el valor de argc, y que justo detrás estará el puntero argv. Aún así, para encontrar mi 0x41414141 tengo que irme más de 140 posiciones abajo en la pila:
Código
wisehacks@wisebox:~$ ./fstrings $(perl -e 'print "AAAA" . ".%08x"x142')
AAAA.00130d20.0804845b.00396ff4.08048450.00000000.bffff268.0026cb56.00000002.bffff294.bffff2a0.b7fff858.bffff250.ffffffff.0013eff4.
08048270.00000001.bffff250.00130326.0013f828.b7fffb40.00396ff4.00000000.00000000.bffff268.694559f4.db308e8b.00000000.
00000000.00000000.00000002.08048360.00000000.00135fc0.0026ca7b.0013eff4.00000002.08048360.00000000.08048381.
08048414.00000002.bffff294.08048450.08048440.00130d20.bffff28c.0013f670.00000002.bffff3fd.bffff408.00000000.bffff6d3.bffff6f5.
bffff708.bffff713.bffff723.bffff774.bffff7af.bffff7c1.bffff7e1.bffff7ed.bffffc8e.bffffcbe.bffffceb.bffffd4d.bffffd5d.bffffd73.bffffdc0.bffffdd1.bffffde8.
bffffdf9.bffffe0e.bffffe1f.bffffe31.bffffe39.bffffe4b.bffffe77.bffffe86.bffffee8.bfffff25.bfffff45.bfffff52.bfffff74.bfffff8d.bfffffc5.bfffffd2.00000000.
00000020.006c0420.00000021.006c0000.00000010.078bf3ff.00000006.00001000.00000011.00000064.00000003.08048034.
00000004.00000020.00000005.00000008.00000007.00123000.00000008.00000000.00000009.08048360.0000000b.000003e8.
0000000c.000003e8.0000000d.000003e8.0000000e.000003e8.00000017.00000000.00000019.bffff3db.0000001f.bffffff1.0000000f.
bffff3eb.00000000.00000000.00000000.00000000.5b000000.5c4988ce.0845cb53.041fef5e.69def3ad.00363836.00000000.00000000.
00000000.662f2e00.69727473.0073676e.41414141
 

No tengo claro qué hacen todas esas variables en la pila hasta la cadena 0x41414141. De hecho, entiendo que 0xbffff294 es la posición de la cadena de entrada, y que parte de lo que hay por el camino es padding del compilador y variables de entorno de la shell, ya que si lanzo el programa con un entorno limpio hay menos basura por el camino (108 posiciones bastan en lugar de 142):

Código
wisehacks@wisebox:~$ env -i ./fstrings $(perl -e 'print "AAAA" . ".%08x"x108')
AAAA.007f2d20.0804845b.00c0eff4.08048450.00000000.bffffcc8.00ae4b56.00000002.bffffcf4.bffffd00.b7fff858.bffffcb0.ffffffff.00800ff4.
08048270.00000001.bffffcb0.007f2326.00801828.b7fffb40.00c0eff4.00000000.00000000.bffffcc8.4c650cf3.ef0b9b8d.00000000.
00000000.00000000.00000002.08048360.00000000.007f7fc0.00ae4a7b.00800ff4.00000002.08048360.00000000.08048381.
08048414.00000002.bffffcf4.08048450.08048440.007f2d20.bffffcec.00801670.00000002.bffffdc5.bffffdd0.00000000.00000000.
00000020.0027e420.00000021.0027e000.00000010.078bf3ff.00000006.00001000.00000011.00000064.00000003.08048034.
00000004.00000020.00000005.00000008.00000007.007e5000.00000008.00000000.00000009.08048360.0000000b.000003e8.
0000000c.000003e8.0000000d.000003e8.0000000e.000003e8.00000017.00000000.00000019.bffffdab.0000001f.bffffff1.0000000f.
bffffdbb.00000000.00000000.00000000.9d000000.d670b826.1ec659ce.6f5583d3.6986a14d.00363836.00000000.662f2e00.69727473.
0073676e.41414141.3830252e.30252e78.252e7838.2e783830

Aún así, lo que más me desconcierta es que la cadena de entrada está en posiciones diferentes en función de la longitud que tenga. Es decir, con 108 se ve 0x41414141 como el 6º valor por la cola, es decir, que con 102 debería salir como el último, pero no sale en absoluto:

Código
wisehacks@wisebox:~$ env -i ./fstrings $(perl -e 'print "AAAA" . ".%08x"x103')
AAAA.001c4d20.0804845b.0077fff4.08048450.00000000.bffffcd8.00655b56.00000002.bffffd04.bffffd10.b7fff858.bffffcc0.ffffffff.001d2ff4.
08048270.00000001.bffffcc0.001c4326.001d3828.b7fffb40.0077fff4.00000000.00000000.bffffcd8.a461b123.912f465c.00000000.
00000000.00000000.00000002.08048360.00000000.001c9fc0.00655a7b.001d2ff4.00000002.08048360.00000000.08048381.
08048414.00000002.bffffd04.08048450.08048440.001c4d20.bffffcfc.001d3670.00000002.bffffdde.bffffde9.00000000.00000000.
00000020.002b5420.00000021.002b5000.00000010.078bf3ff.00000006.00001000.00000011.00000064.00000003.08048034
.00000004.00000020.00000005.00000008.00000007.001b7000.00000008.00000000.00000009.08048360.0000000b.000003e8.
0000000c.000003e8.0000000d.000003e8.0000000e.000003e8.00000017.00000000.00000019.bffffdbb.0000001f.bffffff1.0000000f.
bffffdcb.00000000.00000000.00000000.f1000000.b8baebe6.f82e2dcc.8f76e308.69907b17.00363836.00000000.00000000.00000000.
2f2e0000

Este baile que depende de la longitud de la cadena de entrada me impide escribir en posiciones arbitrarias de memoria con %n y el padding (%100n por ej) ya que al meter 100 ya no está la cadena en el mismo sitio que con 30. Si alguien sabe qué está pasando y puede arrojar un poco de luz sobre el asunto se lo agradezco.

Saludos y gracias
En línea
AlbertoBSD
Estudiante y
Colaborador
***
Desconectado Desconectado

Mensajes: 1.955


Anonymous & Paranoid


Ver Perfil WWW
Re: Problema Format Strings: ¿pero qué $$! hay en la pila?
« Respuesta #1 en: 30 Marzo 2010, 23:08 »

Parece que tienes el Stack en randomize:

Deshabilitando protecciones contra Buffer Overflows

Saludos
En línea

Bien Super Divertido
@wifigdlmx
wisehacks

Desconectado Desconectado

Mensajes: 21


Ver Perfil
Re: Problema Format Strings: ¿pero qué $$! hay en la pila?
« Respuesta #2 en: 31 Marzo 2010, 10:53 »

Hola Anon,

se me olvidó comentarlo, pero no, tengo desactivado el ASLR, compilo además sin SSP y he dejado habilitado NX porque no afecta (he probado también con él deshabilitado). ¿Hay alguien a quien no le pase esto o que sepa por qué pasa?

Gracias
En línea
Ivanchuk


Desconectado Desconectado

Mensajes: 466


LLVM


Ver Perfil WWW
Re: Problema Format Strings: ¿pero qué $$! hay en la pila?
« Respuesta #3 en: 1 Abril 2010, 00:16 »

Hola wisehack,

Probando en un wargame un error de format string me pasó exactamente lo mismo :-\. La unica que se me ocurrio fue de hacer una simulacion de escritura, o sea cambiaba los %n por %ARG$8x donde probaba dandole valores a ARG para encontrar ARGV[1] en la pila. Hasta problemas de alineacion tenia!. Agregandoles espacios al final del parametro lo podia alinear. Pero es un trabajo de hormiga.
Habia hecho un script para automatizar la cosa, si lo encuentro lo paso. O sea, le ponias la dir que querias escribir, el valor y a partir de que numero de argumento comenzaba ARGV[1] y te generaba la cadena con las 4 escrituras. Porque el valor a escribir a cada %n es acumulativo! es decir que lo que acumulas hasta el 1er %n cuenta para el siguiente. Si tenes que sacar numeros a mano te volves loco :P.

El porque del cambio de posicion de argv[1]?
Ahora que lo pienso por ahi puede ser el prologo/epilogo que te agrega gcc para alinear el stack en 16 bytes. Estuve viendo como sacar las opcion pero hasta ahora no he podido :s.
Seguire probando, si llego a alguna conclusion te aviso.

Saludos.
En línea

Sólo quien practica lo absurdo puede lograr lo imposible.

Join us @ http://foro.h-sec.org
wisehacks

Desconectado Desconectado

Mensajes: 21


Ver Perfil
Re: Problema Format Strings: ¿pero qué $$! hay en la pila?
« Respuesta #4 en: 4 Abril 2010, 18:58 »

He estado probando en varias distribuciones y con kernels distintos, pero ninguno más antiguo que 2.6.25 y pasa más o menos igual, puede que haya más o menos espacio en medio, pero sigue habiendo un gap enorme. Además, sigue dependiendo la posición de la cadena de su longitud. (ASLR off, SSP off, NX off, environment limpio). Si saco un rato miraré el código del loader a ver si veo el motivo, o preguntaré por alguna mailing list específica.
Lo que comentas, Ivanchuk, es poco probable, la alineación a 16 bytes no debería suponer un desplazamiento mayor de 15 bytes, y aunque la cadena esté alineada a 16 bytes su posición sigue variando, no sé. Si encuentras algo cuéntame :)

Si alguien tiene alguna idea brillante se sigue agradeciendo ;)
En línea
sirdarckcat
Troll Buena Onda y
CoAdmin
***
Desconectado Desconectado

Mensajes: 6.947


Lavando Platos


Ver Perfil WWW
Re: Problema Format Strings: ¿pero qué $$! hay en la pila?
« Respuesta #5 en: 8 Abril 2010, 06:53 »

Hola

fue un error de blackngel, el codigo con el que hizo ese tutorial es distinto, mira:

Código:
[sdc@zizidi fsof]$ ./fmt2 AAAA.%0.8x.%0.8x.%0.8x.%0.8x.%0.8x.%0.8x.%0.8x
AAAA.bfbf2a0e.000003d1.00000000.00000008.41414141.2e30252e.252e7838

Código
#include <stdio.h>
#include <string.h>
 
int main(int argc, char **argv) {
 char buf[1024];
 strncpy(buf, argv[1], sizeof(buf) - 1);
 
 printf(buf);
 
 return 0;
}

Ese codigo sale mas abajo en su tutorial (sección 4), de seguro se confundio.
http://www.set-ezine.org/index.php?num=37&art=9

Saludos!!
En línea

wisehacks

Desconectado Desconectado

Mensajes: 21


Ver Perfil
Re: Problema Format Strings: ¿pero qué $$! hay en la pila?
« Respuesta #6 en: 10 Abril 2010, 13:02 »

Gracias sirdarckcat,

Esta tarde pruebo con ese código y hago algunas pruebas más con el mío y te cuento sirdarckcat, aunque es raro que una diferencia tan pequeña en el código afecte de esa manera a la pila. ¿En qué sistema has probado (distro, kernel, gcc)?

En línea
Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Powered by SMF 1.1.16 | SMF © 2006-2008, Simple Machines