I, too, can do click-bait title BS!
Alright, this has been in my draft folder for almost two years. I originally decided to create it after a customer discussion on Windows Firewall. BECAUSE YES, THIS IS ABOUT THE BUILT-IN WINDOWS FIREWALL! (oh no! I hope the screaming did not scare IT pros away!) An awesome security person at Microsoft, Jessica Payne, once presented something about the Windows Firewall with Advanced Security (that's the full name of the feature) in a conference. She pointed out that very simple configurations (all with no extra charge) can lead to a dramatic improvement of ones' security posture.
This post is presenting a quick way to kill one of the most used propagation techniques called lateral movement. So nothing new here. This stuff has been around for ever. You're just in denial...
Lateral movement is the way the bad stuff propagates from one machine to another peer. Note that this is past the initial infection. Once one machine gets pwned, the bad stuff will try to connect to all the other machines nearby, using the credentials harvested in the first one (local accounts and domain accounts) or system vulnerabilities (unpatched SMBv1). It is usually possible because of different aggravating factors:
- Poor credential hygiene. Administrators are using their accounts on the same systems they are using their Outlook, their Chrome or their Tor browser. As a result, if this machine gets compromised, the administrator account gets compromised and it's already game over. I have seen pentests lasting 1 minute because the domain admins prepared the machine for the pentesters and has its credentials cached locally... Well, administrators should use dedicated systems, and should never connect to systems from a lower tier.
- Same local administrator password. This basically means that if one machine is compromised, the attacker gains Single-Sign-On on all the systems using the same local administrator password. That is easily fixable with LAPS. If you never heard of LAPS as of today... Hum, you failed at your job. So please do check it out now.
- Insufficient network restrictions. Of course you have firewalls at the perimeter. Or even between different network zones (DMZ, super DMZ, ultra secure DMZ, whatever DMZ). But you don't usually have network firewalls between workstations sitting next to each other. Although you probably don't have a lot of applications doing peer-to-peer type communication. And for this, you have this post!
Defense in depth
You don't cherry pick 1, 2 or 3. Here is the classic attack timeline you probably have seen many times:
Defense in depth is deploying all of them. You want to make the work for the bad stuff complicated, long and noisy. You want to become unattractive for commodity malware. You want to tend toward something like this:
There is still some red, but making the lateral movement a tough journey for the bad guys will also buy you some time. We do not discuss the monitoring capabilities here (ATA, Windows event logs...). But we look at how we can make that yellow bar as long as we can... for... $0 (FYI $0 = ¥0 = 0€).
"It's not 100% bullet proof, so I don't want to do it"
This post suggests blocking certain ports and also introduces some exceptions (see later the section "oops, my admins can't work anymore"). So you might be tempted to give up. Thinking that something bad can still happen anyway. What if you were the chief of Police of your district. Would you say to your agents: "Listen up folks, no Kevlar vest anymore. Since you can get shot in the face, this is deemed useless." I am pretty sure some field agents might shyly raise their hands and state "what if they don't shoot in the face...". After all not everyone got CoD accuracy IRL (sorry, I had to put some gamer stuff here). You have to look at the ROI of your defense mechanisms. And here, since this is a built-in feature, beside the time required to read this post, test it on your lab and wrap your head around it, there is no other cost or investment. Also, we will block SMB in this article. SMB is just one way... We could also add RPC, or even all peer-to-peer (well that one probably not... legit applications are using P2P type of connections for our good, like Skype or some business apps). But eh, blocking SMB is a good start, and it'll show you one methodology.
"I once enabled the firewall and I almost got fired"
I hear that sometimes. Or the even better "I prefer to pay for an expensive third-party firewall because there is this great reporting feature that the built-in firewall doesn't have, well I never use it but the sales person was damn convincing (aka I got lots of goodies)". The firewall has changed. It has, really. And a long time ago. It changed back in Windows Vista. So the experience you might have had with the Windows Server 2003/Windows XP days is not relevant. The "new" firewall is not even close to working the same way. So it is time to reconsider... What is explained here requires to have the firewall enabled though. Jessica's presentation back in the day outlines possible scenarios when it comes to the built-in Windows firewall service status:
- The firewall service is disabled.
- The firewall service is enabled but all profiles are off.
- The firewall service is enabled but all profiles are set to allow inbound traffic by default.
- The firewall service is enabled, the default rules is Allow traffic only if a rule allows it, but then there is a rule which allows all traffic from any to any...
- The firewall service is enabled and configured... 🤔
Number 1 is really bad. It actually can even break stuff. But that's out of topic.
Number 2 is not protecting you at all... At least you're avoiding some glitches when you try to configure WinRM or install Operation Manager agents (damned! I said it would be another topic!).
Number 3 seems also useless... But it is not! Having the profile enabled means that you can start using the firewall logs feature! See the section "Show me the logs".
Number 4 is a poor attempt to pass security assessments. Well done, you are hiding stuff under the big carpet...
Number 5 just rarely happens... Although the default configuration of the firewall is just fine for 100% of the cases as long as you install well developed applications (and quite frankly, since we are also talking money, why would you buy poorly developed apps anyways right?). Application installation programs will create their firewall rules. Because by default all outbound traffic is allowed, usually only inbound rules need to be created. And if your system is a Windows server, when you install and configure a Windows role (like a DNS server, a ADDS domain controllers, ADFS, etc...) it enables its respective rules by default (I've actually seen many customers who thought the firewall was disabled because they never had issues with it and were very surprised when I showed them that it was in fact enabled).
Profiles... From good to great
The Windows Firewall has profiles which are automatically detected and enabled depending on some of the network conditions of the system. Like for example, if the machine can talk to a domain controller, we have the "Domain Profile" enabled. So for all the rules you created you are asked to pick the profiles for which the rules will apply. In my example I will pick all profiles all the time. It is not ideal, but it is better than nothing at all!
STEP 0 - Enable the firewall - My walls are on fire!
ACHTUNG! You can really hurt yourself if you enable the firewall the wrong way... I have seen customers doing tests on a single server and breaking the RDP connection they were using to actually connect to it in the first place 😵 Test in a lab, and always scope the GPO to a subset of test machines first. If you fail just unlink the GPO and wait...
We will assume in this post that the firewall is not configured properly on your workstation and create rules to enforce our restrictions anyway. In a perfect world, your firewalls' rules should be well documented and enforced already with group policies.
We create a GPO that we do not link yet. You can disable the User section of the GPO as we will not use it.
Let's enable the firewall for all profiles...
Scared of breaking something because it was off before? Well in that case, you can do this:
Then you wonder... Wait what is the point of doing this? If I open everything for inbound, it's like it was off. Not quite! If you create a block rule, it will override the default Allow rule you just selected. Ideally you should pick the Block.
STEP 1 - Block incoming traffic - Sorry, no sneakers allowed.
Now we create a new inbound rule as follows:
If we apply this to a machine, even if the local firewall has the rules to allow both TCP 139 and TCP 445, the connection will fail because the one we created will take precedence.
STEP 2 - Allow exceptions - Oops, my admins can't work anymore.
First thing to do is to create an inbound rule that will allow the traffic only if authenticated. If we want to filter who is accessing SMB, we first need to authenticate them. So we create a new inbound rule as follows:
This time we pick "Allow the connection if it is secure".
Click on "Customize". We are going to pick two options here:
- Allow the connection to use null encapsulation. This is great because we don't really care about encryption in our case. We just want to authenticate the traffic. Besides, by not doing encryption, the traffic will still be in the clear, hence if you are doing some troubleshooting (or smart QoS, smart in a sense that it can get over the fact that the SMB traffic is transported over an ESP layer...) we can still look at network traces.
- Override block rules. If we don't pick that option, our rule will not apply because of the first block rule we just created.
Then we will select groups to create exceptions. One for the user accounts:
One for the computer accounts:
STEP 3 - Configure the exceptions - I'm joining somebody inside.
This is not over here... We need to provide a way for machines and users to authenticate. So far we just set the firewall to reject the connections unless authenticated and users and computers member of specific groups. Now we need to tell all participants how to authenticate.
Still on the same GPO, create a new security association rule as follows:
Yes we went custom... In my opinion, the wizard is hiding a complexity that does not really exist...
In the next one we have several options, as long as we require authentication for inbound.
There is room for an accident here! Watch out! We have selected "Require authentication for inbound...". If you do not select specific protocol and/or ports here, the rule will apply for EVERYTHING! And very likely prevent you from establishing any type of remote connection to that system...
Now we need to create the reciprocal rules on the machine we want to grant access (the help-desk users and machines, the SCCM servers and service accounts, the administrative systems, etc...). Again we create a policy. We disable the user's section and will configure the firewall. But this time, we just configure a security association. You can also force the firewall to be on and so on and so forth, you got the drift.
For the next one, we can also restrict the rule to certain subnets if all your workstations are in a specific one, or a few.
This time we pick the Endpoint 2. And again, we accommodate the NetBIOS fallback, but we can also just specify 445. Enough with legacy stuff.
That's it. Then you apply the GPO to the right OUs, with the right security filter (and why not apply a WMI filter looking for OS version to limit the first GPO only on workstations).
STEP 4 - Now what? - Show me the logs!
Let's verify that everything works... Let's connect with SMB from one machine which is allowed to connect and from one who is not. On the machine applying the first GPO, we should see this in the firewall console (wf.msc):
And on the machine which is allowed to connect:
Don't forget to enable some log (useful for troubleshooting... and for more...). Easy, go back to your GPOs and enable it that way:
Go fancy, enable it on all the profiles for DROP and ALLOW and with the maximum size (32Kb ~ 32,768b). It will create a log file of up to 32Kb. When it is full, it will be renamed and saved and another one will be created. When that other one is full, we delete the old one and replace it automatically. So you always have at least 32Kb of logs (and at best 64Kb). This is what the logs look like:
2017-01-04 21:15:44 ALLOW TCP 10.0.0.80 18.104.22.168 52028 5671 0 - 0 0 0 - - - SEND 2017-01-04 21:16:46 DROP TCP 10.0.0.10 10.0.0.80 61564 445 52 S 2716891960 0 8192 - - - RECEIVE 2017-01-04 21:16:46 ALLOW UDP 10.0.0.80 10.0.0.10 60674 53 0 - - - - - - - SEND 2017-01-04 21:16:46 ALLOW TCP 10.0.0.80 22.214.171.124 52030 5671 0 - 0 0 0 - - - SEND 2017-01-04 21:16:49 DROP TCP 10.0.0.10 10.0.0.80 61564 445 52 S 2716891960 0 8192 - - - RECEIVE 2017-01-04 21:16:49 ALLOW ICMP 10.0.0.10 10.0.0.80 - - 0 - - - - 8 0 - RECEIVE 2017-01-04 21:16:49 ALLOW UDP 10.0.0.10 10.0.0.80 137 137 0 - - - - - - - RECEIVE 2017-01-04 21:16:49 DROP TCP 10.0.0.10 10.0.0.80 61567 139 52 S 1261083587 0 8192 - - - RECEIVE
The biggest problem with efficient defenses is that you don't necessarily know if it actually blocked a lateral movement or did nothing. At the end of the day, you learn how to use the firewall, so it's not nothing! But you can do geekier than that. You can parse all the DROP of your workstations' logs and then use PowerBI to see what's up. It would look something like this:
In this post, we looked at what some of you might call a "dirty way" to stop the lateral movement. Why dirty? Because I believe it is better to configure only the right inbound rules on your workstations to start with instead of doing block/override like we do. But it works. And it is damn cheap! If you want to see a more elegant way to manage the firewall rules with GPO and the Windows audit (instead of the old school text log file) etc... Please let me know in the comment section.