First, the good news - it's not a flaw in the operation of Windows Firewall on Windows Vista. It's a design feature, it makes sense, and it fits in with the principle that the firewall should keep out unsolicited traffic. It's not really a hole, but I thought I'd grab your attention.
The symptom first came up in a Usenet posting (thanks, Jesper, for bringing me in) about Vista and a third-party FTP client:
When I do a directory listing, and a PORT command is issued, and the
server attempts to connect, it works, but at the same time a dialogue
appears telling me it's blocked, and I can keep blocking or unblock.
I choose keep blocking but it doesn't actually block it once.
Here's how it looks.
First, if you haven't got a third-party FTP client let's fake it, by copying Microsoft's command-line FTP client from the Windows System32 directory to another directory:
C:\users\MyMe> copy %windir%\system32\ftp.exe
1 file(s) copied.
The FTP client will not display prompts to you, but that's a minor issue - if it upsets you, try downloading a third-party client and trying it.
Anyway, here we go - let's try the issue in question:
- Type ftp ftp.microsoft.com
- After you see the "220" greeting message, enter ftp as the user - press enter.
- Now you're prompted for a password - enter anything and press enter.
- Once you're logged on, enter dir - again, press enter.
- You'll see the directory listing succeed, but you'll also see a warning that a connection is being blocked:
Wow - that's freaky - at the same time you're being told that the connection used for the file listing will be blocked, it allows the connection through!
What's more, even if you specify Keep Blocking, and then go issue another dir command, that one succeeds.
Huh? And why on earth did you make me use a copy of FTP?
Let's go look at the Windows Advanced Firewall Rules for Inbound, and see if this sheds any light:
[That means click the Start button, type Firewall into the search box, and right-click on Windows Firewall with Advanced Security - select Run as Administrator
and accept the elevation prompt from UAC. If you don't have an elevation prompt, then you should really re-enable UAC. Now select Inbound Rules in the left-hand pane]
Me, I've got a few rules labeled File Transfer Program:
That first (and fourth) rule is set to block any listening ports opened by the File Transfer Program in C:\users\myme\ftp.exe, the second two seem to be allowing any listening ports created by the one in C:\windows\system32\ftp.exe.
Obviously, that's why I asked you to copy ftp.exe to a new directory, so that any previous allowance by the firewall rules wouldn't get in the way.
So what's happening here? Is the "Allow" rule somehow overriding the "Block" rule, even though it's not dealing with the same executable?
We can test that simply by deleting both sets of rules - go ahead and do that, I'll wait for you.
Didn't make a bit of difference, did it? It still allowed the traffic, then prompted you if you wanted to block it. Even if you selected to "Keep Blocking", the next and subsequent transfers still worked, right?
Okay - let's consult the Big Book of Knowledge (alright, what I can vaguely remember after mumbleteen years in the networking world). Some routers and firewalls use an Application Layer Gateway (ALG) to translate FTP commands, and open ports. Is that what's going on here?
Let's take a peek at the services on this machine (as an administrator, run services.msc):
Bingo - there it is, the Application Layer Gateway Service. And when you have Internet Connection Sharing running, that's what translates IP addresses in FTP commands for you, and what opens up port mappings and holes in the NAT that ICS hosts.
Oh, but wait a moment - what's that in the "Status" column?
That's right, nothing. This service isn't running.
Something must be happening to open this port up - it's not just a case of "port left open", nor is it an outbound port. Those ports are closed tight until the FTP client starts listening for incoming data connections, and then they're opened up.
Here's where I go into MVP-mode, and start searching in all the nooks and crannies of the web and whatever documentation it holds.
Net result - Windows Firewall in Windows Vista includes something called a "connection inspection engine".
Sounds like something from "Schoolhouse Rock".
No, seriously, there's a "connection inspection engine" for FTP - if you connect to port 21, the firewall monitors your communications on that channel, looking for PORT commands. When it finds one, it opens up a hole in the firewall for the incoming data connection.
So why the scary dialog warning that something's going to block traffic?
Probably because the dialog pops up whenever an application starts listening, whereas the connection inspection engine only opens a hole when it sees a PORT command. And an FTP client can't actually give the PORT command until it's started listening.
So, the process goes something like this:
- Start the FTP client.
- Connect to the FTP server on port 21, waking up the connection inspection engine.
- Log on, then type dir
- The FTP client knows that it needs to open a data connection.
- To start the data connection, the FTP client binds to port 0, and starts listening.
- The firewall says "Oh no, an unknown program has started listening - better warn them that they won't get any traffic."
- The FTP client checks what port it actually got, and sends a matching PORT command.
- The connection inspection engine says "PORT command? That's my cue!" and opens a hole in the firewall to incoming data connections.
Well, that's easy, but what if I don't ever want to do an FTP connection? How do I stop this from becoming a potential hacker tool?
Okay, apart from the obvious - that if a hacker could connect out to a server on port 21, nothing's stopping that hacker from transferring data in - you might want to cripple this functionality.
No problem - just set the following DWORD registry value to 1:
HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Services \ SharedAccess \ Parameters \ FirewallPolicy \ DisableStatefulFTP
The default setting for this value on Windows Vista is 0. [It remains to be seen what value will be the default on Windows Server 2008]
How could Microsoft make this better?
- I'd really like to see this documented. Just so that it's not a surprise to anyone.
- I'd like to know how many other connection inspection engines there are (at least one, judging from the DisableStatefulPPTP value - but I don't know enough about PPTP to know how that affects operation).
- I'd like to know if I can add my own connection inspection engine to the firewall.
- Above all, I'd like to do away with the rather confusing and clumsy "We're going to block your incoming ... wait, what just happened?" dialog. If the connection inspection engine is monitoring a command channel, and the process that owns the socket for that command channel starts listening, perhaps we could wait a quarter of a second for a PORT command before calling this a blocked connection?
Finally, is this a vulnerability, a hole, or anything outside the correct operation of a firewall?
No, because the firewall is documented as blocking unsolicited incoming connections - and by any reasonable definition, the data connection requested by a PORT command is solicited.