 Hello, welcome to track one to his clock talk. Hope you learned something new about SMB. This is William Martin. So as introduced, my name is William Martin. For anyone who saw me yesterday, it's going to be pretty familiar. I'm an OSCP. I'm a pentester based out of Charlotte, North Carolina. I'm a supervisor at RSM US LLP. And this is my second time presenting at DEF CON, first time as yesterday. So lessons learned from yesterday is that if you've got any questions about this talk, want me to clarify or expand or get in contact with me, take a note of the Twitter handle right now that's the best way you're going to be able to reach me. So it's a quick breach. Anyways, so before we get started, I want to make sure all the right people are in the room. We're going to be talking about SMB and SMB based man in the middle of attacks. And for red teamers, this is useful to, you know, add a new kind of attack to your tool set, add a new technique to your arsenal. And for blue teamers, you want to know how to stop the red teamers from using what they learned today. And for like the three guys curious about SMB, it's also for you. That guy right there. Thank you. So first things first, I want to clarify some terminology. When I mentioned SMB server, do not think of like a server 2012 or 2008, it is any Windows PC connected, typically connected to a domain. Every Windows PC runs an SMB server by default, but when you're in a domain typically that ports opened up so that anyone can talk to it. So when I say SMB server on client, it can be a Windows 7 to Windows 7, 2012 to 2012, there is no connotation tied to the actual operating system. So what is SMB? In a nutshell, it's a way to, you know, access files remotely as Microsoft solutions for network-based file sharing, file management. You can read and write files to it, you can authenticate to it, you can map network drives, and you can actually access some, you know, RPC pipes over it as, you know, hackers love like, you know, through PSX and whatnot. What I want to clarify is that through this talk, I'm going to be talking about SMB 1 and SMB versions 2 and versions 3. Now, back when Vista was released, Microsoft pretty much did an entire rework of the SMB protocol. Originally it was based on an IBM system, and that's what we call like NTLM, and Microsoft uses NTLM everywhere, so the names always get mixed up. But SMB version 1 is what we're typically familiar with for like, you know, MS-17010 and things like that. SMB version 2 and 3 is an entire rework of the SMB protocol, and within that there are different versions, they're called dialects. So 2.0.2 is the first version of SMB 2.3, and then you got 2.1, then you got 3.0, and then 3.0.2 and et cetera. So, a typical of this change in SMB looks like this. Someone says, hey, what's in this folder? And SMB will reply, you got documents, desktop, and you know, some not password file. So, we love it past the hash, we love it for system enumeration, and we love it for spidering shares and hunting for sensitive data, such as like, you know, the C-password vulnerability and SysFold, and obviously for MS-17010. Now, the premise of this talk, and the origin of this talk, is SMB signing, particular how it defeats my absolute favorite attack. My favorite attack is the NTLM relay attack, especially against SMB servers. If anyone has used impact, it's the NTLM relay stuff, PY tool, you know, that is it. And I'll tell you, the attack works like this. A victim says, hey, where is my network share? An attacker says, hey, I'm totally that network share. Victim says, cool, let me log in. We then relay that to some random server we pick and say, hey, let me log in as this dude. Server says, yeah, that's cool. Just hash your password with this challenge. We send that back to the victim. They comply. We forward that on to the server. Server lets us log in and then we kick the victim. We ghost them. And once we have that connection, we can enumerate the system, we can exit commands, we can dump it, that's now our box. If the person's a local admin. Now, the thing that sucks about this attack is if anyone's run this, you might have seen this. Signature is required. Now, I had a bit of confusion. I just manipulated the entire authentication process for this victim, yet they have somehow established a secret or trust between each other unbeknownst to me. So I didn't know how could they have done that. Where was there some kind of like public key, you know, certificate kind of thing going on? I had no idea. So when I looked up what is SMB signing, I got vague descriptions. And if you've ever run a Nessa scan, I guarantee you've seen this. So naturally, like most of you, I Google it. Now I got it's answers like it stops man and middle attacks. Stops man and middle attacks. Trust us, it stops man and middle attacks. It's Microsoft solutions to stop man and middle attacks. That's about it. That's all the information I could find. So I knew that it protects the integrity of SMB messages, because we edited it after signing is enabled, we get screwed. It's required by default on DCs. It occurs only after the authentication process. And it stops my favorite attack, which is kind of like a dick move. So I dove into the MSND docs. And this was supposed to be a gift, but you know, whatever. And I saw things like this. And I saw things like that for a while, quite a while. But eventually I found the answer to what SMB signing actually is. And we're gonna dive into that. At the end of the authentication phase, both the client and the server will share the same session-based key, just a 16 byte value. They then use that value to generate other keys to then sign the messages. Now, the goal of what we're about to cover is where does that key come from and how can we compromise it? By the way, that's what a signature looks like for anyone who hasn't used Wireshark on a DC. So the session-based key actually depends on what authentication mechanism is used. So let's talk through NTLMV2, also my favorite type of authentication. There are three messages in NTLMV2. There's a negotiate, a challenge, and an authentication. So negotiate just says, hey, I wanna log in. And they set some empty parameters. Like you can see in this capture, there is no username. There's no workstation. There's no domain name. It just says I wanna initiate this conversation. One flag that can be in this message is called the negotiate key exchange flag. And we're gonna get into that later. But in a nutshell, what that means is that once both the client and the server established that shared session-based key, they're gonna change it again. But that's what that flag means. We'll get to that. The challenge says, cool, all right, hash your password with this data and then send it back to us. And this contains the server challenge information, like the host name, domain name at DNS name, stuff like that. The authentication message contains a lot of stuff. The username, the domain, the client challenge, the NT proof string, which in a nutshell is the hash generated by the client. A bunch of response server versions, things that are in plain text that we don't particularly care about. And an encrypted new session-based key. If you look in this message, you'll see there's a session key value like B485 to whatever. That only exists there if the negotiate key change flag was set earlier. That is the encrypted version of the new session-based key. But if they didn't negotiate that, that value's gonna be empty. And they're just gonna proceed with the keys they generated on their own. So, I thought it was very technical. But let's get down to how the keys are actually generated. And we need to know what HMAX and CMAX are before we can get into that. In a nutshell, they are message authenticating, no, authentication code algorithms. You can think of them, if you're familiar with password salting, you can think of them like a salt where you have a message and you're gonna hash that message. But while you're hashing it, you're gonna include a secret value that only those that secret value can throw in that hashing algorithm to create the same hash. So in HMAX or CMAX, the underlying protocol might vary like some use AES and some use like SHAF 256. But in a nutshell, their goal is to hash the message in addition to like some secret information. So, let's actually walk through generating those session base keys. So, step one is we need the NT response. That is the user's NT hash. So it goes from plain text to NT hash. Step two, we take all of the information from the server challenge and we put that together and we use the HNAC algorithm with the password, with that hash password to the NT hash. And then we have our session base key, which is the NT response, hashed again, again, your password hashed again in addition to all of this server information that you already hashed. All together it looks like that. The key takeaway though is the highlighted information is the only information we don't have in this exchange. To generate the keys that protect all SMB sessions, we just need the user's password, which is great, because they're always secure, we can never crack them. That was my response when I found out that the key concept protecting all these connections was just their password. I mean, think about if TLS was protected not by some random long string generated through the connection established phase, but instead like the dude's password on the website he's connected to. So, the key logic works like this. You have the password, gets converted to the NT hash, gets combined with all that authentication data, and then that generates the session base key. Once you've got that session base key, you can use that to then sign packets, or in other versions of SMB, you can use that to generate the keys to sign the packets. Long story short, this is the value we care about. So, as I mentioned earlier, if that flag is set and you generate that key, you're just gonna use it to decrypt this one and that becomes the new one. So, with that knowledge now of how those session base keys are generated, I want to go back to my favorite attack, the NTLM v2 relay attack, and show where that trust is established and I know there are some Microsoft guys or AD admins in here who are gonna laugh at this for leaving this step out. So, here's what it looked like. We just sent the challenge response, we just sent the authentication message to the server. The victim at this point, before the server replies, has already gathered all the information required to generate that session base key. So, he's cool. The server doesn't have the user's password, unless you're connecting to a DC itself. So, the server actually sends all of that data off to the DC through a mandatory encrypted channel. Please trust me on that one. And the DC will reply if it's a valid login and if it is, the DC will generate the same key in the same way that the victim did and provide that to the server. That's the trusted secret that we don't get. So, I know you're all thinking, what about Kerberos? So, Kerberos is a bit more difficult to get into. Starting from step zero, when the user logs into their workstation, they log in and they send a request to the Kerberos server to believe the DC. Kerberos replies saying, hey, encrypt this timestamp with your password so I know it's legitimate. We send the encrypted timestamp and the Kerberos server replies with our TGT, which is our session key. We're gonna use that for most everything on the domain. We're gonna use that for future communication with the DC. We're gonna use that to request tickets to other resources on the network. Such as when we wanna connect to something called a file server one, just a random file server and the DC will reply with an encrypted service session key in that packet. We'll send the ticket we just received off to the file server. File server will, assuming it's valid, will reply and say, hey, cool, you're good. And if there is extended security, it will reply with another encrypted session key. Which altogether looks like this. Password turns into the Kerberos session key we got when we first logged into Kerberos. That we use to decrypt the service session key we get when we ask for a ticket to a file server. And if they're using that extended logic, we use that last key to decrypt the now new key provided from the file server. These keys are then used to sign the SMB messages. These are the SMB session keys. And the algorithm used to generate these keys and to generate the signatures is very based on the version of SMB. So there's version one, which is MD5. Versions two and 2.1 kind of beeped it up a little bit with SHA-256. And versions three and 311 really beeped it up with AES-128. So now that we know the only thing protecting these sessions is the integrity and the complexity of the user's password, let's go after it. So first things first, we just talked about how to kind of break SMB signing keys and how to break signed SMB connections. But when SMB signing isn't used or we have that, it's essentially HTTP without HPS. If encryption's not used, we can steal copies of files passed over the wire with or without the keys. And encryption's not used by default. If signing is not used, it's fair game. You can replace every file with an identical link that executes our code. You can swap out the contents of legitimate files passed over the network. You can inject fake files into directories and that helps with social engineering. And if signing is used and we know the password, then we can do all of the above. Plus, we can also backdoor some stuff pulled from the DC by the user. So in SMB version one, they don't really use signing by default. And in SMB version two, three, the case is pretty much the same. Unless somebody requires signing on one of the sides, no one uses signing. So we just talked about how to break signing most of the time it's not even in place per the Nessus reference. Also SMB version one, there is no encryption. So for those plain text files passed over the network, we can just grab them. SMB version two and three, it supports encryption version three, but it's not enabled by default. And enabling it is a bit of a pain. So chances are, you can also, regardless, steal files passed over the network. Broken down, there are various versions of SMB and they're supported on various types of operating system. Like Vista came out with SMB version two and that was the first one to come out with it with 202. Then you've got the latest and greatest server 2016 using 311 and Windows 10 using 311. Everyone else uses something earlier. Or rather not earlier, in between those. Notable exceptions in all of this is that DCs require SMB signing by default. Windows 10 2016 have protected paths that always require signing if they're connected to a path that matches these paths. So anything that's like something SysFall or something NetLog on, the client's gonna require signing regardless of what the server says. And that's through a process called UNT hardening. One other notable exception is that if a client supports SMB version three and that's 302 or 311, then regardless of if signing is used or not at the end of the authentication phase, they're gonna send a message to the server saying, hey, just make sure we're all on the same page. Here's the information you gave me during the negotiation phase. Is this still cool? And that's a signed message. So the server now has a way to kind of verify that no one messed with it in between. Even if they're not using signing for any of the subsequent messages. Only catch here is that in that message, it's the one that verifies we're all on the same page. It covers everything except for the authentication mechanisms used. So even with that, you can still downgrade them to NTLMB2 and get away with it. So on the other end of the spectrum, SMB 311 is a beast. And I'll give kudos to Ned Pyle on that one. The SMB keys, rather than just being based on the authentication mechanism used, it's also based on the hash of every packet passed back and forth during the negotiation and authentication. So if you edit anything, then the server and the client are not gonna have the same keys and the connection's gonna drop. So not bad on that one. So to recap, it's used on DCs and on 10 and 2016 on those paths. Encryption's only on SMB3, but it's a manual process. Every dialect up except for 311 can be downgrade on NTLMB2 and signing and encryption keys are at the root based on the user's password. So let's attack that. I built SMBetray, and the goal is just to build a tool to really take advantage of these man-made vulnerabilities. The attacks we've been running before are like the relay attack I described, where we're enumerating the system if we're putting ourselves in between a victim and a server or we're trying to pop it if they have LA. But if they don't have either of those, that's pretty much where the road ends for us on SMB attacks, except for MS-17 or patch-related vulnerabilities. So I wanted to take the focus instead of relaying or putting ourselves to the focus on the server. I wanted to go back on the client. I wanted to go back on the HTTP mindset of attacking the client. So the biggest obstacle in all of that was putting ourselves in the position to attack the client. So we wanted to be right there. We want to be between my buddy Damian's in the crowd. We want to be between Damian and his DC, his file share, and his other file share because many users have multiple. We didn't want to just pick between, you know, being in between Damian and his DC, and that's it. So we're missing a lot of data there. So when I was trying to build this tool and I was trying to put it on top of Man of the Middle framework, I kind of had two options. The first one was through the use of an arbitrary upstream server. A lot of these Man of the Middle tools will use an arbitrary upstream server as a way of misstability. Long story short, you receive a connection during like an ARP cache poisoning attack. IP tables will redirect that connection right back to you. And then in the socket layer, you will then forward it on to wherever you want. The catch is when you're at that layer, you don't have the original destination of the connection you just hijacked. So if Damian was trying to connect to his DC and I intercepted that connection, I might be redirecting him to some random file share I picked. And on his end, that's not going to be what he wants, so he's going to drop the connection and it might not give me all the things I want. I want him using that connection so I can take advantage of every opportunity. I want him downloading files so I can steal them over the wire. The other opportunity for a man-made tool to kind of take advantage of that was the use of Net Filter Queue. Net Filter Queue really gets down to the kernel level and allows you to edit those packets and intercept those packets live time. So you don't have to worry about losing the destination information as you're pointing this intercept. So you can put yourself in between all of those servers. Only catch is that when you're putting yourself in between all those servers, Python is what I was using and Python would just snowball, it would drag. What would seem very quick to us was eons for QCP. So this only solution that I found to do a full transparent man-made middle attack was killing me because it wasn't fast enough, it wasn't parsing the data fast enough to pass the information back on. So I tried to combine them so I get the solution that I wanted. I created a little library called EBClib which I was kind of playing on, there was EdoCap and then there was BetterCap so cheekishly I put EBC for even BetterCap as a man-made middle TCP kind of framework. So it gives you all of the freedom of a transparent proxy built on NFQ where you can just say, hey, put myself in between Damian and whatever he's talking to without editing it or edit if I choose to with the connection stability of like a BetterCap with an upstream proxy. And that's the technical of how it works. Long story short, you get the packet. NFQ rather than trying to edit the packet the entire time do it and do whatever attack you intended instead it just performs one task which it does pretty quickly and that's why the connection doesn't drop. NFQ will get the packet, it will just take the source and the destination information and then store it in a shared piece of memory and then pass it on. That gets redirected like the first type of man-made middle attack to a TCP server. And with there you have the stability of TCP. That TCP server will reach out to that shared memory, find out where this dude was actually trying to go to and then builds that connection dynamically out there. So once you receive a connection that exists it just passes through to the TCP server like business as usual. So now that we compare ourselves in between the server that we want to hit and the user, let's go ahead and let's start attacking them. Let's downgrade the dialect and the authentication mechanism is used. Let's steal the passive files that I've been harping on. Let's inject some files and swap out some content and let's replace files with an identical link so that when they click it, it launches that thing. And of course, if we know the password for the user, let's leverage that information to break those session keys. So the way as the betray is broken down kind of looks like this. We put ourselves in between the victim and whatever server they want, even multiple servers at a time. The victim will say, hey, what's in this folder? And that request occurs simply when you open up a folder in a share and it starts listing out all the files and folders in there. We pass that on to the receiving server. Receiving server will reply saying here, file one, file two. We'll get that and if we know the keys or it's an insecure session, we'll throw in our own file in there or we'll modify the details of the files that were just listed like their file size. The user might request one of the files we just lied about instead of was in that folder. Now, instead of passing that on to the server because the server would reply with an error saying that file doesn't exist, we send them a convenient function, SMB, called an echo. SMB loves to keep its messages in sync. Each request and response has a numeric ID. So if I say I'm gonna pick on Damian again, if I say hi Damian, that has a message of one, when he replies, that's a message ID of one. That conversation is concluded. If I say another thing to him, message ID two, he replies message ID two. That helps verify that we haven't missed anything in this conversation. But if the user just requested a file that does not exist and we're not gonna pass that on to the server, there will now be a discrepancy in how they talk to each other. Their IDs are gonna be misrepresented and they're gonna be off. So to keep them in sync, for every request that is completely forged or malicious by the victim that we're handling, we're gonna send an echo request to the destined server. When the server replies to that echo, we've now incremented the messages again and now we're gonna reply to the victim with whatever we wanted. And that way, when they continue their conversation with each other, no one will identify that they've been swindled, old word. So now let's show a brief demo of what this is gonna look like. So assume we've done an ARP cache poisoning attack on this victim and we're between them and a switch. On the other end of the switch, it's gonna be like a DC and there's gonna be just some file share. So first things first, we're just logging into a user's workstation to show you what a non-attack scenario looks like, what his average PC sees. He's got a file share, a map drive called some network share and there are some files in there. Keep a mental note of the files that you see because we're gonna be injecting some and removing some. Cool. So now we're gonna launch the ARP cache poisoning attack to really put ourselves in between him and whatever he wants to talk to. And also note, the server that he just connected to, one of the files in his map network drive requires SMB signing. File containing a lot of pop credentials. So if you've been running like an LLMNR and NTN net bios poisoning attack on your LAN, you might have these credentials. And we're gonna load these credentials into the tool itself. It's just gonna use them and when it sees a connection coming from that user, it's gonna try to leverage those credentials to pop the SMB signing keys. The attack we're running is gonna be a link swap all attack as well as an inject files. Inject files intuitively just injects files. Makes files appear in the directory that don't actually exist in the directory. And the link swap all is any file at all. We're gonna replace it with instead a link that will run whatever we want. In this case, we're just running calc. And we're running calc because when I was writing up this demo, I didn't have time to fight with Windows Defender, because I've been kicking ass lately. So calc was easy enough. So now Paul Davis is gonna log back into his PC. You can see we capture his hash. Then in the background, you can see that we, it's reported that we broke his session base key through both NTLMV2 and it's cut off a little bit, but it says Kerberos. And now it shows that we just injected some files. So click me, inject me, seems legit, all those. The text file that we opened up earlier is now a link. And when opened, we'll run whatever we want. In this case, it was calc. Inject me, a totally fictitious file that doesn't exist on the server he thinks he's talking to is now there. And any file, thank you. Any file that this user is now downloading or opening, either directly or indirectly, through back end processes and Windows, we will be passively stealing a copy of. And to show the impact of that, I'm gonna run the attack again. But I'm gonna run the attack again with no credentials. And the only thing I'm gonna do is I'm gonna passively steal stuff. So this is useful if you are on a land, they're pretty hard and you can't get LA anyway, you can't crack their creds, but you need to still make some progress on hacking them. So we're removing the credentials and we're just gonna listen passively. As it turns out, when Windows starts up, it downloads a lot of useful information from the DC. And if you are lucky enough to be running attack like this, or if you lost your client or you lost your victim to convince them to reboot their PC, you might just be able to capture all of these valuable pieces of information from the DC. I recorded this demo on a PC from 2012, so it's not gonna be the quickest thing. PC just started up and we've already intercepted some connections. Paul Davis is logging in and we're now stealing some data from the group policy, including the registry.poll file, which contains a lot of valuable information in terms of registry setting configured for the users on the domain. If you want to take a photo, it will be posted this evening. So now that we just kind of demonstrated that SMB keys are based on passwords and that even without the password, we can still intercept and modify a lot of connections. And we can especially download some useful information from the group policy. How do we stop this from happening? Netpile is the guy who I would argue is in charge of SMB globally. Disable SMB once. Second thing, even though we're just demonstrating that you can defeat SMB signing, that's by no means any excuse not to require it. There is, and for those who haven't run Nessa scans, there's an option to just support SMB signing and there is one to require it always. And I highly recommend you require it always unless you're running XP systems, you're going to be able to support that. So SMB version three introduced encryption. And I would love to see organizations really start pushing this thing out. Any SMB three client supports it. So if you're running anything later than Windows seven in your org, you can put encryption pretty much everywhere you want. And it is actually more efficient than signing the messages. So if you, you can support encryption or you can require it. So if you support it, then SMB three negotiations protected. If they negotiate that you can support encryption, they're going to encrypt the session. So UNC hardening is one of the features used by default by Windows 10 and 2016 to protect the SysFall and the Netlogon shares for any connection going out to something that looks like that. But you can manually require that on other shares or any other kind of path. So if you know in your organization that there's a very specific file share that your user connecting to that you want to make sure it's pretty locked down, you can lock down from the server side by requiring signatures or requiring encryption. But you can also lock it down on the client side, prevent them from connecting to rogue servers by throwing in this UNC hardening saying, hey, if you're connecting to this server or a server that looks like this, do XYZ. And I hate to say this because as a pen tester, I love NCLM, but NCLM really is outdated. It was made near the 90s. I was made near the 90s. So if you can run through audits in your organization, see where NCLM is used. And if you can't disable it just carte blanche, out of those properties of carte blanche, if you can't disable it across the org, then find out where it's used and then restrict it just to those systems. For me, that screws me over, but I guess we're all here for security. Kerberos fast armoring is an interesting thing. We showed that if we know the user's password, we can intercept their Kerberos authentication phase and steal their Kerberos session key from the initial logon and then use that to steal their Kerberos ticket session keys from every subsequent request. That can be protected, but it requires Kerberos fast armoring, which in a nutshell, any request going to the Kerberos server is first locked up with the, man, I'm hoping my details right, with the machine accounts Kerberos tickets, which means unless you can pop the machine account password with that obscenely large password, you're not gonna be able to modify or intercept that Kerberos session key even if you know the password. So huge precautions when enabling fast. It requires Windows 8 and 2012 to layer throughout the environment. Just like SMB signing, it can be supported or it can be required. If you just support it, we're gonna take advantage of the benevolence of the server and just downgrade clients. But if you require it, then you better make sure that all your clients can connect to it, otherwise you're gonna break them. They're not gonna be able to talk to the DC. So Microsoft has great documentation on how to push out a fast armoring and I'd highly recommend you going through the procedure of pushing this out through your organization. You know, always use passwords and not passwords. A lot of the SMB signing crap that we just covered in terms of breaking the keys were lies that we compromised their password. So push out strong passwords. Push out strong passwords and require SMB signing and you're a lot better than you were at the beginning of this talk. Even if you don't do all the other complicated and involved things like fast armoring. So that pretty much leaves us to like a Q and A, but right now I wanna acknowledge that a few people have contributed on this talk. Ned Pyle is Principal Program Manager at Microsoft and it was awesome. I did my own research on MSFDN and I said, hey, to the best of my knowledge, here's how SMB works and here are the various circumstances that it behaves. Is this cool? And he was awesome in terms of providing feedback and giving me direction on yes and no things so I didn't give you guys misinformation. So he was awesome. Matthew George also worked side by side with Ned on this one to kind of spot check me on this. And Core Security for the Impact Library for which all of SMBitray is based on and I use their library when I was trying to figure out more on how SMB signing works. So that's about it.