安全描述符
安全描述符(英語:Security descriptors)是安全信息的数据结构,用于可安全(securable)的Windows对象,这些对象可以被唯一名称辨识。安全描述符可用于任何命名对象,包括文件、文件夹、共享、注册表键、进程、线程、命名管道、服务、工作对象以及其他资源。[1]
简介
安全描述符包含自主决定的存取控制串列(DACL),里面包含有访问控制项(ACE),因此可以允许或拒绝特定用户或用户组的访问。它们还包含一个系统访问控制列表(SACL)以控制对象访问请求的日志(logging)。[2][3]ACE可以显式应用于对象,或者从父对象继承。ACE的顺序在ACL中很重要,拒绝访问的ACE应该比允许访问的ACE更早出现。安全描述符还包含对象所有者。
应用
文件和文件夹的权限可以使用各种工具编辑,这包括Windows Explorer、WMI,以及命令行工具如Cacls、XCacls、ICacls、SubInACL[5],免费的Win32控制台FILEACL[6][7],自由实用工具SetACL,以及其他实用工具。要编辑一个安全描述符,用户需要有该对象的WRITE_DAC访问权限[8],该权限通常默认授予管理员和该对象的所有者。
数据结构
typedef struct _SECURITY_DESCRIPTOR {
UCHAR Revision;
UCHAR Sbz1;
SECURITY_DESCRIPTOR_CONTROL Control; //其自身的一些控制位
PSID Owner; //Owner安全标识符(Security identifiers) 相当于UUID,标识用户、用户群、计算机帐户
PSID Group; //Group安全标识符(Security identifiers) 相当于UUID
PACL Sacl; //(System Access Control List),其指出了在该对象上的一组存取方式(如,读、写、运行等)的存取控制权限细节的列表。
PACL Dacl; //(Discretionary Access Control List),其指出了允许和拒绝某用户或用户组的存取控制列表。 如果一个对象没有DACL,那么就是说这个对象是任何人都可以拥有完全的访问权限。
} SECURITY_DESCRIPTOR, *PISECURITY_DESCRIPTOR;
typedef struct _ACL {
BYTE AclRevision;
BYTE Sbz1;
WORD AclSize;
WORD AceCount;
WORD Sbz2;
} ACL, *PACL;
取得对象上的安全设置,或修改对象上的安全设置的Windows API。如:GetNamedSecurityInfo, SetNamedSecurityInfo,GetSecurityInfo, SetSecurityInfo。
底层安全描述符函数:
- 对于文件、目录、邮槽、命名管道,可以使用其专用函数GetFileSecurity和SetFileSecurity函数来取得或设置文件对象的SD,以设置其访问权限。
- 对于进程、线程、访问token、文件映射对象、信号量、事件、互斥锁、可等待定时器,使用 GetKernelObjectSecurity与SetKernelObjectSecurity函数
- 对于Window Station与桌面,使用GetUserObjectSecurity与SetUserObjectSecurity函数
- 对于注册表键,使用RegGetKeySecurity与RegSetKeySecurity函数
- 对于Windows服务对象,使用QueryServiceObjectSecurity and SetServiceObjectSecurity函数
- 对于打印机对象,使用GetPrinter and SetPrinter函数的PRINTER_INFO_2结构参数。
- 对于网络共享,使用NetShareGetInfo and NetShareSetInfo 的网络502级别。
- 对于进程创建的私有对象,使用CreatePrivateObjectSecurity, DestroyPrivateObjectSecurity, GetPrivateObjectSecurity and SetPrivateObjectSecurity函数
例子
#include <windows.h>
void main(void)
{
SECURITY_ATTRIBUTES sa; //和文件有关的安全结构
SECURITY_DESCRIPTOR sd; //声明一个SD
BYTE aclBuffer[1024];
PACL pacl = (PACL)&aclBuffer; //声明一个ACL,长度是1024
BYTE sidBuffer[100];
PSID psid = (PSID)&sidBuffer; //声明一个SID,长度是100
DWORD sidBufferSize = 100;
char domainBuffer[80];
DWORD domainBufferSize = 80;
SID_NAME_USE snu;
HANDLE file;
//初始化一个SD
InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
//初始化一个ACL
InitializeAcl(pacl, 1024, ACL_REVISION);
//查找一个用户hchen,并取该用户的SID
LookupAccountName(0, "uidp1078", psid,&sidBufferSize, domainBuffer,&domainBufferSize, &snu);
//设置该用户的Access-Allowed的ACE,其权限为“所有权限”
AddAccessAllowedAce(pacl, ACL_REVISION, GENERIC_ALL, psid);
//把ACL设置到SD中
SetSecurityDescriptorDacl(&sd, TRUE, pacl, FALSE);
//把SD放到文件安全结构SA中
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = FALSE;
sa.lpSecurityDescriptor = &sd;
//创建文件
file = CreateFile("d:\\testfile",0, 0, &sa, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0);
CloseHandle(file);
}
参见
参考资料
- ^ Securable Objects. Microsoft. 2008-04-24 [2008-07-16]. (原始内容存档于2017-12-22).
- ^ What Are Security Descriptors and Access Control Lists?. Microsoft. [2008-07-16]. (原始内容存档于2008-05-05).
- ^ DACLs and ACEs. Microsoft. 2008-04-24 [2008-07-16]. (原始内容存档于2017-10-08).
- ^ https://msdn.microsoft.com/en-us/library/bb625957.aspx (页面存档备份,存于互联网档案馆) What is the Windows Integrity Mechanism?
- ^ SubInACL home page. [2016-06-23]. (原始内容存档于2010-09-08).
- ^ FILEACL home page. [2016-06-23]. (原始内容存档于2012-08-29).
- ^ FILEACL v3.0.1.6. Microsoft. 2004-03-23 [2008-07-25]. (原始内容存档于2008-04-16).
- ^ ACCESS_MASK Data Type. Microsoft. 2008-04-24 [2008-07-23]. (原始内容存档于2017-12-22).