/* * SfcValidateFileHeader * * Purpose: * * Verify fileheader from retL packet. * */ BOOL SfcValidateFileHeader( HCRYPTPROV hCryptoProv, HCRYPTKEY hCryptKey, ZA_FILEHEADER *FileHeader ) { BOOL bResult, cond = FALSE; HCRYPTHASH hCryptHash = 0; MD5_CTX ctx; bResult = FALSE; do { if (!CryptCreateHash(hCryptoProv, CALG_MD5, 0, 0, &hCryptHash)) break; MD5Init(&ctx); MD5Update(&ctx, (UCHAR*)FileHeader, (UINT)3 * sizeof(ULONG)); MD5Final(&ctx); if (!CryptSetHashParam(hCryptHash, HP_HASHVAL, (const BYTE *)&ctx.digest, 0)) break; bResult = CryptVerifySignatureW(hCryptHash, (const BYTE *)&FileHeader->Signature, sizeof(FileHeader->Signature), hCryptKey, 0, 0); } while (cond); if (hCryptHash != 0) { CryptDestroyHash(hCryptHash); } return bResult; }
/* * SfcVerifyFile * * Purpose: * * Verify file to be legit ZeroAccess signed binary. * */ BOOL SfcVerifyFile( _In_ HCRYPTPROV hProv, _In_ HCRYPTKEY hKey, _In_ MD5_CTX *ctx, _In_ PBYTE Image, _In_ DWORD ImageSize ) { HCRYPTHASH lh_hash = 0; ULONG CRC, SignSize = 0; BYTE e_sign[128]; PBYTE p_resource_sign; PIMAGE_NT_HEADERS32 phdr; BOOL bResult = FALSE; LDR_RESOURCE_INFO resInfo; phdr = (PIMAGE_NT_HEADERS32)RtlImageNtHeader(Image); while (phdr != NULL) { resInfo.Type = (ULONG_PTR)RT_RCDATA; //type resInfo.Name = 1; //id resInfo.Lang = 0; //lang p_resource_sign = SfLdrQueryResourceDataEx(Image, &resInfo, &SignSize); if (p_resource_sign == NULL) break; if (SignSize != 128) break; if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &lh_hash)) break; CRC = phdr->OptionalHeader.CheckSum; memcpy(e_sign, p_resource_sign, sizeof(e_sign)); memset(p_resource_sign, 0, sizeof(e_sign)); phdr->OptionalHeader.CheckSum = 0; MD5Update(ctx, Image, ImageSize); phdr->OptionalHeader.CheckSum = CRC; memcpy(p_resource_sign, e_sign, sizeof(e_sign)); MD5Final(ctx); if (!CryptSetHashParam(lh_hash, HP_HASHVAL, (const BYTE *)&ctx->digest, 0)) { CryptDestroyHash(lh_hash); break; } bResult = CryptVerifySignatureW(lh_hash, (const BYTE *)&e_sign, sizeof(e_sign), hKey, 0, 0); CryptDestroyHash(lh_hash); break; } return bResult; }
//move to zacrypto.c //@@implemented in harusame VOID SfcZAVerifyFile( HCRYPTPROV hProv, HCRYPTKEY hKey, MD5_CTX *ctx, PBYTE Image, DWORD ImageSize ) { HCRYPTHASH lh_hash = 0; ULONG CRC, SignSize = 0; BYTE e_sign[128]; PBYTE p_resource_sign; PIMAGE_NT_HEADERS32 phdr; phdr = (PIMAGE_NT_HEADERS32)RtlImageNtHeader(Image); while (phdr != NULL) { p_resource_sign = SfuQueryResourceData(3, Image, &SignSize); if (p_resource_sign == NULL) break; if (SignSize != 128) break; if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &lh_hash)) break; CRC = phdr->OptionalHeader.CheckSum; memcpy(e_sign, p_resource_sign, sizeof(e_sign)); memset(p_resource_sign, 0, sizeof(e_sign)); phdr->OptionalHeader.CheckSum = 0; MD5Update(ctx, Image, ImageSize); phdr->OptionalHeader.CheckSum = CRC; memcpy(p_resource_sign, e_sign, sizeof(e_sign)); MD5Final(ctx); if (!CryptSetHashParam(lh_hash, HP_HASHVAL, (const BYTE *)&ctx->digest, 0)) { CryptDestroyHash(lh_hash); break; } CryptVerifySignatureW(lh_hash, (const BYTE *)&e_sign, sizeof(e_sign), hKey, 0, 0); break; } }
EXTERN_C BOOL PALAPI CryptVerifySignatureA( HCRYPTHASH hHash, CONST BYTE *pbSignature, DWORD dwSigLen, HCRYPTKEY hPubKey, LPCSTR szDescription, DWORD dwFlags) { _ASSERTE(szDescription == NULL); return CryptVerifySignatureW(hHash, pbSignature, dwSigLen, hPubKey, NULL, dwFlags); }