首页
社区
课程
招聘
[原创]记一次银狐样本分析
发表于: 1天前 623

[原创]记一次银狐样本分析

1天前
623

最近突然心血来潮,想找个样本来分析一下,顺便学习了解一下免杀以及恶意样本的手法,在网上冲浪的时候找到了一个银狐样本,于是拿来分析一下

样本地址:WindowsEvent 病毒木马程序 - 吾爱破解 - 52pojie.cn

样本sha256:1443f7eb60ceebe8752cbfd4029023d8da975d087556af8247011ddd7bf2336f

将整个文件打包压缩,丢到沙箱看看情况

这里看一下沙箱跑出来的执行流程:

可以看到通过这个WindowsEvent.exe创建了命令行任务管理工具,然后外连下载。还有释放文件。

首先die查查成分:

目测就是使用汇编写的,然后没有导入表,那么可能通过PEB来获取外部函数地址了。废话不多说就直接进入分析。由于是汇编写的,这个入口非常的简单,大概就是下面这样:

首先通过init函数来进行初始化

通过decrypt_str函数来进行字符串解密,然后通过自定义的GetDllBase函数获取Kernel32.dll 的基址。然后通过自定义给GetProcAddress函数获取必要的API地址存放到全局变量当中。

这里来看看这个decrypt_str:

可以看到就是一个简单的异或解密,然后addr第一个元素是字符串的长度,这里直接写一个IDAPython脚本,然后解密一下:

解密之后的API信息如下:

通过GetDllBase这个函数来获取制定dll名的基址

这里通过PEB来获取InMemoryOrderModuleList,再通过遍历这个双向链表,然后比较BaseDllName来找到指定的dll,从而获取指定dll的基址。

GetProcAddress就是通过自解析PE结构的导出表,来获取到指定API的外部地址。

初始化完成之后会调用check_fileName来检查当前执行的这个文件的文件名是否有被修改:

这个函数比较字符的时候,会将获取到的字符转成大写,然后再进行比较。通过分析可以发现,仅仅只是对进程名当中的indo片进行了校验,只有在这个校验通过的时候才会返回1,否则返回0。然后进程退出

这里检查进程名可能是为了绕过分析。有些沙箱或者虚拟分析环境在运行样本时,进程名可能是随机生成的,或者带有特定字样。这里可能是在检测这些环境,并且进行绕过。

这个函数会尝试使用schtasks这个计划任务管理器来立即执行这个WinSafe的任务。不过本机上没有这个计划任务。可能是后续恶意代码执行之后才添加的,这里还不太清楚。

恶意程序通过这个函数来解密ShellCode并执行。

由于之前根据解密之后的字符串修复了一下全局变量的名称,这里看就非常的简单了。可以大体流程先是使用VirtualAlloc申请一个内存空间,然后将byte_400AA0这个位置的数据移动到申请的内存空间当中。接着就是对ShellCode当中的数据进行解密,解密算法就是有限域下先 (x + 119) ^ 0x62,最后在使用VirtualProtect修改内存权限,然后直接使用函数指针执行。

这里要注意一下,VirtualAllocVirtualProtect这两个函数的参数,通过参数可以分析在VirtualAllocVirtualProtect执行的过程中,申请的权限分别是可读可写可读可执行,而不是可读可写可执行。这样做的目的是绕过大部分杀软的检测。毕竟直接申请RWX内存是非常危险的操作。

通过分析知道了这个ShellCode的解密方法,那么就可以通过动态调试将这段shellCode dump下来分析,或者是直接获取数据然后解密写道文件当中。这里我选择后者,直接写一个IDAPython脚本来解密,然后顺便写到文件当中:

分析到这里,看起来这个exe已经没有其他逻辑了。

通过上述的分析,这个WindowsEvent.exe其实就是一个ShellCodeLoader,还需要对其中加载的ShellCode进行分析才行。

在使用IDAPython将ShellCode解密,并且写入文件之后,先进行一些信息收集。首先用strings看看能不能提取出来一些有用的字符串:

发现有些有趣的字符串,以及IP地址和域名。还有最下面一串看起来像是逆序了的结构化配置信息,这里使用python回复一下:

通过AI分析,这个字符串定义了这个样本的连接命令与控制服务器的全部参数,包含了三组独立的C2地址:

接下来将这个ShellCode文件丢到IDA当中进行分析

上来首先就是最常见的使用PEB获取DllBase,这里用来判断是否找到正确字符串的方法是 hash 校验,通过计算字符串的hash值与目标字符串的hash值比较,如果比较成功则表示找到了这个字符串,这个也是shellcode当中常见的混淆。

解决方法:解决这种混淆的方法也比较简单。这里有两种方法:

接着就是通过GetFuncByHash来获取API,

这一部分会逐步获取kernel32.dll 以及 ntdll.dll当中的一些API,具体如下:

这个函数是用来获取外部模块提供的API的,这个函数使用了两种方法来获取API。如果参数2传入的是0,则会自己解析导出表来计算函数地址。而另外一种情况是参数2传入一个函数地址,这个函数就会使用传入的这个函数来获取API地址:

上图的上半部分是解析导出表的代码,这里就不放出来了。根据上层函数的逻辑得出,在获取了GetProcAddress函数地址之后,后续的都是通过这个GetProcAddress函数来获取函数地址的。只不过在获取之前,还是会解析一遍导出表。

接下来这个部分,也是笔者第一次了解到,刚看到的时候还有点懵。后来想想是个很不错的设计,这里通过汇编看看逻辑

首先会调用这个gotoNextIns的函数,函数如下,只有短短的两个指令:

将栈顶的值放到eax寄存器当中,此时栈顶是返回地址,也就是这个xor ecx, ecx指令的地址。所以这个函数其实是用了一个非常巧妙的方法,来获取下一条指令的地址。


[培训]《冰与火的战歌:Windows内核攻防实战》!从零到实战,融合AI与Windows内核攻防全技术栈,打造具备自动化能力的内核开发高手。

最后于 1天前 被x0rrrrr编辑 ,原因:
收藏
免费 3
支持
分享
最新回复 (1)
雪    币: 155
活跃值: (4621)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
学习
19小时前
0
游客
登录 | 注册 方可回帖
返回