📄 policy.c
字号:
{
if (PolicyParseOnOffClause(rule, &OnOff) == FALSE)
return FALSE;
LOG(LOG_SS_POLICY_PARSER, LOG_PRIORITY_VERBOSE, ("PolicyParseProtectionRule: Turning overflow protection %s\n", OnOff ? "on" : "off"));
if (OnOff)
pSecPolicy->ProtectionFlags |= PROTECTION_OVERFLOW;
else
pSecPolicy->ProtectionFlags &= ~PROTECTION_OVERFLOW;
return TRUE;
}
if (strlen(Operation) == 8 && _stricmp(Operation, "userland") == 0)
{
if (PolicyParseOnOffClause(rule, &OnOff) == FALSE)
return FALSE;
LOG(LOG_SS_POLICY_PARSER, LOG_PRIORITY_VERBOSE, ("PolicyParseProtectionRule: Turning userland protection %s\n", OnOff ? "on" : "off"));
if (OnOff)
pSecPolicy->ProtectionFlags |= PROTECTION_USERLAND;
else
pSecPolicy->ProtectionFlags &= ~PROTECTION_USERLAND;
return TRUE;
}
if (strlen(Operation) == 9 && _stricmp(Operation, "debugging") == 0)
{
if (PolicyParseOnOffClause(rule, &OnOff) == FALSE)
return FALSE;
LOG(LOG_SS_POLICY_PARSER, LOG_PRIORITY_VERBOSE, ("PolicyParseProtectionRule: Turning debugging protection %s\n", OnOff ? "on" : "off"));
if (OnOff)
pSecPolicy->ProtectionFlags |= PROTECTION_DEBUGGING;
else
pSecPolicy->ProtectionFlags &= ~PROTECTION_DEBUGGING;
return TRUE;
}
if (strlen(Operation) == 5 && _stricmp(Operation, "dos16") == 0)
{
if (PolicyParseOnOffClause(rule, &OnOff) == FALSE)
return FALSE;
LOG(LOG_SS_POLICY_PARSER, LOG_PRIORITY_VERBOSE, ("PolicyParseProtectionRule: Turning dos16/vdm protection %s\n", OnOff ? "on" : "off"));
if (OnOff)
pSecPolicy->ProtectionFlags |= PROTECTION_VDM;
else
pSecPolicy->ProtectionFlags &= ~PROTECTION_VDM;
return TRUE;
}
if (strlen(Operation) == 8 && _stricmp(Operation, "keyboard") == 0)
{
if (PolicyParseOnOffClause(rule, &OnOff) == FALSE)
return FALSE;
LOG(LOG_SS_POLICY_PARSER, LOG_PRIORITY_VERBOSE, ("PolicyParseProtectionRule: Turning keyboard logger protection %s\n", OnOff ? "on" : "off"));
if (OnOff)
pSecPolicy->ProtectionFlags |= PROTECTION_KEYBOARD;
else
pSecPolicy->ProtectionFlags &= ~PROTECTION_KEYBOARD;
return TRUE;
}
if (strlen(Operation) == 5 && _stricmp(Operation, "modem") == 0)
{
if (PolicyParseOnOffClause(rule, &OnOff) == FALSE)
return FALSE;
LOG(LOG_SS_POLICY_PARSER, LOG_PRIORITY_VERBOSE, ("PolicyParseProtectionRule: Turning modem protection %s\n", OnOff ? "on" : "off"));
if (OnOff)
pSecPolicy->ProtectionFlags |= PROTECTION_MODEM;
else
pSecPolicy->ProtectionFlags &= ~PROTECTION_MODEM;
return TRUE;
}
if (strlen(Operation) == 7 && _stricmp(Operation, "sniffer") == 0)
{
if (PolicyParseOnOffClause(rule, &OnOff) == FALSE)
return FALSE;
LOG(LOG_SS_POLICY_PARSER, LOG_PRIORITY_VERBOSE, ("PolicyParseProtectionRule: Turning sniffer protection %s\n", OnOff ? "on" : "off"));
if (OnOff)
pSecPolicy->ProtectionFlags |= PROTECTION_SNIFFER;
else
pSecPolicy->ProtectionFlags &= ~PROTECTION_SNIFFER;
return TRUE;
}
if (strlen(Operation) == 9 && _stricmp(Operation, "extension") == 0)
{
if (PolicyParseOnOffClause(rule, &OnOff) == FALSE)
return FALSE;
LOG(LOG_SS_POLICY_PARSER, LOG_PRIORITY_VERBOSE, ("PolicyParseProtectionRule: Turning extension protection %s\n", OnOff ? "on" : "off"));
if (OnOff)
pSecPolicy->ProtectionFlags |= PROTECTION_EXTENSION;
else
pSecPolicy->ProtectionFlags &= ~PROTECTION_EXTENSION;
return TRUE;
}
if (strlen(Operation) == 3 && _stricmp(Operation, "all") == 0)
{
if (PolicyParseOnOffClause(rule, &OnOff) == FALSE)
return FALSE;
LOG(LOG_SS_POLICY_PARSER, LOG_PRIORITY_VERBOSE, ("PolicyParseProtectionRule: Turning all protection %s\n", OnOff ? "on" : "off"));
pSecPolicy->ProtectionFlags = OnOff == TRUE ? PROTECTION_ALL_ON : PROTECTION_ALL_OFF;
return TRUE;
}
ABORT_PolicyParseRule(("Invalid protection operation '%s'. Valid options are 'overflow', 'userland', 'debugging', 'dos16', 'keyboard', 'modem', 'sniffer', 'extension' and 'all'.\n", Operation));
}
/*
* PolicyParseMediaRule()
*
* Description:
* Parse a media rule.
*
* Parameters:
* pSecPolicy - security policy that the rule is going to be added to.
* Operation - ASCII operation. The only valid option is 'access'.
* Rule - ASCII rule to parse.
*
* Returns:
* Nothing.
*/
BOOLEAN
PolicyParseMediaRule(PSECURITY_POLICY pSecPolicy, PCHAR Operation, PCHAR rule)
{
if (pSecPolicy != &gSecPolicy)
{
LOG(LOG_SS_POLICY_PARSER, LOG_PRIORITY_WARNING, ("PolicyParseMediaRule: Media rules can be setup only in a global policy\n"));
return TRUE;
}
if (strlen(Operation) != 6 || _stricmp(Operation, "access") != 0)
ABORT_PolicyParseRule(("Invalid media operation '%s'. The only valid option is 'access'.\n", Operation));
if (strlen(rule) == 6 && _stricmp(rule, "permit") == 0)
{
MediaRemovableFlags = MEDIA_REMOVABLE_PERMIT;
return TRUE;
}
if (strlen(rule) == 4 && _stricmp(rule, "deny") == 0)
{
MediaRemovableFlags |= MEDIA_REMOVABLE_DISABLE;
return TRUE;
}
if (strlen(rule) == 8 && _stricmp(rule, "readonly") == 0)
{
MediaRemovableFlags |= MEDIA_REMOVABLE_READONLY;
return TRUE;
}
if (strlen(rule) == 9 && _stricmp(rule, "noexecute") == 0)
{
MediaRemovableFlags |= MEDIA_REMOVABLE_NOEXECUTE;
return TRUE;
}
ABORT_PolicyParseRule(("Expecting to see 'permit', 'deny', 'readonly', or 'noexecute' action. Got '%s'\n", rule));
}
/*
* InsertPolicyRule()
*
* Description:
* Adds a rule to a specified security policy (FIFO order).
*
* Parameters:
* pSecPolicy - security policy that the rule is going to be added to.
* PolicyRule - rule to add.
* RuleType - rule type (file, network, etc).
*
* Returns:
* Nothing.
*/
VOID
InsertPolicyRule(PSECURITY_POLICY pSecPolicy, PPOLICY_RULE PolicyRule, RULE_TYPE RuleType)
{
KIRQL irql;
PPOLICY_RULE tmp;
ASSERT(RuleType < RULE_LASTONE);
KeAcquireSpinLock(&pSecPolicy->SpinLock, &irql);
if (pSecPolicy->RuleList[RuleType] == NULL)
{
pSecPolicy->RuleList[RuleType] = PolicyRule;
KeReleaseSpinLock(&pSecPolicy->SpinLock, irql);
return;
}
/* find the last rule and link the new rule to it */
tmp = pSecPolicy->RuleList[RuleType];
while (tmp->Next)
{
tmp = tmp->Next;
}
tmp->Next = PolicyRule;
KeReleaseSpinLock(&pSecPolicy->SpinLock, irql);
}
/*
* PolicyParseObjectRule()
*
* Description:
* Parse an object rule of the following format:
* (name|address) (eq|match) "<objectname>" then (deny|quitedeny|permit|log)
* Rule can also consist of just (deny|quitedeny|permit|log)
*
* example1: name match "c:\file*" then deny
* example2: address eq "192.168.0.1" then log
* example3: quietdeny
*
* Parameters:
* pSecPolicy - security policy that the rule is going to be added to.
* RuleType - rule type (file, network, etc).
* Operation - ASCII operation (read, write, etc).
* Rule - ASCII rule to parse. NOTE: this field gets clobbered.
*
* Returns:
* Nothing.
*/
BOOLEAN
PolicyParseObjectRule(PSECURITY_POLICY pSecPolicy, RULE_TYPE RuleType, PCHAR Operation, PCHAR rule)
{
PCHAR name = NULL;
PCHAR OriginalRule = rule;
int i, TotalStars;
BOOLEAN wildcard, WildcardWarning = FALSE;
BOOLEAN ParseLastToken = FALSE;
ACTION_TYPE ActionType;
MATCH_TYPE MatchType;
PPOLICY_RULE PolicyRule;
UCHAR OperationType;
PCHAR ObjectName = NULL;
size_t ObjectSize = 0;
UCHAR RuleNumber;
LOG(LOG_SS_POLICY_PARSER, LOG_PRIORITY_VERBOSE, ("PolicyParseObjectRule: Parsing rule '%s': '%s'\n", Operation, rule));
/*
* First token can be "name" or "address" for network rules
* Alternatively, the entire rule can consist of an action clause (such as permit, deny, quietdeny or log)
*/
switch (VerifyToken2(&rule, "name", "address"))
{
/* matched token1 - "name" */
case 1: break;
/* matched token2 - "address" */
case 2:
{
/* only network rules can substitute "address" for "name" */
if (RuleType != RULE_NETWORK)
ABORT_PolicyParseRule(("Expecting to see 'name'. Got 'address'\n"));
break;
}
/* didn't match "name" or "address". try to parse as an action clause */
default:
{
ParseLastToken = TRUE;
goto ParseLastToken;
}
}
/*
* Second token should be "eq" or "match"
*/
switch (VerifyToken2(&rule, "eq", "match"))
{
/* matched token1 - "eq" */
case 1: wildcard = FALSE; break;
/* matched token2 - "match" */
case 2: wildcard = TRUE; break;
/* didn't match "eq" or "match" */
default: ABORT_PolicyParseRule(("Expecting to see 'eq' or 'match'. Got '%s'\n", rule));
}
/*
* Third token is the object names in quotes
*/
/* parse the object name surrounded by quotes: "<object name>" */
if (*rule++ != '"')
ABORT_PolicyParseRule(("Initial quote character not found. Object names should be surrounded by quotes.\n"));
name = rule;
TotalStars = i = 0;
while (*rule != 0 && *rule != '"')
{
if (i >= POLICY_MAX_OBJECT_NAME_LENGTH-1)
ABORT_PolicyParseRule(("Object name '%s' is too long.\nMaximum name length is %d characters.\n", rule - POLICY_MAX_OBJECT_NAME_LENGTH, POLICY_MAX_OBJECT_NAME_LENGTH));
// fail bad regexes
if (*rule == '*')
{
if (++TotalStars > POLICY_TOTAL_NUMBER_OF_STARS)
ABORT_PolicyParseRule(("Invalid regular expression. Maximum of %d stars are allowed\n", POLICY_TOTAL_NUMBER_OF_STARS));
}
if (wildcard == FALSE && (*rule == '*' || *rule == '?') && WildcardWarning == FALSE)
{
LOG(LOG_SS_POLICY_PARSER, LOG_PRIORITY_WARNING, ("%S:%d:\n", gPolicyFilename, gPolicyLineNumber));
LOG(LOG_SS_POLICY_PARSER, LOG_PRIORITY_WARNING, ("Found a regular expression with an 'eq' operator. Use 'match' operator to enable regular expressions.\n"));
WildcardWarning = TRUE;
}
++i;
++rule;
}
if (i == 0 || *rule++ != '"')
ABORT_PolicyParseRule(("Final quote character not found. Object names should be surrounded by quotes.\n"));
name[i] = 0;
if (! IS_WHITESPACE(*rule))
{
ABORT_PolicyParseRule(("Expecting to see white space. Got '%s'\n", rule));
}
SKIP_WHITESPACE(rule);
/*
* Fourth token is "then"
*/
if (VerifyToken2(&rule, "then", "") != 1)
ABORT_PolicyParseRule(("Expecting to see 'then'. Got '%s'\n", rule));
/*
* Fifth/Last token is "permit", "deny", "quietdeny", "log" or "ask"
*/
ParseLastToken:
if (PolicyParseActionClause(rule, &ActionType, &RuleNumber) == FALSE)
return FALSE;
/*
* Rule parsed ok. Create a new rule.
*/
if (RuleType > sizeof(ObjectParseOps) / sizeof(ObjectParseOps[0]))
ABORT_PolicyParseRule(("Invalid rule type\n"));
if (name)
{
if ((ObjectSize = ObjectParseOps[RuleType].ObjectNameParser(name, &ObjectName, &wildcard)) == INVALID_OBJECT_SIZE)
ABORT_PolicyParseRule(("Invalid object name '%s'\n", name));
MatchType = (wildcard == TRUE ? MATCH_WILDCARD : MATCH_SINGLE);
}
else
{
ObjectSize = 0;
MatchType = MATCH_ALL;
}
if ((OperationType = ObjectParseOps[RuleType].OperationTypeParser(Operation)) == OP_INVALID)
ABORT_PolicyParseRule(("Invalid operation '%s'\n", Operation));
/* POLICY_RULE already includes 1 character for the name buffer */
PolicyRule = ExAllocatePoolWithTag(NonPagedPool, sizeof(POLICY_RULE) + ObjectSize, _POOL_TAG);
if (PolicyRule == NULL)
{
LOG(LOG_SS_POLICY_PARSER, LOG_PRIORITY_WARNING, ("Object policy parser is out of memory\n"));
return FALSE;
}
RtlZeroMemory(PolicyRule, sizeof(POLICY_RULE));
PolicyRule->ActionType = ActionType;
PolicyRule->MatchType = MatchType;
PolicyRule->OperationType = OperationType;
PolicyRule->RuleNumber = RuleNumber;
PolicyRule->PolicyLineNumber = gPolicyLineNumber;
PolicyRule->pSecurityPolicy = pSecPolicy;
/* ObjectSize can be 0 for MATCH_ALL rules */
if (ObjectSize)
{
PolicyRule->NameLength = (USHORT) ObjectSize;
strcpy(PolicyRule->Name, (PCHAR) ObjectName);
}
/*
* Some rules (such as DLL) are actually enforced by different rules (i.e. section).
* If LearningMode = TRUE then there is no need to convert
*/
if (LearningMode == FALSE)
{
/* DLL rules are enforced by section rules. */
if (RuleType == RULE_DLL)
RuleType = RULE_SECTION;
/* Service rules are enforced by registry rules. */
if (RuleType == RULE_SERVICE)
RuleType = RULE_REGISTRY;
}
InsertPolicyRule(pSecPolicy, PolicyRule, RuleType);
return TRUE;
}
/*
* PolicyParseSyscallRule()
*
* Description:
* .
*
* Parameters:
* .
*
* Returns:
* Nothing.
*/
BOOLEAN
PolicyParseSyscallRule(PSECURITY_POLICY pSecPolicy, PCHAR SyscallName, PCHAR rule)
{
PPOLICY_RULE PolicyRule;
KIRQL irql;
ACTION_TYPE ActionType;
ULONG SyscallNameIndex;
BOOLEAN AcceptAll = FALSE;
#if HOOK_SYSCALLS
LOG(LOG_SS_POLICY_PARSER, LOG_PRIORITY_VERBOSE, ("PolicyParseSyscallRule: Parsing syscall '%s' rule: '%s'\n", SyscallName, rule));
/* expecting to see "permit", "deny", "quietdeny" or "log" */
if (PolicyParseActionClause(rule, &ActionType, NULL) == FALSE)
{
// LOG(LOG_SS_POLICY_PARSER, LOG_PRIORITY_DEBUG, ("PolicyParseSyscallRule: PolicyParseActionClause failed\n"));
return FALSE;
}
#if 0
/*
* all the special system calls such as OpenFile and CreateProce
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -