windows Access Token 、ACL、ACE学习笔记

今日看了看关于windows本身安全机制的一些文章,所以将自己掌握到的一些东西供大家探讨一下。

 

1. Access Token

  windows访问令牌记录着某用户的SID、组ID、Session、及权限等信息,要获取这些信息,可以通过GetTokenInformation API获得。以下是一些代码样例

#define GETATTRI(desc, attri, check) \
if (attri & check)\
{\
	if (desc!=_T(""))\
	{\
		desc += _T(" | ");\
	}\
	desc+=_T(#check);\
}

#define MAKESIDDESC(type) {type, _T(#type)}

struct SIDNameDesc 
{
	SID_NAME_USE type;
	TCHAR* desc;
};

SIDNameDesc gvSidUseType[]=
{
	MAKESIDDESC(SidTypeUser),
	MAKESIDDESC(SidTypeGroup),
	MAKESIDDESC(SidTypeDomain),
	MAKESIDDESC(SidTypeAlias),
	MAKESIDDESC(SidTypeWellKnownGroup),
	MAKESIDDESC(SidTypeDeletedAccount),
	MAKESIDDESC(SidTypeInvalid),
	MAKESIDDESC(SidTypeUnknown),
	MAKESIDDESC(SidTypeComputer),
	MAKESIDDESC(SidTypeLabel),
};

TCHAR* GetSidNameUseDescription(SID_NAME_USE type)
{
	TCHAR* pDesc=NULL;
	int count = sizeof(gvSidUseType) / sizeof(SIDNameDesc);
	for (int i=0;iUser.Sid);
	dump(pUser->User.Attributes);
}


void GetTokenGroup(HANDLE hToken)
{
	DWORD dwReturnedLen=0;
	GetTokenInformation(hToken, TokenGroups, NULL, NULL, &dwReturnedLen);
	if (GetLastError()!=ERROR_INSUFFICIENT_BUFFER)
	{
		cout<<"GetTokenInformation failed with "<GroupCount;i++)
	{
		dump(pGroup->Groups[i].Sid);
		dump(pGroup->Groups[i].Attributes);
		cout<PrivilegeCount;i++)
	{
		dump(pPrivileges->Privileges[i]);
	}
}

void GetOwnerInfo(HANDLE hToken)
{
	DWORD dwReturnedLen=0;
	GetTokenInformation(hToken, TokenOwner, NULL, NULL, &dwReturnedLen);
	if (GetLastError()!=ERROR_INSUFFICIENT_BUFFER)
	{
		cout<<"GetTokenInformation failed with "<Owner);
}


void GetPrimaryGroup(HANDLE hToken)
{
	DWORD dwReturnedLen=0;
	GetTokenInformation(hToken, TokenPrimaryGroup, NULL, NULL, &dwReturnedLen);
	if (GetLastError()!=ERROR_INSUFFICIENT_BUFFER)
	{
		cout<<"GetTokenInformation failed with "<PrimaryGroup);
}

void Print(LPCSTR desc, LUID luid)
{
	LARGE_INTEGER* pli = (LARGE_INTEGER*)&luid;
	cout<QuadPart<TokenId);
	Print("AuthenticationId", pStatistics->AuthenticationId);
	if (pStatistics->TokenType == TokenPrimary)
	{
		cout<<"Primary Token"<SourceName<SourceIdentifier);
}

void GetTokenSessionID(HANDLE hToken)
{
	DWORD dwReturnedLen=0;
	DWORD sessionID;
	if(!GetTokenInformation(hToken, TokenSessionId, &sessionID, sizeof(DWORD), &dwReturnedLen))
	{
		cout<<"GetTokenInformation failed with "<


大家知道在Win7上管理员登录后会关联两个Access Token,一个是有管理员权限的Access Token,另外一个是被限制权限的Access Token,其中Restricted Access Token中Administrators组的属性为SE_GROUP_USE_FOR_DENY_ONLY,说明系统在访问检查时,只会检查给这个组应用了拒绝访问的那些ACE项,而允许访问的ACE项被忽略。而CheckTokenMembership在判断一个Token是否属于某个组时,这个组必须存在并且组属性包含SE_GROUP_ENABLED,才会认为这个Token属于这个组。所以一个权限未提升的进程的令牌是不会认为属于Administrators组的。

2. 安全描述符

安全描述符是windows安全对象管理的一种数据结构,用来描述允许什么用户使用某种权限访问它,拒绝什么用户使用某种权限访问它。(另外还有一些审计操作,不讨论了)。获取ACE信息,见一些代码

void ParseAce(PACE_HEADER pAceHdr);

#define GETATTRI(mask, check) \
if (mask & check)\
{\
	cout<<#check<Mask);
	dump((PSID)&pAllowedAce->SidStart);
}

void ParseAce(PACCESS_DENIED_ACE pAllowedAce)
{
	dumpAccessMask(pAllowedAce->Mask);
	dump((PSID)&pAllowedAce->SidStart);
}

void ParseAce(PSYSTEM_ALARM_OBJECT_ACE pAllowedAce)
{

}

void ParseAce(PSYSTEM_ALARM_ACE pAllowedAce)
{

}


void ParseAce(PSYSTEM_ALARM_CALLBACK_ACE pAllowedAce)
{

}

void ParseAce(PSYSTEM_ALARM_CALLBACK_OBJECT_ACE pAllowedAce)
{

}

void ParseAce(PSYSTEM_AUDIT_ACE pAllowedAce)
{

}

void ParseAce(PSYSTEM_MANDATORY_LABEL_ACE pAllowedAce)
{

}


void ParseAce(PACE_HEADER pAceHdr)
{
	cout<<"-------------------------------------"<AceFlags);
	cout<AceType == ACCESS_ALLOWED_ACE_TYPE)
	{
		cout<<"ACCESS_ALLOWED_ACE_TYPE"<AceType == ACCESS_DENIED_ACE_TYPE)
	{
		cout<<"ACCESS_DENIED_ACE_TYPE"<AceType == SYSTEM_ALARM_OBJECT_ACE_TYPE)
	{
		cout<<"SYSTEM_ALARM_OBJECT_ACE_TYPE"<AceType == SYSTEM_ALARM_ACE_TYPE)
	{
		cout<<"SYSTEM_ALARM_ACE_TYPE"<AceType == SYSTEM_ALARM_CALLBACK_ACE_TYPE)
	{
		cout<<"SYSTEM_ALARM_CALLBACK_ACE_TYPE"<AceType == SYSTEM_ALARM_CALLBACK_OBJECT_ACE_TYPE)
	{
		cout<<"SYSTEM_ALARM_CALLBACK_OBJECT_ACE_TYPE"<AceType == SYSTEM_AUDIT_ACE_TYPE)
	{
		cout<<"SYSTEM_AUDIT_ACE_TYPE"<AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE)
	{
		cout<<"SYSTEM_MANDATORY_LABEL_ACE_TYPE"<


3. 为新建对象使用安全描述符(或更改描述符)

#define MAKESDCDESC(sdc) {sdc, _T(#sdc)}

struct SdcDesc 
{
	DWORD sdc;
	TCHAR* desc;
};

SdcDesc gvSdcDesc[]=
{
	MAKESDCDESC(SE_DACL_AUTO_INHERIT_REQ),
	MAKESDCDESC(SE_DACL_AUTO_INHERITED),
	MAKESDCDESC(SE_DACL_DEFAULTED),
	MAKESDCDESC(SE_DACL_PRESENT),
	MAKESDCDESC(SE_DACL_PROTECTED),
	MAKESDCDESC(SE_GROUP_DEFAULTED),

	MAKESDCDESC(SE_OWNER_DEFAULTED),
	MAKESDCDESC(SE_RM_CONTROL_VALID),
	MAKESDCDESC(SE_SACL_AUTO_INHERIT_REQ),
	MAKESDCDESC(SE_SACL_AUTO_INHERITED),

	MAKESDCDESC(SE_SACL_DEFAULTED),
	MAKESDCDESC(SE_SACL_PRESENT),
	MAKESDCDESC(SE_SACL_PROTECTED),
	MAKESDCDESC(SE_SELF_RELATIVE)
};

void dumpSdc(SECURITY_DESCRIPTOR_CONTROL controlBit)
{
	USES_CONVERSION;

	CString strDesc;
	int count = sizeof(gvSdcDesc)/sizeof(SdcDesc);

	for (int i=0;i


 ps:判断当前用户是否域登录,可以先查询用户所属的组,再用LookupAccountSid查询组Sid的SID_NAME_USE

 

你可能感兴趣的:(windows Access Token 、ACL、ACE学习笔记)