Turla PNG Dropper回来了

PNG Dropper于2017年8月由Carbon Black研究人员首次发现。早在2017年,它就被用来分发Snake,但最近NCC集团的研究人员发现了一个新的有效载荷样本,我们在内部命名为RegRunnerSvc。

PNG Dropper

PNG Dropper17年被Carbon Black的研究团队做了详细研究。

dropper的目的是加载和运行隐藏在许多PNG文件中的PE文件。上图显示了dropper的资源。在这里,您可以看到名称为“PNG”的二进制数据资源条目。这些资源中的每一个都是有效的PNG文件,可以使用任何图像查看器查看,但在打开一个时,您只能看到几个彩色像素,见下图:

使用Microsoft的GDI +库加载PNG。在下图中,我们看到对LockBits的调用,该调用用于从PNG文件中读取像素数据。像素数据中的每个字节表示像素的RGB值。在每个RGB值中编码的是来自PE文件的字节。它并没有形成一个非常有意义的图像,但它是一种将数据隐藏在看似正常的资源中的新方法。

枚举每个PNG资源并提取像素数据,然后将它们连接在一起。结果是包含在内存中的整个PE文件。然后,dropper将手动加载PE文件。处理导入,重定位也是如此。最后执行PE文件的入口点(如下图所示)。

RegRunnerSvc

PNG dropper将从其PNG资源解码并运行RegRunnerSvc。RegRunnerSvc的目的是从注册表中提取加密的有效负载,将其加载到内存中,然后运行它。第一阶段的dropper(我们还没有设法获得)已经将它作为服务安装并执行了一些额外的设置操作。

下图显示了RegRunnerSvc的入口点。在这里,我们可以看到对StartServiceCtrlDispatcher的调用。在这种情况下,服务的名称是WerFaultSvc,显然是为了尝试看起来像Windows错误报告服务的合法部分而选择的。该服务还可用作恶意软件的持久性机制。

执行服务设置功能后,是时候在注册表中查找数据了。通常,注册表值的路径将存储为二进制文件中的(可能是加密/混淆的)字符串,但有趣的是,这不是这种情况。使用RegEnumKeyExA和RegEnumValueA函数枚举注册表项和值。枚举从HKEY_LOCAL_MACHINE键的根开始,并继续使用深度优先搜索,直到找到数据或枚举耗尽为止。另一个有趣的实现细节(如下图所示)是,要调用解密函数的唯一要求是值数据的大小为0x200(512)字节。这并不像它看起来那么低效,因为如果第一级滴管没有执行其设置操作,解密功能将相对快速地退出。然而,很明显,对于恶意软件作者来说,混淆比效率更重要。

注册表中的数据包含加密的有效负载和解密它所需的数据。它不包含解密密钥,但它确实包含用于生成密钥的数据。但是,此数据本身使用Microsoft CNG库函数(NCrypt *)进行部分加密。第一阶段的dropper将生成一个解密密钥,并将其存储在一个系统默认密钥存储提供程序中,在本例中为“Microsoft Software Key Storage Provider”。如果第一阶段dropper未运行,则密钥将不在存储提供程序中,并且解密函数将退出。如果存储提供程序实际包含密钥,则将解密数据的第一个0x200(512)字节。

现在头部信息已被解密,解密的第二部分可以发生。主要有效负载使用AES算法加密。首先,来自注册表的一大块数据被传递给BCryptGenerateSymmetricKey函数,这导致创建AES解密密钥。生成密钥并设置解密属性后,将解密有效负载。然后检查解密的有效负载以确保它是有效的PE文件(它检查MZ和PE魔术字节,并检查PE头中的机器体系结构条目)。如果检查通过,则手动加载文件(导入和重定位)并调用入口点(如下图所示)。

在这篇报告中,我们快速了解了Turla Group对PNG Dropper的新用法。该组现在正在使用一个新组件:RegRunnerSvc,它从注册表中提取并加密PE文件,对其进行解密并运行它。该小组似乎正在从无文件恶意软件中获取想法,例如Poweliks或Kovter。该组确保在二进制文件中尽可能少地留下信息,即不对包含加密数据的注册表项的名称进行硬编码。这意味着无法提取有用的IOC以进行威胁搜索。

