Cómo los hackers se apoderan de los sitios web con SQL Injection y DDoS

imagen

Incluso si solo ha seguido vagamente los eventos de los grupos de piratas informáticos Anonymous y LulzSec, probablemente haya oído hablar de sitios web y servicios pirateados, como los infames ataques de Sony. ¿Te has preguntado alguna vez cómo lo hacen?

Hay una serie de herramientas y técnicas que utilizan estos grupos y, si bien no estamos tratando de darle un manual para que lo haga usted mismo, es útil comprender lo que está sucediendo. Dos de los ataques que escucha constantemente sobre ellos son “Denegación de servicio (distribuida)” (DDoS) e “Inyecciones SQL” (SQLI). Así es como funcionan.

Imagen de xkcd

Ataque de denegación de servicio

imagen

¿Qué es?

Un ataque de «denegación de servicio» (a veces llamado «denegación de servicio distribuida» o DDoS) ocurre cuando un sistema, en este caso un servidor web, recibe tantas solicitudes a la vez que los recursos del servidor están sobrecargados y el sistema simplemente se bloquea y se apaga. El objetivo y el resultado de un ataque DDoS exitoso es que los sitios web del servidor de destino no están disponibles para solicitudes de tráfico legítimas.

¿Como funciona?

La logística de un ataque DDoS se puede explicar mejor con un ejemplo.

Imagine que un millón de personas (los atacantes) se unen con el objetivo de obstaculizar el negocio de la Compañía X al derribar su centro de llamadas. Los atacantes se coordinan para que el martes a las 9 de la mañana todos llamen al número de teléfono de la Compañía X. Lo más probable es que el sistema telefónico de la Compañía X no pueda manejar un millón de llamadas a la vez, por lo que todas las líneas entrantes quedarán bloqueadas por los atacantes. El resultado es que las llamadas legítimas de los clientes (es decir, las que no son los atacantes) no llegan porque el sistema telefónico está atascado en el manejo de las llamadas de los atacantes. Entonces, en esencia, la Compañía X está potencialmente perdiendo negocios debido a que las solicitudes legítimas no pueden llegar.

Un ataque DDoS en un servidor web funciona exactamente de la misma manera. Debido a que prácticamente no hay forma de saber qué tráfico proviene de solicitudes legítimas frente a atacantes hasta que el servidor web procesa la solicitud, este tipo de ataque suele ser muy efectivo.

Ejecutando el ataque

Debido a la naturaleza de «fuerza bruta» de un ataque DDoS, es necesario tener muchos equipos coordinados para atacar al mismo tiempo. Revisando nuestro ejemplo de centro de llamadas, esto requeriría que todos los atacantes supieran que deben llamar a las 9 a.m. y que realmente llamen a esa hora. Si bien este principio ciertamente funcionará cuando se trata de atacar un servidor web, se vuelve significativamente más fácil cuando se utilizan computadoras zombies, en lugar de computadoras tripuladas reales.

Como probablemente sepa, hay muchas variantes de malware y troyanos que, una vez en su sistema, permanecen inactivos y ocasionalmente “llaman a casa” para recibir instrucciones. Una de estas instrucciones podría ser, por ejemplo, enviar solicitudes repetidas al servidor web de la Compañía X a las 9 AM. Por lo tanto, con una sola actualización de la ubicación de inicio del malware respectivo, un solo atacante puede coordinar instantáneamente cientos de miles de computadoras comprometidas para realizar un ataque DDoS masivo.

La belleza de utilizar computadoras zombies no está solo en su efectividad, sino también en su anonimato, ya que el atacante en realidad no tiene que usar su computadora para ejecutar el ataque.

Ataque de inyección SQL

imagen

¿Qué es?

Un ataque de «inyección SQL» (SQLI) es un exploit que se aprovecha de técnicas de desarrollo web deficientes y, generalmente combinado con una seguridad de base de datos defectuosa. El resultado de un ataque exitoso puede variar desde hacerse pasar por una cuenta de usuario hasta comprometer completamente la base de datos o el servidor correspondiente. A diferencia de un ataque DDoS, un ataque SQLI se puede prevenir completa y fácilmente si una aplicación web está programada adecuadamente.

Ejecutando el ataque

Siempre que inicie sesión en un sitio web e ingrese su nombre de usuario y contraseña, para probar sus credenciales, la aplicación web puede ejecutar una consulta como la siguiente:

SELECT UserID FROM Users WHERE UserName='myuser' AND Password='mypass';

Nota: los valores de cadena en una consulta SQL deben estar entre comillas simples, por eso aparecen alrededor de los valores ingresados ​​por el usuario.

Por lo tanto, la combinación del nombre de usuario ingresado (myuser) y la contraseña (mypass) debe coincidir con una entrada en la tabla de Usuarios para que se devuelva un UserID. Si no hay coincidencia, no se devuelve ningún UserID, por lo que las credenciales de inicio de sesión no son válidas. Si bien una implementación en particular puede diferir, la mecánica es bastante estándar.

Entonces, ahora veamos una consulta de autenticación de plantilla que podemos sustituir los valores que ingresa el usuario en el formulario web:

SELECCIONE ID de usuario DE Usuarios DONDE UserName = ‘[usuario]’ Y Contraseña = ‘[contraseña]’

A primera vista, esto puede parecer un paso sencillo y lógico para validar fácilmente a los usuarios; sin embargo, si se realiza una simple sustitución de los valores ingresados ​​por el usuario en esta plantilla, es susceptible a un ataque SQLI.

Por ejemplo, suponga que se ingresa “myuser’–” en el campo de nombre de usuario y se ingresa “wrongpass” en la contraseña. Usando una sustitución simple en nuestra consulta de plantilla, obtendríamos esto:

SELECT UserID FROM Users WHERE UserName='myuser'--' AND Password='wrongpass'

Una clave de esta afirmación es la inclusión de los dos guiones (--). Este es el token de comentario inicial para declaraciones SQL, por lo que cualquier cosa que aparezca después de los dos guiones (inclusive) será ignorada. Básicamente, la base de datos ejecuta la consulta anterior como:

SELECT UserID FROM Users WHERE UserName='myuser'

La omisión evidente aquí es la falta de verificación de contraseña. Al incluir los dos guiones como parte del campo de usuario, pasamos por alto por completo la condición de verificación de contraseña y pudimos iniciar sesión como «myuser» sin conocer la contraseña respectiva. Este acto de manipular la consulta para producir resultados no deseados es un ataque de inyección SQL.

¿Qué daño se puede hacer?

Un ataque de inyección SQL es causado por una codificación de aplicación negligente e irresponsable y es completamente prevenible (que cubriremos en un momento), sin embargo, la extensión del daño que se puede hacer depende de la configuración de la base de datos. Para que una aplicación web se comunique con la base de datos de backend, la aplicación debe proporcionar un inicio de sesión a la base de datos (tenga en cuenta que esto es diferente al inicio de sesión de un usuario en el sitio web). Dependiendo de los permisos que requiera la aplicación web, esta cuenta de base de datos respectiva puede requerir cualquier cosa, desde permisos de lectura / escritura en tablas existentes hasta acceso completo a la base de datos. Si esto no está claro ahora, algunos ejemplos deberían ayudar a proporcionar algo de claridad.

Según el ejemplo anterior, puede ver que al ingresar, por ejemplo, "youruser'--", "admin'--"o cualquier otro nombre de usuario, podemos iniciar sesión instantáneamente en el sitio como ese usuario sin conocer la contraseña. Una vez que estamos en el sistema, no sabemos que en realidad no somos ese usuario, por lo que tenemos acceso completo a la cuenta correspondiente. Los permisos de la base de datos no proporcionarán una red de seguridad para esto porque, por lo general, un sitio web debe tener al menos acceso de lectura / escritura a su base de datos respectiva.

Ahora supongamos que el sitio web tiene el control total de su base de datos respectiva, lo que brinda la capacidad de eliminar registros, agregar / eliminar tablas, agregar nuevas cuentas de seguridad, etc. Es importante tener en cuenta que algunas aplicaciones web podrían necesitar este tipo de permiso, por lo que No es automáticamente malo que se conceda el control total.

