NTLM is the legacy authentication protocol in Windows environment. In the past few years, I’ve had the opportunity to write on this blog about NTLM Relaying to DCOM (twice), to AD CS (ESC11) and to MSSQL. Today I will look back on relaying to HTTPS and how the tooling improved.
I won’t delve into the details of NTLM and relaying here. For those interested, I can recommend the fairly recent and very detailed blog post of Elad Shamir. What you need to know:
HTTP is a good candidate to relay to for two reasons:
If a certification authority exposes an enrollment endpoint over HTTP, it is trivial (e.g. using certipy) to relay any intercepted NTLM handshake and request a certificate in the name of the relayed user or computer (if it is allowed to enroll with a template having the right properties):
$ certipy-ad relay -target http://10.0.0.50
Certipy v5.0.0 - by Oliver Lyak (ly4k)
[*] Targeting https://10.0.0.50/certsrv/certfnsh.asp (ESC8)
[*] Listening on 0.0.0.0:445
[*] Requesting certificate for 'CORP\\Administrator' based on the template 'User'
[*] Certificate issued with request ID 1
[*] Retrieving certificate for request ID: 1
[*] Got certificate with UPN '[email protected]'
[*] Certificate object SID is 'S-1-5-21-...-500'
[*] Saving certificate and private key to 'administrator.pfx'
[*] Wrote certificate and private key to 'administrator.pfx'
[*] Exiting...
Once we started reporting this vulnerability to our customers, many of them disabled the HTTP endpoint altogether on IIS. Great! But the story does not end here, because IIS by default until Windows Server 2022 (included) does not enforce Extended Protection for Authentication and is hence still vulnerable to relaying attacks.
However, to the best of my knowledge, relay to AD CS over HTTPS was not implemented back then in either impacket or certipy. That’s where my colleague Emanuel came up with the elegant solution of relaying to localhost and use socat to add the SSL layer to it:
sudo socat TCP-LISTEN:80,fork,reuseaddr ssl:adcs.example.com:443,verify=0
(this trick is also mentioned in a blog post of Synacktiv)
To be able to identify this vulnerability reliably, we contributed to certipy to check for the presence of web enrollment endpoints on HTTPS and to verify if channel binding was enforced.
Since version 5 of certipy, this was rewritten to be more efficient (this commit) and relaying to HTTPS is supported out of the box (this commit) and can be as simple as:
$ certipy-ad relay -target https://10.0.0.50
There is still much more to NTLM relay. As we were about to publish this blog article, the new tool by SpecterOps RelayInformer was released. Their blog post is a good place to learn more about EPA.
Relaying to HTTP is powerful, to HTTPS as well without channel binding. There are other (Windows) services that use HTTP(S) (e.g. NDES, SCCM, …). As always the following recommendations apply: