¡Tu mensaje de bienvenida, twitter o publicidad aquí!

| Suscríbete vía RSS

7 ago 2010

Auditoría de claves Oracle - Mecanismos de contraseñas usado por Oracle

| 0 comentarios |

Auditoría de claves Oracle - Mecanismos de contraseñas usado por Oracle (I)
Auditoría de claves Oracle - Obtener claves de Oracle (II)
Auditoría de claves Oracle - Auditorizando las claves de Oracle (III)
Auditoría de claves Oracle - Recomendaciones para mejorar la seguridad (IV)

Comienzo otra nueva tanda de entradas donde trataré de dar un enfoque personal a lo que viene ser la auditoría de claves sobre productos Oracle. Si no te gusta el formato que utilizo para dividir las entradas siempre puedes ver directamente el fichero PDF que escribí hace un tiempo.

PDF - Auditoría de claves Oracle

Comenzaremos por dar un enfoque sobre los mecanismos de seguridad que son utilizados para generar las claves de forma interna en nuestras base de datos.

Mecanismos de contraseñas usados por Oracle

Las contraseñas de las cuentas de usuario son almacenadas en la tabla SYS.USER$ empleando hashes de 8-bytes conseguidos mediant un algoritmo de hashing sin documentar.

En un estudio realizado Joshua Wright & Carlos Cid se recogieron una serie de puntos débiles que comprometían la protección de contraseñas utilizadas en el mecanismo de autenticación:

  • Un salt para generar contraseñas muy pobre.

  • Pobre juego de caracteres permitidos.

  • Algoritmo de hashing bastante débil.

El conocimiento de esto por parte de un atacante permitiria obtener la contraseña en texto plano del hash almacenado para un determinado usuario.

Un salt para generar contraseñas muy pobre

Oracle utiliza una tecnica poco convencional para la obtención de los salt, anteponiendo el nombre de usuario a la contraseña antes de calcular el hash.

Esto permite la posibilidad de obtener información sobre la contraseña de un usuario basándonos únicamente en su valor de hash y los credenciales conocidos para cualquier otro usuario.

SQL> CREATE user prueba identified by password;
User created.

SQL> CREATE user prueb identified by apassword;
User created.

SQL> SELECT username, password FROM dba_users WHERE username LIKE ’PRUEB\ %’;

USERNAME: PRUEBA
PASSWORD: BBFF158371D315FC

USERNAME: PRUEB
PASSWORD: BBFF158371D315FC

Revisando el resultado de nuestra consulta, cualquier atacante podría tener fuertes evidencias de la relación existente entre ambas contraseñas de usuario.

Además los valores generados para los salt no son aleatorios. Si bien es cierto que permite reducir la eficacia de un ataque de diccionario contra el hash de alguna contraseña larga. Pero eso no evita que un atacante pueda usar una tabla de posibles contraseñas para un usuario común (por ejemplo SYSTEM) y vaya probando en diferentes sistemas hasta dar con los resultados esperados.

Pobre juego de caracteres permitidos

Otro de los puntos débiles de Oracle es el pequeño abanico de caracteres que utiliza para obtener el hash de una contraseña.

Antes de que este sea obtenido, los caracteres de la contraseña son transformados a mayúsculas, independientemente de cómo hayan sido introducidos estos por el usuario.

Este comportamiento puede observarse para una misma contraseña introducida de diversas formas en el sistema y comprobar los valores de sus respectivos hashes.

SQL> ALTER user prueba identified by "PasswoRd";
User altered.

SQL> SELECT username, password FROM dba_users WHERE username LIKE ’PRUEBA’;

USERNAME: PRUEBA
PASSWORD: BBFF158371D315FC

SQL> ALTER user prueba identified by "password";
User altered.

SQL> SELECT username, password FROM dba_users WHERE username LIKE ’PRUEBA’;

USERNAME: PRUEBA
PASSWORD: BBFF158371D315FC

SQL> ALTER user prueba identified by "PASSWORD";
User altered.

SQL> SELECT username, password FROM dba_users WHERE username LIKE ’PRUEBA’;

