Mostrando entradas con la etiqueta mysql. Mostrar todas las entradas
Mostrando entradas con la etiqueta mysql. Mostrar todas las entradas

12 junio 2012

Vulnerabilidad grave en MySQL/MariaDB - CVE-2012-2122

No es el día de los Santos Inocentes, ni de aquí (28 de Diciembre) ni internacional (April's Fool). El sábado 9 de Junio  Sergei Golubchik, coordinador de seguridad de MariaDB publicaba un post en la lista OSS-SEC sobre una grave vulnerabilidad que afectaba a diferentes versiones de MySQL y MariaDB.

Se evidencia la posibilidad de autenticarse como usuario con máximos privilegios (root) únicamente realizando conexiones simultáneas, con CUALQUIER contraseña introducida como parámetro y contra un servidor vulnerable. Al cabo de un número indeterminado de intentos fallidos, el servidor aceptará la conexión y se realizará la autenticación de forma satisfactoria. Sin más. Sin shellcodes raras, sin casuísticas extrañas: únicamente tenemos que tener delante un servidor vulnerable, que cumpla con las siguientes versiones:

  • Son vulnerables todas las versiones de MariaDB y MySQL hasta la 5.1.61, 5.2.11, 5.3.5 y 5.5.22
  • NO SON vulnerables las versiones de MySQL 5.1.63, 5.5.24 y 5.6.6
  • NO SON vulnerables las versiones de MariaDB 5.1.62, 5.2.12, 5.3.6 y 5.5.23
Con la siguiente línea en shell script, teniendo instalada una base de datos vulnerable en el sistema local, y contando con el cliente 'mysql', se podría realizar una autenticación como usuario root sin conocer la contraseña:

for i in `seq 1 1000`; do mysql -u root --password=blablabla -h 127.0.0.1 2>/dev/null; done

Básicamente, se ejecutará la sentencia de autenticación mediante cliente por consola (comando mysql) como usuario root (-u root) y cualquier contraseña (--password=blablabla) contra el servidor vulnerable  presente en el mismo sistema donde se ejecuta este script (-h 127.0.0.1), sin mostrar ningún mensaje de error por pantalla (2>/dev/null).

Vamos a ver el ejemplo real. Las siguientes pruebas se han realizado sobre una Fedora Core 16, con MySQL versión 5.5.21:


En primer lugar, y para este ejemplo, cambiaremos la contraseña original de MySQL para el usuario root, que antes la teníamos establecida a 'password', para que ahora sea 'SuperPassWordDeLaMuerte':


Seguidamente, salimos de la sesión de root, y nos quedamos como usuario sin privilegios, y ejecutamos la secuencia anterior, que realizará conexiones como usuario root y cualquier contraseña, programando un total de 1000 intentos. A continuación se ejecutará la consola de mysql satisfactoriamente:



Comprobamos el usuario con el que estamos autenticados mediante la sentencia select current_user(), obteniendo como resultado 'root@localhost'


Obviamente, este "ataque" ya se encuentra integrado como exploit de Metasploit Framework, permitiendo además el volcado de hashes de todos los usuarios, todo ello con el módulo mysql_authbypass_hashdump:



Enhorabuena desde SecurityByDefault a los descubridores de este bug, verlo para creerlo...De momento, ¡una de las vulnerabilidades descubiertas favoritas para este año 2012!



Leer más...

10 septiembre 2010

Fortificación de MySQL - 3/3

Parte 1 de 3
Parte 2 de 3
Parte 3 de 3

Continuamos con la tercera y última entrada sobre fortificación de MySQL.

 14.- Comprobación de permisos de ficheros de registros, de configuración y archivos SSL: para que únicamente el usuario que ejecuta la base de datos tenga permisos de lectura y escritura. Estos ficheros se encuentran generalmente en /var/log/mysql/etc/mysql/my.cnf. Los archivos SSL son especificados en las variables: ssl_ca, ssl_cert, ssl_key
shell> ls -l /var/log/mysql
shell> ls -l /etc/mysql/my.cnf
mysql> show variables like "%ssl%";

15.-Actualizar tablas de privilegios mediante el uso de los scripts "mysql_upgrade" y "mysql_fix_privilege_tables" cuando se actualice la base de datos a una nueva versión.
shell> ls -l /var/log/mysql
shell> mysql_fix_privilege_tables --password=ecm2sux
This script updates all the mysql privilege tables to be usable by
the current version of MySQL
done

16.-Verificacar las contraseñas para que todas utilicen el nuevo sistema de hash y asegurar que no existen usuarios sin contraseña. El antiguo hash tenía una longitud de 16 caracteres y el nuevo de 42, por lo tanto la siguiente consulta no debería mostrar resultados:
mysql> select User, Password from mysql.user where length(password) < 41;
Otra opción es habilitar la variable "secure_auth", para deshabilitar directamente estos usuarios, para consultar el estado:
mysql> show variables like "secure_auth"
Los usuarios con contraseñas en blanco se pueden localizar con la consulta:
mysql> select User, Password from mysql.user where length(password) = 0 or password is null;

17.- Comprobación de los hosts permitidos para los usuarios  con el objetivo de que no existan usuarios que puedan realizar la conexión desde cualquier dirección IP. Todos aquellos usuarios que devuelva la siguiente consulta han de ser revisados:
mysql> select user from  mysql.user where host =  '%';

18.- Búsqueda de usuarios con privilegios especiales, que no deberían tener habilitados para usos normales. Los permisos a comprobar son: FILE, PROCESS, SUPER, SHUTDOWN, CREATE USER y RELOAD:
mysql> select user, host from mysql.user where File_priv = 'Y';
mysql> select user, host from mysql.user where Process_priv = 'Y';
mysql> select user, host from mysql.user where Super_priv = 'Y';
mysql> select user, host from mysql.user where Shutdown_priv = 'Y';
mysql> select user, host from mysql.user where Create_user_priv = 'Y';
mysql> select user, host from mysql.user where Reload_priv = 'Y';

19.- Deshabilitar la fusión (MERGE) de tablas que permite acceder a datos incluso si no hay permisos sobre ellas. Para llevar a cabo esta configuración se puede consultar el estado en la variable "have_merge_engine"  y para implantarlo, añadir el parámetro --skip-merge

20.- Deshabilitar el uso de enlaces simbólicos que pueden ser peligrosos especialmente si el usuario que ejecuta la base de datos es root y puede sobrescribir otros ficheros. Para aplicar la medida se define la variable "have_symlink" o el parámetro --skip-symbolic-links
[mysqld]
skip-symbolic-links=on


Referencias:
Leer más...

16 agosto 2010

Fortificación de MySQL - 2/3

Parte 1 de 3
Parte 2 de 3
Parte 3 de 3


Continuamos con la segunda entrada sobre fortificación de MySQL.

7.- Uso de los mínimos privilegios: aplicable a versiones anteriores del motor 5.x. Las bases de datos se han de almacenar propiedad del usuario mysql u otro creado para tal propósito sin privilegios de administración del sistema operativo.
Para comprobar los permisos:

shell> ls -l /var/lib/mysql 
Todos los directorios deberían mostrarse como usuario mysql y grupo mysql, con permisos 700 o lo que es lo mismo: "drwx------". Para modificar el usuario y grupo de un directorio y posteriormente sus permisos:
shell> chown mysql:mysql /var/lib/mysql/mibbdd
shell> chmod 700 /var/lib/mysql/mibbdd

El servicio ha de ser ejecutado con este usuario, que además no puede tener permisos para conectarse localmente. En sistemas Unix, el usuario ha de tener como shell el binario /sbin/nologin

Para comprobar la shell:
shell> grep mysql /etc/passwd
mysql:x:27:491:MySQL Server:/var/lib/mysql:/bin/bash 
Para cambiar la shell:
shell> chsh -s /sbin/nologin mysql 

En el caso de Windows, el usuario ha de estar incluido en los Deny log on locally y ejecutado como usuario NETWORK_SERVICE

8.- Permisos de administración en usuarios: la base de datos dispone de usuarios al igual que el sistema operativo, root es el administrador y únicamente debería ser utilizado para tareas de gestión como altas y bajas de otros usuarios, modificación de permisos, etcétera. Es importante que no se use al usuario root para el acceso a datos. Al igual que los usuarios que tratan datos (selects, inserts o updates) no han de tener habilitados permisos especiales, ya que en caso de encontrarse una inyección de código podrían ejecutarse tareas con privilegios mayores.

Para consultar la lista de usuarios y sus permisos:
mysql> use mysql;
mysql; select * from user;
Para ver los permisos de un usuario en concreto:
mysql> show grants for ‘root’@’localhost’;
El siguiente ejemplo muestra la modificación del usuario "miuser" en la base de datos "mibbdd", dejando únicamente INSERT, SELECT, UPDATE y DELETE:
mysql> show grants for miuser@localhost;
+--------------------------------------------------------------------------------------+
| Grants for miuser@localhost                                                         |
+--------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'miuser'@'localhost' IDENTIFIED BY PASSWORD '6212cdea5883c099' |
| GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX,
 ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW,
 CREATE ROUTINE, ALTER ROUTINE ON `mibbdd`.* TO 'miuser'@'localhost' |
+--------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)

