How it's made: Virusy #2

31.03.2007 13:47 | blackhole_ventYl

V tomto dieli sa podobnejsie pozrieme na to, ako sa chova taky virus v pripade, ze je spusteny na neinfikovanom pocitaci a snazi sa tento pocitac infikovat a nainstalovat sa do systemu. Infekcia systemu rezidentnym virusom je vychodzim bodom pre jeho dalsie cinnosti, ako jeho replikacia, alebo maskovanie existencie.

Uvazujme infikovany subor, u ktoreho zanedbame to, akym sposobom bol infikovany. Infikovany subor sa vyznacuje najma tym, ze obsahuje uplne virusove telo a obsahuje kod, ktory virusovemu telu zabezpeci, ze bude spustene.

Hned na zaciatku si musi virus zistit, ci bol spusteny na stroji, ktory uz tymto virusom nainfikovany je, alebo sa jedna o doposial neinfikovany stroj. Metod overenia instalacie virusu existuje mnoho.

Najjednoduchsou metodou je nastavenie nejakej rezervovanej, alebo nepouzitej pamatovej oblasti na specialnu hodnotu, ktora bude indikovat pritomnost virusu.

Na systemoch, ktore su vybavene shadowingom ROM oblasti je na tento ucel vcelku vhodnych poslednych 16 bytov operacnej pamati, ktore obsahuju kratky usek kodu, ktory je spustany len pri resete pocitaca a obvykle obsahuje jedinu instrukciu dalekeho skoku a dost volneho miesta. Priklad takehoto postupu by mohol vyzerat napriklad nasledovne:

        mov bx, 0xFFFF;
        mov es, bx;
        xor bx, bx;
        add bl, 0x0E;
        cmp es:bx, 0xABCD;
        je infected;
        mov es:bx, 0xABCD;
        jmp infect_system;
infected:
        jmp run_host_program;

V tomto kode hodnota 0xABCD znaci magicku hodnotu, ktora signalizuje pritomnost virusu v systeme. Ak pamat na adrese FFFF:000E tuto hodnotu obsahuje, virus uz je v systeme aktivny, v opacnom pripade dojde k jeho instalacii. Tento postup v komplikovanejsom variante moze vyuzivat nevyuzitu rezervovanu premennu v systemovej oblasti jadra, alebo BIOSu, napriklad nastavenim vektora niektoreho malo vyuzivaneho prerusenia na magicku hodnotu. Uplne najsofistikovanejsie metody detekcie na zaklade magickej hodnoty pouzivaju neobsadene oblasti systemovych premennych. Ako priklad mozno uviest vyuzitie poslednych 4 bytov prveho Memory Control Blocku. MCB je struktura popisujuca alokaciu pamati systemom, je dlha 16 bytov (jeden pamatovy chain). V hornych osmich bytoch obsahuje nazov programu, ktoremu pamatova oblast patri. Prvy MCB je v novsich verziach MS-DOSu alokovany pre DOS datasegment a nazov teda obsahuje hodnotu DOS. Tato hodnota je zapisana ako null-terminated string, cize posledne 4 byty nazvu su vyuzitelne pre ulozenie magickej hodnoty. K segmentovej adrese prveho MCB sa virus dostane pomocou sluzby 0x52 jadra MS-DOSu. Kod moze teda vyzerat napriklad nasledovne:

        mov ah, 0x52;
        int 0x21;
        mov cx, es:[bx-2];
        mov es, cx;
        xor bx, bx;
        add bl, 0x0C;
        cmp es:bx, 0xABCD;
        je infected;
        mov es:bx, 0xABCD;
        jmp infect_system;
infected:
        jmp run_host_program;

Tento kod vykonava v podstate to iste, akurat pre ulozenie magickej hodnoty pouziva MCB DOSu a nie pevnu adresu v pamati. Dovod pre pouzitie MCB, alebo inej systemom alokovanej struktury je v tom, ze jej normalna hodnota je definovana a je mozne sa na tuto hodnotu spolahnut, kdezto hodnota poslednych styroch bytov pamati nema ziaden predpis, ako by mala vyzerat a moze tam byt cokolvek, pri (ne)vhodnej volbe tam moze byt "od prirody" hodnota rovnaka, ako je hodnota magickeho cisla.

Inym sposobom je alokacia vektora prerusenia, ktore sa malo pouziva. V tomto pripade do vektora prerusenia nebude zapisana magicka hodnota, ale vektor prerusenia bude nastaveny tak, aby ukazoval na detekcnu rutinu virusu. Virus potom vyuzije fakt, ze vsetky nealokovane prerusenia su BIOSom obvykle nastavene na rutinu, ktora nevykona nic, iba vrati riadenie volajucemu programu. Modifikovana rutina virusu vykona napriklad zmenu niektoreho registra, alebo zapis hodnoty niekam do pamate:

