📄 policy.c
字号:
if (name[0] != '\\')
{
//XXX this is a hack, we are prepending to our buffer, knowing that there is space there
strcpy(name - 18, "\\Device\\Namedpipe");
*(name - 1) = '\\';
NamedpipeName = name - 18;
}
else
{
NamedpipeName = name;
}
*Object = NamedpipeName;
return strlen(NamedpipeName);
}
/*
* ParseDllObject()
*
* Description:
* Convert user land DLL object names into their kernel land equivalents.
* Since DLL rules are actually enforced by section rules, we just append DLL names to
* '\KnownDlls\' string which is used by section rules.
*
* Parameters:
* name - string value to parse.
* Object - pointer to an Object where the final result will be saved.
* wildcard - pointer to a BOOLEAN that will indicate whether the specified value contained any regular expressions.
*
* Returns:
* Length of the specified string value.
*/
size_t
ParseDllObject(IN PCHAR name, OUT PCHAR *Object, OUT BOOLEAN *wildcard)
{
PCHAR DllName;
/*
* if the DLL name does not start with a slash '\' then prepend '\KnownDlls\' to the name
*/
if (name[0] != '\\')
{
strcpy(name - 11, "\\KnownDlls");
*(name - 1) = '\\';
DllName = name - 11;
}
else
{
DllName = name;
}
*Object = DllName;
return strlen(DllName);
}
/*
* ParseTimeObject()
*
* Description:
* Time rule specifications are not supposed to have any object names specified.
* Return an error.
*
* Parameters:
* name - string value to parse.
* Object - pointer to an Object where the final result will be saved.
* wildcard - pointer to a BOOLEAN that will indicate whether the specified value contained any regular expressions.
*
* Returns:
* An error.
*/
size_t
ParseTimeObject(IN PCHAR name, OUT PCHAR *Object, OUT BOOLEAN *wildcard)
{
return INVALID_OBJECT_SIZE;
}
/*
* ParseServiceObject()
*
* Description:
* Convert user land service object names into their kernel land equivalents.
* Since service rules are actually enforced by registry rules, we just append service names
* to '\Registry\Machine\System\*ControlSet*\Services\' string which is used by registry rules.
*
* Parameters:
* name - string value to parse.
* Object - pointer to an Object where the final result will be saved.
* wildcard - pointer to a BOOLEAN that will indicate whether the specified value contained any regular expressions.
*
* Returns:
* Length of the specified string value.
* INVALID_OBJECT_SIZE is service name is too long.
*/
size_t
ParseServiceObject(IN PCHAR name, OUT PCHAR *Object, OUT BOOLEAN *wildcard)
{
static CHAR buffer[MAX_PATH] = { 0 }; //XXX not SMP safe
if (strlen(name) > 64)
{
return INVALID_OBJECT_SIZE;
}
strcpy(buffer, "\\Registry\\Machine\\System\\*ControlSet*\\Services\\");
strcat(buffer, name);
*wildcard = TRUE;
*Object = buffer;
return strlen(buffer);
}
typedef size_t (*OBJECT_PARSER)(IN PCHAR name, OUT PCHAR *Object, OUT BOOLEAN *wildcard);
typedef UCHAR (*OPERATION_TYPE_PARSER)(IN PCHAR name);
/* in C++ these would be member methods */
struct _ObjectParseOps
{
RULE_TYPE RuleType;
OBJECT_PARSER ObjectNameParser;
OPERATION_TYPE_PARSER OperationTypeParser;
} ObjectParseOps[] =
{
{ RULE_FILE, ParseFileObject, ParseObjectOperation },
{ RULE_DIRECTORY, ParseFileObject, ParseDirectoryOperation },
{ RULE_MAILSLOT, ParseMailslotObject, ParseObjectOperation },
{ RULE_NAMEDPIPE, ParseNamedpipeObject, ParseObjectOperation },
{ RULE_REGISTRY, ParseRegistryObject, ParseObjectOperation },
{ RULE_SECTION, ParseBaseNamedObjectsObject, ParseObjectOperation },
{ RULE_DLL, ParseDllObject, ParseDllOperation },
{ RULE_EVENT, ParseBaseNamedObjectsObject, ParseCreateOpenOperation },
{ RULE_SEMAPHORE, ParseBaseNamedObjectsObject, ParseCreateOpenOperation },
{ RULE_JOB, ParseBaseNamedObjectsObject, ParseCreateOpenOperation },
{ RULE_MUTANT, ParseBaseNamedObjectsObject, ParseCreateOpenOperation },
{ RULE_PORT, ParseStub, ParsePortOperation },
{ RULE_SYMLINK, ParseStub, ParseCreateOpenOperation },
{ RULE_TIMER, ParseBaseNamedObjectsObject, ParseCreateOpenOperation },
{ RULE_PROCESS, ParseProcessObject, ParseProcessOperation },
{ RULE_DRIVER, ParseProcessObject, ParseDriverOperation },
{ RULE_DIROBJ, ParseStub, ParseCreateOpenOperation },
{ RULE_ATOM, ParseStub, ParseAtomOperation },
{ RULE_NETWORK, ParseNetworkObject, ParseNetworkOperation },
{ RULE_SERVICE, ParseServiceObject, ParseServiceOperation },
{ RULE_TIME, ParseTimeObject, ParseTimeOperation },
{ RULE_TOKEN, ParseTimeObject, ParseTokenOperation },
};
/*
* PolicyParseActionClause()
*
* Description:
* .
*
* Parameters:
* .
*
* Returns:
* .
*/
BOOLEAN
PolicyParseActionClause(PCHAR rule, ACTION_TYPE *ActionType, UCHAR *RuleNumber)
{
UCHAR len = 0, num = 0;
SKIP_WHITESPACE(rule);
if (_strnicmp(rule, "permit", 6) == 0)
{
rule += 6;
*ActionType = ACTION_PERMIT;
}
else if (_strnicmp(rule, "deny", 4) == 0)
{
rule += 4;
*ActionType = ACTION_DENY;
}
else if (_strnicmp(rule, "quietdeny", 9) == 0)
{
rule += 9;
*ActionType = ACTION_QUIETDENY;
}
else if (_strnicmp(rule, "log", 3) == 0)
{
rule += 3;
*ActionType = ACTION_LOG;
}
else if (_strnicmp(rule, "ask", 3) == 0)
{
rule += 3;
*ActionType = ACTION_ASK;
}
else
{
ABORT_PolicyParseRule(("Expecting to see 'permit', 'deny', 'quitedeny', 'log' or 'ask' clause. Got '%s'\n", rule));
}
SKIP_WHITESPACE(rule);
/* EOL? */
if (*rule == 0)
{
if (RuleNumber)
*RuleNumber = 0;
return TRUE;
}
/* if it is not EOL then we expect to see "[rule DIGIT]" clause */
if (_strnicmp(rule, "[rule", 5) == 0)
{
rule += 5;
}
else
{
ABORT_PolicyParseRule(("Expecting to see a rule clause. Got '%s'\n", rule));
}
if (! IS_WHITESPACE(*rule))
{
ABORT_PolicyParseRule(("Expecting to see white space. Got '%s'\n", rule));
}
SKIP_WHITESPACE(rule);
/* parse the rule number (a decimal digit) */
while (*rule >= '0' && *rule <= '9')
{
/* don't overflow UCHAR values */
if (++len > 2)
{
ABORT_PolicyParseRule(("The rule number is too long.\n"));
}
num = num*10 + (*rule - '0');
++rule;
}
SKIP_WHITESPACE(rule);
if (*rule != ']')
{
ABORT_PolicyParseRule(("Invalid rule clause: '%s'\n", rule));
}
++rule;
SKIP_WHITESPACE(rule);
/* expecting an EOL */
if (*rule != 0)
{
ABORT_PolicyParseRule(("Expecting to see end of line. Got '%s'\n", rule));
}
if (RuleNumber)
*RuleNumber = num;
return TRUE;
}
/*
* PolicyParseOnOffClause()
*
* Description:
* .
*
* Parameters:
* .
*
* Returns:
* .
*/
BOOLEAN
PolicyParseOnOffClause(PCHAR rule, BOOLEAN *OnOff)
{
SKIP_WHITESPACE(rule);
if (_strnicmp(rule, "on", 2) == 0)
{
rule += 2;
*OnOff = TRUE;
}
else if (_strnicmp(rule, "off", 3) == 0)
{
rule += 3;
*OnOff = FALSE;
}
else
{
ABORT_PolicyParseRule(("Expecting to see 'on' or 'off' clause. Got '%s'\n", rule));
}
SKIP_WHITESPACE(rule);
/* expecting an EOL */
if (*rule != 0)
{
ABORT_PolicyParseRule(("Expecting to see end of line. Got '%s'\n", rule));
}
return TRUE;
}
/*
* VerifyToken2()
*
* Description:
* .
*
* Parameters:
* .
*
* Returns:
* .
*/
UCHAR
VerifyToken2(PCHAR *rule, PCHAR token1, PCHAR token2)
{
USHORT Token1Length, Token2Length;
ASSERT(rule && *rule);
ASSERT(token1);
ASSERT(token2);
SKIP_WHITESPACE(*rule);
Token1Length = (USHORT) strlen(token1);
Token2Length = (USHORT) strlen(token2);
if (_strnicmp(*rule, token1, Token1Length) == 0)
{
*rule += Token1Length;
if (! IS_WHITESPACE(**rule))
{
// LOG(LOG_SS_POLICY_PARSER, LOG_PRIORITY_WARNING, ("Expecting to see whitespace. Got '%s'\n", *rule));
return FALSE;
}
SKIP_WHITESPACE(*rule);
return 1;
}
if (_strnicmp(*rule, token2, Token2Length) == 0)
{
*rule += Token2Length;
if (! IS_WHITESPACE(**rule))
{
// LOG(LOG_SS_POLICY_PARSER, LOG_PRIORITY_WARNING, ("Expecting to see whitespace. Got '%s'\n", *rule));
return FALSE;
}
SKIP_WHITESPACE(*rule);
return 2;
}
return 0;
}
/*
* PolicyParsePolicyRule()
*
* Description:
* Parse a policy rule and adjust the policy default action.
*
* Parameters:
* pSecPolicy - security policy that the rule is going to be added to.
* Operation - ASCII operation (valid options are 'default' and 'path').
* Rule - ASCII rule to parse.
* Critical - Boolean indicating whether the parser should abort parsing the policy due to a critical error.
*
* Returns:
* Nothing.
*/
BOOLEAN
PolicyParsePolicyRule(OUT PSECURITY_POLICY pSecPolicy, IN PCHAR Operation, IN PCHAR rule, OUT BOOLEAN *Critical)
{
ACTION_TYPE ActionType;
UCHAR RuleNumber;
*Critical = FALSE;
if (strlen(Operation) == 7 && _stricmp(Operation, "default") == 0)
{
if (PolicyParseActionClause(rule, &ActionType, &RuleNumber) == FALSE)
ABORT_PolicyParseRule(("Invalid default policy action specification. Format: \"policy_default: (permit|deny|quietdeny|log|ask)\"\n"));
/* did we initialize default policy action already? */
if (pSecPolicy->DefaultPolicyAction != ACTION_NONE)
ABORT_PolicyParseRule(("Duplicate default policy action specification.\n"));
/* this still allows "policy_default: permit [rule 0]", oh well */
if (RuleNumber != 0)
ABORT_PolicyParseRule(("Rule clause cannot appear in default policy action specification.\n"));
pSecPolicy->DefaultPolicyAction = ActionType | ACTION_DEFAULT;
return TRUE;
}
if (strlen(Operation) == 4 && _stricmp(Operation, "path") == 0)
{
CHAR szPath[MAX_PATH];
CHAR szPolicyPath[MAX_PATH];
_snprintf(szPath, MAX_PATH, "%S", gFilePath);
szPath[MAX_PATH - 1] = 0;
rule = StripFileMacros(rule, szPolicyPath, MAX_PATH);
KdPrint(("%s\n%s\n", szPath, rule));
if (WildcardMatch(szPath, rule) == WILDCARD_MATCH)
{
KdPrint(("paths match\n"));
return TRUE;
}
if (LearningMode == FALSE)
*Critical = TRUE;
KdPrint(("paths do not match\n"));
return FALSE;
}
ABORT_PolicyParseRule(("Invalid policy operation '%s'. Valid options are 'default' and 'path'.\n", Operation));
}
/*
* PolicyParseProtectionRule()
*
* Description:
* Parse a protection rule and adjust the protection options such as buffer overflow protection
* and userland (dll injection) protection being on and off
*
* Parameters:
* pSecPolicy - security policy that the rule is going to be added to.
* Operation - ASCII operation. Valid options are 'overflow', 'userland', 'debugging', 'dos16', 'keyboard', 'modem', 'sniffer', 'extension' and 'all'.
* Rule - ASCII rule to parse.
*
* Returns:
* Nothing.
*/
BOOLEAN
PolicyParseProtectionRule(PSECURITY_POLICY pSecPolicy, PCHAR Operation, PCHAR rule)
{
BOOLEAN OnOff;
if (strlen(Operation) == 8 && _stricmp(Operation, "overflow") == 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -