FTP
File Transfer Protocol (FTP) nació para mover archivos entre hosts que podían tener sistemas y representaciones de datos diferentes. Separó la conversación de control de la transferencia propiamente dicha: una conexión recibe comandos y códigos, mientras otra transporta listados o archivos. Esa decisión permitió elegir quién abre el canal de datos y cómo se representa el contenido. También dejó una arquitectura que atraviesa NAT y firewalls con más dificultad que un protocolo de una sola conexión.
Enumerar FTP significa reconstruir ambas conversaciones. Un login correcto solo confirma el canal de control. Un listado bloqueado puede revelar que el puerto pasivo no es alcanzable. Una subida aceptada puede terminar en un directorio diferente por chroot o permisos. Producto, identidad, raíz visible, modo activo o pasivo y protección TLS deben quedar ligados a la misma sesión.
Trivial File Transfer Protocol (TFTP) resolvió otra tarea con un diseño mucho menor. Usa UDP, solicita un archivo por nombre y carece de autenticación o listado estándar. Comparte el propósito general de transferir datos, pero no el modelo de sesión de FTP.
Los ejemplos utilizan TARGET_IP, FQDN, KNOWN_FILE y LOCAL_FILE como placeholders. La referencia de Nmap es el prerrequisito para sus opciones de escaneo.
Orden de trabajo y herramientas
Sección titulada «Orden de trabajo y herramientas»Empieza con Nmap para confirmar puertos y versión. Usa Ncat para leer el banner y comprobar los códigos del canal de control. El cliente ftp permite recorrer comandos y transferencias. wget resulta útil para conservar un árbol ya revisado. OpenSSL separa la negociación FTPS de la sesión FTP. Ninguna herramienta cubre por sí sola la conexión de datos, permisos, TLS y efectos de escritura.
| Pregunta | Herramienta | Comprobación necesaria |
|---|---|---|
| ¿habla FTP y qué anuncia? | Nmap y Ncat | SYST, FEAT y códigos de respuesta |
| ¿admite anonymous o credenciales? | cliente ftp |
identidad efectiva y directorio inicial |
| ¿qué puede listar o transferir? | cliente ftp |
LIST, RETR, STOR, borrado y ruta concreta |
| ¿protege control y datos? | OpenSSL y cliente FTPS | AUTH TLS, PBSZ, PROT y certificado |
| ¿puede copiarse un árbol? | wget |
revisar tamaño, rutas y efectos antes de -m |
| ¿es realmente TFTP? | cliente TFTP o NSE | nombre de archivo conocido y respuesta UDP |
La interacción manual con servicios explica Ncat, CRLF, TLS directo y captura del diálogo.
Cómo funciona FTP
Sección titulada «Cómo funciona FTP»La conexión de control suele llegar a 21/tcp. Por ella viajan los comandos, las credenciales y los códigos de respuesta. Cada listado o transferencia abre además una conexión de datos.
control: cliente:any ───────────────> servidor:21/tcpdatos: se abre otra conexión para LIST, RETR o STOREn modo activo, el cliente anuncia con PORT o EPRT la dirección y el puerto donde escuchará. El servidor inicia la conexión de datos hacia el cliente. FTP clásico utiliza 20/tcp como puerto de origen del servidor, aunque la implementación y la configuración pueden variar.
En modo pasivo, el cliente pide PASV o EPSV. El servidor abre un puerto y el cliente inicia también la conexión de datos. EPSV devuelve solo el puerto y reutiliza la dirección de la conexión de control, lo que evita varios problemas con NAT e IPv6.
| Modo | Quién abre la conexión de datos | Fallo típico |
|---|---|---|
| Activo | Servidor hacia cliente | El firewall o NAT del cliente bloquea la conexión entrante. |
| Pasivo | Cliente hacia servidor | El rango pasivo no está publicado, permitido o anunciado correctamente. |
Si el inicio de sesión funciona pero ls o una descarga quedan esperando, el problema suele estar en la conexión de datos, no en el canal de control.
Comandos y respuestas
Sección titulada «Comandos y respuestas»Los comandos FTP se envían como texto sobre la conexión de control:
| Comando | Función |
|---|---|
USER, PASS |
Autenticación. |
SYST |
Tipo de sistema informado por el servidor. |
FEAT |
Extensiones soportadas, como UTF8, MLSD o AUTH TLS. |
PWD, CWD |
Consultar o cambiar el directorio actual. |
LIST, MLSD |
Listar recursos. MLSD ofrece un formato estructurado. |
TYPE |
Seleccionar transferencia ASCII o binaria. |
PASV, EPSV |
Preparar una conexión de datos pasiva. |
PORT, EPRT |
Anunciar el endpoint de datos en modo activo. |
RETR |
Descargar un archivo. |
STOR |
Subir o reemplazar un archivo. |
DELE, RMD |
Borrar archivos o directorios. |
STAT |
Solicitar estado del servidor o de un recurso. |
El primer dígito del código resume el resultado:
| Rango | Significado |
|---|---|
1xx |
Acción iniciada, pendiente de otra respuesta. |
2xx |
Operación completada. |
3xx |
Falta información, normalmente credenciales. |
4xx |
Fallo temporal. La operación podría repetirse. |
5xx |
Fallo permanente, comando no soportado o acceso denegado. |
Durante una transferencia es normal recibir un 150 antes de los datos y un 226 al completarla. Un 230 confirma el inicio de sesión. Un 530 indica que la sesión no está autenticada o que las credenciales fueron rechazadas.
Identificar el servicio
Sección titulada «Identificar el servicio»En Nmap, -p 21 limita el escaneo al puerto TCP 21 y -sV activa la detección de versiones, que abre una conexión y compara la respuesta con sus firmas:
nmap -sV -p 21 TARGET_IPEl banner puede revelar producto, versión, hostname o sistema operativo. También puede estar oculto o modificado. Confirma el protocolo con una sesión real y conserva por separado lo que el servidor anuncia y lo que la herramienta infiere.
Abrir una sesión manual
Sección titulada «Abrir una sesión manual»El cliente se inicia con el destino. Algunas implementaciones aceptan también el puerto como segundo argumento:
ftp TARGET_IPEmpieza con help para conocer los comandos del cliente local. No todos los clientes implementan debug, trace, passive o status de la misma manera.
Una sesión anonymous suele utilizar anonymous o ftp como usuario. Históricamente se emplea una dirección de correo electrónico como contraseña, aunque muchos servidores aceptan cualquier valor o no solicitan una:
Name: anonymousPassword: anonymous@example.comDespués del inicio de sesión, comprueba el contexto antes de descargar nada:
statussystempwdls -lastatus describe el estado del cliente. system suele enviar SYST. pwd confirma el directorio remoto y ls -la solicita un listado detallado. Los argumentos de LIST, como -la o -R, no forman parte de un formato estándar y algunos servidores los ignoran o rechazan. Si existe MLSD, ofrece datos más fáciles de interpretar.
Activa debug para ver comandos y respuestas del canal de control. trace añade el flujo de llamadas del cliente en implementaciones que lo soportan. El tráfico puede incluir la contraseña en claro cuando no se negocia TLS.
Recorrer y transferir archivos
Sección titulada «Recorrer y transferir archivos»Antes de una transferencia usa binary para evitar conversiones de final de línea o representación sobre ejecutables, archivos comprimidos e imágenes. lcd cambia el directorio local donde se guardan o leen los archivos:
binarylcd /tmp/ftp-reviewget descarga un archivo. mget descarga varios y puede pedir confirmación por cada uno. El comando prompt activa o desactiva esa confirmación en muchos clientes:
get KNOWN_FILEpromptmget *.confEl patrón *.conf selecciona los nombres que terminan en .conf dentro del directorio remoto actual.
put y mput suben archivos. Una transferencia correcta no demuestra que el archivo sea accesible desde otro servicio ni que conserve el mismo nombre, propietario o permisos:
put LOCAL_FILEls -laLa escritura crea o modifica estado en el servidor. Registra directorio, nombre remoto, hash, propietario, permisos y hora. Si la prueba usa un archivo temporal, esa información permite comprobar su efecto y retirarlo después sin confundirlo con datos previos.
Para una descarga recursiva mediante Wget, -m activa el modo mirror y --no-host-directories evita crear una carpeta adicional con el hostname. La URL incluye las credenciales y puede quedar en el historial o en la lista de procesos:
wget -m --no-host-directories \ 'ftp://anonymous:anonymous%40example.com@TARGET_IP/'En la URL, %40 representa el carácter @ de la contraseña. Así no se confunde con el @ que separa las credenciales del hostname.
El modo mirror puede transferir muchos datos. Revisa primero el listado, el tamaño y el espacio local. Un sistema de archivos grande o con enlaces inesperados puede convertir una comprobación pequeña en una descarga extensa.
Enumerar con NSE
Sección titulada «Enumerar con NSE»NSE permite automatizar preguntas concretas. --script selecciona scripts por nombre. ftp-anon prueba el acceso anonymous, lista el directorio raíz y marca entradas escribibles. ftp-syst envía SYST y STAT. Se reutilizan -sV y -p 21, ya explicados al identificar el servicio:
nmap -sV -p 21 --script ftp-anon,ftp-syst TARGET_IPftp-anon limita por defecto el listado. --script-args ftp-anon.maxlist=-1 pasa al script el valor -1, que elimina ese límite:
nmap -sV -p 21 --script ftp-anon \ --script-args ftp-anon.maxlist=-1 TARGET_IPEl script confirma lo que su código prueba. Una entrada marcada como escribible sigue necesitando una validación efectiva si esa propiedad cambia la investigación. Usa --script-help ftp-anon y revisa la documentación antes de depender del output.
FTPS y certificados
Sección titulada «FTPS y certificados»FTP transmite comandos, nombres de usuario, contraseñas y datos sin cifrar. FTPS añade TLS al protocolo FTP. En FTPS explícito, la sesión comienza en el puerto FTP y negocia AUTH TLS. En FTPS implícito, el handshake TLS ocurre al conectar, a menudo en 990/tcp. SFTP pertenece a SSH y no utiliza FTP.
openssl s_client puede negociar FTPS explícito. -connect FQDN:21 selecciona el endpoint, -starttls ftp envía la negociación propia de FTP y -servername FQDN establece SNI:
openssl s_client -connect FQDN:21 -starttls ftp -servername FQDNEl certificado puede revelar SAN, emisor, fechas y nombres adicionales. También permite comprobar si el canal de control acepta TLS. La protección del canal de datos se negocia por separado mediante comandos como PBSZ y PROT, por lo que un inicio de sesión cifrado no demuestra automáticamente que las transferencias también lo estén.
Revisar una configuración vsftpd
Sección titulada «Revisar una configuración vsftpd»Con acceso local, la configuración explica comportamientos que desde la red solo podían inferirse. vsftpd utiliza normalmente /etc/vsftpd.conf, aunque el proceso puede recibir otra ruta.
grep -E activa expresiones regulares extendidas. -v invierte la selección. El patrón descarta líneas vacías y comentarios, de modo que el output contiene las directivas activas:
grep -Ev '^[[:space:]]*(#|$)' /etc/vsftpd.confLas opciones relevantes se interpretan en conjunto:
| Directiva | Efecto |
|---|---|
anonymous_enable |
Acepta los usuarios anonymous y ftp. |
local_enable |
Permite inicios de sesión de cuentas locales. |
write_enable |
Habilita comandos que modifican el sistema de archivos. |
anon_upload_enable |
Permite subidas anonymous si también existen permisos Unix. |
anon_mkdir_write_enable |
Permite crear directorios anonymous con los demás requisitos. |
anon_other_write_enable |
Permite otras operaciones como renombrar o borrar. |
anon_root |
Fija el directorio raíz para la sesión anonymous. |
download_enable |
Habilita o deshabilita descargas. |
hide_ids |
Sustituye propietarios y grupos por ftp en los listados. |
chroot_local_user |
Sitúa por defecto a usuarios locales en un chroot. |
userlist_enable, userlist_deny, userlist_file |
Controlan la lista de cuentas aceptadas o denegadas. |
ssl_enable, implicit_ssl |
Activan TLS explícito o implícito. |
force_local_logins_ssl, force_local_data_ssl |
Exigen TLS para control y datos de usuarios locales. |
pasv_min_port, pasv_max_port, pasv_address |
Definen rango y dirección anunciados para modo pasivo. |
write_enable=YES habilita la posibilidad global de escritura, pero una subida depende además de los permisos del usuario efectivo sobre el directorio y de las opciones específicas de anonymous. hide_ids=YES cambia el listado, no los propietarios reales del sistema de archivos.
/etc/ftpusers suele contener cuentas a las que el stack de autenticación deniega FTP. No es una lista de usuarios válidos ni una prueba de que cada cuenta exista:
En sed, -n desactiva la impresión automática y 1,200p imprime las primeras 200 líneas:
sed -n '1,200p' /etc/ftpusersLos logs, la unidad de servicio y la línea de comandos del proceso ayudan a confirmar qué archivo de configuración está realmente cargado.
FTP bounce
Sección titulada «FTP bounce»El comando PORT permite pedir al servidor FTP que abra la conexión de datos hacia una dirección distinta. Los servidores actuales suelen impedirlo, pero una implementación vulnerable puede convertirse en punto de observación para alcanzar otros hosts y puertos desde su red.
El script ftp-bounce comprueba si el servidor acepta esa operación. Para realizar un FTP bounce scan, Nmap ofrece el tipo de escaneo -b. Su argumento describe las credenciales y el servidor FTP intermediario. El objetivo final aparece al final del comando:
nmap -b USER:PASSWORD@FTP_SERVER:21 BOUNCE_TARGETNmap se autentica en FTP_SERVER y utiliza respuestas a PORT y transferencias para inferir el estado de puertos en BOUNCE_TARGET. El host final observa conexiones procedentes del servidor FTP, no de la máquina que ejecuta Nmap. El servidor intermediario registra la sesión y las peticiones. Incluir la contraseña en el argumento puede exponerla en el historial de la shell y en el listado de procesos.
La técnica depende de que el servidor permita proxy FTP hacia el destino y los puertos elegidos. Muchos bloquean direcciones externas, puertos bajos o cualquier dirección distinta de la conexión de control.
TFTP no ofrece una sesión FTP
Sección titulada «TFTP no ofrece una sesión FTP»TFTP utiliza 69/udp para la petición inicial. La transferencia continúa mediante UDP entre identificadores de transferencia elegidos por cliente y servidor. Solo define operaciones de lectura y escritura de archivos. No incluye autenticación, navegación ni listados.
Con el cliente interactivo, get KNOWN_FILE solicita un nombre conocido y put LOCAL_FILE intenta escribirlo:
tftp TARGET_IPtftp> get KNOWN_FILELa ausencia de listados obliga a obtener nombres de configuración, documentación, logs o convenciones del dispositivo. El script tftp-enum prueba una wordlist de nombres. -sU selecciona UDP, -p 69 limita el escaneo al puerto 69 y --script tftp-enum ejecuta ese script:
nmap -sU -p 69 --script tftp-enum TARGET_IPtftp-enum pertenece a las categorías discovery e intrusive porque genera múltiples solicitudes de archivo. --script-args tftp-enum.filelist=FILE permite sustituir la wordlist por nombres derivados del entorno.
Diagnóstico rápido
Sección titulada «Diagnóstico rápido»| Síntoma | Comprobación |
|---|---|
| Conecta a 21 pero no aparece banner | Enviar FEAT o SYST, comprobar TLS explícito y la detección de versiones. |
| Inicio correcto, listado bloqueado | Cambiar entre activo y pasivo, revisar 227/229, NAT y rango pasivo. |
550 al descargar |
Ruta, directorio actual, permisos efectivos y download_enable. |
| Subida aceptada, archivo no visible | Nombre remoto, chroot, umask, propietario, directorio real y backend. |
| El hash cambia tras descargar | Confirmar modo binary, transferencia completa y tipo de archivo. |
| TFTP no encuentra un archivo | TFTP no lista. Verificar nombre exacto, directorio raíz y logs. |
Evidencia, cambios de estado y cierre
Sección titulada «Evidencia, cambios de estado y cierre»NSE separa capacidades distintas: ftp-syst obtiene SYST y STAT, ftp-anon intenta una sesión anónima y lista cuando puede, y ftp-bounce comprueba si el servidor acepta un destino de datos distinto del cliente. Los scripts ftp-brute, ftp-vsftpd-backdoor, ftp-proftpd-backdoor y ftp-vuln-* no son una continuación automática. Revisa versión, argumentos, número de conexiones y condición comprobada antes de usarlos.
Un banner sin respuesta posterior puede indicar protección previa, TLS implícito, límite de conexiones o un servicio distinto. Un 530 no distingue contraseña incorrecta, cuenta denegada, política por origen o requisito TLS. En modo pasivo, un timeout puede estar en el puerto de datos anunciado, NAT o firewall aunque el canal de control funcione. Conserva siempre los códigos de tres dígitos y la secuencia de comandos.
Una sesión de lectura deja autenticación, CWD, listados y transferencias en logs del daemon y en telemetría de red. STOR, APPE, DELE, RNFR/RNTO, SITE y una transferencia TFTP de escritura modifican estado. Si una prueba necesita escritura, usa un nombre único, registra hash y ruta, verifica el resultado y retira solo el archivo creado por la operación.
El cierre mínimo documenta endpoint, modalidad activa o pasiva, identidad, raíz visible, permisos efectivos, TLS, hashes de archivos recuperados, fallos y siguiente ruta de análisis. Los archivos descargados pasan a análisis como copias inmutables. No se ejecutan desde el directorio de evidencias.
Referencias operativas
Sección titulada «Referencias operativas»La página de herramientas, automatización y NSE compara clientes y scripts. Cierra cada endpoint con la checklist y recupera la sintaxis verificada desde la cheatsheet.