Microsoft Defender for Identity OWIN HTTP Listener

Microsoft Defender for Identity OWIN HTTP Listener

My previous blog post mentioned that the Microsoft Defender for Identity sensor uses an OWIN HTTP listener. In this blog post, I will describe what the HTTP listener is for and how to interact with it.

Introduction

During my previous research, I saw something listening on port 444. I wanted to discover what it was and what I could do with it. After some enumeration, it looked like an OWIN HTTP listener, but what is it for, and can I interact with the service?

First, we need to understand what OWIN is. OWIN stands for Open Web Interface for .NET and allows web applications to decouple from web servers. OWIN is a standard and not a framework like ASP.NET. Since ASP.NET strongly depends on Internet Information Services (IIS) and its capabilities, ASP.NET only runs on IIS. For ASP.NET to run, you need the .NET framework, which runs on Windows, and .ASP.NET applications are dependent on the .NET framework and tightly integrated with IIS.

To remove these dependencies, make it more modular, and build a loosely coupled system, the OWIN standard came alive.

Identifying OWIN HTTP Listener

When checking the active TCP connection and ports on which the server is listening, I found that port 444 is in use.

Image 1: Netstat -A

Note: The HTTP listener only listens to localhost.

Then I looked at which libraries the Microsoft Defender for Identity sensor uses. It was easy to determine that the sensor uses OWIN for the HTTP listener, especially when one of the libraries is called Microsoft.Owin.Host.HttpListener.dll.

Image 2: Libraries used by the sensor

The first thing I did was send a simple GET request to see if I could get a response. I got a certificate error at first, but by skipping the certificate check, I got the error 404.

Image 3: Get request to the OWIN HTTP listener

Results

When reading more about OWIN, I found out that it could be that I was not using the correct endpoint, so I had to figure out the endpoint to talk to. To figure out the endpoint, I dumped the sensor’s processes and checked the strings in the dump to see if I could find anything interesting. I quickly stumbled upon the following URL.

Image 4: Endoint from process dump

Now that I know the endpoint, I wanted to see if I could interact with it.

Image 5: Unauthorized

The message is “Unauthorized,” which is interesting. If you look at the authentication OWIN supports, you see certificate-based authentication, and the sensor uses a self-signed certificate. So, I tried sending a GET request using the “Azure ATP Sensor” certificate, and I got the following message.

Image 6: The requested resource does not support http method ‘GET’

The requested source does not support the HTTP GET method. Fair enough. Let us try a POST request with an empty body, then.

Image 7: Internal Server Error

I got an Internal Server Error, but that looks very promising. I seem authenticated, but the body I am sending needs to be corrected. Looking at the strings of the processes, I found the endpoint and some interesting JSON objects I could try.

Image 8: Dump strings from processes

I could not get it to work in PowerShell. Still, in my previous blog post, I needed to send the JSON object using compression to the API endpoint. So, I used my own Microsoft Defender for Identity API Fiddler to send the JSON object to localhost, and I got some results.

Image 9: Result Performance Counter Metrics

I found this interesting as it gives the handle to the Group Managed Service Account token to impersonate the Group Managed Service Account, but more on that in a future blog post!

Image 10: Result Integer Pointer to Group Managed Service Account Handle

JSON Object Examples

Here are some JSON objects you can send to the OWIN HTTP listener.

{
  "$type": "SnapshotPerformanceCounterMetricSamplesRequest"
}
{
  "$type": "RestrictMemoryRequest"
}
{
  "$type": "RestrictCpuRequest"
}
{
  "$type": "LdapSigningPolicyValueRequest"
}
{
  "$type": "SensorUpdaterRequest"
}
{
  "$type": "LdapAdfsContainerRequest",
  "objectGuid": ""
}
{
  "$type": "GetGroupManagedServiceAccountAccessTokenHandleRequest",
  "accountName": "",
  "domainDnsName": ""
}

Conclusion

I do not know why Microsoft wants to use an OWIN HTTP listener for the data it is providing, but they probably have a good reason. Looking at the data provided by the HTTP listener, I guess the sensor uses this information to see if it needs to limit the CPU and MEM, but I am not sure.

Microsoft Defender for Identity Sensor Identification

Microsoft Defender for Identity Sensor Identification

Someone asked if I knew how to identify if a domain controller holds a Microsoft Defender for Identity sensor, remotely. It was an interesting question, so I took up the challenge. In this blog post, I will explain how I identified the presence of a Microsoft Defender for Identity sensor on a domain controller.

Introduction