Entonces, para ilustrar el daño que se puede hacer en esta situación, usaremos el ejemplo provisto en el cómic anterior ingresando lo siguiente en el campo del nombre de usuario: "Robert'; DROP TABLE Users;--".Después de una simple sustitución, la consulta de autenticación se convierte en:

SELECT UserID FROM Users WHERE UserName='Robert'; DROP TABLE Users;--' AND Password='wrongpass'

Nota: el punto y coma en una consulta SQL se usa para indicar el final de una declaración en particular y el comienzo de una nueva declaración.

Que es ejecutado por la base de datos como:

SELECT UserID FROM Users WHERE UserName='Robert'

Usuarios de DROP TABLE

Así que así, hemos utilizado un ataque SQLI para eliminar toda la tabla de usuarios.

Por supuesto, se puede hacer mucho peor ya que, dependiendo de los permisos SQL permitidos, el atacante puede cambiar valores, volcar tablas (o toda la base de datos) a un archivo de texto, crear nuevas cuentas de inicio de sesión o incluso secuestrar toda la instalación de la base de datos.

Prevenir un ataque de inyección SQL

Como mencionamos varias veces anteriormente, un ataque de inyección de SQL se puede prevenir fácilmente. Una de las reglas cardinales del desarrollo web es que nunca confías ciegamente en la entrada del usuario como lo hicimos cuando realizamos una sustitución simple en nuestra consulta de plantilla anterior.

Un ataque SQLI se frustra fácilmente mediante lo que se denomina desinfectar (o escapar) sus entradas. El proceso de desinfección es bastante trivial, ya que todo lo que esencialmente hace es manejar cualquier carácter de comillas simples (‘) en línea de manera adecuada, de modo que no se puedan usar para terminar prematuramente una cadena dentro de una declaración SQL.

Por ejemplo, si quisiera buscar «O’neil» en una base de datos, no podría usar una sustitución simple porque la comilla simple después de la O haría que la cadena terminara prematuramente. En su lugar, lo desinfecta utilizando el carácter de escape de la base de datos correspondiente. Supongamos que el carácter de escape de una comilla simple en línea precede a cada cita con un símbolo \. Entonces «O’neal» se desinfectaría como «O \ ‘neil».

Este simple acto de saneamiento prácticamente previene un ataque SQLI. Para ilustrar, revisemos nuestros ejemplos anteriores y veamos las consultas resultantes cuando la entrada del usuario se desinfecta.

myuser'--/ paso incorrecto :

SELECT UserID FROM Users WHERE UserName='myuser\'--' AND Password='wrongpass'

Debido a que la comilla simple después de myuser se escapa (lo que significa que se considera parte del valor objetivo), la base de datos buscará literalmente el UserName de "myuser'--".Además, debido a que los guiones se incluyen dentro del valor de la cadena y no en la declaración SQL en sí, serán considerado parte del valor objetivo en lugar de ser interpretado como un comentario SQL.

Robert'; DROP TABLE Users;--/ paso incorrecto :

SELECT UserID FROM Users WHERE UserName='Robert\'; DROP TABLE Users;--' AND Password='wrongpass'

Al simplemente escapar de la comilla simple después de Robert, tanto el punto y coma y los guiones están contenidos dentro de la cadena de búsqueda UserName, por lo que la base de datos buscará literalmente en "Robert'; DROP TABLE Users;--"lugar de ejecutar la eliminación de la tabla.

En resumen

Si bien los ataques web evolucionan y se vuelven más sofisticados o se enfocan en un punto de entrada diferente, es importante recordar protegerse contra ataques probados y verdaderos que han sido la inspiración de varias “herramientas de piratas informáticos” disponibles gratuitamente diseñadas para explotarlos.

Ciertos tipos de ataques, como DDoS, no se pueden evitar fácilmente, mientras que otros, como SQLI, sí. Sin embargo, el daño que pueden causar este tipo de ataques puede variar desde un inconveniente hasta catastrófico, dependiendo de las precauciones que se tomen.