I knew that Windows Firewall with Advanced Security (hereafter WFwAS) was capable of limiting access by application, but I had only worked with it to limit traffic inbound to a workstation, which is the capability that the basic Windows Firewall has had since Windows XP SP2. I hadn't spent much time with the new features introduced in Windows Vista when the name was appended "with Advanced Security". So, I thought I would give it a go.
|To give a frame of reference, here is the console for WF on Windows 10|
I began looking into the Outbound Rules section of the configuration. I was immediately overwhelmed with a very long list of complicated rules. Microsoft had contributed helpful stuff they thought I would need. In addition, all sorts of apps had put in custom rules, usually allowing various applications access to any IP address with any protocol. This would have to be cleaned up. But, the one key thing was here. There are rules that were allowing outbound traffic with specific applications listed in the rule. So far this was looking very promising!
Now that I knew that the rules could be limited to outbound traffic from specific applications, the next problem to tackle was limiting an application to some approved destination and then blocking it from all of the rest. My mind immediately went to my past as a network firewall admin... this was a problem that I learned to solve back in my Cisco Network Academy days when my instructors drilled IOS ACLs into our heads.
- Allow traffic from a source IP/range to a destination IP/range
- Deny all traffic from the source IP/range to ANY
- Continue with rest of list
- Default Deny statement at the end.
|Quick IOS ACL example I whipped up in notepad to limit TCP access to approved telnet and HTTP while blocking all other TCP connections... not very practical in the real world, just using it to illustrate a point.|
Easy enough, right? I wasn't quite sure how these applications I wanted to restrict were being used, but I was pretty sure some of them were being used on the corporate network. I decided that initially I wanted to allow access to my internal private IP address range from these applications but deny access to everything else. This would solve my problem of these apps downloading code from some random site on the internet, hopefully without upsetting the IT cart at my organization. So I had two problems to solve. First, writing the allow/deny rules, and second finding out where the default action was for the WFwAS. I decided to start with PowerShell.exe, which was easy enough to test using the Invoke-WebRequest cmdlet.
Since I didn't like the complexity and openess of the default rule set, I cleared all of the default firewall rules. I then added in my rule to allow PowerShell.exe access to the internal network range. Problem one solved.
Now on to problem two. After looking around a bit I found out that the default action can be set by right clicking "Windows Firewall with Advanced Security..." in the WFwAS console and selecting "Properties". The default for Outbound connections was set to "Allow (default)". Since I had removed a whole list of rules I knew that switching this to "Block" was not an option. If I did, I would kill things like DHCP and DNS and various other critical traffic unless I explicitly listed each app and service and what they were allowed to get to. At this time I just wanted to restrict PowerShell.exe. I left the default action to allow and then went back to the "Outbound rules" and set out to configure a Deny to mimic the IOS example above. I figured I would just allow PowerShell.exe to the internal network, deny PowerShell.exe to Any, get them in the right order, and then let the default action tackle the rest.
I guess that means I was back to problem one. Just a minor setback though. I already had an allow rule, so I added in my deny rule for any traffic from PowerShell.exe to destination Any. I was able to get the rule order correct on the screen by deleting and re-adding the allow rule, and started my testing. (Those of you with experience with WFwAS will know exactly what happened next.) Access to the internet was successfully blocked!!! So far so good. Next I wanted to make sure access to my internal network was also allowed. Easy enough, quick test to a webserver on 192.168.40.11...
And with that wall of red text I was introduced to WFwAS rule processing order of operations. I have worked on at least 7 major firewall/router vendors, all of which process rules from top down, first match wins. So why didn't it work? Simply put, WFwAS doesn't process rules that way. In fact, the order listed in the console didn't seem to make any difference at all. So, I went to the interwebs and hit the search button and landed on TechNet. Here is the WFwAS rule processing order, in summary:
- Windows Service Hardening (huh?)
- Connection security rules (IPSEC... I knew a little about this from a coworker)
- Authenticated bypass rules (more IPSEC magic)
- Block rules
- Allow rules
- Default rules
In my case it was the last 3 that really mattered (hopefully more on the first three in a later blog). WFwAS processes all of the Block rules, and if there is a match the traffic is denied. It then processes all of the Allow rules, and if there is a match the traffic is permitted. If there is no match, it applies the Default action defined in the properties dialog box.
With my PowerShell example, even though I had a more specific allow rule ordered before a broad deny rule, the deny rule was processed first and denied all of my PowerShell traffic and there was never an opportunity to match the allow I had set.
To date this is still the only firewall I have come across that processes rules in this way. It took me quite a while to get comfortable with the idea. I would love an hour with the committee at Microsoft who came up with this, um, most interesting solution. I tell myself it made sense at the time, right? I hope it has something to do with some dependency I don't yet understand.
So, my first attempt failed. After the initial elation I was a bit deflated. Perhaps I could switch to a rule that allowed all apps access to the internal network, things like web browsers access to all of the internet, and PowerShell to just the external ranges I knew it needed, and use a default action of "Block" at the end? This would be the "whitelist" approach. I knew it would work, but I didn't know which applications needed access to the internet outside of web browsers. I knew that there were things like "web ex"perience meetings and meetings that I could "go to" that would need access to all sorts of IPs and that had random names and various hard drive locations they were launched from. I also knew that lots of installers relied on web connectivity to download applications. In short, I just wasn't ready for a full whitelist, and I really just wanted to limit access to PowerShell and a few other applications.
I had my problem before me. Allow access to internal network for restricted apps, allow access to some external IP address ranges, block all else - without processing block rules first, with a default action of "Allow" for the rest (with logging enabled to start building my whitelist - I hope to have more on this later as well). I was stumped and hungry and it was late and I was frustrated with M$ and I wanted to go home and see my family. I shelved my skunkworks project for a few days and mulled it over in the back of my head.
Turns out there is a way to do what I wanted, but I had to stop thinking like a firewall admin and think outside of the allow range. But, this post is already longer than I expected, so I will plan to go over how that was accomplished next week. I'll see if I can keep a cadence of a post a week.
Until then, work hard and spend time with your family.