- Hey everybody, welcome to our talk, Adventures in MitM-land, Using MitM to Attack Active Directory Authentication Schemes.
00:14 - So first, let me introduce us. I’m Yaron, manager on the engineering team at CrowdStrike.
00:25 - I’ve presented two times before at Black Hat and one time at DEFCON, did a lot of research on authentication protocols.
00:36 - Eyal, an engineer, previously presented on Black Hat.
00:42 - And Sagi, also an engineer with extensive background as a security researcher on many organizations.
00:55 - So what is this talk about? So this talk is about an extensive research that we did to see what we can achieve if we have a machine in the middle.
01:07 - So machine in the middle is a technique that has a lot of potential.
01:17 - One slide back. So there’s a lot of potential.
01:21 - So if you’re at a pen test or an attack, and you reach a point where you have no credentials and no zero-days, sometimes a man in the middle is a great technique to move labeling inside a subnet.
01:44 - And our area of focus for this research was Active Directory, and Active Directory has very old protocols, and by default, also the protocols don’t use TLS, but rely on Windows Authentication.
02:02 - So let’s begin with a short introduction to Kerberos and NTLM, which on the AD authentication protocols.
02:11 - So in NTLM, a client machine wants to authenticate to a server, so it sends an NTLM Negotiate request.
02:20 - The server creates a nonce and sends it in a Challenge request, and the client machine signs the nonce with the user’s password.
02:33 - The server does not know how to validate the user’s password, so over the NETLOGON channel, it sends the NTLM Authenticate message, and the DC either approves or rejects the user authentication by validating the user and password.
02:50 - Now, onto Kerberos. So with Kerberos, the client machine, the user first logs in, and in order to log in, the client machine sends an AS request, which for that, it gets back a TGT, a Ticket Granting Ticket.
03:11 - Now, using that Ticket Granting Ticket, the machine requests a TGS record, which is a Ticket Granting Service, and the DC gets a ticket, the Ticket Granting Service is signed with the server’s password, not the user’s password.
03:30 - And now, when the client machine connects to the server over any channel, the channel can be SMB, or LDAP, or HTTP, it will send a Kerberos message, which is called AP requests, and would send the TGS, the Ticket Granting Service, one more click, and the server is able to authenticate the tickets and the service ticket is signed with the server’s password.
04:01 - So as you can see, Kerberos offers a lot more security than NTLM.
04:10 - There’s plenty of material online for any of the attacks or issues that I’ve mentioned here.
04:17 - One most critical issue with NTLM is that NTLM allows app for NTLM relay, which is also worth a short introduction.
04:29 - So with NTLM relay, the setting is that the client wants to connect to a server.
04:36 - The server is compromised, and the attacker on the server wants to use the credentials from the client machine to attack another target, another server.
04:49 - So it relays the Negotiate message to the server and to the attack target.
04:57 - The attack target sends the challenge back with a nonce.
05:06 - This is relayed to the client machine back.
05:09 - The client machine signs the nonce with the user secret.
05:15 - The server relays that NTLM Authenticate message.
05:19 - The attack target would validate it over the NETLOGON channel, and the DC would approve it since it’s the user’s correct secret, and the attack would succeed.
05:32 - So there’s plenty of network and plenty of research on NTLM relay.
05:36 - One talk you might want to review is a talk in DEFCON I did with Marina Simakov in 2019, which really dives deep into NTLM relay internals.
05:59 - And with that, I’ll pass the stage to Eyal.
06:02 - - Thanks, Yaron, as Yaron mentioned, NTLM relay only works if the server does not enforce a sign-in with encryption on the target.
06:14 - Sylvain found that one could authenticate through a certain RPC interface, the Task Scheduler, and it does not enforce signing on to the traffic.
06:25 - It’s even written in the steps. So using the classical technique of NTLM relay, one could relay the authentication to the server, and afterwards, send an unsigned packet that would cause it to run an arbitrary task.
06:41 - This would result effectively in a remote code execution vulnerability.
06:48 - What allowed this attack is the way that RPC handles security.
06:52 - The level of security in RPC session is determined by the authentication level of it.
06:59 - Some RPC service requires packet privacy. That means it require that the session would be encrypted while other only require packet integrity, that is signing.
07:14 - The authentication requirement is determined on an interface-by-interface basis.
07:20 - In fact, the registration API requires the call-out to set up a special function to check for security requirements for an arbitrary authentication level.
07:36 - It does not rely, as one would expect, on the SMB signing settings or on other security for it.
07:49 - You see, when an interface allows for a packet for authentication level of connect, it would be vulnerable to NTLM relay anywhere, on any computer, even on RPC.
08:04 - The question is does this interface has a potential security impact? And indeed, while most of the interfaces implemented by Microsoft in Windows are protected, there might be some instances where the developer neglected this thing.
08:27 - So now, we switch to a very different vulnerability, and we’ll see how it is related.
08:34 - And one of the recent vulnerability involving Print Spooler, one should say one of the many, many recent vulnerabilities of Print Spooler, was discovered by Peleg Hadar and Tomer Bar.
08:54 - And in this vulnerability, you exploit a lack of access check in order to achieve writing arbitrary files in the system.
09:12 - So how does it work? To print something, one needs to specify which printer, printer driver, and by which port it communicates with the printer.
09:25 - The current implementation allows for any user to install a printer driver, and then also of course, to print.
09:37 - So the simplest driver, the list is called a Generic/Text driver, which simply passes the input it gets into the port while the port could be something like COM1 or COM2, what the printer is connected to.
09:56 - It can also be a file. And this means that the user can call this simple printer to print to a file it wants.
10:13 - But what makes all of these a vulnerability is that the access checks were done from a certain execution path, but it was on the client side.
10:27 - So all of this allows effectively a local privilege escalation in which an unprivileged user can write a file.
10:40 - And now, a file to important location doesn’t have privileges to do so.
10:48 - So instead of relying on the document, okay, now, let’s switch to our contribution and instead of relying on the documentation of the RPC interfaces like Printer B, we developed a small scanning tool to allow us to find additional vulnerable interfaces.
11:11 - One of the result was the Print Spooler interface, and we know from previous slides that a Print Spooler interface could allow one to write arbitrary files.
11:26 - Even after it is fixed, one could write files if it has sufficient privilege.
11:36 - So we can combine both vulnerabilities or both our insight into a working example.
11:46 - So now, this is the setting of the previous vulnerability 1048, our local privilege unprivileged user but without formal setting of remote privileged user that contact a certain server, and we relay this request, whatever the request is, to another server using NTLM relay.
12:15 - And there, what we execute on the target server is similar to what happened in the original vulnerability.
12:30 - So let’s see how it’s done. First, we have an authentication request by the client machine that is passed to a rogue server.
12:43 - And now, we create a channel with the target server with the attacker, and we bind to the Print Spooler interface.
12:56 - We relay the authentication and get a challenge that will relay to a client deck, and the client send us the response to the challenge.
13:05 - We’ll relay it back to the DC. So now, it’s verified.
13:09 - Now, it has an authenticated session that is valid, and we can send commands without encryption to this session.
13:22 - Now, we just installed a printer driver. Then we do all the things that you need.
13:31 - We add a port, we install a printer, and we start to write to a file, and that is it.
13:38 - Now, we can see the demo. Okay, so what happens here is that we first used Metasploit.
13:51 - We used here, endpoint mapping query, and we list all the different RPC interface that we see on the remote computer.
14:04 - This remote computer is a DC. And we see here, we have many interfaces.
14:11 - Some of them are local RPC, and the others are remote.
14:20 - And now, we just reformat the output, so it will match a script that we’re about to write.
14:29 - And what this script will do is it will try different interfaces, the same that we found earlier, and it will connect send a garbage packet, and using this packet, we can know, okay, we can know if it’s vulnerable.
14:57 - Now you see, we found the Print Spooler interface there, and it is the error code is unsupported.
15:07 - And we have another interface with error of bad stub data.
15:11 - The error of bad stub data means that the server handled this garbage, and it’s on the standards garbage, and so, it rejects it.
15:25 - They’re unsupported error. On the other end, it’s simply inconclusive, and it actually requires an additional, that we send an additional object ID for it to work.
15:38 - So once we did that, we found that the Print Spooler is indeed vulnerable, and now, I can show you the second demo, which is how to do NTLM relay to the Print Spooler and write a file.
15:57 - And we do it against the DC. And we see here that we first open our man-in-the-middle server, and the client access SharePoint.
16:12 - It types its username and password, and we will shortly see that in the target computer, a file is being written.
16:24 - So we write a file to the SYSVOL volume, which would be present on any computer on the network.
16:33 - So this would allow one to take over the domain.
16:38 - And then now, following me is Sagi, and he will discuss his vulnerabilities.
16:51 - - So actually, Yaron is speaking now. (laughs) So now, I want to highlight another vulnerability, and it was not discovered by us.
17:08 - It was discovered on 2015 by Luke Jennings, and Luke Jennings essentially reset the GPO retrieval process, and wondered what would happen if a MitM would attack that scenario, and he actually found many attacks that can be done.
17:37 - One attack is actually still exploitable, which is that if you have a low-privileged user and a MitM, you could manipulate the GPO using the credentials and inject a malicious GPO.
17:57 - The other one is an attack that requires only MitM and uses NTLM.
18:04 - And in that attack, which Microsoft actually fixed, is an attack that we want to focus on, since we’ve improved this attack and found new avenues to attack it.
18:18 - So if we have a client machine, and the client machine wishes to download GPOs, it would perform an LDAP bind.
18:30 - And then if the GPO retrieval is authenticated with NTLM, an NTLM Negotiate message would appear.
18:39 - And since we’re into accepting this request, instead of the DC, we will send an NTLM Challenge request, and would name the target name as the rogue server.
18:53 - The client machine does not authenticate or validate the NTLM Challenge.
18:59 - And even though the machine initially connected the DC, it doesn’t reject the requests or the NTLM challenge, names another machine as the target, and just send an NTLM Authenticate message with the rogue server name.
19:19 - Now, our machine can, in its own NETLOGON challenge, send the NTLM Authenticate, and the DC would respect this request, since the target of the request is reported to be our rogue server, and the DC would send us back a reply, and the reply would have the session key.
19:44 - So now, we have a session key, and we can send an accept-complete signaling the client it can send requests over the LDAP channel.
19:54 - And even though the request might be signed or sealed, even if the requests are signed or sealed, they’re signed and sealed with the session key that we know, and we can send back any malicious response that we like.
20:11 - In the regional vulnerability, the response was a redirect stating that the GPOs are at some malicious UNC that’s on our control.
20:24 - Now, this exact attack can happen on LDAP as we displayed, but you can let the LDAP be related to the DC without any manipulation.
20:36 - And then when the client machine downloads using SMB, the GPO files themselves, we can do the same technique over SMB.
20:47 - So how has Microsoft fixed that issue? So now, the default is that group policy objects cannot be downloaded using NTLM, and there’s a new registry key for that.
20:59 - And for the SMB case, Microsoft even went deeper.
21:06 - They’ve added a new configuration called Hardened UNC Paths, and that configuration basically forces Kerberos authentication and not NTLM for any UNC over SMB that is on a file on some regexes.
21:26 - The default for this configuration is that there’s a SYSVOL regex and a NETLOGON regex, and this actually stops any chance of intervening with the group policy download process.
21:45 - And with that, I’ll pass the stage back to Eyal, who’s going to present our new attacks.
21:58 - - Okay, thank you, Yaron. So now, we will discuss a bit Azure AD Connect.
22:04 - And the Azure AD Connect is of course the vision of Microsoft of seamless sign-on.
22:12 - So in this perspective, the user that is connected to the web can use its internal company credentials to access some external resources like Office 365 or some internal application without needing a VPN.
22:39 - So how does it work? It works by synchronizing the important Active Directory data to the cloud with the help of a special server that is called the AD Connect Server.
22:56 - The server connects to a domain controller that replicates the password and other data, and then it export its hash to the Azure Active Directory.
23:15 - However, one needs to make sure that it is actually talking to the right domain controller.
23:22 - For instance, it could do it by taking the protocol that supports mutual authentication and certainly, not working in NTLM.
23:31 - So what happens there is that the traffic that’s meant to the original DC might end up in a work server and the things would work just fine as Yaron demonstrated.
23:47 - So what we need to assume for this attack to work is a full man in the middle including DNS, Kerberos, DCE/RPC, and then we first make Kerberos fail, and allowing LDAP to pass through the DC will relay to the actual DC, and we went for a domain replication.
24:16 - When it appears we inject a new change that involves a new password for an account of our choice, and afterwards, it syncs with the Azure AD, and we can log in into Azure AD with the injected password.
24:37 - So let’s see the demo. Okay, so what happens here is we have first, we want to change the password into NTLM injection.
24:51 - Now, we see that the password of this user, ektest, is now, not NTLM injection, but other password.
25:01 - And we have two windows here. One, the first one contains a modified version of Mimikatz.
25:11 - And in this modified version, we specified the target user and the password that we want, and the other window is doing simply follow the LDAP traffic to the DC.
25:24 - And now, I adjusted the speed of the demo, so we can see what happened.
25:34 - The interesting part and it took around a minute or two minutes until we get it.
25:42 - And then now, we got to it, and that we see that it pulled our fake change.
25:52 - And we can now log in and with our new password of full retrieval, let’s see.
26:19 - Okay, so it doesn’t work. We try again.
26:25 - Still doesn’t work. Yeah, it sometimes takes time for the synchronization to occur.
26:35 - And we see that it got the sign-on request okay, and we have access to Office.
26:46 - So now, we can look at the traffic itself, and we can see the bind packet, which is directed to our work cell that’s for Workstation 01.
27:02 - And indeed, that is the response that it returns.
27:07 - And we can also see the LDAP bind packet that are all a return from the DC itself.
27:18 - And you can see it here. So that really concludes the demo.
27:28 - Thanks a lot and now, Sagi will continue. - Now, let’s talk a bit about Kerberos relay.
27:36 - Now, it’s basically the same scenario as the NTLM, just with Kerberos.
27:41 - So a client wants to connect to some service in the target server, and to start off that, it sends an AP request.
27:51 - The attacker intercepts that AP request isn’t server it needed to connect and uses it to establish a session of its own against the target server with the client’s credential.
28:06 - Since the AP request is valid and was actually intended for that target server, it will work.
28:16 - This way, of course, this will work only if the signing and encryption stacks are not turned off inside the AP request or the protocol the attacker chooses supports turning those off as part of the protocol negotiation.
28:34 - Also this works, I guess, on services since most of them do not validate the service principal name, and only SPN can use.
28:48 - Let’s see a specific example using SMB relay.
28:53 - An attacker will intercept some AP request that was made to the target server and then establish a new SMB session of its own against that same target server while negotiating signing and did some auth.
29:09 - Then it uses the same AP request it intercepted to authenticate in that SMB session and basically, get an SMB session with the client’s credentials.
29:21 - And of course, this will, as I said, work only if the target server does not enforce signing and encryption.
29:30 - And as you can understand, the solution for this problem, for the Kerberos server problem, is that it involved, as I said, signing or encryption, which is done in the protocol level and uses a failed circuit that is negotiated inside the AP request and response process.
29:53 - Okay, so encryption in the protocol level solves the unit problem but what happens when we use TLS channels? Since the encryption is done in the construct layer, there is no connection to the underlying authentication in the protocols, and we get a new relay problem.
30:14 - So this is where API comes into play. Using API, we cut the authentication process to the TLS channel using the certificate thumbprint that was presented during the TLS channel negotiation.
30:34 - The thumbprint is inserted inside the checksum field of the AP request authenticator, and servers that support API.
30:44 - API used that field to validate that the certificate path that was presented during the TLS negotiation is in fact turned on, and if not, they reject this connection.
30:59 - API is used in very important services like LDAP, AD FS, and the IIS, and it usually requires to full enforcement.
31:11 - It requires some settings to be turned on, and usually, they are not on by default.
31:19 - And so, can we bypass the API? Of course, for example, an NTLM bypass, again, check out Yaron’s and Marina’s talk from DEFCON ‘19.
31:32 - And as for Kerberos, let’s see what happens when we don’t include the checksum field inside the AP request.
31:41 - So here’s an example of an LDAPS pickup. Of course, it’s negated, so that’s why you see the traffic.
31:52 - And here, we took a regular AP request that was generated by a Windows client, and we tried to relay it, and inside there, the best session, and to authenticate with it to the DC.
32:05 - The DC is set to fully enforce API. And as you can see, the Windows client included a zeroed out hash in the checksum field, and the DC verified the task.
32:18 - Obviously, it saw it’s wrong hash, so the DC rejected the connection.
32:24 - Now, in this pick-up list, which is also an LDAP-executed network traffic, we give it an AP request that was generated by Iron Docket, which by default, does not include the checksum field, and we relayed it to the same DC that is set to enforce API.
32:47 - And as you can see, since the checksum field is not there, the DC approves the connection, and accepts our LDAP search.
32:58 - And obviously, for that attack scenario to work, we need to find one vulnerable client in the network that does not include the checksum field inside the authenticator.
33:11 - Well, let’s talk about KDC spoofing. It’s a very old technique that’s usually used to bypass authentication server.
33:21 - So the basic scenario goes and it’s a user authenticates to server using plain text credentials.
33:28 - Of course, usually through some encrypted channel like SSH or HUPS, the server takes that credentials and using it to create some AP request.
33:42 - An attacker intercepts that AP request and returns a fake TGT attack ticket, and now, the server has no ability to validate the TGT.
33:57 - And since it got one, it just approved the connection of the user, and the user is logged on.
34:06 - Now, let’s see how this problem was solved.
34:09 - We begin with the same basic scenario. A user authenticates to the server with plain text credentials, an AP request is generated.
34:20 - This returns a valid TGT. And as I said, the server has no ability to validate that ticket.
34:29 - And this time, the server uses the TGT to ask for a service ticket to itself.
34:38 - The DC approves that request and returns a TGS that is intended to the server.
34:46 - And with that, the server decrypts the TGS, validates it, and use its own secret.
34:53 - Secret was actually used to decrypt to sign the ticket, and thus, it can validate the DC is a genuine DC.
35:04 - Well, let’s see how it looks in the traffic.
35:08 - Here in this scenario, a user logged on to one station.
35:12 - An AS request was generated, the DC returned a TGT, and then that workstation used that TGT to ask for a service ticket to itself, in this case, with the host SPN.
35:27 - Usually in this scenario, the host SPN will be used.
35:33 - So we can’t manipulate TGS and TGT, so what can we do? Let’s look at the DC selection process.
35:45 - In this process, the machine does some unsecured queries using mostly LDAP and DNS.
35:56 - Also, some C-LDAP. Until it gets enough information and can decide what this is, it just forwards it.
36:08 - As I said, until this stage, all queries are now unsecured and can be tempered with.
36:16 - Now, at this point, a standard Windows client will create a NETLOGON channel against the chosen DC and sends some messages over.
36:26 - This step is the most important one since the creation of a NETLOGON channel actually validates the DC since for establishing the channel, the target server must know the client actual secret.
36:42 - So this channel was established correctly, and at least one message passed.
36:48 - That means that the target server is a genuine DC.
36:53 - So what does it mean? It means that as long as the target server or service does not validate the DC using NETLOGON or other means, we easily can interject in the process and inject the whole DC logon, and then serves data to the target, data like LDAP, SMB, or DCE/RPC traffic.
37:18 - Let’s see the attack scenario. A client machine boots up once you select the DC.
37:26 - As I said, we can intervene in the process since it’s done totally unsecured, and we inject our own rogue DC.
37:36 - Now, as long as the target server or service does not validate the DC, when a user logs in, the same process we discussed earlier begins.
37:50 - The machine creates an AS request. We take this AS request, relay it to the DC, and relay back the response.
37:59 - Now, the verification of the DC by the host request to the machine begins.
38:09 - Again, we relay this message to the DC and the response back to the client.
38:15 - And since an actual DC serves those requests, the machine gets a valid ticket, and approves the user for login.
38:26 - Now, at this stage, usually machines or servers will actually want to know more details about the user, such as display name, organization unit, profile, tasks, and other data.
38:39 - So usually, an LDAP session will be initiated.
38:45 - This session is of course, established against the DC, which in this case is our own DC.
38:51 - So a service ticket to the rouge DC will be asked.
38:56 - We will relay this request to the DC, and return back a genuine TGS for the rogue DC.
39:03 - At this point, since TGS is used, the target for it is our rogue DC, we can still add a protocol such as LDAP, SMB or DCE/RPC, signed or encrypted.
39:18 - So that’s how in this scenario, the machine will initiate an LDAP search.
39:25 - We will pool it, and get back, and return the responses with malicious data, such as lone group memberships, or malicious profile paths, and the other example.
39:46 - So let’s do it for that attack scenario. We need a service that uses Kerberos that ingests data from the DC that does not have a fixed DC configuration.
40:00 - And of course, MitM between that server and this DC, and we need that service to not validate the DC using NETLOGON or other ways.
40:15 - So the attack itself, we’re using MitM. We redirect the traffic to our own DC, and every time the client wants to query the DC, it queries us, and we can inject any data we want.
40:32 - For this to work, we need to for our rogue DC to have registered SPNs like LDAP or some other stuff we might need.
40:43 - Okay, so how can we protect against this attack? We should all use servers and services that use part of NETLOGON to validate the DC or use LDAPS with certificate validation.
41:01 - It is also possible to turn on Kerberos Armoring though we haven’t tested it fully, so we cannot vouch for that.
41:09 - And as a side note, Windows GPO is still safe since the Windows GPO client only enclosed GPO after there is a valid NETLOGON session against the target DC.
41:26 - If there is not one, the GPO client will not call any GPO.
41:31 - Now, we wanted to show you demos of this attack, but unfortunately, the vendors we worked with weren’t able to fully fix the problem yet.
41:43 - And so, stay tuned for updates. And as a side note, this particular problem is pretty common in the Linux client and basically, any non-Windows native clients.
42:01 - So let’s get back to Yaron. - Okay, so we have shown you basically four issues; an NTLM relay, an NTLM injection, and a Kerberos relay, and a Kerberos injection.
42:21 - For the NTLM relay, Microsoft has fixed the issue that we’ve reported.
42:29 - We’ve also noted that there might be other open interfaces, and Microsoft actually asked for any interface we found it to be exploitable to report separately, and we’ve not had the proper time to investigate each interface.
42:47 - For the Azure AD, Microsoft actually says that MitM is basically not a security boundary.
42:56 - I can actually understand their point since Azure AD sits in the data center, and the DC should also sit in the data center, so that connection should probably be more secure.
43:09 - But if this connection is not secure in your network, you should probably have it secured.
43:15 - For the channel bindings issue, the Kerberos over TLS, so Microsoft has chosen not to fix this issue.
43:26 - And for the Kerberos injection, as Sagi mentioned, that issue is probably very widespread, and we’ve notified a few vendors, and you can expect updates soon.
43:41 - So closing remarks, so when we started this research, we weren’t sure if how seriously would our MitM vulnerabilities be taken, and we can see that in some cases, MitM is not considered a security vulnerability or a security boundary, I’m sorry.
44:06 - And technically, what we’ve shown you is that Kerberos is not validating this identity properly if not using NETLOGON, which is not always the case, and GSS-API encryption simply does not guarantee privacy in NTLM that’s by design and in Kerberos if no NETLOGON is performed.
44:31 - And basically, just protecting protocols from MitM is hard.
44:36 - You need to carefully validate that any parties are completely authenticated.
44:45 - And when you’re using external libraries and protocols, that’s not always easy to ascertain.
44:54 - So a couple of tips for defenders. So obviously, you should have in your networks enable server-signing and client-signing.
45:06 - When server-signing and client-signing are not enabled or not enforced, then a lot easier attacks, a lot simpler attacks are able to be achieved.
45:18 - You should regularly patch your software, and you should treat critical servers like Azure AD Connect the same way you would a DC.
45:28 - The connection should probably be secured. Maybe, it should be over secure sockets.
45:36 - For the Kerberos injection, basically, what Sagi showed is that in order to launch the attack, then you need to register the LDAP SPN on a machine that is not a DC.
45:50 - So this is something you can hunt for, to look for successful attacks or attack attempts.
45:58 - And jokes aside, avoid the Microsoft recommendation that you should not be MitM’d.
46:05 - So MitM is a technique that often can be mitigated by properly configuring your network equipment.
46:13 - You need to turn on mitigations for ARP spoofing, for DHCP spoofing, for SLAAC.
46:20 - These are mitigations that are known to work well.
46:24 - So there’s plenty of resources out there on how to protect yourself from MitMs.
46:30 - You need to patch your network equipment, and that’s it.
46:37 - Thanks for listening to our talk. We hope you enjoyed it. .