At the land-based branch of our company, we recently discovered the Popcorn Hour S-300, for what we thought could be a solid solution to run promotion videos in of our shops. It is Linux-based and has a very simple client that allows remote control and uploading of videos.
The protocol it uses is antique plain FTP which seemed like a horrible design decision in the first place. But after all, it is quite solid, known to work and this is not exactly an application where security matters, so we didn’t care very much.
The FTP protocol
The way passive FTP (which this box uses) works is that the client opens a connection to the server, does the login and then sends the PASV command to tell the server to open a new port (usually configurable and somewhere between 1024 – 65535 to allow an unprivileged FTP daemon to open them). In a successful FTP session, this looks like this:
~% telnet ftp.foo.net 21
Trying 1.2.3.4...
Connected to ftp.foo.net.
Escape character is '^]'.
220---------- Welcome to Pure-FTPd [privsep] ----------
220-You are user number 1 of 3 allowed.
220-Local time is now 09:07. Server port: 21.
220 You will be disconnected after 1440 minutes of inactivity.
USER ftpuser
331 User ftpuser OK. Password required
PASS 1234
230-This server supports FXP transfers
230 OK. Current directory is /
PASV
227 Entering Passive Mode (1,2,3,4,245,23)
Right after the client has sent the PASV command, the server responds with a 227 response code and an IP and port for the client to use (1,2,3,4 is the IP 1.2.3.4 and 245,23 can be translated to the port number like this: “245 * 256 + 23 = 62743”).
Now there are a couple of problems with FTP when using a NAT router. Firstly, the FTP server usually does not know it’s external IP address unless you configure it manually (1.2.3.4 in this case) and secondly, the newly opened port must be forwarded to the proper machine in the network. You could configure a smaller range for the PASV ports (it determines the maximum number of concurrent data connections, so even a range of three ports would be sufficient in this case where the number of users is limited to 3 anyway) and manually add forwarding rules to your router. However, the S-300 box does not allow to configure the PASV port range and its default range apparently goes all the way from 10000-65535, which I had to find out via plain testing (sending multiple PASV commands and taking down the ports).
Smart Routers to the Rescue?
Fortunately though, many modern consumer routers like this Telekom Speedport 503V have a feature that makes them automatically identify FTP traffic, change the IP address (in our example it would be the internal address to 1.2.3.4) and open/forward the port to the FTP server for the duration of the session.
So far, so good. This is a nice feature as long as it works and the enduser never needs to care about it. In our case, something went wrong. While the Digital Signage software was able to connect to the box from the LAN, it refused to connect from the outside. The first thing that came to my mind was that something must be wrong with the forwarding of the passive ports, so we tried to add a manual NAT rule for the range in question (yes, all ports 10000-65535. Not very practical in larger installations). It didn’t change anything.
Telnet vs. Proprietary Client
Then, I tried to connect using a simple telnet client (the FTP protocol is in fact based on the telnet protocol) and it worked.
Next was an actual FTP client as well and even file transfers worked flawlessly. I didn’t have an answer to this, so I started the Wireshark packet analyzer and got these results:
What you can tell if you look closely is that the only significant difference between the proprietary client and my telnet session are the line endings. While the client sends “PASV \n” [SPACE-NL], telnet sends “PASV\r\n” [CR-NL] as defined in the protocol specs.
Now, connect the dots…
It took me a while of desperate thinking to figure this out, but then it appeared to be rather obvious, having what we learned about “smart” routers in mind.
The router apparently expects a proper ending on the PASV command before it starts parsing the response of the FTP server to do it’s modifications to it. While it is waiting for this response (or much rather the proper end of the request), it blocks all outgoing traffic from the server. So not a single ACK packet gets through.
Don’t Act Smart
So to conclude.. Dear product vendors, kindly don’t use outdated and entirely inappropriate protocols just because they are simple. And if you absolutely have to do so, please do it correctly at least.
And then maybe one more general advice to the producers of consumer network hardware. Please, don’t try to make it smart based on guesses and assumptions. And again, if you absolutely have to do so, at least inform the user and provide him with a way to disable the behaviour. The only option to us is to replace the router by one that doesn’t have this feature or doesn’t care about the broken protocol implementation.