mysql> revoke all privileges on mibbdd.* from 'miuser'@'localhost';
Query OK, 0 rows affected (0.11 sec)

mysql> show grants for miuser@localhost;
+--------------------------------------------------------------------------------------+
| Grants for miuser@localhost                                                          |
+--------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'miuser'@'localhost' IDENTIFIED BY PASSWORD '6212cdea5883c099' |
+--------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> grant select,insert,update,delete on mibbdd.* to 'miuser'@'localhost';
Query OK, 0 rows affected (0.00 sec)

mysql> show grants for miuser@localhost;
+--------------------------------------------------------------------------------------+
| Grants for miuser@localhost                                                          |
+--------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'miuser'@'localhost' IDENTIFIED BY PASSWORD '6212cdea5883c099' |
| GRANT SELECT, INSERT, UPDATE, DELETE ON `mibbdd`.* TO 'miuser'@'localhost'           |
+--------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)
9.- Eliminación de visualización de base de datos: con esta medida se pretende que los usuarios no puedan conocer que otras bases de datos se encuentran en el servidor, eliminando el acceso comando SHOW DATABASES. Para aplicar esta opción, se puede arrancar el servicio mysqld con el parámetro "--skip-show-database" o añadir al archivo de configuración este mismo nombre:
[mysqld]
skip-show-database
Si por algún motivo se desea asignar este privilegio a un usuario, se puede llevar a cabo mediante el GRANT correspondiente.