infection_test_handler:
        cmp ax, 0xABCD;
        jne .eop;
        mov bx, 0x1234;
.eop:
        iret;

Uvedeny handler vykona nastavenie hodnoty registra BX na 0x1234, ak bude zavolany a sucasne bude v registri AX ulozena hodnota 0xABCD. V opacnom pripade nevykona nic - to je vhodne, ak by rutinu zavolal nahodne iny program, nic sa nestane. Virus pri svojej inicializacii nasledne nastavi register AX na 0xABCD, vyvola prerusenie, na ktorom ocakava testovaciu rutinu a nasledne si overi obsah registra BX. Ak je spravny, povazuje pocitac za uz zavireny.

Modifikaciou tejto metody je vytvorenie fiktivnej sluzby jadra operacneho systemu, alebo BIOSu, ktora vykonava to iste, ako testovacia rutina, akurat nesidli na vlastnom preruseni, ale obsadzuje nevyuzite cisla sluzieb uz existujucich preruseni. Vyhodou tejto metody je, ze virus nepojde zistit jednoduchym pohladom do tabulky preruseni, pretoze ta zostane oproti beznemu stavu nezmenena, resp. sa zmenia len hodnoty alokovane systemom.

Cely proces testovania infikovanosti pocitaca je dolezity hlavne z toho hladiska, ze niektore algoritmy virusovej infekcie mozu byt koncipovane tak, ze dvojnasobna infekcia tym istym virusom povedie k strate zivotne dolezitych udajov pre beh systemu a to povedie k nutnemu padu systemu.

Ked si je virus isty, ze sam uz tento pocitac neinfikoval, moze pristupit k infekcii. Cielom infekcie je dosiahnut vyssiu mieru kontroly nad systemom a obvykle zariadit aj svoju replikaciu. Nezriedka takisto virusy v infikovanom systeme maskuju svoju pritomnost. Prvym krokom infekcie by malo byt prekopirovanie svojho tela na bezpecne miesto v pamati, pretoze ked hostitelsky program ukonci svoju cinnost, bude pamat prenho alokovana uvolnena a telo virusu bude moct byt prepisane inym programom. Vcelku jednoduchym riesenim je poziadat samotny MS-DOS, aby naalokoval oblast pamate potrebnej velkosti, nakopirovat do nej telo virusu a tuto oblast potom poznacit nazvom "SC" alebo "SD", spolu s nastavenim ID vlastnika v MCB na hodnotu 0x8 co sposobi, ze MS-DOS ju neuvolni, lebo ju bude pokladat za systemovu oblast. Inym sposobom je pokusit sa pouzit oblast vysokej pamate, ktora je dostupna pri procesoroch 80286 a vyssie a je to oblast pamate velka 64 kB nachadzajuca sa nad hranicou 1 MB. Takisto je mozne pouzit niektore zriedka vyuzivane oblasti v pamati medzi 640kB a 1MB, kde vsak hrozi riziko, ze dojde ku kolizii s niektorym zariadenim a padu systemu.

Vcelku istou metodou je naalokovat celu volnu pamat pomocou sluzby alokacie pamati MS-DOSu. Nasledne tuto pamat natvrdo uvolnit tym sposobom, ze nastavi vlastnika MCB sam na seba (takyto MCB zacne MS-DOS povazovat za volny), pricom posledny MCB naalokuje tak, aby bol dostatocne velky pre telo virusu. Tento MCB nasledne oznaci vlastnikom 0x8 (jadro MS-DOS) a nastavi nazov vlastnika na SC, cim zabezpeci, ze tento blok pamati sa nebude zobrazovat vo vypise pamati. Virus nasledne do takto alokovaneho bloku zapise svoje telo a moze zapocat fazu instalacie obsluhy preruseni. Kopirovanie moze prebehnut napriklad takto:

(po vytvoreni bloku pamati pre telo virusu ostala segmentova adresa tohto bloku v registri ES)

        call near my_ip;
my_ip:
        pop si;
        sub si, my_ip_offset;
        mov cx, cs;
        mov ds, cx;
        xor di, di;
        mov cx, virus_length;
        rep movsb;

Uvodne volanie call near my_ip sposobi, ze adresa instrukcie s navestim my_ip bude ulozena do zasobnika, nakolko procesor pred skokom do podprogramu ulozi do zasobnika adresu instrukcie nasledujucej po instrukcii volania podprogramu. Od tejto adresy staci odcitat offset navestia my_ip v tele virusu, nastavit pocet kopirovanych bytov a moze sa kopirovat.

