ftp-bounce-attack.md (7869B)
1 --- 2 title: "FTP Bounce attack - Scan" 3 section: "Network Services" 4 sectionSlug: "network-services-pentesting" 5 sourcePath: "src/network-services-pentesting/pentesting-ftp/ftp-bounce-attack.md" 6 sourceUrl: "https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/network-services-pentesting/pentesting-ftp/ftp-bounce-attack.md" 7 sha: "188de82beb54e70956b2952367a0af91d26758b8" 8 isIndex: false 9 modified: true 10 license: "CC-BY-NC-4.0" 11 --- 12 13 # FTP Bounce attack - Scan 14 15 ## FTP Bounce - Scanning 16 17 ### Manual 18 19 1. Connect to the vulnerable FTP server. 20 2. Use **`PORT`** (classic IPv4 active mode) or **`EPRT`** (extended syntax, supports IPv4/IPv6) to make it establish a connection with the _\<IP:Port>_ you want to scan:<sup>[[2]](#references)</sup> 21 22 ```text 23 PORT 172,32,80,80,31,144 # 31*256 + 144 = 8080 24 EPRT |1|172.32.80.80|8080| # IPv4 25 EPRT |2|2001:db8::80|8080| # IPv6 26 ``` 27 28 3. Trigger the data connection with **`LIST`**, **`NLST`** or **`RETR /file/in/ftp`** and read the **whole reply sequence**, not only the first line: 29 - **`125`** means a data connection is already open; **`150`** is only preliminary (the server is about to open it). Treat either as a candidate result. 30 - A terminal **`226`** is the strongest open-port indication because the transfer/data connection completed. 31 - **`425`** means the data connection could not be opened (closed, filtered, unroutable or blocked by egress policy). A **`426`** after `125`/`150` is inconclusive: a listening application may accept the TCP connection and then abort when it receives FTP listing data. 32 - **`450`** / **`550`** can instead indicate a filesystem or authorization failure. Retry with a known-readable file and compare a known-open and known-closed destination from the relay's network position.<sup>[[6]](#references)</sup> 33 34 Example using **`PORT`** (port 8080 of 172.32.80.80 is open and port 7777 is closed): 35 36  37 38 Same example using **`EPRT`** (authentication omitted in the image): 39 40  41 42 Open port using **`EPRT`** instead of **`LIST`** (different env): 43 44  45 46 > For **`EPRT`**, use **`|1|`** with IPv4 addresses and **`|2|`** with IPv6 addresses. 47 48 ### Practical notes 49 50 - **`PORT`** encodes the destination port as two bytes: **`p1 = port // 256`** and **`p2 = port % 256`**. 51 - A `2xx` response to `PORT`/`EPRT` proves only that the server accepted the endpoint syntax. The outbound TCP connection normally happens after the transfer command, so always follow it with `LIST`/`NLST`/`RETR`. 52 - Many daemons only block **privileged ports** **`<1024`**. Even when low ports are protected, high-value internal services such as **`3306`**, **`5000`**, **`6379`**, **`8080`**, **`8443`** or **`9000`** may still be reachable.<sup>[[7]](#references)</sup> 53 - You are testing **reachability from the FTP server**, not from your own host. DNS resolution, routing, egress ACLs and timeouts can differ from your position; use numeric target addresses and repeat ambiguous probes against control ports. 54 55 ### **nmap** 56 57 ```bash 58 nmap -Pn -n -b <name>:<pass>@<ftp_server> <victim_ip> 59 nmap -Pn -n -v -p 21,80 -b ftp:ftp@10.2.1.5 127.0.0.1 # Scan ports 21,80 of the FTP server itself 60 nmap -Pn -n -v -p 21,22,445,80,443 -b ftp:ftp@10.2.1.5 192.168.0.1/24 # Scan the internal network reachable from the FTP server 61 ``` 62 63 ### nmap NSE pre-check 64 65 ```bash 66 nmap -p21 --script ftp-bounce <ftp_server> 67 nmap -p21 --script ftp-bounce \ 68 --script-args 'ftp-bounce.username=<user>,ftp-bounce.password=<pass>,ftp-bounce.checkhost=<target>' \ 69 <ftp_server> 70 ``` 71 72 This NSE script is only a **configuration pre-check**: it sends IPv4 `PORT` commands for a high port (`20560`) and TCP/80 at `checkhost`, but it does **not** issue `LIST` or otherwise trigger the data connection. Therefore, `bounce working!` means the arguments were accepted, not that the relay reached `checkhost`. By default it authenticates as **anonymous / `IEUser@`**, resolves **`scanme.nmap.org`** from the Nmap host, and uses that IPv4 address; override `checkhost` with an authorized address and follow with a real bounce scan.<sup>[[1]](#references)</sup> 73 74 ### Metasploit 75 76 ```bash 77 msfconsole 78 use auxiliary/scanner/portscan/ftpbounce 79 set BOUNCEHOST <ftp_server> 80 set RHOSTS <victim> 81 set PORTS 22,80,443,445,8080,8443 82 set FTPUSER <user> 83 set FTPPASS <pass> 84 run 85 ``` 86 87 The Metasploit module is handy for quick IPv4 sweeps, but it currently does **not** support IPv6, so keep the manual **`EPRT`** workflow for IPv6-capable daemons. 88 89 ### Common vulnerable patterns 90 91 You are more likely to still find FTP bounce in: 92 93 - **Legacy/embedded appliances** such as printers, MFPs, NAS boxes and older internal file workflow services. 94 - Servers intentionally configured to allow **FXP / site-to-site transfers**. 95 - Custom Python FTP services or lab daemons that re-enable foreign-address data connections for convenience. 96 97 If you have shell/config access, the following settings are especially suspicious and worth validating immediately: 98 99 - **ProFTPD:** **`AllowForeignAddress on`**, or an overly broad class supplied to `AllowForeignAddress`.<sup>[[3]](#references)</sup> 100 - **vsftpd:** **`port_promiscuous=YES`** (and often **`pasv_promiscuous=YES`** when FXP was enabled).<sup>[[4]](#references)</sup> 101 - **pyftpdlib:** **`permit_foreign_addresses = True`** or **`--permit-foreign-addresses`**. **`permit_privileged_ports = True`** additionally permits active connections to ports below 1024.<sup>[[5]](#references)</sup> 102 103 ### Mitigation and detection 104 105 The primary fix is to require the `PORT`/`EPRT` address to match the control connection's peer. If active mode is unnecessary, disable it and offer passive mode only. Rejecting destinations below TCP/1024 is useful defense-in-depth but leaves every higher port bounceable, so it is not a complete fix.<sup>[[7]](#references)</sup> 106 107 Keep **`AllowForeignAddress`**, **`port_promiscuous`**, **`permit_foreign_addresses`** and **`permit_privileged_ports`** disabled unless tightly scoped FXP is required. Also restrict the FTP service account/container's outbound network access and alert on address-mismatch/bounce log entries or bursts of `PORT`/`EPRT` followed by transfer commands.<sup>[[3]](#references)[[4]](#references)[[5]](#references)</sup> 108 109 If the server is writable and you want to pivot beyond simple port-scanning, check [FTP Bounce - Download 2ºFTP file](/hacktricks/network-services-pentesting/pentesting-ftp/ftp-bounce-download-2oftp-file). 110 111 112 ## References 113 114 - [1] [Nmap NSE `ftp-bounce` script](https://nmap.org/nsedoc/scripts/ftp-bounce.html) 115 - [2] [RFC 2428 - FTP Extensions for IPv6 and NATs](https://datatracker.ietf.org/doc/html/rfc2428) 116 - [3] [ProFTPD `mod_core` — `AllowForeignAddress`](https://www.proftpd.org/docs/modules/mod_core.html#AllowForeignAddress) 117 - [4] [vsftpd configuration manual](https://security.appspot.com/vsftpd/vsftpd_conf.html) 118 - [5] [pyftpdlib API — foreign-address controls](https://pyftpdlib.readthedocs.io/en/latest/api.html) 119 - [6] [RFC 959 — File Transfer Protocol](https://www.rfc-editor.org/rfc/rfc959.html) 120 - [7] [RFC 2577 — FTP Security Considerations](https://www.rfc-editor.org/rfc/rfc2577.html)