Preorder drugiego tomu książki sekuraka: Wprowadzenie do bezpieczeństwa IT. -15% z kodem: sekurak-book
Deobfuskacja JavaScript – część trzecia
Dla przypomnienia: pierwsza część cyklu o deobfuskacji JavaScript, druga część.
Przypomnijmy sobie zatem zobfuskowany JavaScript, który służył nam za przykład w pierwszej części artykułu
<script> eval(function(p,a,c,k,e,d){e=function(c){return c.toString(36)};if(!''.replace(/^/,String)){while(c--){d[c.toString(a)]=k[c]||c.toString(a)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('g 6=["\\t\\u\\j","\\w\\n\\f\\j","\\i\\k\\h","\\q\\9\\9\\k","\\r\\l\\l\\8\\8\\8\\i","\\h\\m\\o\\f\\9\\s\\m\\v"];g 7=[6[0],6[1],6[2],6[3],6[4],6[5]];a=7[0];b=7[1];c=7[2];d=7[3];e=7[4];p[7[5]]=d+e+a+b+c;',33,33,'||||||_0x3725|_0x64df|x77|x74||||||x61|var|x6C|x2E|x6B|x70|x2F|x6F|x72|x63|document|x68|x3A|x69|x73|x65|x6E|x75'.split('|'),0,{})) </script>
Ten sam kod spróbujemy przetestować na dwóch innych narzędziach, które znane są z możliwości analizy JavaScriptu. Następnie przetestujemy również jedno zobfuskowane przekierowanie do Exploit Kitu oraz obfuskowany JavaScript w kampanii phishingowej. Do dzieła!
Revelo
Na stronie Kahu Security możemy pobrać Windowsowy program Revelo. Według opisu program potrafi przeprowadzić deobfuskacje używając różnych technik oraz posiada wbudowany upiększacz kodu, proxy oraz firewall. Brzmi obiecująco. Przejdźmy zatem do analizy kodu z pierwszego listingu.
Efekt będzie bardziej niż zadowalający. Wystarczy załadować wybrany kod, otoczyć go tagami <script> i uruchomić przyciskiem execute. Revelo sprawnie symuluje uruchomienie JavaScriptu i informuje użytkownika, że skrypt próbuje uzyskać dostęp do strony www.sekurak.pl. Tool od Kahu Security pozwala także modyfikować kod w trakcie emulacji, co może przydać się w trakcie analizy bardziej zaawansowanych skryptów. Przykładem może być opcja “Redirect Eval to Action”, która wyłuska kod przesyłany do funkcji eval() i przedstawi go użytkownikowi w zakładce Results (funkcjonalność zbliżona do Show Code -> Send to Analyze w JSDetox).
Zobaczmy jak Revelo sprawdzi się analizując prawdziwy malware.
Za przykład posłuży nam tym razem Nuclear Exploit Kit. Pliki zip z kilkoma podsłuchanymi transmisjami możemy pobrać ze strony http://malware-traffic-analysis.net/2015/07/30/index.html. W tej analizie skupimy się na skrypcie, który znajduje się w 146. pakiecie pliku 2015-07-29-BizCN-gate-actor-Nuclear-EK-traffic.pcap.
Ładujemy zatem plik do Revelo, dodajemy tagi <script> (można zrobić to automatycznie z poziomu górnego menu Options), klikamy Execute i przy odrobinie szczęścia otrzymamy okienko pop-up z adresem url, do którego dostać się próbuje złośliwy skrypt. Ta sama informacja pojawi się również w zakładce Traffic Log oraz Traffic Detail. Jeśli zechcemy symulacje powtórzyć możemy jeszcze raz kliknąć w przycisk execute lecz… tym razem nic się nie wydarzy. Aby dowiedzieć się skąd wynika ten stan rzeczy przejdźmy do zakładki Tools. W okienku Session Cookies pojawiła się wartość “gKYCABxdieSkjDTL”, której wcześniej tam nie było. Jeśli wyszukamy jej w zobfuskowanym kodzie możemy śmiało stwierdzić, że oryginalny JavaScript sprawdza zawartość pewnego pliku cookie zanim przekieruje użytkownika na złośliwą stronę www.
Spróbujmy zatem “upiększyć” kod, na co pozwala wbudowany w Revelo formater kodu. Okienko upiększacza wywołujemy z zakładki Tools, a po odpowiednim sformatowaniu kod możemy przesłać do głównego okna przy pomocy przycisku “Copy to Main”. Co ciekawe Revelo na swój sposób próbuje zmienić również tagi <script> wstawiając niepotrzebne spacje i modyfikując je do postaci < script >, czego potem nie potrafi zinterpretować.
Po upiększeniu możemy wyszukać wspomnianego ciągu „gKYCABxdieSkjDTL”, który odpowiada za cookies. Przeszukiwanie skryptu dostępne jest w zakładce Tools, ale należy mieć na uwadze, że powrót do początku dokumentu realizuje się przyciskiem Reset. Po przeszukaniu widać, że funkcja OnLgiyHrZEAfI() składa się z instrukcji warunkowej if, która zwraca true tylko w przypadku gdy cookie o zadanej nazwie jeszcze nie istnieje. Z drugiej strony funkcja OnLgiyHrZEAfI() jest warunkiem koniecznym do przejścia innej instrukcji if znajdującej się u dołu skryptu. Jeśli zatem przerobimy ją w ten sposób, aby zwracała wartość true za każdym razem, unikniemy problemu z tym, że emulacja kodu kończy się sukcesem tylko za pierwszym razem.
Revelo w zakładce Tools udostępnia jeszcze jedną opcję: Spoof User Agent. W założeniu autorów powinna ona zapewne służyć do symulacji odpowiedniego rodzaju i wersji przeglądarki w trakcie uruchamiania JavaScriptu. Niestety w wersji v0.6 nie działa to tak, jak powinno. Abstrahując od enigmatycznych opisów przeglądarek dostępnych na liście (np. MSIE (Old Version)), Revelo wydaje się być obojętne na jakiekolwiek zmiany. Jest to bug, który dość mocno utrudnia analizę, zwłaszcza, jeśli malware dedykowany jest dla konkretnej wersji przeglądarki internetowej.
Revelo wydaje się być nieco mniej elastyczne i przyjazne użytkownikowi niż JSDetox. Jego zaletą jest łatwość emulacji bez żadnych zmian w kodzie (ten sam kod w JSDetox trzeba było lekko zmodyfikować, aby symulacja w pełni się powiodła). Do plusów można zaliczyć także bez wątpienia zakładki Traffic Log oraz Traffic Detail, które mogą być pomocne w przypadku śledzenia wielu zapytań pochodzących z jednego skryptu. Przydatne mogą się okazać także różne funkcje modyfikowania kodu w trakcie uruchamiania. Główną wadą Revelo jest natomiast bardzo ograniczona komunikacja narzędzia z użytkownikiem. Używając Revelo nie można być pewnym czy to, że po kliknięciu element GUI nic się nie dzieje, jest efektem poprawnego wykonania się skryptu, czy też drobnym błędem twórców programu. Na dłuższą metę kłopotliwe staje się także dodawanie tagów <script> na początku i na końcu skryptów.
SpiderMonkey
SpiderMonkey to napisany w C silnik javascriptu. Jego ciekawą modyfikacje, wyposażoną w dodatkowe funkcjonalności przydatne przy analizie złośliwego kodu, opublikował Didier Stevens. SpiderMonkey dla systemu Linux działa w wieszu poleceń. Przeanalizujmy przy jego pomocy kod z pierwszego listingu. SpiderMonkey w wersji Didiera Stevensa nie wyświetla informacji na ekranie, ale tworzy pliki .log, które zawierają analizę wykonania się JavaScriptu. Ilość i nazwa plików log zależy od rodzaju funkcji, która jest emulowana.
W przypadku analizy kodu z pierwszego listingu SpiderMonkey stworzył dwa pliki log, które zawierają informacje o wywołaniach funkcji eval(). Jeden z tych plików zapisany jest w formacie ASCII (eval.001.log), a drugi w formacie Unicode (eval.001.uc.log). Plik logu wyświetla, jak sama nazwa wskazuje, argument przesyłany do funkcji eval(). Na tym jednak kończy się analiza. Niestety SpiderMonkey nie rozpoznał, że skrypt próbuje przekierować użytkownika na www.sekurak.pl, chociaż dalszą analizę można przeprowadzić chociażby w JSBeautifier, który przedstawi w czytelnej formie zakodowane znaki.
Zobaczmy jak SpiderMonkey sprawdzi się analizując prawdziwy malware.
Do tej pory, w poprzednich edycjach cyklu artykułów o deobfuskacji JavaScript zajmowaliśmy się złośliwym skryptem ukrytym w przekierowaniach, bądź w osadzonych na stronach internetowych elementach. Tym razem przeanalizujemy JavaScript osadzony na stronie, na którą cyberprzestępcy zwabiali ofiarę za pomocą kampanii phisingowych (z JavaScriptem w phishingu można spotkać się także w kontekście załączników html, które po otwarciu wykonują złośliwy kod). W pliku pcap dostępnym na stronie http://www.malware-traffic-analysis.net/2015/01/13/index.html znajdują się trzy pliki JavaScript, przeanalizujmy pierwszy, dostępny w 39. pakiecie transmisji. Po otwarciu go w edytorze tekstu ukazuje się nam ogromna ilość znaków z ograniczonego zakresu symboli. Zobaczmy, co na to SpiderMonkey.
Mimo, że SpiderMonkey zapewne poprawnie zdekodował tajemnicze symbole, to w wyjściowym kodzie doszukał się funkcji setTimeout(), której nie potrafi zinterpretować. Można się tylko domyślać, że służy ona zapewne opóźnieniu wykonania wynikowego kodu bądź przekierowania, ale aby być tego pewnym należy zdekodować skrypt. Czytelnicy, który czytali pierwszą część artykułu mogą mieć skojarzenia z kodowaniem JSFuck, które było tam omawiane. W tym przypadku jednak autor strony malware-traffic-analysis.net podpowiada nam, że użyte zostało kodowanie jjencoding – pora więc znaleźć odpowiedni dekoder. Ten dostępny jest w jednym z projektów na githubie w postaci niemal 500-linijkowego pliku html z osadzonym JavaScriptem. Aby zdekodować skrypt należy zapisać projekt w postaci pliku html (najlepiej na wydzielonej do analizy malware maszynie wirtualnej), a następnie wkleić zawartość zobfuskowanego pliku jquery-1.14.94.js. Wynikowy kod będzie dużo bardziej czytelny i umożliwi nam dalszą analizę.
Na pierwszy rzut oka widać, że główna funkcja która będzie nas interesować znajduje się u góry kodu. Widać również domenę, ale warto dowiedzieć się jakie argumenty metody HTTP GET są przekazywane do kolejnego JavaScriptu. Poniżej w kodzie, zaczynając od linii 15 znajdują się dwa warunki, które w jakiś sposób (odwołując się do ruchów myszką oraz wspomnianego już wcześniej setTimeout()) uruchamiają w końcu główną funkcję szl7S7oV4MrlLKj(). Usuńmy wszystko zaczynając od linii 15, zastępując oba warunki wywołaniem wprost głównej funkcji szl7S7oV4MrlLKj() i przejdźmy do analizy przy pomocy SpiderMonkey.
SpiderMonkey będzie miał jeszcze drobne problemy z interpretacją elementów języka JavaScript, które są typowe dla przeglądarek (takie jak navigator.userAgent, screen.width, screen.height czy createElement). Aby przeskoczyć te niedogodności należałoby usunąć elementy typowo przeglądarkowe lub też, w przypadku gdy ich wartości przypisywane są do zmiennych, posłużyć się mniej lub bardziej losowym ciągiem znaków, który można następnie wyłuskać z parametrów GET url (canary word). Tak na prawdę niepotrzebny jest nam kod w liniach 8,9,10,12,13. Przypisanie wartości charakterystycznych dla przeglądarki w liniach 6 i 7 możemy zastąpić przypisaniem dowolnego łańcucha znaków, a linię 11 przerobić na funkcję document.write(). Po tych zabiegach powinniśmy być w stanie zasymulować skrypt w SpiderMonkey oraz zobaczyć jego wynik w pliki write.log
SpiderMonkey jest dość skutecznym emulatorem JavaScript, chociaż brakuje mu wsparcia dla paru podstawowych elementów (brak logowania chociażby document.location). Ma problemy z symulacją środowiska przeglądarki internetowej, chociaż każda linia kodu, która przerywała analizę i wymagała ręcznych poprawek stanowiła wyzwanie również dla JSDetox (JSDetox nie również nie zinterpretował funkcji setTimeout czy wartości screen). Brakuje funkcji upiększania kodu, ale SpiderMonkey może przydać się do stosowania równolegle z innymi narzędziami omawianymi w tej serii artykułów.
Linki
— Marcin Szymankiewicz
No proszę, Firefox blokuje link do Revelo.
This web page at http://www.kahusecurity.com has been reported to contain unwanted software and has been blocked based on your security preferences.