Microsoft Defender for Identity is relatively passive on a server. The sensor does not broadcast much or open anything, like ports, to identify the presence of a sensor. The sensor, e.a., does create two services, a self-signed certificate, and opens two UDP ports for Syslog and RADIUS, but nothing interesting, at least, that you can use to identify a sensor remotely.

Note: The sensor uses an OWIN HTTP listener, but it only listens on localhost, so you can not access it remotely, but more on that in a future blog post.

Named Pipes

The only thing I could find during my research was named pipes that might help identify a sensor. If we look at the named pipes on a domain controller, we see multiple named pipes with exciting names.

Image 1: Named pipes

I am still determining what CPF stands for, but ATP stands for Advanced Threat Protection, and the digits are the process ID, where the last part is the Common Language Runtime version. So, by the look of it, this is how the named pipe gets its name.

\\.\pipe\CPFATP_PID_vCLRVERSION

Here you can see the process ID used in the name of the named pipe.

Image 2: Process ID MDI Sensor

You can not connect to the named pipe anonymously, so I needed to find another way to identify if the names pipe exists.

Image 3: Local Policy Named Pipes that can be accessed anonymously

You can connect to the named pipe as ‘BUILTIN\Administrators’ or ‘NT AUTHORITY\SYSTEM,’ but that means I am already on the domain controller, which probably kills the idea of identifying the sensor in the first place.

Since we can not connect to the named pipe unauthenticated, let us see what we get if we connect to it using a low-privileged user.

Image 4: Error when named pipe exists

We get the error “Access to the path is denied,” but the interesting thing is that you get a different error message if you connect to a named pipe that does not exist.

Image 5: Error when named pipe does not exist

Capturing the correct error message means that if we know the name of the named pipe, we can identify if Microsoft Defender for Identity is running. There is a catch, though: The named pipe contains the process ID, which we do not know.

Performing the identification as a low-privileges user is not an issue, but not knowing the name of the named pipe is. The only way I could come up with is brute-forcing it, as it is fast enough to determine the named pipe within minutes.

I developed the following PowerShell script to identify if a Microsoft Defender for Identity sensor is running on a server.

$IPAddress= "10.211.55.90"
$i = 1
$foundNamedPipe = 0
while ($i -le 12999) {
  try {
    $namePipe = "CPFATP_" + $i +"_v4.0.30319"
    $pipe = new-object System.IO.Pipes.NamedPipeClientStream $IPAddress, $namePipe ,"In"
    $i++
    $pipe.Connect(100)
  }
  catch {
    if ($_ -match "Access to the path is denied") {
      Write-Host "Found a named pipe using the name: $namePipe"
      $foundNamedPipe++
    }
  }
}
if ($foundNamedPipe -gt 1) {
  Write-Host "Found $foundNamedPipe named pipes and likely MDI is running on IP address: $IPAddress"
}
else {
  Write-Host "Found $foundNamedPipe named pipe(s) and likely MDI is NOT running on IP address: $IPAddress"
}

Note: Since Microsoft Defender for Identity always creates two named pipes, and I am unsure if any other service uses a named pipe with the same name, I decided to build in a check for at least two named pipes to identify Microsoft Defender for Identity.

Conclusion

You can identify if a Microsoft Defender for Identity sensor is running, but I am not too fond of the brute-forcing part. Even though the brute-force does not impact any service, it is the only method I have found.

Microsoft Defender for Identity Hidden Feature Custom Logs Location

Microsoft Defender for Identity Hidden Feature Custom Logs Location

Although Microsoft did not document this feature yet, it is possible to set a custom location for your log files for Microsoft Defender for Identity since sensor version 2.197. In this short blog post, I will describe how to set up a custom location for the Microsoft Defender for Identity log files.

Introduction

The Microsoft Defender for Identity logs provides insight into what each component of the Microsoft Defender for Identity sensor is doing at any given time. Recently you did not have the option to save the log files in a different location than the default.

Set Custom Location

Once you have installed version 2.197 of the Microsoft Defender for Identity sensor, you will see a new entry in the SensorConfiguration.json file containing a “SensorCustomLogLocation” option.

{
  "$type": "SensorMandatoryConfiguration",
  "SecretManagerConfigurationCertificateThumbprint": "",
  "SensorCustomLogLocation": null,
  "SensorProxyConfiguration": null,
  "WorkspaceApplicationSensorApiWebClientConfigurationServiceEndpoint": {
    "$type": "EndpointData",
    "Address": "thalpiussensorapi.atp.azure.com",
    "Port": 443
  }
}

Changing the SensorCustomLogLocation to any path you like and restarting the service is enough to set the custom location.

