Windows file sharing operates via an old protocol called SMB (Server Message Block.) In modern Windows operating systems, it operates over TCP/445, though older versions of Windows also made use of NetBIOS (UDP/137, UDP/138, and TCP/139). Due to the ubiquity of Windows file shares on corporate Intranets, in general these ports are open to basically everyone on the internal network, though they are blocked at edge firewalls. Even UNIX/Linux machines often use these ports, due to a Windows-file-sharing-compatibility package called SaMBa.
There have been many security vulnerabilities in NetBIOS in the past, and some in SMB, so these protocols are (rightly) considered moderately risky by network administrators. However, scarier than any of these patched vulnerabilities is the flaw in the design — SMB is subject to a sort of replay attack, called SMB Relay or SMB Reflection.
SMB at first appears safe from replay attacks. After all, it uses challenge-response authentication (normally; there is a protocol for SMB with cleartext, but basically no client or server will accept this protocol now), whose whole purpose is to prevent eavesdropping and relay. If you try to replay the same response to a server, it won’t work, because the challenge is different. There are three ways SMB allows challenge-response authentication — LANMAN, NTLM, and two-way NTLM. In any case, the principle is the same — the client asks to authenticate, the server sends a challenge, the client encrypts the challenge with a password, and sends the encrypted result as a response.
So how do you perform a replay attack on SMB? Via SMB Relay (to attack another host) or SMB Reflection (to attack the client.) It goes like this:
- Client (C) connects to you (a malicious server, M) and asks for a challenge.
- M connects to C in a separate sessions and asks for a challenge. It still has the connection from (1) on hold, having not responded yet.
- C receives the request from M, and responds with a challenge (challenge_C).
- M takes challenge_C, modifies it to appear to be coming from M (challenge_M), and responds to the connection from (1) with it.
- C finally receives the challenge (challenge_M) that it asks for. It uses its credentials to respond to it (response_M).
- M receives response_M, which is correct for challenge_M, and so grants C the access it requested. Of course, this response also matches up with the challenge it’s holding onto (challenge_C). It forwards it right back to C as response_C.
- C receives response_C, which is correct for challenge_C, and so grants M the access it requested.
No, C doesn’t ever realize that it just received and responded to the challenge that it, itself, sent out moments before. By requesting access to M, I have unwittingly given it all it needs to authenticate against me at the same time. It can’t be carried out later — the reflection attack has to happen at the moment I am trying to connect.
Note that this is a design flaw — there’s no “bug” to patch here (I suppose Microsoft could modify SMB to ensure that it’s not responding to its own challenges; it would be possible but not trivial), this is the behavior of SMB since time immemorial. No buffer overrun is exploited; SMB is acting precisely as it’s intended to. This issue has been known since 2001.
Host firewalls like Windows Firewall and ZoneAlarm help some — at least, they keep SMB Reflection attacks out. However, they don’t help if the attack is coming from a zone you trust — i.e. if you’re sharing files with your corporate Intranet, someone on the corporate Intranet can attack you this way if you try to authenticate against them. And it also doesn’t stop SMB Relay — if I connect to M with my firewall up, he can’t use reflection to attack me, but he can relay to yet another host and impersonate me, passing me its challenge and relaying my response to the remote host.
It actually gets a bit worse than this, because the NTLM package used to authenticate SMB is the same one used to authenticate you against Intranet websites in Internet Explorer. The attacker might not need to get you to try to make a file-share connection to him; a web connection can be sufficient.
This attack sounds relatively tricky to carry out, and it is… by hand. However, the ever-popular Metasploit Framework contains an SMB Relay module (which also works for SMB Reflection) that makes it quite quick and easy (you need the live-tree version of Metasploit out of CVS, not the release build, as the module is relatively new and was just demonstrated at Defcon 15 this August.) You do have to disable SMB on your computer to use it, though (which is simple on Linux, but on Windows involves unbinding the Server service.)
This makes SMB reflection trivial. You load the module, tell it your IP address, load your choice of many payloads (such as having a shell started and passed to you, or simply having an SMB connection opened that you can do with as you will), and then wait for someone to connect to you. You can either specify a target server if you want SMB Relay, or leave that unspecified for an SMB Reflection back to the person connecting. The only thing Metasploit won’t do for you is make people connect to you.
So the moral of the story is apparently to be careful who you connect to, especially on local networks where your file-sharing ports are open. That’s a pretty good moral in general… but it’s really not enough. People who run Windows Firewall often have a blanket exception for File & Printer Sharing, which opens port TCP/445… if you’re not behind a home firewall or router, this sort of attack may be able to be carried out on you from any site on the Internet. And tomorrow, I’ll be talking about why nothing of any kind is ever safe on a public wireless hotspot.