W tym artykule opiszemy i pokażemy, jak za pomocą protokołu LDAP w Active Directory będziemy mogli w legalny sposób zakodować i zapisać złośliwy kod malware w Active Directory, a następnie pobrać go i wykonać z innego komputera w sieci. Opiszemy też próbę wprowadzenia koncepcji wewnętrznego serwera C2, która wykorzystuje standardowe właściwości obiektów domeny Active Directory w domyślnej jej konfiguracji.


Wprowadzenie

„Egzotyczne” kanały komunikacji używane przez serwery dowodzenia i kontroli (C2) od zawsze interesowały atakujących. Mechanizmy obronne w postaci wyspecjalizowanego oprogramowania stają się coraz bardziej wyrafinowane i skuteczne w wyłapywaniu złośliwej komunikacji. Standardowe kanały, które jeszcze do niedawna posiadały niski współczynnik wykrywalności malware takie jak np. protokół DNS powoli tracą swoją skuteczność. Dzieje się tak ponieważ pojawiły się na rynku rozwiązania, które mogą zaadresować problemy w nim występujące.
Jakiś czas temu na naszym portalu pisaliśmy o egzotycznej metodzie eksfiltracji/infliltracji danych, a także sposobu komunikowania się malware w środowisku informatycznym przy użyciu protokołu DNS. Podczas jednego z naszych projektów związanego z ćwiczeniami penetracyjnymi zastawialiśmy się, czy jest jakiś inny ogólnodostępny protokół w firmie, który pozwalałby na swobodną komunikację w sieci pomiędzy komputerami i zarazem komunikacja przez niego byłą trudna do wychwycenia przez rozwiązania do bezpieczeństwa. Pomysł padł na protokół LDAP, który jest dostępny w każdym środowisku informatycznym z wdrożonym Active Directory. Tak to już jest, że w środowisku AD każdy użytkownik lub komputer ma dostęp do centralnej bazy danych, która daje możliwości zapisu i odczytu wielu atrybutu obiektów. O tym jakie to są atrybuty powiemy później, lecz w pierwszej kolejności chcielibyśmy wyjaśnić scenariusz, w którym moglibyśmy wykorzystać LDAP do takiej właśnie niewykrywalnej komunikacji pomiędzy komputerami.


W czym tkwi problem?

Jednym z zadań Active Directory jest połączenie sieci komputerów (stacji roboczych i serwerów) w logiczną całość i zarządzania nimi z jednego centralnego miejsca. Oprócz spięcia sieci komputerów, AD pełni rolę katalogu usług i repozytorium użytkowników oraz grup. Dzięki niemu użytkownicy mogą się logować swoim kontem do dołączonych do niego komputerów.
W konfiguracjach rozległych sieci często jest tak, że niektóre komputery np. stacje robocze i serwery wydzielone są w osobnych specjalnych segmentach sieci i ograniczona jest do nich komunikacja. Dla przykładu stacje robocze mogą łączyć się z Internetem, a serwery już nie. Ze względów bezpieczeństwa taki sposób jest praktykowany w wielu firmach. Są też takie konfiguracje, że pomiędzy określonymi segmentami sieci np. Segment X i Segment Y komunikacja jest całkowicie blokowana.
Jeśli komputery w segmentach X i Y należą do tej domeny/lasu Active Directory, istnieje możliwość, że będziemy mogli poprzez protokół LDAP nawiązać pomiędzy nimi komunikację.
W celu zdalnego sterowania stacjami roboczymi (segment X i Y) w obu segmentach za pomocą serwera C2, moglibyśmy stworzyć narzędzie, które wykorzystywałoby udostępniony komponent Active Directory do zbudowania kanału komunikacji.


Jak wykonać komunikację poprzez LDAP pomiędzy odizolowanymi sieciami?

W celu odpowiedzenia na to pytanie w pierwszej kolejności musimy sprawdzić do jakich atrybutów(właściwości) obiektów Active Directory ma domyślnie dostęp zwykły użytkownik.

W tym celu sprawdziliśmy uprawnienia użytkownika kapitanhack.pl do własnego konta.

Jak się okazuje domyślne konto użytkownika w AD posiada uprawnienia do zapisu niektórych z tych atrybutów. Na przykład użytkownicy mogą aktualizować dane osobowe, takie jak numery telefonów lub lokalizacja biura dla własnego konta. Nie są do tego potrzebne żadne specjalne uprawnienia, ponieważ informacje te można zapisać dla tożsamości SELF, czyli samego konta. Jest to skonfigurowane w schemacie usługi Active Directory, jak pokazano na zrzucie ekranu poniżej.

Powyższe oznacza tyle, że wszyscy użytkownicy mogą pisać i czytać we własnych „Informacjach osobistych” (Personal Information) w Active Directory. Jest to tak zwane ustawienie właściwości w AD, które zostały utworzone w celu grupowania określonych wspólnych właściwości w celu zmniejszenia wymagań dotyczących miejsca w bazie danych Active Directory. Uprawnienia ustawione na powyższym zrzucie ekranu zapewniają dostęp do atrybutów zdefiniowanych w zestawie właściwości Informacje osobiste. Ten zestaw właściwości zawiera ponad 40 atrybutów, z których użytkownicy mogą czytać i zapisywać. Pełna lista atrybutów znajduje się w następującym artykule Microsoft.


Atrybut jako magazyn danych?

Domyślnie każdy użytkownik, który został pomyślnie uwierzytelniony w tym samym lesie, jest „uwierzytelnionym użytkownikiem”. Oznacza to, że możemy używać usługi Active Directory jako tymczasowego magazynu danych i wymieniać dane między dwiema izolowanymi sieciami, zapisując dane w tych atrybutach, a następnie odczytując dane z innego segmentu.
Jeśli mamy dostęp do konta użytkownika, możemy używać tego konta użytkownika w obu segmentach sieci jednocześnie do wymiany danych przez Active Directory. Działa to bez względu na ustawienia zabezpieczeń stacji roboczej, ponieważ konto będzie komunikować się bezpośrednio z kontrolerem domeny zamiast ze stacją roboczą.


Jakie atrybuty najlepiej użyć do komunikacji LDAP?

Wiemy już, że zalogowany użytkownik może zapisywać informacje w AD do konkretnych atrybutów(właściwości) swojego konta. Zobaczmy teraz, które właściwości mogą pomieścić najwięcej danych, badając schemat obiektu „użytkownik” w naszej domenie. Wykonując poniższe polecenie otrzymamy listę atrybutów:

[DirectoryServices.ActiveDirectory.ActiveDirectorySchema]:: GetCurrentSchema().FindClass(‘user’).optionalproperties | select name,rangeupper | ?{$_.RangeUpper} | Sort-Object -Descending -Property rangeupper | Select -First 10

W wyniku powyższego zapytana dostaniemy listę wszystkich właściwości ogólnego obiektu „użytkownik”, biorąc pod uwagę bieżący schemat domeny. Nie wszystkie z tych właściwości są dla użytkownika możliwe do samodzielnego zapisu. Do zapewnienia najlepszej elastyczności w kanale komunikacji najlepiej jakbyśmy wybrali taki atrybut, który pomieści jak największa ilość danych oraz znajduje się również w zestawie właściwości „Informacje osobiste”. Najlepszym atrybutem do tego celu będzie pole mSMQSignCertificates, ponieważ posiada górny limit 1 MB i spełnia wszystkie nasze kwalifikacje. A ponieważ każdy użytkownik może edytować właściwość mSMQSignCertificates dla własnego obiektu użytkownika, stwarza nam to doskonały dwukierunkowy kanał danych, w którym mamy do dyspozycji aż 1 MB przestrzeni :)! Oczywiście mamy tez wybór innych atrybutów, które możemy wykorzystać chociażby do zapisu sumy kontrolnej itp.


Scenariusz – zakodowanie złośliwego skryptu PowerShell w atrybucie AD i odczyt z wywołaniem go z drugiego komputera?

W celu przeprowadzenia naszego scenariusza użyjemy dwóch odseparowanych w sieci komputerów Windows 10 będących członkami jednej domeny Active Directory o nazwie „Kapitan.Hack”.

Na pierwszym z komputerów po zalogowaniu się na zwykłego użytkownika kapitanhack.pl użyjemy specjalnej komendy w PowerShell, która zakoduje i zapisze w atrybucie użytkownika mSMQSignCertificates złośliwy skrypt w PowerShell – w naszym przypadku będzie to uruchamianie procesu kalkulatora.

Na drugim komputerze na tym samym zalogowanym użytkowniku wykonamy drugie polecenie PowerShell, które odczyta i wykona lokalnie zakodowany złośliwy skrypt z atrybutu mSMQSignCertificates.


Krok 1 – Zakodowanie złośliwego skryptu

W tym kroku użyjemy specjalnego narzędzia napisanego w PowerShell umożliwiającego zakodowanie dowolnego skryptu. Metoda New-ADPayload umożliwi nam wykonanie tego kroku.

Skrypt jaki będziemy chcieli zakodować w atrybucie użytkownika to proste uruchomienie procesu kalkulatora.

Start-Process calc.exe

Zapisanie wraz z zakodowaniem skryptu do atrybutu mSMQSignCertificates użytkownika kapitanhack.pl:

Wynik – zakodowany skrypt w atrybucie użytkownika


Krok 2 – Pobranie i uruchomienie złośliwego skryptu z AD

W tym kroku użyjemy także tego samego narzędzia do pobrania i zdekodowania wartości skryptu przechowywanej w naszym atrybucie użytkownika kapitanhack.pl. Użyjemy metody Get-ADPayload i przekażemy jej wynik do zmiennej Payload, a następnie wywołamy ją z poziomu linii komend.


Podsumowanie

Pomyślnie udało nam się w sposób niezauważony dla oprogramowania do bezpieczeństwa zakodować skrypt, wpisać jego zawartość do atrybutu użytkownika i uruchomić go z drugiego komputera. Możliwość ta stwarza nowy wektor dla organizacji/firm, które w nieodpowiedni sposób lub w ogóle nie monitorują tego typu aktywności. Oczywiście w celu zbudowania funkcjonalności pod potrzeby serwera C2 moglibyśmy rozszerzyć skrypt o funkcje kontroli – zapisu sumy kontrolnej CRC oraz wprowadzić bufor czasu, gdyż w rozbudowanych środowiskach AD znaczący wpływ na propagację wartości atrybutów może mieć replikacja miedzy kontrolerami domeny AD. Przypominamy, że katalog globalny usługi Active Directory to „kontroler domeny, który przechowuje pełną kopię wszystkich obiektów w katalogu dla swojej domeny hosta oraz częściową kopię wszystkich obiektów tylko do odczytu dla wszystkich innych domen w lesie”. Nie wszystkie atrybuty obiektu są replikowane, ale tylko te w „częściowym zestawie atrybutów” zdefiniowanym w schemacie domeny. Możemy sprawdzić takie obiekty i atrybuty wszystkie obiekty schematu za pomocą filtru LDAP „(isMemberOfPartialAttributeSet -like TRUE)

Get-ADObject -Filter ‘Name -eq “MSMQ-Sign-Certificates”‘ -SearchBase “CN=Schema,CN=Configuration,DC=kapitan,DC=hack” -Properties * | Where isMemberofPartialAttributeSet -like ‘true’

Na szczęście używany przez nas atrybut mSMQSignCertificates znajduje się w częściowym zestawie atrybutów schematu domyślnego! Jest to również udokumentowane przez Microsoft tutaj.


Jak sobie radzić z problemem?

W artykule o PowerShell pisaliśmy o tym jak zabezpieczyć się przed możliwością uruchomienia złośliwych skryptów PowerShell w celu uniknięcia uruchomienia złośliwego oprogramowania. Trzeba pamiętać, że do zapisu w atrybutach konta możemy użyć innego języka skryptowego np. skryptu napisanego w Visual Basic Script.
W celu umożliwienia wykrycia takiej komunikacju przez kanał LDAP w środowisku informatycznym warto abyśmy najpierw mogli zidentyfikować linę bazową. Czyli musimy wiedzieć, jak duży ruch uważa się za normalny, rodzaj ruchu itp. Po zidentyfikowaniu tych informacji możemy odfiltrować anomalie, takie jak:

  • Nietypowa ilość ruchu od klientów do kontrolera domeny
  • Duża liczba zmian w obiektach AD, dlatego należy monitorować zdarzenia o numerze ID 5136 w logach Security na kontrolerach domeny lub wdrożyć dedykowany system do rejestrowania takich zmian.
  • Włączyć i sprawdzać logi z protokołu LDAP. Uwaga na dużą ilość logów! Tutaj dowiesz się jak to zrobić.
  • Użyj specjalistycznego narzędzia do monitorowania zapytań LDAP oraz zmian w Active Directory najlepiej z wdrożoną sztuczną inteligencją.

Pamiętajmy, że atakujący może łatwo korzystać z różnych atrybutów, co czasem może uczynić opisywaną powyżej taktykę zapobiegawczą nieskuteczną, jeśli atakujący zmień atrybuty. W każdym bądź razie na podstawie historii zmian atrybutów, będziemy mogli na pewno znaleźć źródło problemu.