← Back to Blog

You’re Connected. So Why Can’t You See Any Files?

I was mid-engagement when a consultant asked me about an FTP service with anonymous login. They connected but there were no files and were ready to move on. However they remembered that I already told them about the files I had found there. So they asked, “What files?”. They assured me there was nothing. Immediately I knew they hadn’t switched to active mode. How did I know? I have made the same mistake. Which made me think, this would make a good blog post.

FTP uses two separate connections

Most protocols use a single connection and everything flows through it. FTP is not one of those. It uses two TCP connections.

  1. A control connection on port 21. This is the port you are most likely to see when you run your nmap scan and it’s where the commands such as USER, PASS, LIST, RETR go. This connection stays open the whole session.
  2. A data connection. An additional connection gets opened for every directory listing or transfer.

Most people don’t realize this is the case and most don’t think about it until something breaks.

Passive mode: what your client asks for

FTP clients often default to passive mode. After login, the client sends PASV and the server replies with an IP address and port. The client opens the data connection to that address.

client --> server:21  (control)
client sends: PASV
server replies: connect to 10.10.110.100:45032
client --> 10.10.110.100:45032  (data)

This flow makes sense. The client initiates both connections. Often the client is behind NAT and if the client asked the server to initiate the connection, the inbound connection would be blocked by the firewall. This works great unless the server’s behind NAT too.

Passive mode: what happens when the server is behind NAT

The FTP server in this engagement was on an internal network. When the client sent PASV, the server handed back its internal IP address. Something like 172.16.1.100. From our side, that address was not reachable. The client tried to connect to 172.16.1.100 but silently failed. When the consultant sent ls it seemingly came back with an empty listing. We saw no error, no timeout, nothing. The login worked fine because port 21 was listening on an IP address we could reach. But when ls ran, the client tried to open the data connection which got rejected and dropped straight back to the ftp> prompt.

This is uncommon but if you are a little lucky you might see an error message that indicates what happened. Usually you won’t. You get an empty listing and move on. You document the finding that anonymous login was enabled on the FTP server.

Active mode: flipping it around

In active mode the client picks a port on its own machine and tells the server to connect there.

client --> server:21  (control)
client sends: PORT CLIENT_IP:PORT
server --> CLIENT_IP:PORT  (data)
ftp> passive
Passive mode: off; fallback to active mode: off.

The consultant typed one command. Files appeared. One word. They’d been one word away the whole time.

When active mode breaks instead

Active mode isn’t a universal fix. Now the server initiates the data connection back to the client. If the client is behind NAT the server can’t reach it. Understanding which mode to use when is important.

  • Server behind NAT, advertising an internal IP: Active mode
  • Client behind NAT or a firewall blocking inbound: Passive mode (default)
  • Working through a tunnel that routes the server’s internal subnet: Passive mode works again

That last one matters. Later in the same engagement we set up a tunnel into the 172.16.1.0/24 subnet. Passive mode worked. The internal IP the server advertised was suddenly reachable. Same server, same anonymous login with a different result.

Don’t write off an empty listing

An empty directory does not always mean there is nothing there. Not understanding a little bit of how the protocol works can cause you to be blind to what is really there. This was a good learning experience on the engagement and the consultant told me they won’t make that mistake again. As someone who has done the same thing, I can confirm that once you have moved past some data because you thought there was nothing there, that lesson sticks with you.