{
  "$type": "SensorMandatoryConfiguration",
  "SecretManagerConfigurationCertificateThumbprint": "",
  "SensorCustomLogLocation": "c:\\logs",
  "SensorProxyConfiguration": null,
  "WorkspaceApplicationSensorApiWebClientConfigurationServiceEndpoint": {
    "$type": "EndpointData",
    "Address": "thalpiussensorapi.atp.azure.com",
    "Port": 443
  }
}

You can also use the argument “logsPath” during the installation to set a custom location.

"Azure ATP Sensor Setup.exe" logspath="c:\logs"

You will end up with the log files in a custom location.

Image 1: Custom location for the Microsoft Defender for Identity Log Files

Conclusion

Although log files have a maximum of 50 MB and the oldest get deleted after ten consecutive files, there are circumstances when you do not want the log files in the default location. Maybe you already have something in place to send files to your SIEM solution, and you want a single folder to store all log files for your domain controller. Anyway, with version 2.197, you can ☺️

Microsoft Defender Vulnerability Management Authenticated Scan Security Risks

Microsoft Defender Vulnerability Management Authenticated Scan Security Risks

Microsoft Defender Vulnerability Management is a service that provides advanced vulnerability management capabilities. Microsoft Defender Vulnerability Management includes many features, including Asset Discovery and Inventory Windows Authenticated Scans, which can run scans on unmanaged Windows devices. Unfortunately, the authenticated scan comes with serious security risks. In this blog post, I will go through the security risks so you can identify the risks when performing an authenticated scan.

Introduction

During the private preview last year, I provided feedback to the program team for the Windows Authenticated Scans. The program team was very supportive, and I love the way they handled the feedback 🙏🏻

Microsoft did add a warning after providing feedback on how an attacker can use the scan to their advantage. However, there are still some risks that I want to warn you about when using an authenticated vulnerability scan.

Note: The scanner installation is straightforward and out-of-scope of this blog post. The scanner registers itself in the cloud, which you then use to create a new scan. When creating a new scan is where it gets interesting.

NTLM Authentication

You can select two authentication methods for the authenticated scan, Kerberos and Negotiate. When selecting Negotiate, you see a warning saying, “Negotiate option will fallback to NTLM in case Kerberos fails. Using NTLM is not recommended as it is not a secure protocol“.

Image 1: Authentication methods including the warning

It is insecure because if an attacker is in the same target range and you perform a scan, the attacker can sniff the NTLM challenge, replay the credentials, and authenticate as that user or brute-force the hash to get the plain-text password.

Image 2: NTLM Hash sniffing to replay or brute-force using Inveigh

Important: To lower the risk, do not use a wide range of IP addresses to scan to mitigate the risk of an attacker sniffing the NTLM hash.

Azure Key Vault

When selecting a Windows authenticated scan, you can get credentials to perform the scan from an Azure Key Vault.

Image 3: Using a Key Vault to store the credentials

The scanner needs access to the Azure Key Vault to get the secret, and since you can not set permissions on a single secret, the scanner gets access to all secrets in the Key Vault. So, when an attacker compromises a device that has the Device Discovery scanner installed, the attacker can get the bearer token with access to the Azure Key Vault and read all secrets in the Key Vault.

Image 4: Reading the bearer token from memory using a dump with Task Manager
Image 5: Authenticate to the Key Vault and read all secrets

To make it even worse, an attacker can dump the process and get plain-text credentials from memory.

Image 6: Reading plain-text credentials using the default Key Vault Secret Name

Important: To lower the risk of compromised secrets, use a separate Key Vault for the Windows Authenticated Scan and do not add any other secrets.

Conclusion

The Windows Authenticates Scan is an excellent way to better identify devices within your network. Unfortunately, it does come with security risks. Although there are ways to lower the risk, which I mentioned in this blog post, please be careful when performing a Windows Authenticated Scan in your network.

Microsoft Defender for Identity Lateral Movement from Forest to Forest without a Forest trust

Microsoft Defender for Identity Lateral Movement from Forest to Forest without a Forest trust

In my previous blog post, I described the inner workings of the Microsoft Defender for Identity REST API. In this blog post, I will explain how multi-forest authentication works, how you can use the REST API endpoint to hop from forest to forest without a forest trust, and the risks associated with using Directory Service Account within Microsoft Defender for Identity.

Introduction

I want to take this opportunity to thank the Microsoft Defender for Identity team for their support. I am in close contact with the Microsoft Defender for Identity team, so they know most things I do. Microsoft Defender for Identity is an excellent product, and they also have a great team. Thank you 🙏

