套娃式的FormBook家族样本对抗部分分析

FormBook样本对抗部分分析

0x00 FormBook简介

FormBook作为一款商业木马,价格仅售30美刀,FormBook用C++和x86汇编语言编写,它与许多竞争性恶意软件的不同之处在于其极高的易用性,即使是没有经验的木马使用者也可以使用此病毒,FormBook可用于从受感染的计算机中窃取各种信息。

以上由搜索引擎的介绍获取的;前面的三个PE都是普普通通的PE Loader而已,而FormBook主体程序的分析难度还是挺大的,用到了各种检测沙箱、反主防、反EDR的方法,在弄清楚背后的检测的技术原理对于我的提升还是挺大的。反正在经过分析后我个人还是觉得这个作者只卖30美刀亏大了。

0x01 样本信息

文件: White.exe
大小 689664 bytes
MD5 2A6DA285D3FE9F86598CD708CC9AADBD
SHA1 C4AE1FB228A823CA1AE416E78FC817C66445B8DC
CRC32 9A4BEB2A

0x02 静态分析

根据EXEINFO的结果显示,该样本为C#样本,依靠前面的资料查询,FromBook为C和x86汇编语言编写,所以大胆推测所使用的为一款使用.net框架的PE Loader。
795949_UJWV53FNFXFJ95G
根据DNSpy反编译的结果,可以看到具有大量的混淆
795949_6QFWDETAFNSHB9P
根据经验一般来说.net的PE loader 会将要loader 的pe的十六进制加密后放入资源之中;将样本使用de4dot解混淆:
795949_MF6YQSPP7SCEW8M

0x03 动态调试

PE1

入口点和绝大数使用C#编写的PE Loader一样,为运行一个窗口。
795949_3Z3TJKC444PY8VX
加载类0中的KeysOrderedAcrossPartitions stRing对象将该string对象进行url解码,该对象是保存在资源之中,将解码后的资源进行load,调用其Buta导出方法。
795949_P65U48656HDJBK3

PE2——DLL

加载的dll也是一个被混淆的dll,Buta函数为整体为for的死循环内执行Switch case语句,整体case的顺序为default、6、4;然后退出进程。
795949_HASERE4XCRCAVS5
会将资源中的cXRsF进行读取后解密调用dll导出方法Kuchi解压缩,得到一个PE文件。
795949_ED79EWNPEM8AFRX
加载该PE文件,无参数。 795949_HKX3T5PR7EXPVWA
将PE文件dump出来,看了一下依旧有混淆,去混淆后继续分析。

PE3

在mAIn函数之前会先初始化一些环境、初始化一些静态类的静态变量。其中第二个类会解密获取一些配置字符串和解密资源得到一个PE文件,资源名叫做"UxllYqyI"。
795949_GPW7C3VW5669ATZ
其中一个解密流程为:先将“NAzjGQJblQU”转为unicode字符串数组bytes,后取出资源文件中最后一个字符亦或112赋值为num2,然后将资源文件中每个字符亦或上num2再亦或之前的bytes中的对应字符bytes[num],num<= bytes的长度,解密函数1如下:
795949_UFJKE6NT5FZSCM4
解密函数一之后还要进行一个解密函数2,该解密函数只是一个简单的循环亦或,解密函数2完成后才能得到真正的PE文件:
795949_6H39YCE5YA6YDNV
795949_RKDX9MHNTJ4W63B
到达Main函数,会尝试打开一个名为wDLeShQFqJdZStOKqq的Mutex,如果没有就创建,用来防止多开。
795949_YM6QZTN3Z6UMX8J
会以挂起的形式重启该进程所在路径的进程,然后将刚刚解密的PE文件的Text段对重启的进程替换空间中的.text段来进行进程镂空。
795949_ZPM45JAX5NRNTJR
795949_B6XJ236YDWJGF3S

PE4-FormBook

