346 lines
10 KiB
C
346 lines
10 KiB
C
/* ___ _ _ _
|
|
* |_ _|_ _| |_ ___ _ _ _ _ __ _| | | |_ _ _ _ __ ___ ___
|
|
* | || ' \ _/ -_) '_| ' \/ _` | | | _| || | '_ \/ -_|_-<
|
|
* |___|_||_\__\___|_| |_||_\__,_|_| \__|\_, | .__/\___/__/
|
|
* |__/|_|
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
//
|
|
// SDK/WDK
|
|
//
|
|
#include <ntifs.h>
|
|
#include <ntintsafe.h>
|
|
#include <ntimage.h>
|
|
#include <bcrypt.h>
|
|
|
|
//
|
|
// Public
|
|
//
|
|
#include "Domito.h"
|
|
|
|
|
|
/* _ _ _ ___ _ _ _
|
|
* | \| | |_| \| | | ___| |_ __
|
|
* | .` | _| |) | | | / -_) _/ _|_
|
|
* |_|\_|\__|___/|_|_| \___|\__\__(_)
|
|
*
|
|
*/
|
|
|
|
// Structure representing a loaded module
|
|
typedef struct _SYSTEM_MODULE_INFORMATION_ENTRY
|
|
{
|
|
PVOID Unknown1;
|
|
PVOID Unknown2;
|
|
PVOID Base;
|
|
ULONG Size;
|
|
ULONG Flags;
|
|
USHORT Index;
|
|
USHORT NameLength;
|
|
USHORT LoadCount;
|
|
USHORT PathLength;
|
|
CHAR ImageName[256];
|
|
} SYSTEM_MODULE_INFORMATION_ENTRY, * PSYSTEM_MODULE_INFORMATION_ENTRY;
|
|
|
|
// Structure representing the loaded module information
|
|
typedef struct _SYSTEM_MODULE_INFORMATION
|
|
{
|
|
ULONG Count;
|
|
SYSTEM_MODULE_INFORMATION_ENTRY Module[ANYSIZE_ARRAY];
|
|
} SYSTEM_MODULE_INFORMATION, * PSYSTEM_MODULE_INFORMATION;
|
|
|
|
// Function prototype for ZwQuerySystemInformation
|
|
NTSYSAPI NTSTATUS NTAPI ZwQuerySystemInformation(
|
|
ULONG SystemInformationClass,
|
|
PVOID SystemInformation,
|
|
ULONG SystemInformationLength,
|
|
PULONG ReturnLength
|
|
);
|
|
|
|
typedef struct _LDR_DATA_TABLE_ENTRY
|
|
{
|
|
LIST_ENTRY64 InLoadOrderLinks;
|
|
PVOID ExceptionTable;
|
|
ULONG ExceptionTableSize;
|
|
PVOID GpValue;
|
|
PVOID NonPagedDebugInfo;
|
|
PVOID ImageBase;
|
|
PVOID EntryPoint;
|
|
ULONG SizeOfImage;
|
|
UNICODE_STRING FullImageName;
|
|
UNICODE_STRING BaseImageName;
|
|
ULONG Flags;
|
|
USHORT LoadCount;
|
|
USHORT TlsIndex;
|
|
LIST_ENTRY64 HashLinks;
|
|
PVOID SectionPointer;
|
|
ULONG CheckSum;
|
|
ULONG TimeDateStamp;
|
|
PVOID LoadedImports;
|
|
PVOID EntryPointActivationContext;
|
|
PVOID PatchInformation;
|
|
} LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY;
|
|
|
|
typedef PVOID(NTAPI* t_RtlImageDirectoryEntryToData)(
|
|
IN PVOID Base,
|
|
IN BOOLEAN MappedAsImage,
|
|
IN USHORT DirectoryEntry,
|
|
OUT PULONG Size
|
|
);
|
|
|
|
typedef NTSTATUS(*QUERY_INFO_PROCESS) (
|
|
__in HANDLE ProcessHandle,
|
|
__in PROCESSINFOCLASS ProcessInformationClass,
|
|
__out_bcount(ProcessInformationLength) PVOID ProcessInformation,
|
|
__in ULONG ProcessInformationLength,
|
|
__out_opt PULONG ReturnLength
|
|
);
|
|
|
|
/* __ __ __ __ _
|
|
* | \/ |___ _ __ ___ _ _ _ _ | \/ |__ _ _ _ __ _ __ _ ___ _ __ ___ _ _| |_
|
|
* | |\/| / -_) ' \/ _ \ '_| || | | |\/| / _` | ' \/ _` / _` / -_) ' \/ -_) ' \ _|
|
|
* |_| |_\___|_|_|_\___/_| \_, | |_| |_\__,_|_||_\__,_\__, \___|_|_|_\___|_||_\__|
|
|
* |__/ |___/
|
|
*/
|
|
|
|
//
|
|
// Default pool tag
|
|
//
|
|
#define DOMITO_POOL_TAG 'imoD'
|
|
|
|
//
|
|
// Function pointers for malloc/free variants
|
|
//
|
|
typedef struct
|
|
{
|
|
PFN_DOMITO_ALLOCATE_ROUTINE Allocate;
|
|
|
|
PFN_DOMITO_FREE_ROUTINE Free;
|
|
} DOMITO_MEMORY;
|
|
|
|
//
|
|
// Global instance, individual field can be adjusted by the caller
|
|
//
|
|
extern DOMITO_MEMORY G_Memory;
|
|
|
|
|
|
/* ___ _ ___ _ _ _
|
|
* / __|___ __| |___ |_ _|_ _| |_ ___ __ _ _ _(_) |_ _ _
|
|
* | (__/ _ \/ _` / -_) | || ' \ _/ -_) _` | '_| | _| || |
|
|
* \___\___/\__,_\___| |___|_||_\__\___\__, |_| |_|\__|\_, |
|
|
* |___/ |__/
|
|
*/
|
|
|
|
/**
|
|
* Resets a PolicyInfo struct - frees the dynamically allocated buffer in PolicyInfo (ChainInfo) if not null.
|
|
* Zeros the entire PolicyInfo struct.
|
|
*
|
|
* @param PolicyInfo - the struct to reset.
|
|
*
|
|
* @return the struct which was reset.
|
|
*/
|
|
_IRQL_requires_max_(PASSIVE_LEVEL)
|
|
typedef
|
|
PVOID
|
|
(NTAPI*
|
|
t_CiFreePolicyInfo)(
|
|
_Inout_ MINCRYPT_POLICY_INFO* PolicyInfo
|
|
);
|
|
|
|
|
|
/**
|
|
* Win7SP1-Win8.1 only (KB3033929 installed). Use CiValidateFileObject on Win10!
|
|
*
|
|
* Given a file digest and signature of a file, verify the signature and provide information regarding
|
|
* the certificates that was used for signing (the entire certificate chain)
|
|
*
|
|
* @param Hash - buffer containing the digest
|
|
*
|
|
* @param HashSize - size of the digest, e.g. 0x14(160bit) for SHA1, 0x20(256bit) for SHA256
|
|
*
|
|
* @param HashAlgId - digest algorithm identifier, e.g. CALG_SHA1(0x8004), CALG_SHA_256(0x800C)
|
|
*
|
|
* @param SecurityDirectory - pointer to the start of the security directory
|
|
*
|
|
* @param SizeOfSecurityDirectory - size the security directory
|
|
*
|
|
* @param PolicyInfo[out] - PolicyInfo containing information about the signer certificate chain
|
|
*
|
|
* @param SigningTime[out] - when the file was signed (FILETIME format)
|
|
*
|
|
* @param TimeStampPolicyInfo[out] - PolicyInfo containing information about the timestamping authority (TSA) certificate chain
|
|
*
|
|
* @return STATUS_SUCCESS if the file digest in the signature matches the given digest and the signer cetificate is verified.
|
|
* Various error values otherwise, for example:
|
|
* STATUS_INVALID_IMAGE_HASH - the digest does not match the digest in the signature
|
|
* STATUS_IMAGE_CERT_REVOKED - the certificate used for signing the file is revoked
|
|
* STATUS_IMAGE_CERT_EXPIRED - the certificate used for signing the file has expired
|
|
*/
|
|
_IRQL_requires_max_(PASSIVE_LEVEL)
|
|
typedef
|
|
NTSTATUS
|
|
(NTAPI*
|
|
t_CiCheckSignedFile)(
|
|
_In_ PVOID Hash,
|
|
_In_ UINT32 HashSize,
|
|
_In_ ALG_ID HashAlgId,
|
|
_In_ PVOID SecurityDirectory,
|
|
_In_ UINT32 SizeOfSecurityDirectory,
|
|
_Out_ MINCRYPT_POLICY_INFO* PolicyInfo,
|
|
_Out_ LARGE_INTEGER* SigningTime,
|
|
_Out_ MINCRYPT_POLICY_INFO* TimeStampPolicyInfo
|
|
);
|
|
|
|
|
|
/**
|
|
* Win7SP1-Win8.1 only (KB3033929 installed). Use CiValidateFileObject on Win10!
|
|
*
|
|
* Checks if the SHA-1 message digest is contained within a verified system catalog
|
|
*
|
|
* @note must be attached to the PsInitialSystemProcess first!
|
|
*
|
|
* @param Hash - buffer containing the digest
|
|
*
|
|
* @param HashSize - size of the digest, e.g. 0x14(160bit) for SHA1, 0x20(256bit) for SHA256
|
|
*
|
|
* @param HashAlgId - digest algorithm identifier, e.g. CALG_SHA1(0x8004), CALG_SHA_256(0x800C)
|
|
*
|
|
* @param IsReloadCatalogs - is reload catalogs cache.
|
|
*
|
|
* @param Always0 - this is for IsReloadCatalogs, Always0 != 0 ? 16 : 24;
|
|
*
|
|
* @param Always2007F - unknown, always 0x2007F, maybe a mask.
|
|
*
|
|
* @param PolicyInfo[out] - PolicyInfo containing information about the signer certificate chain.
|
|
*
|
|
* @param CatalogName[out option] - catalog file name.
|
|
*
|
|
* @param SigningTime[out] - when the file was signed (FILETIME format)
|
|
*
|
|
* @param TimeStampPolicyInfo[out] - PolicyInfo containing information about the timestamping authority (TSA) certificate chain.
|
|
*
|
|
* @return STATUS_SUCCESS if the file digest in the signature matches the given digest and the signer cetificate is verified.
|
|
* Various error values otherwise, for example:
|
|
* STATUS_INVALID_IMAGE_HASH - the digest does not match the digest in the signature
|
|
* STATUS_IMAGE_CERT_REVOKED - the certificate used for signing the file is revoked
|
|
* STATUS_IMAGE_CERT_EXPIRED - the certificate used for signing the file has expired
|
|
*/
|
|
_IRQL_requires_max_(PASSIVE_LEVEL)
|
|
typedef
|
|
NTSTATUS
|
|
(NTAPI*
|
|
t_CiVerifyHashInCatalog)(
|
|
_In_ PVOID Hash,
|
|
_In_ UINT32 HashSize,
|
|
_In_ ALG_ID HashAlgId,
|
|
_In_ BOOLEAN IsReloadCatalogs,
|
|
_In_ UINT32 Always0,
|
|
_In_ UINT32 Always2007F,
|
|
_Out_ MINCRYPT_POLICY_INFO* PolicyInfo,
|
|
_Out_opt_ UNICODE_STRING* CatalogName,
|
|
_Out_ LARGE_INTEGER* SigningTime,
|
|
_Out_ MINCRYPT_POLICY_INFO* TimeStampPolicyInfo
|
|
);
|
|
|
|
|
|
#if (NTDDI_VERSION >= NTDDI_WIN10)
|
|
|
|
/**
|
|
* Parse the publisher name from the certificate
|
|
*
|
|
* @param Certificate - &PolicyInfo.ChainInfo->ChainElements[x].Certificate
|
|
*
|
|
* @param AllocateRoutine - used to allocate PublisherName buffer.
|
|
*
|
|
* @param PublisherName[out] - publisher name.
|
|
*
|
|
* @return buffer length.
|
|
*/
|
|
typedef
|
|
NTSTATUS
|
|
(NTAPI*
|
|
t_CiGetCertPublisherName)(
|
|
_In_ MINCERT_BLOB* Certificate,
|
|
_In_ PMINCRYPT_ALLOCATE_ROUTINE AllocateRoutine,
|
|
_Out_ PUNICODE_STRING PublisherName
|
|
);
|
|
|
|
|
|
typedef
|
|
VOID
|
|
(NTAPI*
|
|
t_CiSetTrustedOriginClaimId)(
|
|
_In_ UINT32 ClaimId
|
|
);
|
|
|
|
/**
|
|
* Given a file object, verify the signature and provide information regarding
|
|
* the certificates that was used for signing (the entire certificate chain)
|
|
*
|
|
* @param FileObject - FileObject of the PE in question
|
|
*
|
|
* @param Unknown1 - unknown, 0 is a valid value. (Unknown1 and Unknown2 together calculate the minimum support algorithm)
|
|
*
|
|
* @param Unknown2 - unknown, 0 is a valid value. (^ the words above refer to 'CipGetHashAlgorithmForLegacyScenario')
|
|
*
|
|
* @param PolicyInfo[out] - PolicyInfo containing information about the signer certificate chain.
|
|
*
|
|
* @param TimeStampPolicyInfo[out] - PolicyInfo containing information about the timestamping authority (TSA) certificate chain.
|
|
*
|
|
* @param SigningTime[out] - when the file was signed (FILETIME format)
|
|
*
|
|
* @param Hash - buffer containing the digest
|
|
*
|
|
* @param HashSize - size of the digest, e.g. 0x14(160bit) for SHA1, 0x20(256bit) for SHA256
|
|
*
|
|
* @param HashAlgId - digest algorithm identifier, e.g. CALG_SHA1(0x8004), CALG_SHA_256(0x800C)
|
|
*
|
|
* @return STATUS_SUCCESS if the file digest in the signature matches the given digest and the signer cetificate is verified.
|
|
* Various error values otherwise, for example:
|
|
* STATUS_INVALID_IMAGE_HASH - the digest does not match the digest in the signature
|
|
* STATUS_IMAGE_CERT_REVOKED - the certificate used for signing the file is revoked
|
|
* STATUS_IMAGE_CERT_EXPIRED - the certificate used for signing the file has expired
|
|
*/
|
|
_IRQL_requires_max_(PASSIVE_LEVEL)
|
|
typedef
|
|
NTSTATUS
|
|
(NTAPI*
|
|
t_CiValidateFileObject)(
|
|
_In_ FILE_OBJECT* FileObject,
|
|
_In_opt_ UINT32 Unknown1,
|
|
_In_opt_ UINT32 Unknown2,
|
|
_Out_ MINCRYPT_POLICY_INFO* PolicyInfo,
|
|
_Out_ MINCRYPT_POLICY_INFO* TimeStampPolicyInfo,
|
|
_Out_ LARGE_INTEGER* SigningTime,
|
|
_Out_ UINT8* Hash,
|
|
_Inout_ UINT32* HashSize,
|
|
_Out_ ALG_ID* HashAlgId
|
|
);
|
|
|
|
#endif // NTDDI_VERSION >= NTDDI_WIN10
|
|
|
|
//
|
|
// Function pointers to CI.dll exports
|
|
//
|
|
typedef struct
|
|
{
|
|
t_CiFreePolicyInfo CiFreePolicyInfo;
|
|
|
|
t_CiCheckSignedFile CiCheckSignedFile;
|
|
|
|
t_CiVerifyHashInCatalog CiVerifyHashInCatalog;
|
|
|
|
t_CiGetCertPublisherName CiGetCertPublisherName;
|
|
|
|
t_CiSetTrustedOriginClaimId CiSetTrustedOriginClaimId;
|
|
|
|
t_CiValidateFileObject CiValidateFileObject;
|
|
|
|
} DOMITO_CODE_INTEGRITY;
|
|
|
|
//
|
|
// Global instance
|
|
//
|
|
extern DOMITO_CODE_INTEGRITY G_CI;
|