freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

强对抗的 SquidLoader 针对中国企业发起攻击
2024-06-26 00:34:50

研究人员近期发现了一种高对抗强度的 Loader,其通过钓鱼邮件附件传递给受害者。根据恶意软件所具备的引诱和规避行为,研究人员将其命名为 SquidLoader。SquidLoader 最早在 2024 年 4 月下旬被发现,但研究人员认为其至少已经活跃了一个月以上。

SquidLoader 后续投递的是 Cobalt Strike,也都经过加强以对抗静态分析。根据 SquidLoader 的配置信息,研究人员发现过去两年中主要在针对讲中文的受害者进行攻击。攻击者的攻击技术与攻击策略有可能会被他人模仿,在不久的将来被其他攻击者应用到攻击其他受害者。

Loader 分析

2024 年 4 月下旬,研究人员观察到一些特别的钓鱼邮件附件,文件名为“华为工业级路由器相关产品介绍和优秀客户案例”。顺藤摸瓜发现一系列以中国企业/组织名称命名的恶意附件,如“中国移动集团XX分公司”、“嘉X智能科技”与“XX水利技术学院”。所有样本都使用 Word 文档的图标,吸引受害者打开这些文档文件,但实际上执行的是二进制文件。

这些 Loader 具备强大的引诱和规避能力,帮助恶意样本保持不被发现,也阻止分析人员进行分析。下载的 Shellcode 也加载进同一 Loader 中,不写入磁盘也降低了被发现的风险。

发现的大多数样本文件都使用合法的过期证书,使样本文件看起来很正常。使用证书之一是颁发给杭州瑛格科技有限公司的,在 2021 年 7 月 15 日到期。证书的指纹为 3F984B8706702DB13F26AE73BD4C591C5936344F,序列号为 02 0E B5 27 BA C0 10 99 59 3E 2E A9 02 E3 97 CB。当然,这并不是唯一的无效证书。

SquidLoader 使用的 C&C 服务器采用自签名证书,其签发者和主体都包含:

  • Common Name: localhost
  • Organizational Unit: group
  • Organization: Company
  • Locality: Nanjing
  • State/Province: Jiangsu
  • Country: CN

首次执行时,SquidLoader 会复制到特定位置(C:\BakFiles\install.exe),再从新位置重新启动。这可能是攻击者故意的,想通过不可疑的名称执行,因为 SquidLoader 并不具备任何持久化机制。只是后续投递的 Cobalt Strike 能够创建服务并修改注册表,可以实现攻击者的持久化目标。

Shellcode 通过 5 字节的异或密钥进行加密,密钥使用小端存储硬编码为 DE FF CC 8F 9A。

1719332758_667aef96a3c4a5d785a40.png!small?1719332758440

异或解码

尽管文件名和图片都模拟 Word 文档文件,但样本文件中包含大量引用微信或 mingw-gcc 等软件的代码,以此来误导研究人员。文件的元数据中也是如此,想让受害者相信恶意文件只是这些软件的合法组件。当然,这些代码永远不会被执行。

1719332776_667aefa8807fb0d6a9f85.png!small?1719332776425

其他代码

所有观察到的可执行文件都有类似于 Microsoft Office Word 的文档图标,样本文件还会弹出中文告警信息:

1719332790_667aefb6b9bdf75b0e9f5.png!small?1719332790381

告警信息

检测规避技术

SquidLoader 使用了大量的检测规避技术,此处简单列举几个:

使用无意义/模糊的指令

文件中包含模糊且无意义的 x86 指令,例如 pause、mfence 或 lfence。某些函数还包含填充指令,例如根本不使用的随机算术计算。这可能是攻击者想要破坏或者绕过反病毒模拟器的尝试,这些检测手段可能并未实现不太常见的指令,或者可能只能运行模拟指令。

加密代码段

恶意软件开始执行后立即加载内嵌的加密 Shellcode,在动态分配的内存段中进行解密,赋予该段执行权限并调用。加密算法是固定位移的单字节异或加密,如下所示。解密过程中还包括诱饵指令,进一步混淆代码,但没有实际用途。

1719332803_667aefc39287898e9fc6e.png!small?1719332803211

异或解密

栈内加密字符串

加密 Shellcode 中的敏感字符串都被异或加密作为局部变量嵌入函数体中,甚至会使用多字节异或密钥进行字符串解密。将字符串存储在栈中可以更轻松地隐藏特定信息,当栈更新时其内容将从内存中被删除。如下所示,恶意软件解密字符串获得 NtWriteVirtualMemory 后调用其 API。

1719332815_667aefcfa41a19dc8167f.png!small?1719332815450

加密变量

跳转指令

某些函数包含 call 或 jmp 指令,跳转到另一个函数内的地址,这使得反汇编程序对函数体产生错误的汇编。

如下所示。用 IDA 查看 14000770E+2 处无法得到正确的汇编输出。

1719332828_667aefdcd9297e4fec864.png!small?1719332828862

调用跳转

该地址被 IDA 认为在不同函数中间,140007710 甚至不会出现。

1719332839_667aefe7218dd7f031ecb.png!small?1719332838829

解析错误

手动标记函数起始位置后,IDA 才能够正确进行反汇编。

1719332853_667aeff57edbb38d4fe7b.png!small?1719332853339

修正解析结果

反汇编的隐藏函数位于 __scrt_common_main_seh函数中,调用的目标是解密和执行内嵌加载程序 Shellcode 的代码。但该函数是标准 C 编译器生成的,旨在启动 WinMain/main 函数。换句话说,此处不应该出现自定义代码。从 WinMain 开始的程序流程就完全被改变了。

返回地址混淆

负责加载和执行此前提到的 Shellcode 的代码也通过栈操作执行返回地址混淆。如下所示,代码中可以看到返回地址如何指向 __scrt_common_main_seh+14。在最后一个函数调用后,通过不正确的指令操作栈。这会使函数到达 retn 指令时,栈指向解密 Shellcode 地址作为返回地址,这种技术主要阻止分析人员进行分析。

1719332872_667af0086924661d7af19.png!small?1719332872472

原始返回地址

1719332887_667af0170fb42e1db80ff.png!small?1719332889371

实际返回地址

控制流图混淆

Shellcode 函数还使用了控制流图混淆,在无限循环中包含大量 Switch 语句。Switch 语句由变量进行控制,看似随机的值来选择下面要执行的分支。这种混淆方式使得不进行动态分析就不可能知道 Switch 语句是否会被执行。

控制流图混淆如下所示:

1719332901_667af025472544c571e92.png!small?1719332903029

控制流图混淆

调试器检测

Loader 使用了三种方法检测调试器,一旦发现就会执行非法指令触发崩溃。

  • 检查已知调试器进程名称列表。通过 SystemProcessInformation (0x5) 调用 NtQuerySystemInformation 获取正在运行的进程列表。检查的进程包括:
Ida64.exe
Ida.exe
DbgX.Shell
Windbg.exe
X32dbg.exe
X64dbg.exe
Olldbg.exe

1719332921_667af03953719dcd6e6e1.png!small?1719332921985

进程检查

  • 调用 NtQueryInformationProcess 并使用未记录的 0x1e 作为 ProcessInformationClass 参数的值来查找附加到正在运行进程的调试器。如果存在会返回调试对象
NtQueryInformationProcess (in: ProcessHandle=0xffffffffffffffff, ProcessInformationClass=0x1e, ProcessInformation=0x26ce8ff788, ProcessInformationLength=0x8, ReturnLength=0x26ce8ff788 | out: ProcessInformation=0x26ce8ff788, ReturnLength=0x26ce8ff788) returned 0xc0000353
  • 通过使用 SystemKernelDebuggerInformation (0x23) 系统信息类调用 NtQuerySystemInformation 来查找内核调试器的存在
