Stan zagrożeń w internecie znajduje się obecnie na poziomie standardowym. Nie występują duże epidemie a eksperci z Kaspersky Lab nie zanotowali żadnych poważnych incydentów związanych z bezpieczeństwem. Poziom zagrożenia: 1

Powrót do Stuxneta: brakujące ogniwo

Aleksander Gostiew
Kaspersky Lab Expert
Dodany 11 czerwca 2012, 14:20 CEST

Dwa tygodnie temu, kiedy ogłosiliśmy wykrycie oprogramowania szpiegowskiego Flame, poinformowaliśmy o dużym podobieństwie kodu i stylu programowania Flame’a do platformy Tilded, na której oparte były szkodniki Stuxnet i Duqu.

Postulowaliśmy jednak, że Flame i Tilded są zupełnie odmiennymi projektami, bazującymi na różnych architekturach i posiadającymi różne cechy charakterystyczne. Na przykład, Flame nigdy nie używa sterowników systemowych, podczas gdy głównym sposobem Stuxneta i Duqu na ładowanie modułów do wykonania było wykorzystanie sterownika jądra.

Okazuje się jednak, że byliśmy w błędzie. Błąd polegał na tym, że wierzyliśmy, iż Flame i Stuxnet to dwa, niepowiązane ze sobą projekty. Nasze badanie ujawniło kilka nieznanych wcześniej faktów, które rzucają nowe światło na to, jak Stuxnet został stworzony i jaki jest jego związek z Flamem.

Flame wewnątrz Stuxneta

Przede wszystkim, przypomnijmy historię Stuxneta. Udało nam się pozyskać tylko trzy różne warianty tego robaka, utworzone w czerwcu 2009 roku oraz w marcu i kwietniu 2010 roku.

Wariant z marca 2010 roku odpowiedzialny był za największą liczbę infekcji, a wykryty został w czerwcu 2010 roku przez specjalistów z białoruskiej firmy VirusBlokAda. Ta szczególna wersja została poddana najbardziej szczegółowej analizie przez firmy antywirusowe.

Krótko po tym, jak rozniosła się wieść o Stuxnecie, wykryto pliki związane z wariantem robaka z czerwca 2009 roku. Ta wersja, nazwana Stuxnet.A (1.0), różniła się znacznie od wariantów z 2010 roku.

Głównymi różnicami były:

  • Wariant z 2009 roku nie wykorzystywał luki MS10-046 znajdującej się w funkcjach obsługujących skróty LNK.
  • Wariant Stuxneta z 2009 roku posiadał tylko jeden plik sterownika; w roku 2010 były to dwa pliki (drugi plik został dodany specjalnie do operowania na luce LNK).
  • Wariant Stuxneta z 2009 roku używał specjalnej sztuczki z plikiem „autorun.inf” do infekowania napędów USB.

Wszystkie pozostałe różnice dotyczą drobnych modyfikacji wewnętrznej struktury Stuxneta – niektóre moduły zostały usunięte, a ich funkcje zostały przeniesione na inne moduły.

Najważniejsza z tych zmian obejmowała zasób 207. Zasób „207” posiada rozmiar 520 192 bajtów i odnaleźć go można w wersji Stuxneta z 2009 roku. Został również użyty w wersji z 2010 roku, gdzie jego kod został wkomponowany w inne moduły.

klp_flame_stuxnet_01s.png
Lista zasobów w wariancie Stuxneta z marca 2010 roku

klp_flame_stuxnet_02s.png
Lista zasobów w wariancie Stuxneta z 2009 roku

Mimo że Stuxnet był przedmiotem wnikliwej analizy wielu ekspertów i zespołów badawczych – i powstało wiele publikacji na temat jego struktury - z jakiegoś powodu tajemniczy zasób 207 z roku 2009 pozostał w dużej mierze niezauważony. Okazuje się, że jest to brakujące ogniwo między Flamem i Stuxnetem, dwoma, zdawałoby się, zupełnie odrębnymi projektami.

Zasób 207

Zasób 207 jest zaszyfrowanym plikiem DLL, który zawiera inny zasób z plikiem PE (o rozmiarze 351 768 bajtów).

klp_flame_stuxnet_03s.png
Informacje o dacie utworzenia modułu

klp_flame_stuxnet_04s.png
Informacje o pliku w zasobie

Ten plik PE jest wtyczką Flame’a.

