⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 policy.c

📁 臭氧层主动防御系统驱动源代码!臭氧层主动防御系统驱动源代码!
💻 C
📖 第 1 页 / 共 5 页
字号:
/*
 * Copyright (c) 2004 Security Architects Corporation. All rights reserved.
 *
 * Module Name:
 *
 *		policy.c
 *
 * Abstract:
 *
 *		This module implements various security policy parsing and enforcement routines.
 *
 * Author:
 *
 *		Eugene Tsyrklevich 16-Feb-2004
 *
 * Revision History:
 *
 *		None.
 */

// XXX rename all funcs as SpYYY ? (same for other modules?)

#include <NTDDK.h>
#include "policy.h"
#include "pathproc.h"
#include "procname.h"
#include "hookproc.h"
#include "media.h"
#include "learn.h"
#include "misc.h"
#include "i386.h"


#include "process.h"
#include "log.h"


BOOLEAN PolicyParseRule(OUT PSECURITY_POLICY pSecPolicy, IN PCHAR rule, OUT BOOLEAN *Critical);
BOOLEAN PolicyParsePolicyRule(OUT PSECURITY_POLICY pSecPolicy, IN PCHAR Operation, IN PCHAR rule, OUT BOOLEAN *Critical);
BOOLEAN PolicyParseObjectRule(PSECURITY_POLICY pSecPolicy, RULE_TYPE RuleType, PCHAR Operation, PCHAR rule);
BOOLEAN PolicyParseSyscallRule(PSECURITY_POLICY pSecPolicy, PCHAR SyscallName, PCHAR rule);
BOOLEAN	PolicyParseProtectionRule(PSECURITY_POLICY pSecPolicy, PCHAR Operation, PCHAR rule);
BOOLEAN	PolicyParseMediaRule(PSECURITY_POLICY pSecPolicy, PCHAR Operation, PCHAR rule);


#ifdef ALLOC_PRAGMA
#pragma alloc_text (INIT, InitPolicy)
#pragma alloc_text (PAGE, PolicyPostBootup)
#pragma alloc_text (PAGE, PolicyRemove)
#endif


/*
 * example:
 *
 * SystemRoot - \device\harddisk1\windows
 * SystemRootUnresolved - c:\windows
 * SystemRootDirectory - \windows
 * CDrive - \device\harddisk1
 */

CHAR			SystemDrive, SystemRoot[MAX_PATH], SystemRootUnresolved[MAX_PATH], *SystemRootDirectory, CDrive[MAX_PATH];
USHORT			SystemRootLength = 0, SystemRootUnresolvedLength = 0, SystemRootDirectoryLength = 0, CDriveLength = 0;

USHORT			gPolicyLineNumber;
PWSTR			gPolicyFilename, gFilePath;

// to be portable on 32 & 64 bit platforms
ULONG			NumberOfBitsInUlong, UlongBitShift;

/* LoadPolicy() can be used by only one thread at a time due to use of global variables */
KMUTEX			LoadPolicyMutex;

/* Global Security Policy */
SECURITY_POLICY	gSecPolicy;



/*
 * InitPolicy()
 *
 * Description:
 *		Initialize the policy engine. Load the global policy.
 *
 *		NOTE: Called once during driver initialization (DriverEntry()).
 *
 * Parameters:
 *		None.
 *
 * Returns:
 *		TRUE if everything is OK, FALSE if failed.
 */

