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>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:
#include <stdio.h>
int main(int argc, char* argv[]){
printf(argv[1]);
printf("\n");
return 0;
}
Código
blackngel@linux:~$ ./fmt AAAA.%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08xSin embargo, si uso mi código de ejemplo y utilizo la misma cadena de ejemplo, obtengo esto otro:
AAAA.bffff727.000000d3.bffff450.bffff5e4.f63d4e2e.00000003.b7e78cbc.41414141
blackngel@linux:~$
Código
wisehacks@wisebox:~$ ./fstrings AAAA.%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08xAsumo 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:
AAAA.00a3ed20.0804845b.00308ff4.08048450.00000000.bffff508.001deb56.00000002
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










Autor


En línea



. 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.
.