Albo, by być bardziej precyzyjnym, protoplastą Flame’a – modułem, który niezaprzeczalnie ma wiele wspólnego z obecną wersją pliku „mssecmgr.ocx”, i który w roku 2012 przeistoczył się we Flame’a. Uważamy, że można mówić o platformie „Flame”, i że ten konkretny moduł został stworzony na podstawie jej kodu źródłowego.

Kilka dni temu widziałem na Twitterze raczej humorystyczny wpis, którego autor twierdził, że Flame jest taki niebezpieczny dlatego, że w swoich zasobach zawiera całego Stuxneta. Okazuje się, że to zasoby Stuxneta zawierają składnik platformy Flame’a.

Zbieżności z obecnymi odmianami Flame’a to:

  1. Nazwy mutexów (mutex - ang. mutual exclusion – algorytmy wzajemnego wykluczania): TH_POOL_SHD_PQOMGMN_%dSYNCMTX oraz TH_POOL_SHD_MTX_GMN94XQ_%d
  2. Algorytm deszyfrowania ciągów znaków
  3. Nazwa klasy manipulowania: ?AVnxys_uwip i podobne.
  4. Nazwa podobna do używanej w architekturze Flame’a - pliki .ocx (atmpsvcn.ocx)

Co więcej, plik zawiera cechy, które wcześniej przypisywane były wyłącznie Stuxnetowi:

  1. Nazwy plików „wyzwalających”: %temp%\dat3A.tmp oraz snsm7551.tmp
  2. Funkcje użytkowe parsowania modułów oraz ich wzajemne powiązania i architektura
  3. Zasady asemblacji kodów zwracanych funkcji
  4. Podobny styl kodu powłoki
  5. Struktura opisu wersji wrażliwych systemów operacyjnych i algorytmu sprawdzania
  6. Własny import

To jest właśnie „atmpsvcn.ocx” – moduł platformy Flame’a wewnątrz Stuxneta.

Co ciekawe, obecne warianty Flame’a bazują na pliku dat3C.tmp, podczas gdy moduł Flame’a wewnątrz Stuxneta używał pliku „dat3a.tmp” jako identyfikatora do zaznaczenia swojej obecności w systemie. Można się tylko zastanawiać, czy istniał w tym czasie także istniał jakiś plik „dat3b.tmp”.

Ogromne fragmenty kodu w najnowszych modułach Flame’a są takie same jak kod w atmpvsvcn.ocx. Jednak, najbardziej oczywiste podobieństwo to nazwy mutexów:

TH_POOL_SHD_PQOMGMN_%dSYNCMTX
TH_POOL_SHD_MTX_GMN94XQ_%d

Co więcej, są inne znane moduły Flame’a używające mutexu TH_POOL_SHD_MTX_FSW95XQ_%d, który datowany jest na rok 2010, np. comspol32.ocx.

Podobieństwa są jeszcze bardziej zdumiewające na poziomie kodu:

klp_flame_stuxnet_05s.png
Funkcja “getdecrypted” z zasobu 207

klp_flame_stuxnet_06s.png
Funkcja “getdecrypted” z pliku mssecmgr.ocx

klp_flame_stuxnet_07s.png
Funkcja “DecryptString” z zasobu 207

klp_flame_stuxnet_08s.png
Funkcja “DecryptString” z pliku mssecmgr.ocx

klp_flame_stuxnet_09s.png
Funkcja “DecryptString” z pliku browse32.ocx (moduł deinstalacyjny Flame’a krążący na przestrzeni maja i czerwca 2012 roku)

klp_flame_stuxnet_10s.png
Mutex użyty w zasobie 207

klp_flame_stuxnet_11s.png
Mutex użyty w pliku mssecmgr.ocx

Główną funkcjonalnością zasobu 207 było zapewnienie propagacji szkodnika na napędach USB poprzez sterownik autorun.inf, jak również przez wykorzystanie nieznanej wtedy luki w win32k.sys, pozwalającej na zwiększenie przywilejów w systemie.

klp_flame_stuxnet_12.png

Rozprzestrzenianie przez autorun.inf jest kolejną cechą wspólną Stuxneta z roku 2009 i obecnych wersji Flame’a. Zasób 207 infekuje nośniki wymienne, kopiuje na nie Stuxneta i dodaje do jego kodu specjalny plik autorun.inf. Plik jest prawidłowo przetwarzany przez system operacyjny i dzięki temu robak jest uruchamiany, gdy zgłoszony zostanie dostęp do urządzenia.