BOOLEAN
InitPolicy()
{
	NumberOfBitsInUlong = sizeof(ULONG) * 8;
	UlongBitShift = sizeof(ULONG) == 4 ? 5 : 6;


	/* gets reinitialized correctly once bootup is complete (see PolicyPostBootup) */
	SystemDrive = 'C';

	if (ReadSymlinkValue(L"\\SystemRoot", SystemRootUnresolved, MAX_PATH) == FALSE)
	{
		LOG(LOG_SS_POLICY, LOG_PRIORITY_DEBUG, ("InitPolicy: ReadSymlinkValue failed\n"));
		return FALSE;
	}

	SystemRootUnresolvedLength = (USHORT) strlen(SystemRootUnresolved);

	ResolveFilename(SystemRootUnresolved, SystemRoot, MAX_PATH);


	/* extract the system directory name by itself (i.e. \windows) */
	SystemRootDirectory = strrchr(SystemRoot, '\\');

	if (SystemRootDirectory == NULL)
	{
		LOG(LOG_SS_POLICY, LOG_PRIORITY_DEBUG, ("InitPolicy: SystemRootDirectory is NULL\n"));
		return FALSE;
	}

	SystemRootDirectoryLength = (USHORT) strlen(SystemRootDirectory);


	if (ReadSymlinkValue(L"\\??\\C:", CDrive, MAX_PATH) == FALSE)
	{
		LOG(LOG_SS_POLICY, LOG_PRIORITY_DEBUG, ("InitPolicy: Failed to open C: symbolic link\n"));
		return FALSE;
	}

	CDriveLength = (USHORT) strlen(CDrive);


	if (PolicyPostBootup() == FALSE)
	{
		/*
		 * if boot process is not complete yet then we cannot get SystemRootUnresolved (i.e. c:\windows)
		 * because parts of registry are not initialized yet (see PolicyPostBootup)
		 *
		 * In that case, try to assemble SystemRootUnresolved manually
		 */

		SystemRootUnresolved[0] = SystemDrive;
		SystemRootUnresolved[1] = ':';

		strcpy(SystemRootUnresolved + 2, SystemRootDirectory);
	}


	LOG(LOG_SS_POLICY, LOG_PRIORITY_VERBOSE, ("InitPolicy: SystemRoot=%s (%s, %s)\n", SystemRoot, SystemRootUnresolved, SystemRootDirectory));


	KeInitializeMutex(&LoadPolicyMutex, 0);

	RtlZeroMemory(&gSecPolicy, sizeof(gSecPolicy));

	KeInitializeSpinLock(&gSecPolicy.SpinLock);


	if (LearningMode == TRUE)

		return TRUE;


	if (FindAndLoadSecurityPolicy(&gSecPolicy, L"computer", NULL) == FALSE)
	{
		LOG(LOG_SS_POLICY, LOG_PRIORITY_WARNING, ("InitPolicy: LoadSecurityPolicy(computer.policy) failed\n"));
		gSecPolicy.DefaultPolicyAction = ACTION_PERMIT_DEFAULT;
	}


	if (gSecPolicy.DefaultPolicyAction != ACTION_PERMIT_DEFAULT)
	{
		LOG(LOG_SS_POLICY, LOG_PRIORITY_WARNING, ("InitPolicy: Global policy default action must be permit\n"));
		gSecPolicy.DefaultPolicyAction = ACTION_PERMIT_DEFAULT;
	}


	return TRUE;
}



/*
 * PolicyPostBootup()
 *
 * Description:
 *		Finish initializing system variables once the bootup process is complete.
 *		We are unable to read the SystemRoot registry value before the bootup is complete since
 *		that part of the registry has not been initialized yet.
 *
 * Parameters:
 *		None.
 *
 * Returns:
 *		TRUE to indicate success, FALSE if failed.
 */