NtQuerySystemInformation (in: SystemInformationClass=0x23, SystemInformation=0x26ce8ff388, Length=0x2, ResultLength=0x0 | out: SystemInformation=0x26ce8ff388, ResultLength=0x0) returned 0x0

一旦检测到调试器,不仅触发自身程序崩溃,还会将 WinHttpConnect 替换为自己代码的入口点。这样 Loader 就不能正常加载库文件,也就不能正常连接 C&C 服务器,避免暴露。

1719332949_667af055d6706cb4bd6a1.png!small?1719332951989

代码变更

文件检查

Loader 检测以下几个文件是否存在,存在文件的话即会退出:

  • C:\temp\diskpartScript.txt
  • C:\Users\Admin\My Pictures\My Wallpaper.jpg
  • C:\Program Files (x86)\Google\Chrome\Application\chrome.exe

执行直接系统调用

攻击者尽量避免调用 Windows NT API,直接执行自己实现的系统调用。攻击者创建了多个 NT API 的 Wrapper,每个 NT API 都对应一个 Wrapper。如下所示,为具有四个参数的 NT API Wrapper:

1719332965_667af06519537db5a57a9.png!small?1719332966167

NT API Wrapper

Wrapper 解析 NtQuerySystemInformation,后续通过 jump_to_syscall 指令将给定的系统调用号移动到 EAX 并执行跳转 NtQuerySystemInformation+12。这样完全避免使用 NT API,也就绕过了很多检测 Hook 点位,也就不会在执行日志中现形。

1719332987_667af07bc1b884f69a19a.png!small?1719332987529

jump_to_syscall 函数体

1719333002_667af08a240aa4d6c1080.png!small?1719333006626

jmp 指令跳转 syscall 指令

Payload

分析人员只观察到了使用相同 CFG 混淆的 Cobalt Strike,很可能是出自相同攻击者之手。但其中并不包含反调试和反虚拟机技术,可能攻击者认为 Loader 已经确认过。

恶意样本模拟 Kubernetes 流量,向 /api/v1/pods 发起 GET 请求。如果 C&C 服务器没有响应或者不是预期响应,Payload 就会无限循环 ping C&C 服务器。

1719333015_667af097db54edf923f91.png!small?1719333015848

C&C 请求

头字段 X-Method 有三个可能值:

  • con:回连上线
  • snd:回传信息
  • rcv:接收任务

Cobalt Strike 读取 C&C 服务器的响应信息,进行检查:

  • HTTP 响应代码 200
  • 存在 X-Session

满足条件时,恶意软件收集失陷主机信息并通过 /api/v1/pods 的 POST 请求回传 C&C 服务器。收集的信息很多,例如用户名、计算机名称、ACP、OEMCP 与网络接口 IP 地址等。

1719333035_667af0ab24f69ffc6bdad.png!small?1719333037255

收集信息

窃取的信息会加密发送:

1719333049_667af0b940aa13a1df819.png!small?1719333049510

失陷主机信息

窃取系统信息后,向 C&C 服务器发送的 HTTP GET 请求再执行任务。通过 C&C 信道以加密形式发送要执行的指令,加密算法存在大量的位运算。

1719333075_667af0d3df4759df48a14.png!small?1719333077126

加密方式

Win32 API 混淆

因为 Payload 需要与位置无关,因此 Win API 导入需要动态解析。恶意软件在内存中创建包含所需的所有 API 函数地址的表,并不存储函数的直接地址,而是存储 ~(_DWORD) api_addr & 0xCAFECAFE | api_addr & 0xFFFFFFFF35013501 的结果值。

1719333085_667af0dd652e37e3b43ae.png!small?1719333085169

存储地址

调用 API 前要撤销此操作,API 调用如下所示:

1719333098_667af0ea309edcd3826e1.png!small?1719333098206

展开并调用

结论

SquidLoader 明显具备很强的对抗检测能力,两年多一直使用相似的攻击手段针对讲中文的受害者。

参考来源

LevelBlue

# 后门 # 木马 # 数据窃密
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者
文章目录