这个镂空的代码段用到的对抗点有点多。镂空的text段的入口:
795949_KXKUAND5FE4HJ6N
该镂空的PE应该就是FormBook本体了
首先会初始化一个控制块,在该控制块中包含着对抗调试的各类信息,和各类初始化环境信息。
795949_A8AXDHGUQMW3C5W
在该模块中资源都是写在代码段之中的,获取相关资源的时候都是通过 Call 0;pop eax ,add eax +2来获取,如:
795949_79Q32XTD8ZGU43J
检测代码执行时间来反虚拟机,检测进程中是否含有特定模块,如果含有特定模块则破坏后续的函数hash,导致后续无法获取正确函数地址而无法走完整个流程。
795949_JCJ9HVKN54AZ3DJ
在进行模块名比较的时候,是使用取模块名hash比较的,后续比较导出表函数地址也类似。
795949_G6WD5R5A2JPARPM
重载两份ntdll并自行构建部分ntdll敏感函数调用表,类似于增量链接。重载ntdll,是为了防止某些edr,主防工具在3环的ntdll上下钩子做检测。
795949_873D7H5DNHM7X99
795949_26J9F7TMAHCNDBX
判断当前进程是否是Wow64进程,如果是Wow64进程就检查Wow32Reserved 是否有被下钩子。具体为检查Wow32Reserved的地址的Base的COFF Magic 是否等于0x20B
795949_ANAQ3PRGXUAXT4J
795949_X8Q3ZZDS59WJYPX
查询SystemKernelDebuggerInformation来反调试,如果没有查到内容则会恢复部分函数Hash。
795949_RW2CTEJ6C2RKZU2
查询ProcessDebugPort来检测是否存在调试,如果没有查到内容则会恢复部分函数Hash。
795949_59YKF4TMZVVFRJB
检测系统中是否存在黑名单进程,进程名是否被修改,模块路径是否是黑名单之中的,还有用户名是否是是黑名单用户名;里面的字符串比较都是通过取hash后与hash比较。在检测通过后都会恢复部分函数hash。
795949_KHFWDBF6HKWPK63
之后检测相应的检测点。所以如果仅仅pass掉这里,后续流程也无法正常走通。
795949_Y2CCGTF2FSE4SB6
检测点通过后进行进程的提权,无论提权是否成功都会继续往下走。
795949_A8XBQSHVRNZ5DSN
到达第一次攻击函数,首先设置环境变量,变量名为用户名加密后的值,变量值为本进程路径。
795949_GYQFNE44ZHA6VS8
Map当前PE。
795949_6XFX8MHP3MY3G22
尝试获取Explorer中的线程,对线程进行劫持。
795949_26EFC9GXHV23XFE
如果Explorer不是32位进程的话,从该进程中读取某个特定位置,获取到32位进程信息。构造一个切换为64位段选择子的跳转,因为32位段选择子的cs为23,而64位cs段选择子为33。
795949_9PX3GTE2HBQ5ASS
有一点一直困扰着我:就是按道理来说读取64位进程时使用64位API读取,那么传递的地址参数应该是64位的才对,为什么这里传递的32位的,我之前还怀疑究竟是不是读取的64位进程的explorer,然后通过Pchunter查看句柄所对应的EPROCESS结构的地址和Explorer的EPROCESS结构地址是相同的。在如图显示,传递的是目标64位进程的32位的地址,其中数据区域中可以看到有调用0x1122330,该地址处是一个远跳切换段选择子的过程,跳转为33的段选择子后,执行0x11B1218处的代码。我思考的结果就是只能够在这里面进行一个地址的转换。
795949_PPW5CH4THGTKR48
795949_KZN8Y3D5C9UGREK
于是将0x11B1218的硬编码给扣了出来,x64dbg中查看,还是不对,按道理来说段选择子的base应该都是0,应该不会出现不对的情况。如果要搞清楚到底后面是怎么执行wow64层的,需要用windbg双机调试重新把Patch掉那些检查处查看,这....交给有缘人来看吧。
795949_6B9WDXGQGKYR5YP
795949_HD6ZFAG824XXBDW
向Explorer进程的主线程发送消息来挂起的方式启动某个32位进程,从Explorer中读取到某32位进程信息,如ipconfig,control、wlanext等。
795949_NP5B2HGJEFRSADB
795949_KGY734XFQJHX7JQ
795949_9MHVC6ZHYCQWJ8P
打开其主线程。
795949_GHJ97AK3FHGKEX6
然后就是Map目标32位进程,将自身PE模块给放入目标进程空间之中,然后修改OEP跳转到自身的执行入口,恢复线程。
795949_KPKEU6NFS5BXB2T

劫持的32位进程

这个是劫持后构建好的OEP。
795949_TSCXDMDXR59CQJ6
OEP实际跳转到的执行函数,可以看到还需要重新执行构造一次控制块,也就是会重新检查一下调试环境。
795949_6GS5B5EXQMD9Y43
从之前设置的环境变量中获取到原病毒文件的路径,之后会设置互斥体,将病毒文件重新载入内存之中。
795949_FBTM4VZJ2E2BENJ
构造删除原病毒文件的命令并使用cmd传参执行。
795949_XPGT4AEF4X3SXXB
之后会从programfile下随机构造路径,构造的路径字符串通常由一个随机大写字母加上六个随机字母作为次目录,然后获取某进程名后续添加4个字符构造文件名,然后构造copy命令。
795949_J9UFD6BPVDNAZQ4
设置错误模式,获取下一次进程镂空,线程劫持的入口,计算相关偏移。
795949_MFCWGMRT2S6E62X
之后获取当前的进程,遍历进程,通过进程名hash比较,劫持进程中的线程。
795949_PP2VU9RAYHT9V9N
795949_VAZW32YZ87VHYQB

再次劫持某进程。

劫持后的线程入口:
795949_VK8TVFEPYANZJK8
795949_9JXJD4FQJ5SE78U
先不分析了,这个样本有点肝。。。

0x04 小结

原本想随便找个样本继续练习练习,没想到随手找到的就是这么套娃的样本。
在这次样本分析之中,我花费了两天时间学习了Wow64ext技术,也就是32位注入64位进程、32位64位进程互读互写,但这个样本中并没有用到32位注入64位进程的技术;反正有所收获就很开心。

标签