Hasła użytkowników, w szczególności administratorów są jak klucze do królestwa, a po ich zdobyciu zawsze jest co robić :). O metodach pozyskania takich haseł dużo pisaliśmy na Kapitanie Hack’u. Możesz te informacje znaleźć w artykułach:

Istnieją także narzędzia, takie jak Mimikatz („szwajcarski scyzoryk do haseł”), za pomocą których można takie hasła poznać, wydobywając je z pamięci systemu. Problem w tym, że najczęściej są one wykrywane przez większość specjalistycznego oprogramowania do bezpieczeństwa, w tym słynnego antywirusa.

W dzisiejszym artykule opiszemy i pokażemy kolejny, ciekawy sposób na przechwycenie haseł lokalnych użytkowników Windows, w tym administratorów. Metoda za pomocą której wydobędziemy hasła użytkowników wykorzystywać będzie implementację nieudokumentowanej przez Microsoft funkcji MsvpPasswordValidate(). Funkcję zaimplementował i wykorzystał w swojej bibliotece DLL badacz o pseudonimie last-byte. Cały kod napisany w C++ możecie znaleźć tutaj.


Czy na pewno jest to problem?

Opisywany przypadek ciężko nazwać problemem. Raczej nazwalibyśmy go „możliwością”, która udostępnia nam niskopoziomowe API Windows. W bibliotece Windows NtlmShared.dll znajduje się nieudokumentowana przez Microsoft funkcja o nazwie MsvpPasswordValidate() o następującej składni:

BOOLEAN __stdcall MsvpPasswordValidate (
BOOLEAN UasCompatibilityRequired,
NETLOGON_LOGON_INFO_CLASS LogonLevel,
PVOID LogonInformation,
PUSER_INTERNAL1_INFORMATION Passwords,
PULONG UserFlags,
PUSER_SESSION_KEY UserSessionKey,
PLM_SESSION_KEY LmSessionKey
);

To, co nas interesuje w powyższej funkcji to czwarty argument, „Passwords”, który jest typu PUSER_INTERNAL1_INFORMATION.
Jest to wskaźnik do struktury SAMPR_USER_INTERNAL1_INFORMATION, której pierwszym argumentem jest w rzeczywistości skrót hasła (NTLM Hash):

typedef struct _SAMPR_USER_INTERNAL1_INFORMATION {
ENCRYPTED_NT_OWF_PASSWORD EncryptedNtOwfPassword;
ENCRYPTED_LM_OWF_PASSWORD EncryptedLmOwfPassword;
unsigned char NtPasswordPresent;
unsigned char LmPasswordPresent;
unsigned char PasswordExpired;
} SAMPR_USER_INTERNAL1_INFORMATION,
*PSAMPR_USER_INTERNAL1_INFORMATION;

Jak słusznie zauważył użytkownik FuzzySecurity i napisał o tym na Twitterze:

Podpięcie się własną biblioteką pod proces „lsass.exe” i użycie funkcji MsvpPasswordValidate i wskaźnika do SAMPR_USER_INTERNAL1_INFORMATION zwróci nam hash hasła użytkownika logującego się do Windows!

Jest to interesujące spostrzeżenie – z wiadomych względów :)! Czas przejść do implementacji kodu w C++ (własnego narzędzia do zrzucania haseł).


Złośliwa biblioteka DLL przechwytująca hasła użytkowników

Poniżej prezentujemy listing niestandardowej biblioteki DLL (HppDLL), która przechwytuje MsvpPasswordValidate, wyodrębnia skrót hasła (NTHash) i zapisuje go na dysku. Biblioteka korzysta z Microsoft Detours do wykonywania akcji.

W nagłówku „hppdll.h” oraz pozostałych plikach projektu znajduje się reszta kodu (między innymi definicje innych funkcji InstallHook() oraz RemoveHook()).

Na koniec, jedyne co musimy wykonać to skompilować powyższy projekt (bibliotekę) w VC++ do pliku HppDLL.dll i wstrzyknąć ja do procesu lsass.exe (proces odpowiedzialny w Windows za uwierzytelniania użytkowników).


Scenariusz przechwytywania haseł na Windows


Poniżej prezentujemy scenariusz użycia biblioteki HppDLL.dll do przechwycenia haseł lokalnych użytkowników. Scenariusz wykonamy na najnowszej edycji systemu operacyjnego Windows 10 20H2 posiadającego wszystkie ostatnie wgrane aktualizacje.

UWAGA! W celu wykonania opisanych operacji potrzebna będą uprawnienia lokalnego administratora na Windows lub uprawnienie SeDebugPrivilege.

Uprawnienia te są wymagane do wstrzyknięcia naszej biblioteki do procesu lsass.exe. Ale kto w dzisiejszych czasach ich nie posiada? Żartujemy oczywiście, bo nie powinniśmy używać konta z tak wysokimi uprawnieniami w trakcie normalnej pracy na komputerze. Jeśli z jakiś względów takie uprawnienia posiadamy albo zdobędzie je cyberprzestępca (patrz kampania CYBER KILL CHAIN) to mamy gotowy sposób, na to, aby poznać hasła logujących się do naszego systemu użytkowników!


Krok 1 – „wstrzyknięcie” biblioteki do procesu lsass.exe

Sposobów na wstrzyknięcie biblioteki DLL do istniejącego procesu Windows jest wiele. Można napisać własny program/skrypt, wykorzystać metodę DLLInjection lub skorzystać z porad opisanych w naszym artykule tutaj.
Tym razem poszliśmy na łatwiznę i użyliśmy narzędzia Process Hacker. Skompilowana biblioteka waży 67 KB, więc przekopiowanie jej na system nie stanowi większego problemu.

W narzędziu Process Hacker wstrzykujemy ją używając opcji „Inject DLL.”

Jeśli wszystko się powiedzie, załadowaną do lsass.exe bibliotekę zobaczymy na liście modułów:


Krok 2 – przechwycenie hasła administratora

Zanim zaczniemy przechwytywanie haseł najpierw wykonamy mały rekonesans. Jesteśmy zalogowani do systemu Windows jako zwykły użytkownik KapitanHack.pl. Zobaczmy jakie konta są na naszym Windows w lokalnych administratorach.
W tym celu wyświetlamy zawartość grupy „Administrators” za pomocą poniższego polecenia z wiersza linii komend (cmd.exe):

– net localgroup Administrators

Widać, że w grupie administratorów są dwa konta („Administrator” oraz „kapitan”) oraz grupa domenowa Domain Admins.

Atakujemy konto lokalnego administratora o nazwie „kapitan”.
W celu przechwycenia hasła użytkownika „kapitan” przez naszą wstrzykniętą bibliotekę DLL musimy w jakiś sposób zmusić system Windows o zapytanie się nas o to konto lub poprosić administratora/użytkownika, aby się sam zalogował do systemu.
Doskonałym sposobem na to będzie użycie komendy „runas.exe” i uruchomienie wiersza linii poleceń na naszym w kontekście docelowego użytkownika (kapitan).

– runas /u:kapitan cmd.exe

Po naciśnięciu klawisza „Enter” Windows poprosił nas o hasło użytkownika kapitan. Wpisujemy cokolwiek i wciskamy Enter.

Ciekawostką jest, że wpisując nawet niepoprawne hasło użytkownika nasza biblioteka DLL (podczepiona pod proces lsass.exe) rejestruje w pliku tekstowym na dysku prawidłowy hash konta administratora!

W tym momencie został utworzony plik „credentials.txt” na dysku „C:”, którego zawartość pokazuje NTHash naszego administratora „kapitan” 🙂

Od teraz możemy użyć NTHash w innych narzędziach rób zdekodować je w narzędziu Hashcat.


Jak się chronić?

Poniżej zamieszczamy kilka porad:

  • Sprawdzać i ufać tylko podpisanym bibliotekom w systemie.
  • Użyć dodatkowych mechanizmów zabezpieczania logowania MFA (choć je też można obejść patrz tutaj).
  • Użyć specjalistycznych narzędzi do monitorowania.
  • Monitorować proces lsass.exe pod kątem wszelkich nowych, podejrzanych bibliotek DLL.

Demo

Na koniec przedstawiamy jeszcze film demonstrujący atak:

Podziel się z innymi tym artykułem!