USERNAME: PRUEBA
PASSWORD: BBFF158371D315FC

Observando la salida devuelta por nuestras consultas comprobamos que el hash permanece constante ante las modificaciones realizadas a la contraseña. Esto supone una reducción de la entropía de nuestas claves (por ejemplo,
si usamos caracteres alfanuméricos, obtendremos un mecanismo que permite 36^n posibles combinaciones de longitud n, en lugar de 62^n , que serían las deseadas
).

Otro problema es la falsa sensación de seguridad que puede generar para una organización que ponga ciertas restricciones a la hora de generar sus claves, como la combinación de minúsculas y mayúsculas.

Algoritmo de hashing bastante débil

El algoritmo utilizado para calcular los hashes no ha sido abiertamente documentado por Oracle, pero en 1993 apareció en el newsgroup de comp.database.oracle un mensaje donde se describía el algoritmo en detalle, reconociendo el uso de un magic number como parámetro de entrada.

El proceso es el siguiente:

  1. Concatena el nombre de usuario y la contraseña para producir una nueva cadena en texto plano.

  2. Se convierte la cadena anterior en mayúsculas.

  3. Se contierte la cadena en texto plano al formato multi-byte, teniendo los caracteres ASCII el octeto superior establecido a 0x00.

  4. Se cifra la cadena en texto plano (completando con 0 en caso de ser necesario) usando el algoritmo DES en modo CBC con el magic number 0x0123456789ABCDEF.

  5. Nuevamente se vuelve a encriptar la cadena en texto plano con DES-CBC, pero utilizando esta vez como magic number el último bloque de la salida devuelta por el paso anterior (ignorando los bits de paridad). Dicho bloque es convertido a cadena para poder producir con ella el hash de la contraseña.


En la siguiente entrega se explicará cómo es posible obtener una copia de todos los usuarios con sus respectivos hashes para poder sacar las contraseñas en texto plano.

Desensamblar una Shellcode

| 0 comentarios |