My previous blog post described how you could decrypt all encrypted passwords in the sensor’s log file. I reported this to the Microsoft Defender for Identity team, who acknowledged it was an issue and fixed it within a week or so. From sensor version 2.194, the log file shows only masked passwords.

Image 1: Log file contains encrypted bytes in v2.193
Image 2: Log file only shows masked passwords in v2.194

Respect for the Microsoft Defender for Identity team for quickly acknowledging and fixing the issue.

Note: When you change anything regarding the Directory Service Accounts in the Microsoft 365 Defender portal, the sensor fetches the changes periodically using a REST API request and saves the configuration in the log file, including the encrypted passwords. Since version 2.194, it only shows masked passwords.

Let me describe how Microsoft Defender for Identity uses Directory Service Accounts in a multi-forest environment to understand the risks of these accounts.

Multi-Forest Authentication

Microsoft Defender for Identity supports a multi-forest environment allowing you to easily monitor activity and profile users across forests. Authentication must occur in a different forest when the sensor wants to collect data cross-forest. So, the type of authentication depends if there is a forest trust between the forest and if you use a Directory Service Account or a Group Managed Service account.

The documentation by Microsoft needs to be more explicit when using a multi-forest environment, to be honest. The documentation does state only one Directory Service Account is required to support all forests with a two-way trust and requires a Directory Service Account per forest without a forest trust. When there is a forest trust, any user in the trusted forest can perform LDAP queries, so there is no need for an additional Directory Service Account. It is different when you use a Group Managed Service Account for authentication, though. Since only the principals added to the “msDS-ManagedPassword” property of the Group Managed Service Account can get the password for the account, additional configuration is needed.

The recommendation is to create a Domain Local group in the trusted forest and add the “Domain Controllers” group from the trustee forest. Then add the Domain Local group to the “msDS-ManagedPassword” property of the Group Managed Service Account so all domain controllers can read the account’s password, including cross-forests domain controllers.

Plain Text Passwords

Since all domain controllers in all domains are allowed to retrieve the managed password in the setup described above, once an attacker gets hold of a single Microsoft Defender for Identity sensor, the attacker can read the password for the Group Managed Service Account in plain text.

The Microsoft documentation states that using a Directory Service Account with limited privileges is essential. Still, it is a way for attackers to get the plain-text password for identities in a different forest, even when using Group Managed Service Accounts.

So, no trust, no worries?

An additional Directory Service Account is needed per forest to support untrusted forests. Since the sensor needs to perform the authentication, the sensor also needs to be aware of the Directory Service Account, including the password.

Note: Since there is no trust, the account can not be a Group Managed Service Account.

How does the sensor get the Directory Service Accounts? The sensor sends a REST API request to the cloud to get all Directory Service Accounts, including their encrypted password.

Image 3: Using a REST API request, you can still get the encrypted passwords using my tool.

Mimicking a Microsoft Defender for Identity sensor using my tool makes it possible to get all encrypted passwords using a REST API request. As described in a previous blog post, it is possible to decrypt all passwords and get plain text passwords from all Directory Service Accounts, excluding Group Managed Service Accounts.

Note: I updated my Microsoft Defender for Identity API Fiddler, which now includes encrypting and decrypting the passwords.

Image 4: I added the encryption and decryption of the passwords in my tool.

So, once an attacker gets the plain text password for a different forest, the attacker can authenticate to the other forest even when there is no forest trust.

Important: When you compromise a single Microsoft Defender for Identity sensor, you can get all Directory Service Accounts passwords in plain text, including those of forests without a forest trust, and including Group Managed Service Accounts.

Password Decryption

How does the sensor decrypt the password of the Directory Service Account from another forest? That is a good question!

All Directory Service Accounts are encrypted using all sensor’s public keys. Microsoft encrypts all passwords with every public key of all sensors to be sure that every sensor can decrypt all passwords. The sensor sends a REST API request to the cloud to get all encrypted passwords matching its certificate and decrypt all passwords for all Directory Service Accounts, excluding Group Managed Service Accounts, as they do not have a password.

Conclusion

Although some authentication is by design in a Windows environment, when there is no forest trust, an attacker can still authenticate using a plain text password to the different forest using a REST API request using my tool. So, getting plain text passwords for another forest introduces a possibility for attackers to hop from forest to forest, including those without a forest trust. There is no mitigation for getting the encrypted password using my tool, as the sensor uses this authentication method.

Remember, though, never reuse passwords as attackers use the password for password sprays, potentially compromise other identities, and only use low-privilege accounts, as Microsoft’s documentation states.