INTRODUCCIÓN
En la actualidad, un gran número de sitios y aplicaciones web interactúan con bases de datos, muchas veces es porque a través de éstos, se maneja información de diferentes tipos y niveles de acceso, que deben ser almacenados, consultados o modificados, es decir, gestionados de algún modo. Toda esta información es accedida a través de sentencias SQL, embebidas desde el mismo código fuente de la página o scripts incluidos que son el objetivo de los delincuentes que buscan obtener acceso no permitido a las aplicaciones y/o información contenida en las bases de datos.
RESUMEN
El SQL Inyection es una práctica muy común en los últimos días debido a que la mayor parte de sitios web del mundo tiene vinculada una base de datos, es decir que tiene interacción con ellas. Los delincuentes informáticos buscan ventaja del desconocimiento por parte de los actuales diseñadores web ya que estos últimos buscan inicialmente funcionalidad de los aplicativos, luego una apariencia agradable y por ultimo aplican algunos mecanismos de seguridad por lo cual esta no es bien aplicada dejando grandes huecos muy difíciles de cubrir por la falta de conocimiento.
HISTORIA DE SQL INJECTION
SQL Inyection se utiliza hace más de 10 años. Incontables bases de datos se han borrado, alterado o robado mediante esta técnica. Muchos accesos y comprobaciones han sido burlados, como también se han obtenido remotamente cuentas de máximo privilegio dentro de los servidores.
Todo esto a través del servidor web (puerto 80 o servicio http) de un sitio.
Metodología
Básicamente, luego del carácter no filtra do (‘ o ;, paréntesis en algunos casos sin
Contar las técnicas de evasión-), es algo más que escribir puro código SQL.
En principio, hay que encontrar un campo o punto vulnerable a la inyección. Ya sea un formulario de acceso user /pass, uno de búsqueda, de recuperación de password, de comprobación de cualquier dato, de contacto, link con variables, links ocultos al público ligados a la DB, scripts y archivos de testeo, CGIs por defecto, aplicaciones del tipo foro y otras de terceros públicas y licenciadas, ya sea vía método GET o POST.
Después, haciendo una previa de data-base gathering o tratando de mapear cuáles son las data-bases del servidor, los nombres, sus tablas, sus registros, sus usuarios y sus privilegios. Generalmente, se utiliza HAVING y GROUP BY para las primeras. Sobre la base de esos datos, se trata de ir armando nuestras consultas inyectadas, puliéndolas, viendo qué sentencias se pueden utilizar, si hay espacios demás, cómo interactuarlas.
EL SQL INYECTION:
La interacción en los sitios web en la mayoría de los casos ocurre así:
· El usuario introduce datos en un formulario o hace clic en un link del tipo
· El sitio web podría estar programado en .asp o php y este a su vez contendrá, en su código fuente, strings SQL (sentencias).
· Éstas, junto con los datos suministrados por el visitante, irán directamente a la base de datos. La accederán y esta les retornará la información requerida.
· El resultado puede mostrarse al usuario o no, o bien puede dar un error de sistema.
La ausencia de seguridad en la mayor parte de los portales obedece a que el empeño de los actuales diseñadores se centra en apariencia, diseño y facilidad
dejando la seguridad en el último plano, esta seguridad mal aplicada consiste la mayor parte de veces en el número máximo de campos a introducir, el tipo de caracteres y la inclusión o no de caracteres especiales, estas reglas se pueden evadir mediante la manipulación del código SQL alcanzo el objetivo que es el atacar las páginas web parta sacar provecho de la información obtenida.
dejando la seguridad en el último plano, esta seguridad mal aplicada consiste la mayor parte de veces en el número máximo de campos a introducir, el tipo de caracteres y la inclusión o no de caracteres especiales, estas reglas se pueden evadir mediante la manipulación del código SQL alcanzo el objetivo que es el atacar las páginas web parta sacar provecho de la información obtenida.
La primera ley del desarrollador web en cuanto seguridad es:
· Jamás con fiar en que todos los usuarios o visitantes introducirán los datos correctos o esperados dentro de un formulario online.
La segunda regla es no creer que todos los visitantes vayan a respetar la sintaxis de la URL de consulta sin modificarla al realizar el query o petición http.
· By pass de acceso
Dentro del archivo .asp está la sentencia SQL o rutina de validación para el acceso a una intranet. Esta acción proveniente de la orden o sentencia que verificara el usuario, password y cuenta sean correctos para acceder al visitantes, en caso de que los datos sean ingresados correctamente.
SELECT id FROM login WHERE usuario = ‘$usuario’ AND clave = ‘$clave’ AND cuenta = ‘$cuenta’
Ahora bien, ¿Cómo el intruso inyectará una sentencia SQL en lugar de colocar usuario, password y cuenta? Es muy simple. Si los campos de datos, la aplicación y el gestor de datos no están sanitizados (no escapa a los caracteres especiales) y asegurados, se podrá incluir una comilla simple ‘y seguido a ella, el resto de lo que será interpretado por el gestor de base de datos como código SQL.
SELECT id FROM login WHERE usuario = ‘admin’ AND clave = ‘‘ ‘ OR 1=1 AND cuenta = 0303456
Un parámetro no esperado, como esta comilla, cambia el comportamiento de la aplicación. De este modo, si el usuario es el admin y tiene un password /condición, si 1 es igual a 1 (que por su puesto lo es), éste será validado y tendrá acceso a la intranet.
· Herramientas automatizadas
Existen decenas de herramientas que son capaces de trabajar de modo automatizado en algunos aspectos de la inyección de código SQL.
Estas herramientas no son mágicas, ya que por sí solas no pueden hacer mucho sinla lógica que le apliquemos nosotros y la configuración necesaria para que nos brinden algún tipo de ventaja en tiempo o resultado. Es conveniente tomar se el tiempo que sea necesario y hacer el chequeo de la aplicación a mano. Cuando necesitamos automatizar algo (sabiendo que podemos sacar provecho de ello), podemos usar las
herramientas que aparecen a continuación.
· Sql ninja
Su sitio oficial es: http://sqlninja.sourceforge.net, y sus características destacadas son:
• Detección vía fingerprint del servidor SQL remoto: versión, usuario que ejecuta la aplicación, privilegios de éste, verifica disponibilidad de xp_cmdshell y modo de autentificación DB.
• Brute force del usuarios vía diccionario e incremental.
• Creación de un xp_cmdshell si el original fue removido.
• Upload de archivos, net, cat o cualquier ejecutable utilizando http.
• Escaneo de TCP/UDP hacia el atacante para encontrar un puerto y así a través de la red poder atacar.
· Sql map:
Esta herramienta tiene gran cantidad de funciones, entre ellas:
· Muestra versiones de los objetivos y tecnología.
· Muestra contenidos de los archivos, en el caso de MySQL
· Mapea en texto plano el contenido de los registros.
· Muestra los usuarios y privilegios involucrados.
· Muestra los nombres de las tablas y bases de datos existentes en el objetivo.
· SQL Inyection Pentesting Tool
Esta es una herramienta bajo Windows muy amigable que muestra diversas vulnerabilidades de los sitios a analizar.
· Inyecta a través de POST y GET con cookies.
· Sube archivos al servidor.
· Lee archivos del servidor.
· Hace dumping en las bases de datos.
· Ejecuta Shell inversas desde las bases de datos.
Algunas formas de evitar la Inyección SQL en los diversos lenguajes de programación en entornos WEB.
· PHP
En el lenguaje PHP, hay diferentes funciones que pueden servir de ayuda para usar con distintos sistemas de gestión de bases de datos. Para MySQL, la función a usar es mysql_real_escape_string:
$query_result = mysql_query("SELECT * FROM usuarios WHERE nombre = \"" . mysql_real_escape_string($nombre_usuario) . "\"");
· Java
En lenguaje Java, se puede usar la clase PreparedStatement en lugar de:
Connection con = (acquire Connection)
Statement stmt = con.createStatement();
ResultSet rset = stmt.executeQuery("SELECT * FROM usuarios WHERE nombre = '" + nombreUsuario + "';");
· Perl
En lenguaje Perl DBI, el método DBI::quote filtra los caracteres especiales (asumiendo que la variable $sql contiene una referencia a un objeto DBI):
$query = $sql->prepare
(
"SELECT * FROM usuarios WHERE nombre = "
.
$sql->quote($nombre_usuario)
);
O también se puede usar la característica placeholder (con comillado automático) como sigue:
$query = $sql->prepare("SELECT * FROM usuario WHERE nombre = ?");
$query->execute($nombre_usuario);
· En C#
En lenguaje C#, de la plataforma .NET (o su alternativa libre Mono), se tiene ADO.NET SqlCommand (para Microsoft SQL Server) o OracleCommand (para servidores de bases de datos Oracle). El ejemplo siguiente muestra cómo prevenir los ataques de inyección de código usando el objeto SqlCommand. El código para ADO.NET se programa de forma similar, aunque puede variar levemente según la implementación específica de cada proveedor.
En vez de:
using( SqlConnection con = (acquire connection) ) {
con. Open();
using( SqlCommand cmd = new SqlCommand("SELECT * FROM usuarios WHERE nombre = '" + nombreUsuario + "'", con) ) {
using( SqlDataReader rdr = cmd.ExecuteReader() ){
...
}
}
}
se podría usar lo siguiente:
using( SqlConnection con = (acquire connection) ) {
con. Open();
using( SqlCommand cmd = new SqlCommand("SELECT * FROM usuarios WHERE nombre = @nombreUsuario", con) ) {
cmd.Parameters.AddWithValue("@nombreUsuario", nombreUsuario);
using( SqlDataReader rdr = cmd.ExecuteReader() ){
...
}
}
}
· Ruby on Rails
En el framework Ruby on Rails RoR), las consultas son verificadas automáticamente por cualquiera de los métodos de búsqueda incluidos.
Por ejemplo:
Project.find(:all, :conditions => ["name = ?", params[:name]])
# o bien
Project.find(:all, :conditions => {:name => params[:name]})
La única forma de que un usuario mal intencionado pueda usar una inyección de SQL en RoR es que mediante código se transforme la variable a tipo string y se utilice como argumento de la búsqueda directamente.
Por ejemplo:
Project.find(:all, :conditions => "name = '#{params[:name]}'")
· Parametrización de sentencias SQL
Connection con = (acquire Connection)
PreparedStatement pstmt = con.prepareStatement("SELECT * FROM usuarios WHERE nombre = ?");
pstmt.setString(1, nombreUsuario);
ResultSet rset = pstmt.executeQuery();
· Escape de las variables a insertar en la sentencia SQL
Escapar el texto contenido en la variable reemplazando los caracteres especiales en SQL por su equivalente textual, de tal forma que SQL interprete todo el contenido de la variable como si fuera texto.
Connection con = (acquire Connection)
Statement stmt = con.createStatement();
ResultSet rset = stmt.executeQuery("SELECT * FROM usuarios WHERE nombre = '" + nombreUsuario.replace("\\", "\\\\").replace("'", "\\'") + "';");
También se puede utilizar el método escapeSQL de la clase StringEscapeUtils procedente de la librería de Apache Commons Lang
Connection con = (acquire Connection)
Statement stmt = con.createStatement();
ResultSet rset = stmt.executeQuery("SELECT * FROM usuarios WHERE nombre = '" + StringEscapeUtils.escapeSQL(nombreUsuario) + "';");
REFERENCIAS
No hay comentarios:
Publicar un comentario