Incluso si solo ha seguido vagamente los eventos de los grupos de hackers Anonymous y LulzSec, probablemente haya oído hablar de sitios web y servicios que han sido 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 intentamos 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
¿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 al mismo tiempo 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 en el 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.
Imagínese un millón de personas (los atacantes) que se reúnen con el objetivo de obstaculizar el negocio de la Compañía X desmantelando 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 llamar a las 9 a. 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 a.m. 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 radica solo en su efectividad, sino también en su anonimato, ya que el atacante no tiene que usar su computadora para ejecutar el ataque.
Ataque de inyección SQL
¿Qué es?
Un ataque de "inyección SQL" (SQLI) es un exploit que se aprovecha de técnicas de desarrollo web deficientes y, normalmente 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:
SELECCIONE ID de usuario DE Usuarios DONDE UserName = 'myuser' Y Contraseña = '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 particular puede diferir, la mecánica es bastante estándar.
Así que ahora veamos una consulta de autenticación de plantilla que podemos sustituir los valores que el usuario ingresa en el formulario web:
SELECCIONE ID de usuario DE Usuarios DONDE UserName = '[user]' Y Contraseña = '[pass]'
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, supongamos que se ingresa "myuser'–" en el campo del nombre de usuario y se ingresa "wrongpass" en la contraseña. Usando una sustitución simple en nuestra consulta de plantilla, obtendríamos esto:
SELECCIONE ID de usuario DE Usuarios DONDE 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:
SELECCIONE ID de usuario DE Usuarios DONDE 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, omitimos 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 back-end, la aplicación debe proporcionar un inicio de sesión en 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 ingresando, por ejemplo,
"suusuario '-", "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 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. No es automáticamente algo malo que se otorgue 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:
SELECCIONE ID de usuario DE Usuarios DONDE UserName = 'Robert'; DROP TABLE Usuarios; - 'AND Password =' wrongpass '
Nota: el punto y coma en una consulta SQL se utiliza 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:
SELECCIONE ID de usuario DE Usuarios DONDE 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 en realidad bastante trivial, ya que todo lo que esencialmente hace es manejar cualquier carácter de comillas simples (") en línea de manera apropiada, de modo que no se puedan usar para terminar prematuramente una cadena dentro de una declaración SQL.
Por ejemplo, si desea buscar "O’neil" en una base de datos, no puede 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 respectiva. Supongamos que el carácter de escape de una comilla simple en línea precede a cada comilla 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 se desinfecta la entrada del usuario.
myuser '-
/
paso incorrecto
:
SELECCIONE ID de usuario DE Usuarios DONDE 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 en el valor de la cadena y no en la declaración SQL en sí, se considerarán parte del valor objetivo en lugar de interpretarse como un comentario SQL.
Robert '; Usuarios de DROP TABLE; -
/
paso incorrecto
:
SELECCIONE ID de usuario DE Usuarios DONDE UserName = 'Robert \'; DROP TABLE Usuarios; - '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 literalmente buscará
"Robert '; DROP TABLE Users; -"
en 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.