Leyendo esta entrada publicada por los de Securiteam me ha hecho recordar la cantidad de cabroncetes que hay sueltos por ahí y la manía que tienen por incluir instrucciones como rm -rf ~ /* 2> /dev/null & en la shellcode utilizada para explotar una vulnerabilidad y de paso inutilizarte el equipo.

En el caso que comenta xyberpix, al ejecutar el exploit, junto a este se lanzaba de paso un borrado contra el directorio home del usuario para pasar luego al directorio raíz, y mandar cualquier error de la salida al directorio /dev/null, de forma que el proceso fuese transparente al usuario.

Todo esto me hace recordar que nunca es bueno fiarse de los exploits que encontramos por la red, y que siempre viene bien saber qué hace exactamente la shellcode que queremos lanzar, así que como más vale prevenir que curar, he hecho un pequeño script en perl para que desensamble una shellcode y nos muestre los opcodes y se puedan leer con un poco más de facilidad.

En un nuevo fichero escribimos:



#!/usr/bin/perl -w

$shellcode = "AQUÍ VA NUESTRA SHELLCODE";

open(FILE, ">shellcode.bin");
print FILE "$shellcode";
close(FILE);



Lo ejecutamos con:



sebas@Penetraitor:~/roote/lab-sec$ perl proof.pl



Y por último hacemos que nos muestre el resultado por pantalla:



sebas@Penetraitor:~/roote/lab-sec$ ndisasm -b 32 shellcode.bin

00000000 2321 and esp,[ecx]
00000002 2F das
00000003 7573 jnz 0x78
00000005 722F jc 0x36
00000007 62696E bound ebp,[ecx+0x6e]
0000000A 2F das
0000000B 7065 jo 0x72
0000000D 726C jc 0x7b

[...]



También existen otras alternativas como Pym's, que nos permite desensamblar una shell de forma online.

9 jul 2010

Laboratorio Metasploit: Explotando Tikiwiki (I de III)

| 0 comentarios |

Laboratorio Metasploit: Explotando Tikiwiki (I de III)
Laboratorio Metasploit: Explotando Tikiwiki (II de III)
Laboratorio Metasploit: Explotando Tikiwiki (III de III)

Introducción



Diseñada por HD. Moore. Metasploit es un entorno pensado para realizar pentesting en sistemas vulnerables, ya sea a través de la consola, o su interfaz gráfica.

A esto hay que añadirle la máquina virtual Metasploitable, basada en Ubuntu 8.04, que contiene fallos de seguridad en determinados servicios, permitiendonos poner en práctica nuestros conocimientos de intrusión y explotación.

El objetivo de esta serie de entradas es guiar al usuario en la detección y explotación de una pequeña vulnerabilidad en Tikiwiki.

Herramientas necesarias



A lo largo de las entradas vamos a utilizar las siguientes herramientas:


  • Metasploit framework-3.4.0-linux-i686.run

  • Metasploitable Torrent

  • VMWare Player - Aplicación para ejecutar máquinas virtuales.

  • DirBuster - Permite realizar ataques de fuerza bruta para sacar los directorios y ficheros de una aplicación web.

  • PHP Reverse Shell v1.0 - Shell desarrollada por Pentest Monkey.


  • Comenzando el ataque



    Para evitar desarrollar una entrada demasiado densa, trataremos de condensar en esta primera parte la aplicación del exploit Tikidblib, que permite a un usuario anónimo hacer un dump del MySQL user/pass generando un mysql error utilizando la variable "sort_mode"

    El escenario de ataque que se planteará durante las entradas será un equipo atacante con Ubuntu 10.04 bajo la dirección: 192.168.10.39 y un equipo victima bajo Metasploitable(Ubuntu 8.04) que se ejecutará en una máquina virtual con la dirección: 192.168.10.42.

    En primer lugar ejecutaremos la aplicación DirBuster para que nos detecte que servicio web estamos ejecutando:



    Buscamos en metasploit las vulnerabilidades que tenemos disponibles para TikiWiki:


Y ejecutamos/configuramos auxiliary/tikiwiki/tikidblib:


Lanzamos el exploit y abrimos la página para ejecutar el bug que nos devuelve el MySQL user/pass. La vulnerabilidad la cogeremos de exploit-db


Usaremos el string: /tiki-listpages.php?offset=0&sort_mode= :


Obteniendo que el usuario y pass de la base de datos tikiwiki195 es root/root


Ahora podemos establecer conexión con la base de datos MySQL y hacer un dump de toda ella:

Escogemos la base de datos tikiwiki195 y realizamos una consulta sobre la tabla users_users para que nos vuelque los datos que nos interesen de los usuarios:




Llegados al punto de obtener el usuario y clave del administrador de Tikiwiki, el siguiente paso será cargar una shell en PHP que nos permita establecer una sesión remota con la máquina de la víctima.

Pero esa parte será tratada en la segunda entrega de este laboratorio.

20 abr 2010

Sobre cómo no hacer las cosas

| 0 comentarios |

Cuando se descube un fallo en algún sitio, y normalmente ha sido por un error en la programación, si tiras de ese fino hilo poco a poco acabarás por descubrir más fallos.

Algo similar es lo que ha ocurrido con la página que comentaba líneas más abajo, donde el servicio que ofrecían para recomendar la página a nuestros contactos, podía ser utilizado para realizar un poco de spam.

Mientras navegaba por ella observe que la dirección url se presentaba de la siguiente forma:


http://xxxx/yyyy/zzzz.php?$sesion_idioma=1&$menu=1&identifica=participa&nombrexml=104

Ahí había algo que no me cuadraba... eso de $sesion_idioma, $menu, me hace pensar que de alguna forma las variables del código no están siendo filtradas y que las muestra directamente en la barra de direcciones, y probablemente el valor que estas tomen se verá reflejado de alguna forma en el código fuente de la página y con ello el valor que le demos.

Una prueba nos sacará de dudas:


http://xxxx/yyyy/zzzz.php?$sesion_idioma='&$menu=1&identifica=participa&nombrexml=104

Mirando el contenido de la página notamos que ha cambiado, eso me indica que en cierta manera, lo que pase a los parámetros de la url se verá reflejado en el contenido de esta. Pero vamos hacer otra prueba más, y comprobemos si en el código hay alguna parte donde se haga referencia a esto.



Vamos que estábamos en lo cierto y cualquier cosa que coloquemos en las variables se reflejará en el código fuente. Intentemos ejecutar directamente código PHP en cualquiera de las variables, si todo funciona y teníamos razón conseguiremos que en aquellos lugares del código fuente donde se reflejen los valores pasados a las variables se sustituya por el resultado devuelto de la ejecución de nuestra instrucción.

Vamos a probar con lo siguiente:



Simplemente vamos a tratar de realizar una inyección de código, que una vez interpretada por el servidor nos devolverá lo siguiente:


Parece que alguien no ha hecho la tarea bien en más de una ocasión.

El problema de los formularios con cURL

| 1 comentarios |

A veces pensamos que las restricciones que se imponen en algunos portales para poder comentar una noticia o simplemente rellenar los campos de un formulario son una tontería, pero si están ahí es por algo. Ya sea un captcha, autentificación, token o cualquier método que se os pueda ocurrir.

El caso es que si no haces tus deberes como es debido y planteas un mecanismo patatero, te puede costar caro. Y eso es con lo que me he encontrado hace un rato mientras visitaba cierta página web.

Tenemos como escenario un servicio para recomendar la citada web a nuestros contactos mediante un simple formulario con el que enviamos un correo.



Lo primero que se me ha ocurrido ha sido rellenar los datos con valores falsos y poner una cuenta de correo válida para el remitente. El resultado ha sido el esperado y he recibido en mi bandeja de entrada un correo.

Lo siguiente que he pensado ha sido realizar un pequeño script en php que mediante cURL recibiera los parámetros del formulario, los rellenara con los valores que quisiera y con un bucle indicara el número de mensajes que quería hacer llegar a la víctima. El resultado, ha sido el esperado:



Sí, son 360 mensajes en un intervalo de 20 segundos a la cuenta de correo del remitente, ¿alguien necesita viagra?

El script, bastante sencillo no ha ocupado más de 15 líneas [script]. El resto ha sido ejecutar el código en el servidor de pruebas y esperar al resultado:


Denada, todo un placer.


He borrado algunas partes del mismo por razones obvias, no obstante si alguno está interesado en ver cómo funciona cURL puede visitar las páginas de PHP.

19 abr 2010

Adress space layout randomization

| 0 comentarios |

Introducción


Más conocida como ASLR, es una técnica de seguridad que se viene encargando de la aleatorización de direcciones de memoria. De forma que no podamos predecir cuál será la dirección de retorno de un determinado buffer o de cualquier otra dirección que se encuentre en la pila.

Esto complica la tarea de cualquier atacante que intente ejecutar un ataque de return-to-libc que tendrá que buscar el código a ejecutar, o aquellos que traten de ejecutar una shellcode, deberán primero averiguar dónde se encuentra la pila.

¿Cómo funciona?


Para demostrar el funcionamiento vamos a utilizar el siguiente código.Que compilaremos utilizando la opción -ggdb:

$ gcc -ggdb -o Prueba Prueba.c

/tmp/ccCPLK8V.o: In function `main':
/home/sebas/Lab/Ensamblador/Prueba.c:19: warning: the `gets' function is dangerous and should not be used.


El mensaje de aviso, es para indicarnos que la función gets es peligrosa y no debería ser utilizada, esto es debido a que no estamos controlando en ningún momento la longitud que vamos a introducirle y podríamos provocar un buffer overflow.

Si ejecutamos la aplicación y hacemos un grep por el nombre de esta para que nos muestre información del proceso, obtenemos la siguiente información:

$ ps -aux | grep Prueba
Warning: bad ps syntax, perhaps a bogus '-'? See http://procps.sf.net/faq.html
sebas 11777 0.0 0.0 1656 328 pts/0 S+ 00:32 0:00 ./Prueba 10 40
sebas 11783 0.0 0.0 3352 812 pts/1 S+ 00:32 0:00 grep Prueba


El PID es el 11777, ahora podemos buscarlo en la carpeta /proc y mostrar por pantalla cómo está organizada la memoria para permitir la ejecución de la aplicación:

$ cat /proc/11777/maps
08048000-08049000 r-xp 00000000 08:09 850507 /home/sebas/Lab/Ensamblador/Prueba
08049000-0804a000 r-xp 00000000 08:09 850507 /home/sebas/Lab/Ensamblador/Prueba
0804a000-0804b000 rwxp 00001000 08:09 850507 /home/sebas/Lab/Ensamblador/Prueba
b75ac000-b75ad000 rwxp b75ac000 00:00 0
b75ad000-b7709000 r-xp 00000000 08:09 82774 /lib/tls/i686/cmov/libc-2.9.so
b7709000-b770a000 ---p 0015c000 08:09 82774 /lib/tls/i686/cmov/libc-2.9.so
b770a000-b770c000 r-xp 0015c000 08:09 82774 /lib/tls/i686/cmov/libc-2.9.so
b770c000-b770d000 rwxp 0015e000 08:09 82774 /lib/tls/i686/cmov/libc-2.9.so
b770d000-b7710000 rwxp b770d000 00:00 0
b7722000-b7725000 rwxp b7722000 00:00 0
b7725000-b7726000 r-xp b7725000 00:00 0 [vdso]
b7726000-b7742000 r-xp 00000000 08:09 65422 /lib/ld-2.9.so
b7742000-b7743000 r-xp 0001b000 08:09 65422 /lib/ld-2.9.so
b7743000-b7744000 rwxp 0001c000 08:09 65422 /lib/ld-2.9.so
bfaad000-bfac2000 rw-p bffeb000 00:00 0 [stack]


El segmento de direcciones donde se encuentra nuestra pila es bfaad000-bfac2000 y el offset es bffeb000. Si probamos ahora a repetir el mismo proceso (ejecutando la aplicación y averiguando su respectivo PID) obtenemos el siguiente resultado.

$ cat /proc/13372/maps
08048000-08049000 r-xp 00000000 08:09 850507 /home/sebas/Lab/Ensamblador/Prueba
08049000-0804a000 r--p 00000000 08:09 850507 /home/sebas/Lab/Ensamblador/Prueba
0804a000-0804b000 rw-p 00001000 08:09 850507 /home/sebas/Lab/Ensamblador/Prueba
b7668000-b7669000 rw-p b7668000 00:00 0
b7669000-b77c5000 r-xp 00000000 08:09 82774 /lib/tls/i686/cmov/libc-2.9.so
b77c5000-b77c6000 ---p 0015c000 08:09 82774 /lib/tls/i686/cmov/libc-2.9.so
b77c6000-b77c8000 r--p 0015c000 08:09 82774 /lib/tls/i686/cmov/libc-2.9.so
b77c8000-b77c9000 rw-p 0015e000 08:09 82774 /lib/tls/i686/cmov/libc-2.9.so
b77c9000-b77cc000 rw-p b77c9000 00:00 0
b77de000-b77e1000 rw-p b77de000 00:00 0
b77e1000-b77e2000 r-xp b77e1000 00:00 0 [vdso]
b77e2000-b77fe000 r-xp 00000000 08:09 65422 /lib/ld-2.9.so
b77fe000-b77ff000 r--p 0001b000 08:09 65422 /lib/ld-2.9.so
b77ff000-b7800000 rw-p 0001c000 08:09 65422 /lib/ld-2.9.so
bfeed000-bff02000 rw-p bffeb000 00:00 0 [stack]


El segmento donde se encuentra nuestra pila ha cambiado, teniendo ahora el valor de bfeed000-bff02000, lo que se mantiene igual es el valor del offset a bffeb000.

Este hecho viene provocado por la variable del sistema randomize-va-space, que nos permite especificar al sistema el tipo de aleatorización a utilizar, donde:

  • value 0 - Desactiva la aleatorización del espacio de direcciones ocupado por el proceso. Se establece por defecto en aquellos sistemas que no soportan esta característica o son iniciados con el parámetro norandmaps

  • value 1 - Asigna direcciones de memorias aleatorias a mmap base, stack y VDSO page. Entre otras cosas las librerías compartidas son cargadas en direcciones al azar, incluyendo también los binarios de PIE-enlazados y el inicio de ejecución de la aplicación. Se establece por defecto si la opción CONFIG_COMPAT_BRK está activada.

  • value 2 - Adicionalmente habilita la aleatorización del montículo (heap). Se establece por defecto si la opción CONFIG_COMPAT_BRK está desactivada.



Para ver el valor que tenemos asignado basta con: cat /proc/sys/kernel/randomize_va_space y si quieres cambiarla: echo valor_numerico > /proc/sys/kernel/randomize_va_space

Quizás sea oportuno comentar que existen varias formas de saltarse este tipo de protección a día de hoy, y que confiar plenamente en ello puede generarnos una falsa sensación de seguridad que podría ocasionarnos algún que otro disgusto. También se pondrá en duda esa aleatoriedad a la hora de generar los segmentos de memoria, donde comprobaremos que realmente sólo 3 bytes de los 4 que componen nuestra dirección sufrirán variación alguna, provocando que de los 32 bits que esta ocupa, tan sólo sean 24 los que sufren el cambio. Pero de eso hablaremos en otra entrada, hoy sólo vamos a mostrar en qué consiste.

30 mar 2010

SHAbr, fuerza bruta para SHA-1

| 1 comentarios |

Introducción


Cuando hacemos password guessing, el siguiente paso viene a ser obtener en texto plano el valor de algún elemento cifrado (password cracking). Herramientas para eso hay a patadas, pero el otro día buscando alguna que me permitiera realizar un ataque de fuerza bruta con éxito sobre hashes cifrados con SHA-1 me encontré con SHAbr.

Su creador, Daniel Niggerbrugge ha conseguido optimizar el código hasta el punto de alcanzar un total de 60Mhashes/s. Obteniendo buenos resultados para longitudes inferiores a 16 caracteres (eso dice él... la práctica es otra cosa :P). También permite el uso de varios procesadores y utiliza SSE2 para hashear los valores en texto plano.

El código fuente lo podéis encontrar en su blog, por si queréis echarle un vistazo, así como el binario para plataformas Windows.

Uso


El uso de la aplicación es bastante sencillo: shabr SHA1_hash -c charset
Dónde:

  • SHA1_hash: Es el hash de 40 caracteres.

  • -c charset: Es el juego de caracteres a usar (all, loweralpha, upperalpha, mixalpha, numeric, loweralpha-numeric, upperalpha-numeric, mixalpha-numeric).



Como parámetros opcionales tenemos:

  • -B: Establecemos la prioridad por debajo de lo normal

  • -Q: Indicamos que no nos muestre el proceso mientras se ejecuta

  • -t threads: Cantidad de hilos a usar

  • -l max length: Por defecto 15

  • -m min length: Por defecto 1



Práctica


Pero vamos a la parte práctica y hagamos algunas pruebas:


En este caso hemos pasado al programa el hash correspondiente a la palabra "hola y no ha tardado nada en obtenerla. También han sido 4 caracteres loweralpha, así que no le hemos hecho trabajar demasiado.

Pasando un hash loweralpha-numeric obtenemos el siguiente caso de prueba:



Ha tardado 110.79 segundos en sacar abc123, ocupando un 60% de las posibles combinaciones. No esta nada mal.

Sin embargo en este otro caso:



Las pruebas resultan ser demasiado costosas utilizando un juego de caracteres al completo (minúsculas, mayúsculas, símbolos y números). Va por 6 caracteres y ha tardado 10 minutos en completar un 1% (la contraseña era SHA-1br, puesta a maldad). Quizás deberíamos plantearnos hablar de procesamiento paralelo para agilizar el tiempo de cómputo.

No obstante, puede darse el caso de que realmente resulte inviable el hecho de intentar romper el hash de una contraseña. Recordad que a mayor entropía mayor tiempo de cálculo, y viceversa. Pero aun así en esos casos que necesitéis realizar una auditoría de passwords y os encontréis con SHA-1, recordad a SHAbr.