10.- Configuración de los registros: siempre y cuando el sistema no haga demasiadas peticiones, se pueden almacenar todas las peticiones que reciba el servicio. Esta opción no es recomendable si la base de datos tiene mucho tráfico ya que genera mucha carga e información en disco. Para activarla, modificar el archivo my.cnf con:
[mysqld]
log=/var/log/mylogfile
Este fichero log, al igual que el de registro, como el de errores, el archivo binario, o el de consultas lentas solo han de tener permisos para los usuarios mysql y root. Puede causar problemas importantes de confidencialidad si otros usuarios del sistema tienen acceso.

11.- Almacenar los datos de la base de datos en una partición distinta al sistema operativo: evitando que la base de datos sufra pérdidas por ataques de denegación de servicio que llenen el disco duro libre del sistema operativo.
[mysqld]
datadir=/path/dir
12.- Eliminación del historial del cliente de MySQL: que almacena los comandos ejecutados por el cliente mysql y puede facilitar información crítica. Para configurarlo, añadir la siguiente línea al /etc/profile:
declare -r MYSQL_HISTFILE=/dev/null
Además es recomendable crear un enlace de los ficheros a /dev/null también.

shell> ln -s /dev/null $HOME/.mysql_history
13.- Comprobación de contraseñas almacenadas en texto claro: que se guardan en la variable de entorno MYSQL_PWD y en el archivo de configuración, bajo la directiva password.

Para evitar que se use la variable de entorno añadir al archivo /etc/profile:
declare -r MYSQL_PWD
En el archivo de configuración comprobar que no existe la linea "password":
[client]
password=TuContraseña


Referencias:
Leer más...

09 agosto 2010

Fortificación de MySQL - 1/3

Parte 1 de 3
Parte 2 de 3
Parte 3 de 3
 
MySQL se ha convertido en el motor de bases de datos más usado y potente del mundo opensource. Pero debido a la versatilidad que ofrece,  la configuración por defecto en los paquetes de distribución y el suyo propio no considera todos los aspectos de seguridad que se han de contemplar en un entorno controlado.