YARA

rule turla_png_dropper {
    meta:
        author = "Ben Humphrey"
        description = "Detects the PNG Dropper used by the Turla group"
        sha256 = 
"6ed939f59476fd31dc4d99e96136e928fbd88aec0d9c59846092c0e93a3c0e27"

    strings:
        $api0 = "GdiplusStartup"
        $api1 = "GdipAlloc"
        $api2 = "GdipCreateBitmapFromStreamICM"
        $api3 = "GdipBitmapLockBits"
        $api4 = "GdipGetImageWidth"
        $api5 = "GdipGetImageHeight"
        $api6 = "GdiplusShutdown"

        $code32 = {
            8B 46 3C               // mov     eax, [esi+3Ch]
            B9 0B 01 00 00         // mov     ecx, 10Bh
            66 39 4C 30 18         // cmp     [eax+esi+18h], cx
            8B 44 30 28            // mov     eax, [eax+esi+28h]
            6A 00                  // push    0
            B9 AF BE AD DE         // mov     ecx, 0DEADBEAFh
            51                     // push    ecx
            51                     // push    ecx
            03 C6                  // add     eax, esi
            56                     // push    esi
            FF D0                  // call eax
        }

        $code64 = {
            48 63 43 3C            // movsxd rax, dword ptr [rbx+3Ch]
            B9 0B 01 00 00         // mov ecx, 10Bh
            BA AF BE AD DE         // mov edx, 0DEADBEAFh
            66 39 4C 18 18         // cmp [rax+rbx+18h], cx
            8B 44 18 28            // mov eax, [rax+rbx+28h]
            45 33 C9               // xor r9d, r9d
            44 8B C2               // mov r8d, edx
            48 8B CB               // mov rcx, rbx
            48 03 C3               // add rax, rbx
            FF D0                  // call rax
        }

    condition:
        (uint16(0) == 0x5A4D and uint16(uint32(0x3c)) == 0x4550) and
        all of ($api*) and 
        1 of ($code*)
}

rule turla_png_reg_enum_payload {
      meta:
                author = "Ben Humphrey"
                description = "Payload that has most recently been dropped by the
Turla PNG Dropper"
               shas256 =
"fea27eb2e939e930c8617dcf64366d1649988f30555f6ee9cd09fe54e4bc22b3"

      strings:
          $crypt00 = "Microsoft Software Key Storage Provider" wide
          $crypt01 = "ChainingModeCBC" wide
          $crypt02 = "AES" wide

      condition:
          (uint16(0) == 0x5A4D and uint16(uint32(0x3c)) == 0x4550) and
          pe.imports("advapi32.dll", "StartServiceCtrlDispatcherA") and 
          pe.imports("advapi32.dll", "RegEnumValueA") and 
          pe.imports("advapi32.dll", "RegEnumKeyExA") and 
          pe.imports("ncrypt.dll", "NCryptOpenStorageProvider") and 
          pe.imports("ncrypt.dll", "NCryptEnumKeys") and 
          pe.imports("ncrypt.dll", "NCryptOpenKey") and 
          pe.imports("ncrypt.dll", "NCryptDecrypt") and
          pe.imports("ncrypt.dll", "BCryptGenerateSymmetricKey") and 
          pe.imports("ncrypt.dll", "BCryptGetProperty") and 
          pe.imports("ncrypt.dll", "BCryptDecrypt") and 
          pe.imports("ncrypt.dll", "BCryptEncrypt") and 
          all of them
}

IOCs

  1. 6ed939f59476fd31dc4d99e96136e928fbd88aec0d9c59846092c0e93a3c0e27 (PNG Dropper)
  2. fea27eb2e939e930c8617dcf64366d1649988f30555f6ee9cd09fe54e4bc22b3 (Payload contained in the PNG dropper)

报告链接:https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2018/november/turla-png-dropper-is-back/

参考报告:https://www.carbonblack.com/2017/08/18/threat-analysis-carbon-black-threat-research-dissects-png-dropper/

发表评论

电子邮件地址不会被公开。 必填项已用*标注