- Hey everybody, welcome to our talk,
Adventures in MitM-land, Using MitM
to Attack Active Directory Authentication Schemes.
So first, let me introduce us.
I'm Yaron, manager on the engineering team at CrowdStrike.
I've presented two times before at Black Hat
and one time at DEFCON,
did a lot of research on authentication protocols.
Eyal, an engineer, previously presented on Black Hat.
And Sagi, also an engineer with extensive
background as a security researcher
on many organizations.
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.
So machine in the middle is a technique
that has a lot of potential.
One slide back.
So there's a lot of potential.
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.
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.
So let's begin with a short introduction
to Kerberos and NTLM,
which on the AD authentication protocols.
So in NTLM, a client machine
wants to authenticate to a server,
so it sends an NTLM Negotiate request.
The server creates a nonce
and sends it in a Challenge request,
and the client machine signs the nonce
with the user's password.
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.
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.
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.
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.
So as you can see, Kerberos offers
a lot more security than NTLM.
There's plenty of material online
for any of the attacks or issues
that I've mentioned here.
One most critical issue with NTLM
is that NTLM allows app for NTLM relay,
which is also worth a short introduction.
So with NTLM relay, the setting is that
the client wants to connect to a server.
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.
So it relays the Negotiate message to the server
and to the attack target.
The attack target sends
the challenge back with a nonce.
This is relayed to the client machine back.
The client machine signs the nonce
with the user secret.
The server relays that NTLM Authenticate message.
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.
So there's plenty of network
and plenty of research on NTLM relay.
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.
And with that, I'll pass the stage to Eyal.
- Thanks, Yaron, as Yaron mentioned,
NTLM relay only works if the server
does not enforce a sign-in with encryption on the target.
Sylvain found that one could authenticate
through a certain RPC interface, the Task Scheduler,
and it does not enforce signing on to the traffic.
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.
This would result effectively
in a remote code execution vulnerability.
What allowed this attack is the way
that RPC handles security.
The level of security in RPC session
is determined by the authentication level of it.
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.
The authentication requirement is determined
on an interface-by-interface basis.
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.
It does not rely, as one would expect,
on the SMB signing settings
or on other security for it.
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.
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.
So now, we switch to a very different vulnerability,
and we'll see how it is related.
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.
And in this vulnerability,
you exploit a lack of access check
in order to achieve writing
arbitrary files in the system.
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.
The current implementation allows for any user
to install a printer driver,
and then also of course, to print.
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.
It can also be a file.
And this means that the user can call
this simple printer to print to a file it wants.
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.
So all of this allows effectively
a local privilege escalation
in which an unprivileged user can write a file.
And now, a file to important location
doesn't have privileges to do so.
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.
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.
Even after it is fixed, one could write
files if it has sufficient privilege.
So we can combine both vulnerabilities
or both our insight into a working example.
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.
And there, what we execute on the target server
is similar to what happened
in the original vulnerability.
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.
And now, we create a channel
with the target server with the attacker,
and we bind to the Print Spooler interface.
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.
We'll relay it back to the DC.
So now, it's verified.
Now, it has an authenticated session that is valid,
and we can send commands without
encryption to this session.
Now, we just installed a printer driver.
Then we do all the things that you need.
We add a port, we install a printer,
and we start to write to a file,
and that is it.
Now, we can see the demo.
Okay, so what happens here is that
we first used Metasploit.
We used here, endpoint mapping query,
and we list all the different RPC interface
that we see on the remote computer.
This remote computer is a DC.
And we see here, we have many interfaces.
Some of them are local RPC,
and the others are remote.
And now, we just reformat the output,
so it will match a script
that we're about to write.
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.
Now you see, we found the Print Spooler interface there,
and it is the error code is unsupported.
And we have another interface
with error of bad stub data.
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.
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.
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.
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.
It types its username and password,
and we will shortly see that in the target computer,
a file is being written.
So we write a file to the SYSVOL volume,
which would be present on any computer on the network.
So this would allow one to take over the domain.
And then now, following me is Sagi,
and he will discuss his vulnerabilities.
- So actually, Yaron is speaking now.
(laughs)
So now, I want to highlight another vulnerability,
and it was not discovered by us.
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.
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.
The other one is an attack that
requires only MitM and uses NTLM.
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.
So if we have a client machine,
and the client machine wishes to download GPOs,
it would perform an LDAP bind.
And then if the GPO retrieval
is authenticated with NTLM,
an NTLM Negotiate message would appear.
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.
The client machine does not authenticate
or validate the NTLM Challenge.
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.
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.
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.
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.
In the regional vulnerability,
the response was a redirect stating
that the GPOs are at some malicious UNC
that's on our control.
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.
And then when the client machine downloads using SMB,
the GPO files themselves,
we can do the same technique over SMB.
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.
And for the SMB case, Microsoft even went deeper.
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.
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.
And with that, I'll pass the stage back to Eyal,
who's going to present our new attacks.
- Okay, thank you, Yaron.
So now, we will discuss a bit Azure AD Connect.
And the Azure AD Connect is of course
the vision of Microsoft of seamless sign-on.
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.
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.
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.
However, one needs to make sure
that it is actually talking
to the right domain controller.
For instance, it could do it by taking the protocol
that supports mutual authentication
and certainly, not working in NTLM.
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.
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.
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.
So let's see the demo.
Okay, so what happens here is we have first,
we want to change the password into NTLM injection.
Now, we see that the password of this user, ektest,
is now, not NTLM injection, but other password.
And we have two windows here.
One, the first one contains
a modified version of Mimikatz.
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.
And now, I adjusted the speed of the demo,
so we can see what happened.
The interesting part and it took around
a minute or two minutes until we get it.
And then now, we got to it,
and that we see that it pulled our fake change.
And we can now log in
and with our new password of full retrieval, let's see.
Okay, so it doesn't work.
We try again.
Still doesn't work.
Yeah, it sometimes takes time
for the synchronization to occur.
And we see that it got the sign-on request okay,
and we have access to Office.
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.
And indeed, that is the response that it returns.
And we can also see the LDAP bind packet
that are all a return from the DC itself.
And you can see it here.
So that really concludes the demo.
Thanks a lot and now, Sagi will continue.
- Now, let's talk a bit about Kerberos relay.
Now, it's basically the same scenario
as the NTLM, just with Kerberos.
So a client wants to connect
to some service in the target server,
and to start off that, it sends an AP request.
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.
Since the AP request is valid
and was actually intended for that
target server, it will work.
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.
Also this works, I guess, on services
since most of them do not validate
the service principal name,
and only SPN can use.
Let's see a specific example using SMB relay.
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.
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.
And of course, this will, as I said,
work only if the target server
does not enforce signing and encryption.
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.
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.
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.
The thumbprint is inserted inside the checksum field
of the AP request authenticator,
and servers that support API.
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.
API is used in very important services
like LDAP, AD FS, and the IIS,
and it usually requires to full enforcement.
It requires some settings to be turned on,
and usually, they are not on by default.
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.
And as for Kerberos, let's see what happens
when we don't include the checksum field
inside the AP request.
So here's an example of an LDAPS pickup.
Of course, it's negated,
so that's why you see the traffic.
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.
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.
Obviously, it saw it's wrong hash,
so the DC rejected the connection.
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.
And as you can see,
since the checksum field is not there,
the DC approves the connection,
and accepts our LDAP search.
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.
Well, let's talk about KDC spoofing.
It's a very old technique that's usually
used to bypass authentication server.
So the basic scenario goes
and it's a user authenticates to server
using plain text credentials.
Of course, usually through some encrypted channel
like SSH or HUPS, the server takes that credentials
and using it to create some AP request.
An attacker intercepts that AP request
and returns a fake TGT attack ticket,
and now, the server has no ability
to validate the TGT.
And since it got one,
it just approved the connection of the user,
and the user is logged on.
Now, let's see how this problem was solved.
We begin with the same basic scenario.
A user authenticates to the server
with plain text credentials,
an AP request is generated.
This returns a valid TGT.
And as I said, the server has no ability
to validate that ticket.
And this time, the server uses the TGT
to ask for a service ticket to itself.
The DC approves that request
and returns a TGS that is intended to the server.
And with that, the server decrypts the TGS, validates it,
and use its own secret.
Secret was actually used to decrypt to sign the ticket,
and thus, it can validate the DC is a genuine DC.
Well, let's see how it looks in the traffic.
Here in this scenario,
a user logged on to one station.
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.
Usually in this scenario,
the host SPN will be used.
So we can't manipulate TGS and TGT,
so what can we do?
Let's look at the DC selection process.
In this process, the machine does some
unsecured queries using mostly LDAP and DNS.
Also, some C-LDAP.
Until it gets enough information
and can decide what this is, it just forwards it.
As I said, until this stage,
all queries are now unsecured
and can be tempered with.
Now, at this point, a standard Windows client
will create a NETLOGON channel against the chosen DC
and sends some messages over.
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.
So this channel was established correctly,
and at least one message passed.
That means that the target server is a genuine DC.
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.
Let's see the attack scenario.
A client machine boots up
once you select the DC.
As I said, we can intervene in the process
since it's done totally unsecured,
and we inject our own rogue DC.
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.
The machine creates an AS request.
We take this AS request, relay it to the DC,
and relay back the response.
Now, the verification of the DC by the host
request to the machine begins.
Again, we relay this message to the DC
and the response back to the client.
And since an actual DC serves those requests,
the machine gets a valid ticket,
and approves the user for login.
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.
So usually, an LDAP session will be initiated.
This session is of course,
established against the DC,
which in this case is our own DC.
So a service ticket to the rouge DC will be asked.
We will relay this request to the DC,
and return back a genuine TGS for the rogue DC.
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.
So that's how in this scenario,
the machine will initiate an LDAP search.
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.
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.
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.
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.
For this to work, we need to for our rogue DC
to have registered SPNs like LDAP
or some other stuff we might need.
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.
It is also possible to turn on Kerberos Armoring
though we haven't tested it fully,
so we cannot vouch for that.
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.
If there is not one,
the GPO client will not call any GPO.
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.
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.
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.
For the NTLM relay, Microsoft has fixed
the issue that we've reported.
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.
For the Azure AD, Microsoft actually says
that MitM is basically not a security boundary.
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.
But if this connection is not secure in your network,
you should probably have it secured.
For the channel bindings issue,
the Kerberos over TLS,
so Microsoft has chosen not to fix this issue.
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.
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.
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.
And basically, just protecting protocols
from MitM is hard.
You need to carefully validate that any parties
are completely authenticated.
And when you're using external libraries and protocols,
that's not always easy to ascertain.
So a couple of tips for defenders.
So obviously, you should have in your networks
enable server-signing and client-signing.
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.
You should regularly patch your software,
and you should treat critical servers
like Azure AD Connect the same way you would a DC.
The connection should probably be secured.
Maybe, it should be over secure sockets.
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.
So this is something you can hunt for,
to look for successful attacks or attack attempts.
And jokes aside, avoid the Microsoft recommendation
that you should not be MitM'd.
So MitM is a technique that often
can be mitigated by properly
configuring your network equipment.
You need to turn on mitigations for ARP spoofing,
for DHCP spoofing, for SLAAC.
These are mitigations that are known to work well.
So there's plenty of resources out there
on how to protect yourself from MitMs.
You need to patch your network equipment,
and that's it.
Thanks for listening to our talk.
We hope you enjoyed it.