一、前言
大家好,我是来自顺丰安全成文实验室的一名老兵,代号“PX0”,我的任务是追踪威胁情报,深入分析最新黑灰产动向。近期,实验室捕获到一组“银狐”样本,经查,样本来源于伪装成主流会议软件的网站,网站通过提高搜索引擎的收录权重来诱骗用户下载该病毒软件。此前我也曾分析过“银狐”相关样本,但这回的新版本,免杀技术简直出神入化,主流的安全软件几乎拿它没辙。这让我心里直犯嘀咕:“难道真的有免杀界的高手‘叛变’,跑去给黑灰产当军师了?”不过别担心,接下来,就让我来带大家揭秘这位高手的免杀大招,再教大家几个怎么识别和防住它的高招!二、本文关注点
- 此银狐分支样本在出现阶段,主流沙箱、EDR几乎无法检测,本文主要分享新增部分功能
- 攻击者更加注重杀软和防御能力对抗,引入了bypass检测、防病毒模拟器检测、RPC构建持久化
- 样本的进化更倾向于多段的内存加载、运行时动态解密,后续可能会出现rootkit类型的完全隐蔽后门
- 根据样本的函数代码通用特征提取检测规则、检测思路分享
三、正文分析
1、加载过程
在近期捕获的一批样本中,初始投递的加载器代码几乎一致,攻击者通过最少的API调用完成第一阶段的shellcode加载 (对通用杀毒软件来说,敏感API调用越少,风险相对越小);shellcode加载完成后,通过内联jmp rbx跳转0x1B0000执行,这里其实是有一步mov的地址转移操作,作用是避免出现jmp rax的明显内存调用特征,在8月迭代样本也出现了其他的寄存器调用;2、解密过程
进入shellcode内部,实际只有call一个有效指令,后续的所有字节都是加密状态;这类似cobaltstrike睡眠解密,此类函数适合作为检测特征,区别是此函数需在程序启动时检测;解密函数即运行时的内部计算,进行了一系列循环右移、减法和取反操作,用于动态解密后续指令;经对比可以看出,右侧部分指令被解密,被解密出来的部分实际是一个新的异或解密函数;经过长期跟踪发现,此函数出现在银狐多个版本,为了更清楚地了解功能和检测,我们代码还原这个函数;unsigned char key = 0x91;
unsigned long shellcode_len = 0x9E15;
unsigned char *shellcode_ptr = (unsigned char *)0x18001F;
while (shellcode_len != 0) {
*(shellcode_ptr + shellcode_len) ^= key;
key += *(shellcode_ptr + shellcode_len);
shellcode_len--;
}
从内存可以看到整个倒序解密的过程,运行完成后,整块shellcode代码被解密完成;
3、环境检测、绕过
解密完成后首先进入sub_99A5函数,此函数集成一些bypass和环境检测能力,是对比以往样本的增强部分;首先是bypass ETW和AMSI,实现方式完全相同;都是通过patch到对应函数开头一个0x3C字节即ret指令,完成扫描、日志输出的代码跳过;4、模拟环境检测
微软防病毒为首次扫描的程序提供了特殊的二进制模拟器环境,会附带一些虚拟模块和预定返回值;接下来的几个check函数是关联性代码,整体功能是为了检测Defender模拟环境;
判断程序名,如果匹配v5数组中的:\myapp.exe(模拟进程名称,不是实际运行的进程)则退出进程;以下是对防病毒模拟器初始化功能的部分逆向代码(详细内容可以参考2018年 BlackHat);此函数使用两个未公开函数获取ntdll的导出表,并通过自定义ror算法计算apiHash(ntdll运行时模拟函数),如果命中任意3个Mpclient函数hash则返回错误码0xC0000462,再通过上层函数判断退出进程;分别调用Windows内核函数NtIsProcessInJob和NtCompressKey传入无效句柄,判断是否会返回虚拟模块的预定值,返回预期值则退出进程;
5、防御绕过
传入无效标识符,尝试动态加载COM类对象,判断返回值CLASS_E_CLASSNOTABAILABLE是否符合预期;在堆分配一块较大的内存空间,尝试是否可以成功,通过这种方式验证系统环境;调用VirtualAllocExNuma函数申请物理内存,此函数的运行环境要求存在多个物理CPU;判断SxIn.dll模块是否被当前进程加载(360沙箱的分析dll) ;获取SYSTEM_INFO结构体,该结构体包含系统的硬件信息 ,判断处理器数量;获取当前主机名,通过主机名字符创建互斥体对象,判断是否存在;获取令牌信息,判断进程是否能提升权限,尝试runas以管理员身份启动,进入死循环(用户未通过会无限弹窗)判断c:\\xxxx.ini文件是否存在,此文件默认由Gh0st后门创建;通过GetTickCount64函数来测量Sleep调用前后的时间差,判断环境是否加速,__rdtsc()函数同理;6、防御削弱
通过扫描进程列表、服务进程、检索窗口类综合判断360杀软是否存在,综合来看攻击者更倾向于个人电脑;通过API发送线程消息、控制信号尝试关闭360杀软,若失败跳转到后续代码下载BYOVD驱动模块结束杀软;检测WindowsDefender防病毒相关进程服务是否存在;
执行powershell命令添加C:\ProgramData和C:\User\Public目录到扫描排除项(后门存放路径),在8月的版本中会新增Program Files (x86)目录;攻击者整体使用凯撒密码对字符串解密,此算法比较简单,使用固定key进行逐字节移位;此处解密完成后得到存储桶地址;根据地址表下载一组后门文件,下载完成后根据偏移标识填入随机值,使得下载文件没有固定hash(在以往的样本中,银狐会通过多种方式实现此功能);下载后的文件会随机存储在C:\Users\Public目录,并在下层创建随机字符目录;在某些版本,会另外下载一组后门隐藏在C:\ProgramData目录中;下载BYOVD驱动模块,当进程权限不足时跳过此部分;payload下载完成后以内存dll形式解压,并获取导出函数指针,再使用RPC管道构建计划任务配置并调用NdrClientCall3函数创建,此任务用于维持BYOVD模块;此驱动漏洞属于EDR Killer类型,可以通过传入特定的控制码0x22E044和进程pid 在内核强制结束对应的进程;驱动内部会根据传入控制码触发调用,通过IOCTL(IO control codes)命令执行结束进程(支持Win11);7、后门远控
后门程序使用一组白加黑配合两个加密的payload文件, 这是银狐的惯用手法;dll使用VMProtect保护,运行后使用RC4算法对payload进行解密,完成后加载log.src文件,再次解密得到内存dll(VMProtect保护);获取内存dll的导出函数CLRCreateInstance,此函数内部会为后门程序创建持久化任务、禁用UAC等功能;最后会加载vcxproj后缀文件解密,完成后得到Gh0st变种后门,上线前会请求ip地址表,查看是否更新;Gh0st包含很多功能模块,具体功能此处不详细介绍了,后门还包含一些固定的cmd命令,适合作为检测补充;四、检测思路分享
- 可以通过程序中的加解密函数代码创建yara规则,代码结构最好连续且固定;
- 通过攻击者样本或实际应急过程中发现的TTPs作为检测特征;
- 在威胁情报痛苦金字塔的下三层中,域名相对更有效,也可根据情况选择hash检测;
B736A809E7A0F1603C97D43BBC7D2EA8A9CD080B
A672825339ADBB5EEEF8176D161266D4E4A4A625
E49938CB6C4CE0D73DB2B4A32018B1FF71A2D7F0
9CAA4EC93CE1CD40BD5975645A110A4325310A3B
D7F41D457C8358AF840B06914D1BC969EF7939D0
48B2090FDCEA7D7C0EB1544EBCDAF911796A7F67
omss.oss-cn-hangzhou.aliyuncs.com
upitem.oss-cn-hangzhou.aliyuncs.com
1o2.oss-cn-beijing.aliyuncs.com
25o.oss-cn-beijing.aliyuncs.com
98o.oss-cn-beijing.aliyuncs.com
vauwjw.net
cinskw.net
hucgiu.net
(针对样本的具体yara、TTPs规则等,后续将会同步到顺丰安全应急响应中心预推出的成文实验室知识星球,敬请期待!)