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