BOOLEAN
PolicyPostBootup()
{
	ASSERT(BootingUp == FALSE);


	if (ReadStringRegistryValueA(L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion", L"SystemRoot", SystemRootUnresolved, MAX_PATH) == FALSE)
	{
		LOG(LOG_SS_POLICY, LOG_PRIORITY_DEBUG, ("PolicyPostBootup: Failed to open SystemRoot registry key\n"));
		return FALSE;
	}

	SystemRootUnresolvedLength = (USHORT) strlen(SystemRootUnresolved);

	SystemDrive = (CHAR) toupper(SystemRootUnresolved[0]);


	return TRUE;
}



/*
 * PolicyRemove()
 *
 * Description:
 *		Shutdown the policy engine. Delete the global policy
 *
 * Parameters:
 *		None.
 *
 * Returns:
 *		Nothing.
 */

void
PolicyRemove()
{
	PolicyDelete(&gSecPolicy);
}



/*
 * PolicyDelete()
 *
 * Description:
 *		Delete a security policy. Free all the rules associated with a policy.
 *
 * Parameters:
 *		pSecPolicy - pointer to a security policy to delete.
 *
 * Returns:
 *		Nothing.
 */

void
PolicyDelete(IN PSECURITY_POLICY pSecPolicy)
{
	PPOLICY_RULE		r, tmp;
	KIRQL				irql;
	UCHAR				i;


	if (pSecPolicy == NULL)
	{
		LOG(LOG_SS_POLICY, LOG_PRIORITY_DEBUG, ("PolicyDelete: pSecPolicy is NULL\n"));
		return;
	}


	if (pSecPolicy->Initialized == FALSE)
	{
		LOG(LOG_SS_POLICY, LOG_PRIORITY_VERBOSE, ("PolicyDelete: pSecPolicy is not initialized\n"));
		return;
	}


	KeAcquireSpinLock(&pSecPolicy->SpinLock, &irql);

	for (i = 0; i < RULE_LASTONE; i++)
	{
		r = pSecPolicy->RuleList[i];

		while (r)
		{
			tmp = r;
			r = (PPOLICY_RULE) r->Next;

			ExFreePoolWithTag(tmp, _POOL_TAG);
		}
	}

	if (pSecPolicy->Name)
	{
		ExFreePoolWithTag(pSecPolicy->Name, _POOL_TAG);
		pSecPolicy->Name = NULL;
	}

	pSecPolicy->Initialized = FALSE;

	RtlZeroMemory(pSecPolicy->RuleList, sizeof(pSecPolicy->RuleList));


	KeReleaseSpinLock(&pSecPolicy->SpinLock, irql);
}



/*
 * LoadSecurityPolicy()
 *
 * Description:
 *		Parses and loads a security policy.
 *
 * Parameters:
 *		pSecPolicy - pointer to a security policy to initialize.
 *		PolicyFile - string containing the policy filename to parse
 *		FilePath - string containing full program path of the file we are loading policy for
 *
 * Returns:
 *		TRUE if security policy was successfully parsed and loaded, FALSE otherwise.
 */

BOOLEAN
LoadSecurityPolicy(OUT PSECURITY_POLICY pSecPolicy, IN PWSTR PolicyFile, IN PWSTR FilePath)
{
	OBJECT_ATTRIBUTES		oa;
	HANDLE					hFile = 0;
	UNICODE_STRING			usPolicyFile;
	ULONG					size;
	NTSTATUS				status;
	IO_STATUS_BLOCK			isb;
	CHAR					*p, buffer[POLICY_MAX_RULE_LENGTH];
	INT64					offset;
	BOOLEAN					ret = TRUE, Critical = FALSE;


	if (pSecPolicy == NULL || PolicyFile == NULL)
	{
		LOG(LOG_SS_POLICY, LOG_PRIORITY_DEBUG, ("LoadSecurityPolicy(%x, %x, %x): NULL parameter\n", pSecPolicy, PolicyFile, FilePath));
		return FALSE;
	}


	pSecPolicy->Initialized = FALSE;
	pSecPolicy->DefaultPolicyAction = ACTION_NONE;
	pSecPolicy->ProtectionFlags = BootingUp ? PROTECTION_ALL_OFF : PROTECTION_ALL_ON;


	RtlInitUnicodeString(&usPolicyFile, PolicyFile);

	LOG(LOG_SS_POLICY, LOG_PRIORITY_VERBOSE, ("LoadSecurityPolicy: Parsing %S\n", usPolicyFile.Buffer));


	InitializeObjectAttributes(&oa, &usPolicyFile, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);

	if (!NT_SUCCESS(ZwCreateFile(&hFile, GENERIC_READ, &oa, &isb,
									NULL, 0, FILE_SHARE_READ, FILE_OPEN,
									FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0)))
	{
		LOG(LOG_SS_POLICY, LOG_PRIORITY_VERBOSE, ("LoadSecurityPolicy: Failed to open file %S\n", usPolicyFile.Buffer));
		return FALSE;
	}


	offset = 0;
	buffer[0] = 0;


	/* only one thread at a time can use LoadPolicyMutex due to use of global variables (PolicyLineNumber, buffer) */
	KeWaitForMutexObject(&LoadPolicyMutex, Executive, KernelMode, FALSE, NULL);


	gPolicyLineNumber = 1;
	gPolicyFilename = usPolicyFile.Buffer;
	gFilePath = FilePath;

	while (1)
	{
		status = ZwReadFile(hFile, NULL, NULL, NULL, &isb, (PVOID) buffer, sizeof(buffer) - 1,
							(PLARGE_INTEGER) &offset, NULL);

		if (! NT_SUCCESS(status))
		{
			if (status != STATUS_END_OF_FILE)
			{
				LOG(LOG_SS_POLICY, LOG_PRIORITY_DEBUG, ("LoadSecurityPolicy: ZwReadFile failed rc=%x\n", status));
				ret = FALSE;
				PolicyDelete(pSecPolicy);
			}

			break;
		}

		if (isb.Information == 0)
			break;

		buffer[isb.Information] = '\0';

		/*
		 * strchr() will return NULL when the line we read exceeds the size of the buffer or
		 * the last line was not '\n' terminated
		 */

		if ((p = strchr(buffer, '\n')) == NULL)
		{
			/* don't try to parse very long lines */

			if (isb.Information == sizeof(buffer) - 1)
			{
				LOG(LOG_SS_POLICY_PARSER, LOG_PRIORITY_WARNING, ("LoadSecurityPolicy(%s:%d): Rule is too long\n", gPolicyFilename, gPolicyLineNumber));

				PolicyDelete(pSecPolicy);

				ret = FALSE;
				break;
			}


			/* the last rule was not '\n' terminated */

			if (PolicyParseRule(pSecPolicy, buffer, &Critical) == FALSE)
			{
				if (Critical == TRUE)
				{
					LOG(LOG_SS_POLICY_PARSER, LOG_PRIORITY_DEBUG, ("LoadSecurityPolicy(%S:%d): Encountered a critical error. Aborting.\n", gPolicyFilename, gPolicyLineNumber));

					PolicyDelete(pSecPolicy);

					ret = FALSE;
					break;
				}
			}
			
			ret = TRUE;

			break;
		}

		*p = 0;

		if (p != buffer && *(p - 1) == '\r')
			*(p - 1) = 0;


		if (PolicyParseRule(pSecPolicy, buffer, &Critical) == FALSE)
		{
			if (Critical == TRUE)
			{
				LOG(LOG_SS_POLICY_PARSER, LOG_PRIORITY_DEBUG, ("LoadSecurityPolicy(%S:%d): Encountered a critical error. Aborting.\n", gPolicyFilename, gPolicyLineNumber));

				PolicyDelete(pSecPolicy);

				ret = FALSE;
				break;
			}
		}


		offset += p - buffer + 1;


		if (++gPolicyLineNumber > 10000)
		{
			LOG(LOG_SS_POLICY_PARSER, LOG_PRIORITY_WARNING, ("LoadSecurityPolicy: Policy '%S' is too long. Maximum number of lines is 10000.\n", gPolicyFilename));

			PolicyDelete(pSecPolicy);

			ret = FALSE;
			break;
		}
	}

	ZwClose(hFile);


	if (ret != FALSE)
	{
		pSecPolicy->Initialized = TRUE;

		if (pSecPolicy->DefaultPolicyAction == ACTION_NONE)
			pSecPolicy->DefaultPolicyAction = DEFAULT_POLICY_ACTION;
	}


	LOG(LOG_SS_POLICY, LOG_PRIORITY_VERBOSE, ("LoadSecurityPolicy: Done Parsing %S. Total number of lines %d. (ret=%d)\n", usPolicyFile.Buffer, gPolicyLineNumber, ret));


	KeReleaseMutex(&LoadPolicyMutex, FALSE);


	return ret;
}



/*
 * FindAndLoadSecurityPolicy()
 *
 * Description:
 *		Finds and loads a security policy associated with a specified executable filename.
 *
 * Parameters:
 *		pSecPolicy - pointer to a security policy to initialize.
 *		FilePath - string specifying the complete path to an executable
 *		UserName - optional username, if specified check for a policy in "username" directory first
 *
 * Returns:
 *		TRUE if security policy was successfully parsed and loaded, FALSE otherwise.
 */

BOOLEAN
FindAndLoadSecurityPolicy(OUT PSECURITY_POLICY pSecPolicy, IN PWSTR FilePath, IN PWSTR UserName)
{
	PWSTR		filename;
	WCHAR		PolicyPath[MAX_PATH];
	BOOLEAN		ret;
	int			len;


	if (pSecPolicy == NULL || FilePath == NULL)
	{
		LOG(LOG_SS_POLICY, LOG_PRIORITY_DEBUG, ("FindAndLoadSecurityPolicy: NULL argument %x %x\n", pSecPolicy, FilePath));
		return FALSE;
	}


	if (KeGetCurrentIrql() != 0)
	{
		LOG(LOG_SS_POLICY, LOG_PRIORITY_DEBUG, ("FindAndLoadSecurityPolicy(): irql=%d\n", KeGetCurrentIrql()));
		return FALSE;
	}


	filename = wcsrchr(FilePath, L'\\');

	if (filename == NULL)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -