la pila de una funcion en c y sus abusos

Upload: unknown

Post on 06-Jul-2018

217 views

Category:

Documents


0 download

TRANSCRIPT

  • 8/16/2019 La Pila de Una Funcion en c y Sus Abusos

    1/21

    La Pila de una Función en C:

    Siguiendo con mi estudio del Exploiting en Linux (gracias al Libro "Linux Exploiting" de

    Blackngel), quise ver la evolución de la pila dentro de una función de un programa escrito en C; es

    una manera de entender mejor el proceso y lo ice para mi, (necesito ver las cosas en directo) pero

    despu!s pens! que podr"a ser #til para los que quieren comen$ar en el fabuloso mundo del

    exploiting y est!n tan verdes como yo ;)

    %reo que para empe$ar ay que tener estas cosas b&sicas muy claras y nada mas did&ctico que

    seguir la pila, paso a paso, y ver donde podemos intervenir para obtener una ventaja; que a este

    nivel siempre es la misma, llegar a alterar el EIP, registro que indica al procesador la siguiente

    dirección que debe ejecutar, de forma que el programa contin#e por donde nosotros queramos, que

    normalmente sera ac"a un sellcode, para as" conseguir ejecutar nuestro código'

    uiero comentar que todo el proceso a sido reali$ado en un sistema GNU/Linux, en concreto un

    Debian !ee# de x$%&%, sobre un ejecutable compilado para un sistema de *+; y que al ser la

     base la arquitectura intel, la información creo que es totalmente extrapolable a los sistemas

    indo-s'

    '( E)t*uctu*a de la Pila en +e,o*ia(

    .ara empe$ar vamos a ver como esta organi$ada la memoria de un programa durante su ejecución/

  • 8/16/2019 La Pila de Una Funcion en c y Sus Abusos

    2/21

    En este caso lo que nos interesa es la $ona de la pila o -tack , que como vemos es una $ona de

    memoria que crece de valores de direcciones altas a direcciones bajas y su estructura es del tipo

    LIF., lo #ltimo en entrar es lo primero en salir' Siempre se a comparado con una columna de

     platos; pero ay que tener en cuenta que siendo una $ona de memoria siempre tenemos nuevos

     platos por encima y por debajo y sera los registros E-P y EBP los que delimiten los platos con los

    que podemos trabajar' .ara complicar un poco el asunto, como E-P apunta a la cima de platos y la

     pila crece acia abajo, tenemos que su dirección siempre sera menor que EBP; como vemos en esta

    imagen/

  • 8/16/2019 La Pila de Una Funcion en c y Sus Abusos

    3/21

    %omo anali$aremos en nuestro ejemplo, dentro de una uncion01 se declara unos valores de EBP y

    E-P que ser&n utili$ados solo dentro de la función y que se denomina el marco de la pila para dica

    función, 0)tack *a,e0 ' EBP siempre estar& en una dirección superior a E-P y mientras EBP se

    mantiene fijo dentro de la función, E-P sera el registro que se mueva cuando se aga uso de la pila,

    indicando en cada instante cual es la dirección que corresponde a la cima de la pila'

    1uy importante, tened en cuenta que el valor de EBP y E-P son las direcciones de esa $ona de

    memoria reservada para la pila, no tiene nada que ver con el valor que aya en esa $ona dememoria; como ya veremos E-P es la dirección y D.2D P32 4E-P5 esta se2alando a los *+

     bits alojados en esa $ona concreta de memoria indicada por la dirección de ES.'

    6( +ane7o de la Pila en En)a,blado*(

    3 nivel ensamblador, el registro E-P se ve afectado por cuatro instrucciones/

    4PU-8, sirve para subir un valor a la pila, de modo que ES. como tiene que apuntar

    a este nuevo valor, disminuye su valor en unidades (Si es un jaleo, pero como crece acia abajo,

    es as"'''')4P.P9 es lo contrario, saca el valor que se encuentra encima de la pila, que esta

    se2alado por ES. y podemos ver como 5675 .879ES.:; al sacarlo de la pila ES. se actuali$a

    aumentando su valor en unidades' ablamos de unidades porque estamos en un sistema de *+

    donde el registro ES. son bytes'

    4CLL, es la instrucción que indica una llamada a una función, por tanto como la

    ejecución del programa va a continuar en otra $ona, es imprescindible saber donde volver cuando

    termine; por tanto se sube a la pila la dirección siguiente a la %all y el valor de ES. se ajusta para

    se2alar a ese valor'

    42E3, es la instrucción complementaria a la anterior, la pila durante la ejecución de

    la función se debe encargar (como veremos mas adelante) de que al terminar, la dirección que

    emos guardado antes, se encuentre en la cima de la pila osea esta direccionada por ES. y se reali$a

    un .6. que saca ese valor y el valor de ES. se ajusta' Lo mejor de esta instrucción es que ese valor

    sustituye al valor de E

  • 8/16/2019 La Pila de Una Funcion en c y Sus Abusos

    4/21

    %omo veis, es un simple programa para explicar lo que es una y yo quiero un programa de *+, ay que

    indicarlo'

    =no=)tack=p*otecto* y = exec)tack  son para evitar que el compilador a2ada las

     protecciones a la pila y nos deje jugar con ella' 3dem&s en este caso me interesa que no se vaya

    cambiando la direcciones de la pila en cada reinicio para no volverme mas loco de lo que ya

    estoy''''''''''

    ?na ve$ compilado tenemos un ejecutable llamado Global, para empe$ar vamos a ver el códigodesensamblado con ob7du,p y en este caso con la opción =-9 que es muy #til cuando emos

    compilado con la opción =g9 pues nos me$cla el código original con las instrucciones en

    ensamblador/

    0804841c :#include

    void funcion();

    int cantidad;

     main(){

    804841c: 55 push ebp

    804841d: 89 e5 mov ebp,esp804841f: 83 e4 f0 and esp,0xfffffff0cantidad = 10;

    8048422: c7 05 c4 96 04 08 0a mov DWORD PTR ds:0x80496c4,0xa8048429: 00 00 00

    funcion();

    804842c: e8 02 00 00 00 call 8048433 }

    8048431: c9 leave8048432: c3 ret

    08048433 :void funcion(){8048433: 55 push ebp8048434: 89 e5 mov ebp,esp8048436: 83 ec 18 sub esp,0x18

    printf("Valor del parametro = %d\n", cantidad);

    8048439: a1 c4 96 04 08 mov eax,ds:0x80496c4804843e: 89 44 24 04 mov DWORD PTR [esp+0x4],eax8048442: c7 04 24 e0 84 04 08 mov DWORD PTR [esp],0x80484e08048449: e8 b2 fe ff ff call 8048300

    }

    804844e: c9 leave

    804844f: c3 ret

  • 8/16/2019 La Pila de Una Funcion en c y Sus Abusos

    5/21

    Solo e puesto la parte que nos interesa, pues sale el desensamblado de todo el ejecutable' 1e a

     parecido interesante ver como las instrucciones en % se plasman en el código en ensamblador'

    .uede ser muy interesante para reversear código, viendo como se representan estructuras mas

    complejas como if''''else , for, do'''-ile, s-itc''''case, etc''''

    %on esta información ya estamos preparados para ver su ejecución y como se va utili$ando la pila

    durante ese proceso(

    >( -iguiendo la Pila(

    .ara ello vamos a abrir el programa Global con el debugger por defecto de =@?ALinux, gdb, cuya

    utili$ación pod!is repasar en los manuales correspondientes de 0Int*oducción al C*acking en

    Linux":

    ttp/AA---'sared'comAdirA*B>CDBFABf+eeB+A%racGingHenHLinux'tml

    %argamos el programa/

    $ gdb -q Global

    I colocamos dos di)pla# para que nos mantenga informado de los valores de E-P y EBP y si no lo

    ten!is colocado en el arcivo (gdbinit, debemos colocar la orden para que nos muestre el

    desensamblado en formato intel y no en 388 ( odio a 388, jejeje, no soy capa$ de acostumbrarme)/

    gdb> display $ebpgdb> display $esp

    gdb> set disassembly-flavor intel

    3ora solo queda colocar un breaGpoint en ,ain01 y ejecutar el programa con * 0*un1/

    gdb> b mainBreakpoint 1 at 0x8048422: file Global.c, line 5.gdb> r

    El programa para aqu"/

    0x8048422 : mov DWORD PTR ds:0x80496c4,0xa

    0x804842c : call 0x8048433 0x8048431 : leave0x8048432 : ret0x8048433 : push ebp

    3 partir de aora ir! colocando primero la instrucción que ya se a ejecutado y como queda la pila

    despu!s de su ejecución, con los valores que nos da display tanto para E-P como EBP y la pila en

    memoria tal como nos muestra la orden "x/'?@ Ae)p" , de forma que veamos gr&ficamente como

    se modifica' .ara empe$ar ejecutamos la orden "ni" en gdb para que ejecute la primera instrucción/

    mov DWORD PTR ds:0x80496c4,0xa2: $esp = (void *) 0xffffd450 1: $ebp = (void *) 0xffffd458

    http://www.4shared.com/dir/37685719/7f21ee72/Cracking_en_Linux.htmlhttp://www.4shared.com/dir/37685719/7f21ee72/Cracking_en_Linux.html

  • 8/16/2019 La Pila de Una Funcion en c y Sus Abusos

    6/21

    gdb> x/10w $esp 0xffffd450: 0x08048460 0x00000000 0xffffd4d8 0xf7e6be460xffffd460: 0x00000001 0xffffd504 0xffffd50c 0xf7fde8600xffffd470: 0xf7ff4821 0xffffffff

    .ara que se vea mas claro la salida de 0x/'?@ Ae)p0 la e colocado en columna, en formaDi*ección: alo*' %omo emos visto antes, en memoria la pila se ver"a as"/

    0xffffd474: 0xffffffff |0xffffd470: 0xf7ff4821 |0xffffd46c: 0xf7fde860 |0xffffd568: 0xffffd50c |0xffffd564: 0xffffd504 |0xffffd560: 0x00000001 |0xffffd45c: 0xf7e6be46 v0xffffd458: 0xffffd4d8 EBP 

    0xffffd454: 0x000000000xffffd450: 0x08048460 ESP 

    .ero al final, me a sido mas f&cil colocar la pila de forma cl&sica con el E-P encima (igual que lo

    vemos en 6llydbg) aunque para la numeración de las direcciones siempre tenemos que tener en

    cuenta que la pila crece acia abajo' .or tanto en este caso la pila la veremos de esta forma/

    0xffffd450: 0x08048460 ESP 0xffffd454: 0x000000000xffffd458: 0xffffd4d8 EBP 0xffffd45c: 0xf7e6be46 ^0xffffd560: 0x00000001 |0xffffd564: 0xffffd504 |0xffffd568: 0xffffd50c0xffffd46c: 0xf7fde8600xffffd470: 0xf7ff48210xffffd474: 0xffffffff

    En este caso emos cargado en la variable cantidad locali$ada en d):?x$?>%c> el valor '?, en

    exadecimal es ?xa y podemos comprobarlo con gdb/

    gdb> x 0x80496c40x80496c4 : 0x0000000a 

    %ontinuamos con la orden ")i" de gdb, para en este caso seguir la ejecución del programa entrando

    en la unción01/

    call 0x8048433 2: $esp = (void *) 0xffffd44c 1: $ebp = (void *) 0xffffd458

    0xffffd44c: 0x08048431 ESP 

    0xffffd450: 0x08048460 ^0xffffd454: 0x00000000 |0xffffd458: 0xffffd4d8 EBP

  • 8/16/2019 La Pila de Una Funcion en c y Sus Abusos

    7/21

    0xffffd45c: 0xf7e6be460xffffd560: 0x000000010xffffd564: 0xffffd5040xffffd568: 0xffffd50c0xffffd46c: 0xf7fde8600xffffd470: 0xf7ff4821

    Se a ejecutado la instrucción CLL y por tanto se a subido la dirección de retorno donde

    debemos continuar despu!s de que se ejecute esta llamada, lo marcamos en rojo para seguir su

    evolución' .odemos comprobar que es la dirección correcta con gdb/

    gdb> disas main Dump of assembler code for function main:0x0804841c : push ebp0x0804841d : mov ebp,esp0x0804841f : and esp,0xfffffff00x08048422 : mov DWORD PTR ds:0x80496c4,0xa

    => 0x0804842c : call 0x8048433 0x08048431 : leave 0x08048432 : retEnd of assembler dump.

    .or otro lado, E-P se a despla$ado para se2alar este nuevo valor que a a2adido el %3LL a la pila,

    en este caso a pasado de valer ?xd>? a valer ?xd>>c y ya sabemos el porque'

    asta el final, seguimos con la orden "ni" en gdb y as" ver las siguientes instrucciones pero sin

    entrar en ninguna función m&s'

    push ebp2: $esp = (void *) 0xffffd448 1: $ebp = (void *) 0xffffd458

    0xffffd448: 0xffffd458 ESP  0xffffd44c: 0x08048431  ^0Xffffd450: 0x080484600xffffd454: 0x000000000xffffd458: 0xffffd4d8 EBP  0xffffd45c: 0xf7e6be46

    0xffffd460: 0x000000010xffffd464: 0xffffd5040xffffd468: 0xffffd50c0xffffd46c: 0xf7fde860

    Se a subido EBP a la cima de la pila, por tanto el valor que se2ala E-P es la dirección de EBP;

    este EBP es la base de la pila de la función ,ain01 anterior y tambi!n vamos a marcarlo en a$ul

     para ver su evolución' %omo siempre, E-P a cambiado para se2alar la cima de la pila y pasa a

    valer ?xd>>$'

    mov ebp,esp2: $esp = (void *) 0xffffd448 1: $ebp = (void *) 0xffffd448

  • 8/16/2019 La Pila de Una Funcion en c y Sus Abusos

    8/21

  • 8/16/2019 La Pila de Una Funcion en c y Sus Abusos

    9/21

      eip = 0x8048439 in funcion (Global.c:9); saved eip 0x8048431called by frame at 0xffffd460source language c.Arglist at 0xffffd448, args:Locals at 0xffffd448, Previous frame's sp is 0xffffd450Saved registers:

    ebp at 0xffffd448, eip at 0xffffd44c

    No arguments.No locals.

    %omo vemos los 0-a5' En este caso el

    tama2o de la pila no a variado, solo emos macacado el valor anterior indicado por E-PH> por el

    valor de la variable cantidad, que en este caso es ?xa'

    mov DWORD PTR [esp],0x80484e02: $esp = (void *) 0xffffd4301: $ebp = (void *) 0xffffd448

    0xffffd430: 0x080484e0 ESP 0xffffd434: 0x0000000a ESP+0x4 0xffffd438: 0xffffd50c0xffffd43c: 0xffffd4580xffffd440: 0xf7e847f5

    0xffffd444: 0xf7fee5900xffffd448: 0xffffd458 EBP0xffffd44c: 0x080484310xffffd450: 0x080484600xffffd454: 0x000000000xffffd458: 0xffffd4d80xffffd45c: 0xf7e6be460xffffd460: 0x000000010xffffd464: 0xffffd5040xffffd468: 0xffffd50c

    0xffffd46c: 0xf7fde860

    %on esta orden tampoco afectamos el tama2o de la pila, por lo que E-P no cambia, aunque si

  • 8/16/2019 La Pila de Una Funcion en c y Sus Abusos

    10/21

    emos macacado el valor que indicaba ES. con la dirección ?x$?>$>e?/

    gdb> x/s 0x80484e00x80484e0: "Valor del parametro = %d\n"

    3ora ya estamos preparados para llamar a la función p*int , con los par&metros necesarios en la

     pila' Mamos a aprovecar para recordar que los par&metros de una función deben cargarse dedereca a i$quierda, si miramos el código/

    printf("Valor del parametro = %d\n", cantidad)

    .or eso emos subido primero la variable NcantidadO a 4e)pH>5 y la cadena 0Malor del parametro P

    QdRn0 en segundo lugar a 4e)p5

    call 8048300 Valor del parametro = 10  ; resultado de printf

    2: $esp = (void *) 0xffffd430 1: $ebp = (void *) 0xffffd448

    0xffffd430: 0x080484e0 ESP 0xffffd434: 0x0000000a ESP+0x40xffffd438: 0xffffd50c0xffffd43c: 0xffffd4580xffffd440: 0xf7e847f50xffffd444: 0xf7fee5900xffffd448: 0xffffd458 EBP

    0xffffd44c: 0x080484310xffffd450: 0x080484600xffffd454: 0x000000000xffffd458: 0xffffd4d80xffffd45c: 0xf7e6be460xffffd460: 0x000000010xffffd464: 0xffffd504

    %omo vemos con la orden "ni" emos pasado la CLL sin entrar y por tanto gdb nos da el

    resultado mostrado por p*int( e mostrado la pila para comprobar que en todas las funciones se

    salvaguardan sus valores, y como podemos comprobar son exactamente iguales antes y despu!s de

    la llamada a p*int '

    leave2: $esp = (void *) 0xffffd44c 1: $ebp = (void *) 0xffffd458

    La instrucción lea

  • 8/16/2019 La Pila de Una Funcion en c y Sus Abusos

    11/21

    0xffffd438: 0xffffd50c0xffffd43c: 0xffffd4580xffffd440: 0xf7e847f50xffffd444: 0xf7fee5900xffffd448: 0xffffd458 EBP y ESP 0xffffd44c: 0x08048431 

    0xffffd450: 0x080484600xffffd454: 0x000000000xffffd458: 0xffffd4d80xffffd45c: 0xf7e6be460xffffd460: 0x000000010xffffd464: 0xffffd5040xffffd468: 0xffffd50c0xffffd46c: 0xf7fde860

    La dirección de EK. a macacado ES., por tanto los dos valen lo mismo, ?xd>$'

    + pop ebpT

    0xffffd448: 0xffffd458 v0xffffd44c: 0x08048431  ESP0xffffd450: 0x080484600xffffd454: 0x000000000xffffd458: 0xffffd4d8 EBP 0xffffd45c: 0xf7e6be460xffffd560: 0x000000010xffffd564: 0xffffd504

    0xffffd568: 0xffffd50c0xffffd46c: 0xf7fde8600xffffd470: 0xf7ff4821

    emos sacado el valor indicado por ES., ?xd>$ y emos macacado EK.; por tanto EK.

    vuelve a tener la dirección inicial que le correspond"a en ,ain01 ' 3dem&s ES. se actuali$a

    disminuyendo el tama2o de la pila y por tanto su dirección pasa a ser ?xd>>c'

    ret

    2: $esp = (void *) 0xffffd450 1: $ebp = (void *) 0xffffd458

    0xffffd448: 0xffffd458 |0xffffd44c: 0x08048431   v0xffffd450: 0x08048460 ESP0xffffd454: 0x000000000xffffd458: 0xffffd4d8 EBP0xffffd45c: 0xf7e6be460xffffd560: 0x000000010xffffd564: 0xffffd5040xffffd568: 0xffffd50c0xffffd46c: 0xf7fde8600xffffd470: 0xf7ff4821

  • 8/16/2019 La Pila de Una Funcion en c y Sus Abusos

    12/21

    %on *et tomamos el valor de la cima de la pila y sustituimos EIP, de forma que el programa

    continuar& en ?x$?>$>;'' ES. debe actuali$arse pues emos sacado un valor, por lo que pasa a ser

    ?xd>? ' Si miramos la dirección de EIP con gdb vemos que todo esta correcto'

    gdb> x $eip

    => 0x8048431 : leave

    Ia emos visto, como el marco de la pila ,ain01 se a restablecido totalmente; pero como la misma

    función main() tambi!n debe restablecer la pila de la función que la llamo, vamos a continuar/

    0x08048431 : leave2: $esp = (void *) 0xffffd45c1: $ebp = (void *) 0xffffd4d8

    mov esp,ebp

    0xffffd448: 0xffffd458 |0xffffd44c: 0x08048431 |0xffffd450: 0x08048460 v0xffffd454: 0x000000000xffffd458: 0xffffd4d8 EBP y ESP 0xffffd45c: 0xf7e6be460xffffd560: 0x000000010xffffd564: 0xffffd5040xffffd568: 0xffffd50c0xffffd46c: 0xf7fde860

    0xffffd470: 0xf7ff4821

    Se iguala la dirección de E-P con respecto a EBP' S< os fij&is nuestro valor a$ul, que empe$ó

    siendo el EBP N3IGU., a llegado a ser la dirección de E-P(

    + pop ebp

    0xffffd448: 0xffffd4580xffffd44c: 0x080484310xffffd450: 0x080484600xffffd454: 0x00000000

    0xffffd458: 0xffffd4d80xffffd45c: 0xf7e6be46 ESP0xffffd560: 0x000000010xffffd564: 0xffffd5040xffffd568: 0xffffd50c0xffffd46c: 0xf7fde8600xffffd470: 0xf7ff48210xffffd474: 0xffffffff0xffffd478: 0xf7ffcff40xffffd47c: 0x080482540xffffd480: 0x000000010xffffd484: 0xffffd4c00xffffd488: 0xf7fedc160xffffd48c: 0xf7ffdac0

  • 8/16/2019 La Pila de Una Funcion en c y Sus Abusos

    13/21

    0xffffd490: 0xf7fdeb580xffffd494: 0xf7fb3ff40xffffd498: 0x000000000xffffd49c: 0x000000000xffffd4a0: 0xffffd4d80xffffd4a4: 0x67220d99

    0xffffd4a8: 0x55f6db890xffffd4ac: 0x000000000xffffd4b0: 0x000000000xffffd4b4: 0x000000000xffffd4b8: 0x000000010xffffd4bc: 0x080483300xffffd4c0: 0x000000000xffffd4c4: 0xf7ff39c00xffffd4c8: 0xf7e6bd6b0xffffd4cc: 0xf7ffcff40xffffd4d0: 0x00000001

    0xffffd4d4: 0x080483300xffffd4d8: 0x00000000 EBP

    El valor se2alado por E-P se extrae de la pila y macaca EBP, por tanto como sospec&bamos los

    valores de EK. en diferentes frames se encadenan, por tanto EBP acaba valiendo ?xd>d$' I lo

    que es mas importante, E-P se actuali$a, reduciendo la pila asta su valor ?xd>c' 3ora la

    cima de la pila se2ala otra dirección de retorno, ?xe%be>%' Sigo manteniendo nuestro valor a$ul

    ?xd>$9 para que comprob!is que su valor consecutivo superior ?xd>c (EDBH>), nos

    se2ala una dirección con retorno, osea otra forma de llegar a conseguir controlar el EIP'

    0x08048432 : ret2: $esp = (void *) 0xffffd4601: $ebp = (void *) 0xffffd4d8

    0xffffd448: 0xffffd4580xffffd44c: 0x080484310xffffd450: 0x080484600xffffd454: 0x000000000xffffd458: 0xffffd4d80xffffd45c: 0xf7e6be46 v0xffffd560: 0x00000001 ESP 

    0xffffd564: 0xffffd5040xffffd568: 0xffffd50c0xffffd46c: 0xf7fde8600xffffd470: 0xf7ff48210xffffd474: 0xffffffff0xffffd478: 0xf7ffcff40xffffd47c: 0x080482540xffffd480: 0x000000010xffffd484: 0xffffd4c00xffffd488: 0xf7fedc160xffffd48c: 0xf7ffdac0

    0xffffd490: 0xf7fdeb580xffffd494: 0xf7fb3ff40xffffd498: 0x00000000

  • 8/16/2019 La Pila de Una Funcion en c y Sus Abusos

    14/21

    0xffffd49c: 0x000000000xffffd4a0: 0xffffd4d80xffffd4a4: 0x67220d990xffffd4a8: 0x55f6db890xffffd4ac: 0x000000000xffffd4b0: 0x00000000

    0xffffd4b4: 0x000000000xffffd4b8: 0x000000010xffffd4bc: 0x080483300xffffd4c0: 0x000000000xffffd4c4: 0xf7ff39c00xffffd4c8: 0xf7e6bd6b0xffffd4cc: 0xf7ffcff40xffffd4d0: 0x000000010xffffd4d4: 0x080483300xffffd4d8: 0x00000000 EBP

    %on *et se extrae el valor de EIP de la pila, por lo que reducimos la pila de forma que E-P  es ladirección ?xd%?; de este modo emos terminado la función main() y continuamos ya en

    librer"as del sistema libc con su marco de pila adecuado y en la $ona adecuada/

    0xf7e6be46 : mov DWORD PTR [esp],eax0xf7e6be49 : call 0xf7e84550

    %omo veis, de esta manera salimos del programa llamando a la función exit(

    ( U)o # abu)o de la Pila(

    7especto al uso, en general no nos debemos de preocupar porque todo este proceso lo reali$a el

    compilador por defecto' Eso si el manejo de la pila en ciertos niveles, puede ser muy interesante

     para dar una cierta complejidad a nuestro programa, dando una protección a2adida a nuestro código'

    3ora mismo estaba pensando en los )tolen b#te) de los antiguos a)p*otect, que eran ocultados

    con diferentes instrucciones, aciendo y desaciendo mediante la pila, para ocultar el valor correcto

    del código que iniciaba el programa ( que tiempos aquellos''''')'

    .ara el exploiting, lo que nos interesa es abusar de la pila para obtener ventajas que en su estructura

    original no se ab"an previsto' La ventaja es siempre la misma, acernos con el EIP para conseguir

    que el programa contin#e por donde nosotros queramos y ejecute el código que nos interese'

    .ara empe$ar necesitamos un programa vulnerable y por tanto el primer responsable es el

     programador, que siempre deber"a tener la seguridad como pensamiento mientras estructura su

     programa y nunca olvidar las .r&cticas de .rogramación Segura' .ero en fin, ya sabemos, el eslabón

    mas d!bil es el umano y el programador tambi!n es umano /)

    5entro del programa, debemos buscar una función donde se pueda interactuar con el programa; ya

    sea porque nos pida datos, pas&ndole argumentos, pasando variables locales'''' sea como sea, la

    función recibir& nuestros datos y los guardara en una $ona de la pila que a preparado para tal fin

    llamada bue* y como es lógico estar& dentro del marco de la pila de esa función' Ese bue* 

    tendr& un tama2o prefijado y si el programador, con buena fe, piensa que nunca ning#n usuario seva a poner a introducir 3333333333s como un loco, y no comprueba que los valores

    introducidos no superen el tama2o del buffer, pues tendr& un problema bien gordo' Esos problemas

  • 8/16/2019 La Pila de Una Funcion en c y Sus Abusos

    15/21

    son mucos, pero para empe$ar vamos a ver varias t!cnicas cl&sicas para sacar proveco/

    = -tack . pues tanto E-P como E-PH?x> son los argumentos de p*int ' Esta nueva funciónimaginaria y bastante simplona /4., nos pide que "Introduzca una frase no mas larga de 16 letras" ,

     pues el buffer ocupa > bytes; pero deja sin comprobar lo que de verdad emos introducidos' En

    este caso los errores son mucos, el primero la confian$a en el usuario medio de que sepa contar

    (jajaja), tampoco se valoran los espacios en blanco (es un byte Ux+U) y sobretodo, te puedes

    encontrar con un rebelde que no admite reglas, y por tanto pone + 3 porque le da la gana ;)

    .ara representarlo vamos a usar gdb' .rimero debes activar la escritura en memoria, mediante la

    orden 0)et @*ite on0 y despu!s ir cambiando todo el buffer por el valor ascii de  en exadecimal,

    que es ?x>'

    gdb> set write ongdb> set {long}($esp+8)=0x41414141gdb> set {long}($esp+c)=0x41414141

  • 8/16/2019 La Pila de Una Funcion en c y Sus Abusos

    16/21

    gdb> set {long}($esp+10)=0x41414141gdb> set {long}($esp+14)=0x41414141gdb> set {long}($esp+18)=0x41414141gdb> set {long}($esp+1c)=0x41414141

    Si vemos la pila despu!s de introducir las 6> queda as"/

    0xffffd430: 0x080484e0 ESP 0xffffd434: 0x0000000a ESP+0x40xffffd438: 0x414141410xffffd43c: 0x414141410xffffd440: 0x41414141 BUFFER0xffffd444: 0x414141410xffffd448: 0x41414141 EBP0xffffd44c: 0x41414141 EIP0xffffd450: 0x080484600xffffd454: 0x00000000

    %omo vemos las +3 an rebosado el buffer y an seguido macacando $onas a donde nunca

    deber"an aber llegado, la mas interesante, el valor de EIP que a subido la instrucción CLL(

    Si seguimos con "ni" se ejecutara la instrucción lea'>'' En este momento vemos que gdb ya nos dice que no tiene acceso a esa

    dirección de memoria/

    => 0x41414141: Error while running hook_stop:

    Cannot access memory at address 0x41414141 0x41414141 in ?? ()

    Si de todos modos queremos continuar nos dar& una excepción que termina el programa;

    gdb> ni

    Program received signal SIGSEGV, Segmentation fault.

    ?na ve$ conseguida la excepción y adem&s comprobamos, por el error, que a sido por nuestra

    acción; ya solo quedar"a el proceso de crear un exploit que aprovece esta vulnerabilidad' En este

    caso ser"a complicado pues tenemos un buffer rid"culo donde tenemos poco espacio para meter

    nuestro código; lo importante es que se entienda los peligros que puede provocar un simple buffer

    overflo-'

  • 8/16/2019 La Pila de Una Funcion en c y Sus Abusos

    17/21

     

    = taJue al F*a,e Pointe*(

    El F*a,e Pointe* es otra forma de llamar al registro EBP; que como emos visto es la dirección

    clave para conservar estable dentro de una función el marco de la fila y tambi!n es muy importante

     para recuperar el marco de la pila anterior cuando la función termine'

    Este ataque al frame pointer, puede ser interesante en aquellos casos donde aunque aya desborde

    del buffer no podamos llegar al valor EIP y solo podamos acceder al EBP; que como ya emos

    comentado se2ala a un valor en la pila que es el EBP N3IGU. y que marcamos en a$ul para

    comprobar su evolución durante todo el proceso'

    Estamos otra ve$ en la dirección ?x?$?>$>>e9 cuando se va a ejecutar lea (este programador no tiene remedio,jeje)'

    %on esta premisas, sabemos que podemos desbordar el buffer pero solo llegamos asta EBP y no

     podemos acceder al E$ el

    que nos va a darla solución' Si miramos el punto * y seguimos el valor marcado en a$ul, podemos

    concluir tres cosas /

    4 ?xd>$ es el valor del EBP de la funcion anterior, ,ain 01

    4 3l final de la función ,ain01 se vuelve a repetir la pareja lea

  • 8/16/2019 La Pila de Una Funcion en c y Sus Abusos

    18/21

     

    + pop ebp

    0xffffd454: 0x000000000xffffd458: 0xffffd4d8

    0xffffd45c: 0xf7e6be46 ESP EIP4 .or tanto la dirección que debemos controlar es cuatro unidades por encima de la que

     pongamos en lugar del UxffffdDC'

    Mamos a acerlo y lo veremos mejor; seguimos en ?x?$?>$>>e

    0xffffd430: 0x080484e0 ESP

    0xffffd434: 0x0000000a ESP+0x40xffffd438: 0xffffd50c0xffffd43c: 0xffffd4580xffffd440: 0xf7e847f5 BUFFER

    0xffffd444: 0xf7fee5900xffffd448: 0xffffd458 EBP0xffffd44c: 0x08048431 EIP

     @os ace falta una dirección que controlemos y que podamos modificar; para ello tenemos el

    bue* y podemos utili$ar la primera, ?xd>;$ que corresponde con E-PH$  y sera donde se

     ponga la dirección que queramos sea el EIP , en nuestro caso usaremos ?x>'>'>'>'' %on gdb

     podemos acerlo f&cilmente y lo comprobamos/

    gdb> set {long}($esp+8)=0x41414141gdb> x/10x $esp0xffffd430: 0x080484e0 0x0000000a 0x41414141 0xffffd4580xffffd440: 0xf7e847f5 0xf7fee590 0xffffd458 0x080484310xffffd450: 0x08048460 0x00000000

    3ora es el momento de atacar el frame point, para ello como es una prueba, vamos a sustituir el

    valor guardado en EBP  por el valor que controlamos pero quit&ndole unidades, por tanto seria

    ?xd>;>/

    gdb> set {long}$ebp=0xffffd434 

    gdb> x/10x $esp0xffffd430: 0x080484e0 0x0000000a 0x41414141 0xffffd4580xffffd440: 0xf7e847f5 0xf7fee590 0xffffd434 0x080484310xffffd450: 0x08048460 0x00000000

    La pila queda asi/

    0xffffd430: 0x080484e0 ESP 0xffffd434: 0x0000000a ESP+0x40xffffd438: 0x41414141 EIP para 2º RET 0xffffd43c: 0xffffd458

    0xffffd440: 0xf7e847f50xffffd444: 0xf7fee5900xffffd448: 0xffffd434 EBP

  • 8/16/2019 La Pila de Una Funcion en c y Sus Abusos

    19/21

    0xffffd44c: 0x08048431 EIP para 1º RET

    Mamos a seguir ejecutando lea info registerseax 0x19 0x19ecx 0xffffd418 0xffffd418edx 0xf7fb5360 0xf7fb5360

  • 8/16/2019 La Pila de Una Funcion en c y Sus Abusos

    20/21

    ebx 0xf7fb3ff4 0xf7fb3ff4esp 0xffffd43c 0xffffd43cebp  0xa 0xa esi 0x0 0x0edi 0x0 0x0eip 0x41414141 0x41414141

    eflags 0x296 [ PF AF SF IF ]

    Lo emos conseguido, tenemos el EIP controlado atacando el valor de EBP; si seguimos ya

    sabemos lo que va a pasar/

    gdb> ni

    Program received signal SIGSEGV, Segmentation fault.

    = .=b#=.ne(

     @o iba a explicar mas t!cnicas para abusar de la pila, pero esta t!cnica conocida como .=

    b#=one viene perfectamente como continuación de la anterior'

    En este caso nos encontramos con un buffer que no podemos desbordar, pero curiosamente debido a

    alg#n problema emos permitido que podamos desbordar un )olo b#te despu!s del bue*' .or lo

    que explica Blackngel en su libro, este problema puede deberse a determinar mal donde poner el

     byte final de cadena AxUU o por problemas de calcular la cantidad de bytes, ya sab!is no es lo mismo

    empe$ar desde U o empe$ar desde UU'

    En fin, sea como sea, tenemos un solo byte que podemos utili$ar, y aunque parece poca cosa, en

    nuestro caso va a ser mas que suficiente' .ara poder utili$ar esta t!cnica ay que tener en cuenta doscondiciones/

    'K La arquitectura intel de los xC> utili$a el formato little endian para colocar las

    direcciones en memoria' Este significa que en memoria una dirección como ?xFFFFD>$, esta

    colocada al contrario ?x$ ?xD> ?xFF ?xFF9 de forma que el byte menos significativo se coloca el

     primero' Este nos viene de perlas, pues como solo tenemos un byte que alterar ese sera el del final

    de la dirección'

    Lo podemos ver con gdb, si con la orden x en lugar de que nos muestre los bytes juntos (la

    opción por defecto) le decimos que nos muestre los bytes independientes/

    gdb> x $esp0xffffd44c: 0x08048431

    gdb> x/4b $esp0xffffd44c: 0x31 0x84 0x04 0x08 

    6K %omo consecuencia de lo anterior, las situaciones donde est& t!cnica nos ser& #til

    son aquellas donde la dirección de EBP y la dirección que vamos a usar falsa tengan los tres

     primeros bytes de la dirección iguales' .or eso este caso es perfecto, como tenemos un buffer tan

     peque2o la dirección de EK. es ?xFFFFD>$ y la que pusimos en su lugar era ?xFFFFD>;>; por

    tanto con solo cambiar el #ltimo byte ( vi!ndolo en memoria, por el little endian, es el primero) essuficiente, siendo el resto de la t!cnica exactamente igual al ataque al frame pointer'

  • 8/16/2019 La Pila de Una Funcion en c y Sus Abusos

    21/21

    .ara acer la prueba con gdb ser"a igual que el anterior, pero solo vamos a cambiar un byte/

    gdb> x $ebp0xffffd448: 0xffffd458

    gdb> set write on

    gdb> set {char}$ebp=0x34 gdb> x $ebp0xffffd448: 0xffffd434 gdb> x/4b $ebp0xffffd448: 0x34 0xd4 0xff 0xff

    %( Conclu)ión:

    %omo siempre, iba solo a explicar la evolución de la pila en una función y se me a ido la mano,

     jeje, pero bueno la verdad es que tambi!n quer"a compartir con todos lo que voy aprendiendo sobre

    Exploiting en Linux' Sobretodo espero que aya quedado claro y sirva para todos aquellos que

    quieren empe$ar con el estudio de la explotación de vulnerabilidades en sistemas Linux'

    %ualquier comentario a cvtuGan(arroba)gmail'com o en la lista de %racGslatinos'

    ttp/AAgroups'google'comAgroupA%racGSLatinoS