Ten szczególny kod, który pasuje do kodu w zasobie 207, jest aktualnie używany przez Flame’a, gdzie jest wykonywany przez moduł „Autorun_infector”.

Stare dobre 0-day

Zasób 207 modułu Flame’a w Stuxnecie zawiera exploit zwiększający przywileje EoP (EoP – ang. Escalation of Privilege). Jest to funkcja interesująca sama w sobie.

Kod exploitu w pliku atmpsvcn.ocx jest podobny do tego, co znaleźliśmy w wersjach Stuxneta z roku 2010 i co było celem poprawki MS10-073. Styl kodu, logika i szczegóły implementacji były takie same dla kodu z roku 2009 i 2010. Mówiąc jaśniej – jesteśmy przekonani, że obie części kodu exploita zostały napisane przez tego samego programistę.

W wersji Stuxneta z 2009 roku użyty został odmienny exploit - celował w inną lukę starszego typu, która została załatana w 2010 r.

W chwili gdy stworzony został zasób 207 (luty 2009), luka nie była publicznie znana, więc mieliśmy do czynienia z prawdziwą luką 0-day.

Podstawę luki stanowi brak kontroli danych wejściowych, co zezwala funkcji NtUserRegisterClassExWOW() na nadpisanie danych WORD poza przydzielonym zakresem pamięci w win32k.

Adres funkcji w strukturze _gpsi jest nadpisywany w dwóch krokach przy pomocy kodu powłoki. Następnie wywoływana jest funkcja NtUserMessageCall(), która przekazuje kontrolę do kodu powłoki z przywilejami na poziomie jądra.

Żadna funkcja nie jest eksportowana do trybu użytkownika, co oznacza, że adresy i parametry dla usług wywoływania mogą zostać odnalezione bezpośrednio na dysku przez moduły parsujące (user32 & win32k).

Opis tej luki jest uderzająco podobny do opisu luki „Windows Kernel Could Allow Elevation of Privilege (968537)”, która została załatana w czerwcu 2009 roku przy pomocy łaty MS09-025; jednakże, wciąż jesteśmy na etapie wnikliwej analizy kodu i nie możemy w stu procentach potwierdzić tej obserwacji.

klp_flame_stuxnet_13s.png
Główna funkcja Stuxneta z 2009 roku wykorzystująca lukę EoP

klp_flame_stuxnet_14s.png
Główna funkcja Stuxneta z 2009 roku wykorzystująca lukę EoP

klp_flame_stuxnet_15s.png
Kod przeznaczony do wywołania kontrolowanych funkcji w luce z 2009 roku

klp_flame_stuxnet_16s.png
Kod przeznaczony do wywołania kontrolowanych funkcji w luce MS010-073

Wnioski

Nasza analiza wskazuje kilka ważnych wniosków, które podsumujemy poniżej:

  • W czasie gdy tworzony był Stuxnet (styczeń - czerwiec 2009 roku), istniała już platforma Flame’a (optujemy, że powstała ona nie później niż w lecie 2008 roku) i jego struktura modułowa.
  • Kod Stuxneta z roku 2009 używał modułu zbudowanego na platformie Flame’a, prawdopodobnie stworzonej specjalnie do pracy w ramach Stuxneta.
  • Moduł został usunięty ze Stuxneta w roku 2010 z powodu wprowadzenia nowego sposobu rozmnażania (luka MS10-046) zamiast „starej” sztuczki ze sterownikiem autorun.inf.
  • Moduł Flame’a w Stuxnecie wykorzystywał lukę, która nie była znana w tamtym czasie. To była prawdziwa luka 0-day. Pozwoliło to na zwiększenie przywilejów, prawdopodobnie przy wykorzystaniu luki MS09-025.
  • Po roku 2009 ewolucja platformy Flame’e postępowała niezależnie od Stuxneta.

Powyższe wnioski wskazują na istnienie dwóch niezależnych zespołów deweloperskich, które mogą zostać nazwane ”Zespół F” (Flame) i ”Zespół D” (TildeD). Każdy z tych zespołów rozwija swoją platformę od roku 2007 - 2008 do dnia dzisiejszego.

W roku 2009 część kodu platformy Flame’a została użyta w Stuxnecie. Uważamy, że użyty został kod źródłowy, a nie całe moduły binarne. Od 2010 roku platformy są rozwijane niezależnie, istnieją jednak podobieństwa, chociażby na poziomie wykorzystania tych samych luk.