π‘οΈ Methodology Checklist
- Banner grab:
nc [TARGET] 21 - Anonymous login:
ftp [TARGET]β usernameanonymous - List files:
ls -laβ check for sensitive data - Download interesting files:
get [filename] - Brute-force credentials:
hydra -L users.txt -P passwords.txt ftp://[TARGET] - Check FTP version against CVEs (vsftpd 2.3.4, ProFTPD exploits)
- Try bounce attack if old server version
- Check for writable dirs:
put test.txttest
π― Operational Context
Think Dumber First: Try
anonymous:anonymousbefore any tooling. Most HTB boxes with FTP have anonymous read access or trivially-weak credentials. If anonymous login works, immediately check if the FTP root overlaps with the web root β uploading a PHP webshell there skips all exploit work entirely.
When you land here: Port 21 is open in nmap. Banner grab reveals vsftpd/ProFTPd/Pure-FTPd version. Cross-reference against known CVEs (vsftpd 2.3.4 backdoor triggers a shell on port 6200). Check for world-readable config files, backup archives, and SSH keys before attempting brute-force.
β‘ Tactical Cheatsheet
| Command | Tactical Outcome |
|---|---|
sudo nmap -sV -p21 -sC -A [TARGET_IP] | Nmap scan with version detection and default scripts |
ftp [TARGET_IP] | Connect to FTP service |
nc -nv [TARGET_IP] 21 | Raw banner grab on port 21 |
openssl s_client -connect [TARGET_IP]:21 -starttls ftp | SSL/TLS certificate grab (reveals hostnames, emails) |
ftp [TARGET_IP] β user: anonymous pass: anonymous | Anonymous login attempt |
ls -R | Recursive directory listing inside FTP shell |
get [FILE] | Download a specific file |
put [FILE] | Upload a file (if write permissions exist) |
wget -m --no-passive ftp://anonymous:anonymous@[TARGET_IP] | Recursively download all files |
sudo nmap --script-updatedb | Update Nmap script database |
π¬ Deep Dive & Workflow
Initial Enumeration
- Nmap scan:
sudo nmap -sV -p21 -sC -A [TARGET_IP] - Check Nmap output for: version string,
ftp-anonresult (anonymous allowed?),ftp-syst - Banner grab:
nc -nv [TARGET_IP] 21β note software version (e.g., vsFTPd 3.0.3) - SSL/TLS check:
openssl s_client -connect [TARGET_IP]:21 -starttls ftpβ extract CN hostnames - Attempt anonymous login (
anonymous/anonymous) - If logged in:
ls -Rto view all files recursively - Check
/etc/vsftpd.conf(if local access) for dangerous settings
Attacks
- Anonymous upload to web directory β web shell if FTP root overlaps with web root
- Attempt credential brute-force if anonymous fails (Hydra/Medusa)
- Download all files:
wget -m --no-passive ftp://anonymous:anonymous@[TARGET_IP] - Check for sensitive files:
.bash_history, config files, credentials, SSH keys - Check for writable directories β upload reverse shell payload
Core Concept
FTP is a clear-text application-layer protocol (TCP/IP stack).
- Control Channel (Port 21): Client commands, server status codes.
- Data Channel (Port 20): Data transmission.
Connection Modes
- Active Mode: Client opens a port; server connects back. Firewalls often block this.
- Passive Mode (PASV): Server opens a port; client connects. Works better with client-side firewalls.
TFTP (Trivial FTP)
- Protocol: UDP Port 69 β no authentication.
- Only works in world-readable/writable directories.
- Commands:
connect,get,putβ no directory listing.
Dangerous vsFTPd Settings (/etc/vsftpd.conf)
| Setting | Risk |
|---|---|
anonymous_enable=YES | Allows unauthenticated access |
anon_upload_enable=YES | Allows anonymous file uploads |
hide_ids=YES | Shows all ownership as βftpβ β complicates permission analysis |
π οΈ Troubleshooting & Edge Cases
| Problem | Cause | Fix |
|---|---|---|
Anonymous login accepted but ls hangs forever | Active mode blocked by client-side firewall | Type passive in ftp shell; alternatively use wget --passive-ftp ftp://anonymous:anonymous@[TARGET]/ |
| Binary file downloads are corrupt | ASCII transfer mode is ftp default | Run binary in ftp shell before any get command; wget handles this automatically |
wget -m recursive download fails midway | PASV port randomly blocked mid-transfer | Add --retry-connrefused --tries=3; alternatively use lftp -e 'mirror / /tmp/ftp_loot' ftp://anonymous:@[TARGET] |
| vsftpd 2.3.4 backdoor β port 6200 doesnβt respond | Backdoor may have already triggered and closed | Wait 30s; try login attempt again with USER x:) trigger; confirm exact version with nc [TARGET] 21 |
| openssl STARTTLS fails with handshake error | Server uses implicit TLS (FTPS port 990), not STARTTLS | Connect directly: openssl s_client -connect [TARGET]:990; extract cert for hostname enumeration |
π Reporting Trigger
Finding Title: Anonymous FTP Access β Unauthenticated File System Exposure
Impact: Unauthenticated read access exposes sensitive files (SSH keys, configs, backups). Write access combined with a web root overlap enables direct webshell upload and RCE.
Root Cause: anonymous_enable=YES set in vsftpd.conf without IP restriction or write controls. No chroot_local_user enforcement.
Recommendation: Set anonymous_enable=NO. Enforce authentication with strong credentials. Implement chroot jails (chroot_local_user=YES). Enforce FTPS/TLS (ssl_enable=YES, force_local_logins_ssl=YES). Audit and remove writable directories accessible to FTP accounts.