Las siguientes entradas pretenden enumerar brevemente cuales son los puntos más importantes que se deberían revisar en una implantación segura de esta aplicación.

El archivo de configuración de MySQL se encuentra en el archivo: "C:\Program Files\MySQL\MySQL Server 5.x" en el caso de Windows o /etc/mysql/my.cnf en el caso de sistemas Linux.

1.- Restringir o deshabilitar el acceso mediante red: si el servicio se encuentra en el mismo equipo que la aplicación que realiza las consultas no es necesario que mysql escuche peticiones en todos los interfaces de red. Una de las medidas más importantes es dejar únicamente el puerto abierto en aquellas IPs donde sea estrictamente necesario. Para efectuar este cambio y que solo se pueda conectar localmente, en la sección [mysqld] indicar:
[mysqld]
bind-address=127.0.0.1
Si por el contrario queremos deshabilitar por completo el acceso mediante un socket de red, basta con añadir la directiva skip-network:
[mysqld]
skip-networking

Por último, si se ha de utilizar el servicio en remoto, todos los usuarios de las aplicaciones que conecten deben estar limitados mediante su dirección de origen (host). Desde el prompt de mysql:
mysql> GRANT SELECT, INSERT ON basededatos.* TO 'usuario'@'host';

2.- Eliminar el acceso a la tabla "user" de la base de datos a todos los usuarios excepto los de administración: de esta forma otros usuarios del motor no podrán consultar las contraseñas y accesos que contiene MySQL.

Para ver los privilegios de un usuario:
mysql> SHOW GRANTS FOR 'usuario'@'host';
Para eliminar privilegios:
mysql> REVOKE ALL PRIVILEGES, GRANT OPTION FROM usuario;

3.- Deshabilitar el uso de LOCAL INFILE: mediante estos permisos se pueden leer ficheros del sistema operativo desde la base de datos, algo común cuando se explota una inyección de código SQL. Para deshabilitar esta función se configura la variable local-infile a 0:

En MySQL  anterior a 5.5
[mysqld]
set-variable=local-infile=0

Para MySQL 5.1 o superior:
[mysqld]
local-infile=0

4.- Cambio de nombre de usuario root y su contraseña: al igual que en los sistemas operativos, se recomienda que el administrador de la base de datos no sea el usuario root y mantenga una contraseña segura. Si MySQL es una versión superior a 5.0.2
mysql> RENAME USER root TO r00tz

En caso de que la versión de MySQL sea inferior:
mysql> use mysql;
mysql> update user set user="nuevousuario" where user="root";
mysql> flush privileges;

Para modificar la contraseña de un usuario se puede utilizar el comando mysqladmin o se puede hacer mediante SQL:
mysql> use mysql;
mysql> SET PASSWORD FOR 'username'@'%hostname' = PASSWORD('newpass');
5.- Eliminar la base de datos "test": que se distribuye con el servicio y no es necesaria. Para hacerlo directamente en SQL:
mysql> drop database test;
O mediante línea de comandos:
shell> mysqladmin -u username -p drop test 

6.- Eliminación de cuentas obsoletas y acceso anónimo: que son creadas en algunas instalaciones de MySQL, para comprobar si existen este tipo de usuarios:
mysql> select * from mysql.user where user="";
Si se muestran usuarios, se pueden eliminar mediante DROP USER (en MySQL 5)
mysql> DROP USER "";

Si la versión de MySQL es inferior a 5.0:
mysql> use mysql;
mysql> DELETE FROM user WHERE user="";
mysql> flush privileges;


Referencias:

Leer más...

12 enero 2010

¿0Day en MySQL?


Hace tiempo que el negocio de las vulnerabilidades irrumpió en el mundo de la seguridad y a su calor, nacieron múltiples empresas que recompensan a los descubridores con sumas nada despreciables de dinero a cambio de la información.

Según leo en el SANS, una de estas empresas, intevydis que comercializa un 'pack' de exploits para la herramienta Canvas, ha colgado un video en el que muestra un supuesto 0day para MySQL versiones 5.x (la última versión es 5.1)

¿realidad o hoax? El tiempo lo dirá, aun así conviene no perder la pista a los servidores en los que tengamos MySQL en ejecución.
Leer más...