Added DomitoValidateFileLegacyMode

This commit is contained in:
Benjamin Höglinger-Stelzer 2023-07-01 07:03:25 +02:00
parent c3b0116581
commit ad92db405c
2 changed files with 178 additions and 10 deletions

View File

@ -30,12 +30,13 @@ typedef EVT_DOMITO_ALLOCATE_ROUTINE* PFN_DOMITO_ALLOCATE_ROUTINE;
// This structure encapsulates a signature used in verifying executable files.
//
#if !defined(WIN_CERTIFICATE)
typedef struct _WIN_CERTIFICATE {
typedef struct _WIN_CERTIFICATE
{
DWORD dwLength;
WORD wRevision;
WORD wCertificateType;
BYTE bCertificate[ANYSIZE_ARRAY];
} WIN_CERTIFICATE, * LPWIN_CERTIFICATE;
} WIN_CERTIFICATE, *LPWIN_CERTIFICATE;
#endif
//
@ -103,9 +104,9 @@ _IRQL_requires_max_(PASSIVE_LEVEL)
EXTERN_C
NTSTATUS
DomitoFindModuleBaseAddress(
_In_ STRING ModuleName,
_In_ PFN_DOMITO_ALLOCATE_ROUTINE Allocator,
_Inout_opt_ PVOID * ModuleBase
_In_ STRING ModuleName,
_Inout_opt_ PVOID* ModuleBase
);
//
@ -119,7 +120,7 @@ NTSTATUS
DomitoFindExportedFunctionAddress(
_In_ PVOID ModuleBase,
_In_ STRING FunctionName,
_Inout_opt_ PVOID * FunctionAddress
_Inout_opt_ PVOID* FunctionAddress
);
//
@ -136,7 +137,7 @@ DomitoMemorySearchPattern(
_In_ SIZE_T puLen,
_In_ PVOID pcBase,
_In_ SIZE_T puSize,
_Outptr_result_maybenull_ PVOID * ppMatch
_Outptr_result_maybenull_ PVOID* ppMatch
);
//
@ -197,3 +198,20 @@ DomitoGetProcessImageName(
_In_ ULONG ProcessId,
_Inout_ PUNICODE_STRING* ProcessImageName
);
_Success_(return == STATUS_SUCCESS)
_Must_inspect_result_
_IRQL_requires_max_(PASSIVE_LEVEL)
EXTERN_C
NTSTATUS
DomitoValidateFileLegacyMode(
_In_ PFN_DOMITO_ALLOCATE_ROUTINE Allocator,
_In_ HANDLE FileHandle,
_In_ PVOID Hash,
_In_ UINT32 HashSize,
_In_ ALG_ID HashAlgId,
_In_ const IMAGE_DATA_DIRECTORY* SecurityDirectory,
_Inout_ MINCRYPT_POLICY_INFO* PolicyInfo,
_Out_ LARGE_INTEGER* SigningTime,
_Inout_ MINCRYPT_POLICY_INFO* TimeStampPolicyInfo
);

View File

@ -84,8 +84,8 @@ _Must_inspect_result_
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS
DomitoFindModuleBaseAddress(
_In_ STRING ModuleName,
_In_ PFN_DOMITO_ALLOCATE_ROUTINE Allocator,
_In_ STRING ModuleName,
_Inout_opt_ PVOID * ModuleBase
)
{
@ -760,3 +760,153 @@ cleanUp:
return status;
}
#pragma code_seg()
_Success_(return == STATUS_SUCCESS)
_Must_inspect_result_
_IRQL_requires_max_(PASSIVE_LEVEL)
#pragma code_seg("PAGED")
NTSTATUS
DomitoValidateFileLegacyMode(
_In_ PFN_DOMITO_ALLOCATE_ROUTINE Allocator,
_In_ HANDLE FileHandle,
_In_ PVOID Hash,
_In_ UINT32 HashSize,
_In_ ALG_ID HashAlgId,
_In_ const IMAGE_DATA_DIRECTORY * SecurityDirectory,
_Inout_ MINCRYPT_POLICY_INFO * PolicyInfo,
_Out_ LARGE_INTEGER * SigningTime,
_Inout_ MINCRYPT_POLICY_INFO * TimeStampPolicyInfo
)
{
PAGED_CODE();
NTSTATUS status = STATUS_SUCCESS;
PVOID certDirectory = nullptr;
KAPC_STATE systemContext = {};
do
{
SigningTime->QuadPart = 0;
CiFreePolicyInfo(PolicyInfo);
CiFreePolicyInfo(TimeStampPolicyInfo);
if (HashSize != MINCRYPT_SHA1_LENGTH)
{
status = STATUS_INVALID_IMAGE_HASH;
break;
}
if (SecurityDirectory->Size != 0u &&
SecurityDirectory->VirtualAddress != 0u)
{
certDirectory = Allocator(SecurityDirectory->Size);
if (certDirectory == NULL)
{
status = STATUS_INSUFFICIENT_RESOURCES;
break;
}
LARGE_INTEGER offset = {};
IO_STATUS_BLOCK ioStatusBlock = {};
offset.LowPart = SecurityDirectory->VirtualAddress;
status = ZwReadFile(
FileHandle,
NULL,
NULL,
NULL,
&ioStatusBlock,
certDirectory,
SecurityDirectory->Size,
&offset,
NULL
);
if (status == STATUS_PENDING)
{
ZwWaitForSingleObject(
FileHandle,
FALSE,
NULL
);
MemoryBarrier();
status = ioStatusBlock.Status;
}
if (!NT_SUCCESS(status))
{
break;
}
KeStackAttachProcess(PsInitialSystemProcess, &systemContext);
{
status = CiCheckSignedFile(
Hash,
HashSize,
HashAlgId,
certDirectory,
SecurityDirectory->Size,
PolicyInfo,
SigningTime,
TimeStampPolicyInfo
);
}
KeUnstackDetachProcess(&systemContext);
if (NT_SUCCESS(status))
{
break;
}
if (status != STATUS_INVALID_IMAGE_HASH)
{
break;
}
}
KeStackAttachProcess(PsInitialSystemProcess, &systemContext);
{
status = CiVerifyHashInCatalog(
Hash,
HashSize,
HashAlgId,
FALSE,
0,
0x2007F,
PolicyInfo,
NULL,
SigningTime,
TimeStampPolicyInfo
);
if (status == STATUS_INVALID_IMAGE_HASH)
{
status = CiVerifyHashInCatalog(
Hash,
HashSize,
HashAlgId,
TRUE,
0,
0x2007F,
PolicyInfo,
NULL,
SigningTime,
TimeStampPolicyInfo
);
}
}
KeUnstackDetachProcess(&systemContext);
} while (FALSE);
if (certDirectory)
{
ExFreePool(certDirectory);
}
return status;
}
#pragma code_seg()