Ked je telo virusu bezpecne skopirovane mimo sparov alokacnej rutiny MS-DOSu, moze prebehnut instalacia obsluh preruseni. Ta obvykle spociva v prekryti niektoreho systemoveho prerusenia obsluhou prerusenia vo viruse tak, aby sa pri poziadavke o prerusenie najprv dostal ku slovu virus a az tak povodna obsluha. To dava virusu moznost kontrolovat, co sa v systeme deje. Najcastejsie obsadzovanymi preruseniami su prerusenie 0x21 jadra MS-DOS a prerusenie 0x13 diskoveho ovladaca BIOSu.

        xor bx, bx;
        mov es, bx;
        mov word int_x21_offset, es:[0x21*4];
        mov word int_x21_segment, es:[(0x21*4)+2];
        ...
jmp_x21_handler:
        bogo_jmp_far_instruction db 0xEA
        int_x21_offset dw ?
        int_x21_segment dw ?

Uvedeny kod skopiruje do premennych int_x21_offset a int_x21_segment adresu obsluhy prerusenia 0x21 z tabulky vektorov prerusenia, navyse este pred tieto hodnoty uklada byte s hodnotou 0xEA, co znamena, ze po ulozeni hodnot z tabulky vektorov preruseni vytvori kod za navestim jmp_x21_handler legitimnu instrukciu dalekeho skoku na povodnu obsluhu prerusenia 0x21. Ked je povodna adresa obsluhy ulozena, je mozne do tabulky vektorov preruseni ulozit hodnotu novu presne opacnym mechanizmom:

        xor bx, bx;
        mov es, bx;
        mov ax, cs;
        mov word es:[0x21*4], offset virus_x21_handler;
        mov word es:[0x21*4+2], ax;

Tento kod ulozi do tabulky preruseni pre vektor prerusenia 0x21 adresu virusovej obsluhy prerusenia. Predpokladom je, ze kod, ktory instalaciu vykonava, bezi v rovnakom segmente, v akom sa nachadza obsluha, aby mohol vyuzit obsah registra CS ako segmentovu adresu obsluhy prerusenia. Offset obsluhy je cislo ziskane pri kompilacii a urcuje pocet bytov od zaciatku tela virusu, o ktore je obsluha prerusenia vo viruse posunuta oproti zaciatku segmentu.

Virus moze namiesto obsluhy 0x21 jadra MS-DOSu obsadit prerusenie 0x13 diskoveho radica, alebo moze obsadit obe prerusenia odrazu, pripadne moze obsadzovat aj dalsie prerusenia MS-DOSu. V kazdom pripade vsak plati, ze ak chce zachovat povodnu funkcnost systemu, musi po vykonani virovych akcii v obsluhe prerusenia odovzdat riadenie na povodnu obsluhu prerusenia. Prave na to sluzi navestie jmp_x21_handler.

Obsluha prerusenia sa vyvolava volanim instrukcie INT, ktora na zasobnik ulozi segmentovu aj offsetovu adresu instrukcie nasledujucej za instrukciou INT, preto z virovej obsluhy prerusenia sa musi kontrola odovzdavat instrukciou JMP, ktora obsah zasobnika na rozdiel od instrukcie CALL nemeni. Taktiez je dolezite, ze povodna obsluha prerusenia musi dostat obsah registrov presne taky, aky by dostala, keby tam virus nebol.

Jednoducha obsluha prerusenia 0x21 moze vyzerat napriklad nasledovne. Uvedeny fragment kodu implementuje test infikovania pocitaca virusom pomocou fiktivnej sluzby existujucej obsluhy prerusenia.

virus_x21_handler:
        cmp AX, 0x99AB;
        jne .no_test;
        mov BX, 0x1234;
        iret;
.no_test:
        jmp jmp_x21_handler;

Uvedeny kod v pripade, ze register AH bude obsahovat hodnotu 0x99 (sluzba 0x99) a register AL hodnotu 0xAB naplni register BX hodnotou 0x1234 (magicka hodnota) a vrati riadenie volajucemu programu. V opacnom pripade odovzda riadenie obsluhe prerusenia MS-DOSu.

Virus, ktory ma uspesne obsadene niektore systemove prerusenie, ziskava kontrolu nad systemom a obvykle zacina vykonavat svoju hlavnu cinnost: replikaciu. Nezriedka takyto virus zacina maskovat svoju pritomnost.

V dalsom dieli sa pozrieme na to, ako sa sprava pri spusteni bootovaci rezidentny virus a ako tento vykonava svoju instalaciu.

    • Re: How it's made: Virusy #2 05.04.2007 | 18:55
      Avatar lekvar   Používateľ

      Mnozstvo drobnych nepresnosti :)

      ---
      Zerte lequar, je kua zdravy !

      --- Zerte lequar, je kua zdravy !
      • Re: How it's made: Virusy #2 06.04.2007 | 14:25
        Avatar blackhole_ventYl   Používateľ

        jj, pripustam. ak mas chut, konkretizuj, niektore su mozno klucove. ale push pop registrov do ukazok vkladat nebudem, len to zneprehladni kod...

        ---
        Cuchat s nadchou, to je ako sniffovat bez promiscu.

        --- Cuchat s nadchou, to je ako sniffovat bez promiscu.