`
shangjava
  • 浏览: 1229525 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

Access Control List and Process(如何设置DACL)

阅读更多

ACL即访问控制表,由一个ACL头和零到多个ACE(Access_control entry 访问控制实例)构成。<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

  ACL的应用平台是WindowsNT/2000/XP/2003,实际上WindowsNT3.1之后的使用NT内核的操作系统都支持这个结构。ACL标志了第三方对某一个对象的访问权限,这个对象可以是任何类的实例,当然也包括了进程(Process)对象。

1??????? 概述

每一个ACE包含一个授权对象(Trustee)和一组权限,一个有效的SecurityDescriptor(安全标志)包含两个ACL,即DACLSACL

WindowsNT下,使用OpenProcess打开进程的时候,系统会根据相应进程的DACL结构确定对象的访问权限,假如DACL不存在,那么将开放所有权限;假如DACL存在但是为空,那么将拒绝一切形式的访问。

实际上,在不同的操作系统下,对DACL为空的处理是不尽相同的,有可能不拒绝系统管理员权限进程的任意形式访问。

SACL的作用是允许系统管理员纪录所有对安全对象的访问情况,SACLACE即是需要被记录的项目。

DACL的工作原理如下图:

<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" /><shapetype id="_x0000_t75" stroked="f" filled="f" path="m@4@5l@4@11@9@11@9@5xe" o:preferrelative="t" o:spt="75" coordsize="21600,21600"><stroke joinstyle="miter"></stroke><formulas><f eqn="if lineDrawn pixelLineWidth 0"></f><f eqn="sum @0 1 0"></f><f eqn="sum 0 0 @1"></f><f eqn="prod @2 1 2"></f><f eqn="prod @3 21600 pixelWidth"></f><f eqn="prod @3 21600 pixelHeight"></f><f eqn="sum @0 0 1"></f><f eqn="prod @6 1 2"></f><f eqn="prod @7 21600 pixelWidth"></f><f eqn="sum @8 21600 0"></f><f eqn="prod @7 21600 pixelHeight"></f><f eqn="sum @10 21600 0"></f></formulas><path o:connecttype="rect" gradientshapeok="t" o:extrusionok="f"></path><lock aspectratio="t" v:ext="edit"></lock></shapetype><shape id="_x0000_i1025" style="WIDTH: 455.25pt; HEIGHT: 233.25pt" type="#_x0000_t75"><imagedata o:title="ACL" src="file:///D:/Temp/msoclip1/03/clip_image001.jpg"></imagedata></shape>

2??????? DACL and CreateProcess

2.1????? SECURITY_ATTRIBUTES

SECURITY_ATTRIBUTES结构用于在创建进程时指定访问安全级别。

typedef struct _SECURITY_ATTRIBUTES 

{

? DWORD ??nLength; 

??LPVOID  lpSecurityDescriptor; 

??BOOL?? ??bInheritHandle; 

} SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES;

  其中lpSecurityDescriptor指向一个SECURITY_DESCRIPTOR结构。

2.2????? SECURITY_DESCRIPTOR

SECURITY_DESCRIPTOR结构不能直接修改,只能通过调用API函数来修改,它的内容包括进程的所有者(SID Owner)、所属工作组(SID PrimaryGroup)DACL(一个)SACL(一个)、对前面项目的修改等级。

主要的API函数包括:

(1)?? ?InitializeSecurityDescriptor

初始化一个SECURITY_DESCRIPTOR结构,除SECURITY_DESCRIPTOR_REVISION是默认的修改等级,Owner等项目全部为空或者为NULL值。

(2)?? ?SetSecurityDescriptorDacl

本函数设置SECURITY_DESCRIPTOR结构中的DACL,参数中包含了指向ACL结构的指针。

(3)?? SetSecurityDescriptorGroup

本函数设置SECURITY_DESCRIPTOR结构中的主工作组(primary group)信息,原先如果存在主工作组信息,执行本函数时原信息将被覆盖。

(4)?? SetSecurityDescriptorOwner

本函数设置SECURITY_DESCRIPTOR结构中的所有者(owner)信息,并覆盖原有信息。

(5)?? SetSecurityDescriptorRMControl

本函数设置SECURITY_DESCRIPTOR中对应资源管理程序的64位信息,资源管理程序通过访问这8个字节的信息,获取进程对象的相关资料。

(6)?? SetSecurityDescriptorSacl

本函数设置SECURITY_DESCRIPTOR结构中的SACL,参数中包含了指向ACL结构的指针。

  通过以上六个函数,我们可以完成对SECURITY_DESCRIPTOR结构的访问。

2.3????? CreateProcess

函数声明

BOOL CreateProcess(

? LPCTSTR lpApplicationName,???????????????? ?// name of executable module

? LPTSTR lpCommandLine,????????????????????? // command line string

? LPSECURITY_ATTRIBUTES lpProcessAttributes, ?// SD

? LPSECURITY_ATTRIBUTES lpThreadAttributes,? // SD

? BOOL bInheritHandles,????????????????????? ??// handle inheritance option

? DWORD dwCreationFlags,???????????????????? // creation flags

? LPVOID lpEnvironment,?? ???????????????????// new environment block

? LPCTSTR lpCurrentDirectory,??????????????? ??// current directory name

? LPSTARTUPINFO lpStartupInfo,????????????? ?// startup information

? LPPROCESS_INFORMATION lpProcessInformation // process information

);

部分参数说明:

lpCommandLine 指向字符串的指针,是新进程的命令行。命令行字符串以空字符结束,同样的’\0’也代表字符的结束。当lpApplicationNameNULL的时候,本字符串将被看成是新进程的可执行文件路径和文件名,这时要注意空格的处理;

LpProcessAttributeslpThreadAttributes 这两个指针指向的内容代表了对新进程和其线程的可继承性的设定。特别的,在NT内核情况下,指向一个SECURITY_ATTRIBUTES结构。如前所述,它包含了对象安全级别的信息;

DwCreationFlags 这个DWORD值用于设置进程的创建模式和优先权,大多flag值是可以组合的。

3??????? ACL

3.1????? ACL头定义

typedef struct _ACL { 

??BYTE AclRevision; 

??BYTE Sbz1; 

??WORD AclSize; 

??WORD AceCount; 

??WORD Sbz2; 

} ACL*PACL;

参数说明:

AclRevision 内容修正等级,一般是ACL_REVISION,在NT内核下,当结构中存在指定对象ACE时,应该设置为ACL_REVISION_DS

Sbz1, Sbz2  填料;

AceCount 结构中包含ACE的数量;

AclSize??? ACL头和所有ACE的总字节数。

结构说明:

?3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1

???? 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0

???? +----------------------------------+----------------+---------------+

???? |???  ? AclSize?? ??????|?? ?Sbz1 ???|AclRevision |

? ?+----------------------------------+----------------+---------------+

???? |????? ???Sbz2????? ????|???? ??AceCount? ??????|

?? +----------------------------------+---------------------------------+

  ACL是由ACL(ACL结构)和不定数量的ACE构成的,ACL中每个ACE0n-1编号,因此,n就是ACLACE的数量,即n = AceCount。编辑ACL的时候,应用程序通过ACE编号来访问每个单独的ACE

  如前所述,ACL有两种,即DACLSACL

  DACL由对象所有者(Owner)进程和拥有该对象WRITE_DAC权限的任何进程维护。这种机制类似于某一个文件的主人或者管理员有权决定能让谁看到这份文件。

  一个对象同样拥有系统级的安全设定,这就是SACLSACL由系统管理员(administrator)维护,它决定了对于某个对象,系统管理员能够纪录并审核哪些访问。

3.2????? ACE for DACL

ACEACL中标志访问权限的单元,以下是已经定义的能够在DACL中使用的ACE类型:

ACCESS_ALLOWED_ACE

这个结构允许指定的用户或群组访问某一个对象;

ACCESS_ALLOWED_OBJECT_ACE

  这个结构允许指定的用户或群组访问某一个特定的对象,应用在Windows2000/XP。当ACL中包含这个类型的ACE时,AclRevision应设置为ACL_REVISION_DS

ACCESS_DENIED_ACE

  这个结构拒绝指定的用户或群组访问某一个对象;

ACCESS_DENIED_OBJECT_ACE

这个结构拒绝指定的用户或群组访问某一个特定的对象,应用在Windows2000/XP。当ACL中包含这个类型的ACE时,AclRevision应设置为ACL_REVISION_DS

为了进一步说明ACE,以下介绍ACE的数据结构。

typedef struct _ACE_HEADER { 

??BYTE AceType; 

??BYTE AceFlags; 

??WORD AceSize; 

} ACE_HEADER; 

typedef ACE_HEADER *PACE_HEADER;

  参数说明:

  AceType 指定ACE类型;

  AceFlags ACE的控制标志,可以是几个标志的组合;

  AceSize  ACE的字节长度。

  每个ACE都以ACE_HEADER开头,并包含了其全长(按字节)

3.3????? 如何应用ACL

本节将介绍如何往一个DACL中添加ACCESS_DENIED_ ACE元素,并实现对一个进程的访问保护。

3.3.1? AddAccessDeniedAce函数

BOOL AddAccessDeniedAce(

? PACL pAcl,??????????? // access control list

? DWORD dwAceRevision,? // ACL revision level

? DWORD AccessMask,???? // access mask

? PSID pSid???????????? // security identifier

);

部分参数说明:

dwAceRevision 如果ACL中已经包含了一个以上ACCESS_ALLOWED_OBJECT_ACE或者ACCESS_DENIED_OBJECT_ACE类型的ACE对象,应设置为ACL_REVISION_DS,否则应设置为ACL_REVISION

AccessMask 访问类型掩码,它可以标志一种访问类型或者多种访问类型的组合,本函数中这些被标志的访问类型将被禁用;

pSid TruteeID信息。这个参数指向一个SID结构,它指定了那些用户将被剥夺访问权限,这些用户可以是普通用户、群组以及共享用户。

另外,在ACL中,应该按照先设ACCESS_DENIED_ACE再设ACCESS_ALLOWED_ACE的顺序来添加ACE,否则将会导致错误。这一点十分重要,也是初学者容易犯的错误。在这里添加的只是ACCESS_DENIED_ACE,不需要考虑顺序问题。

3.3.2?? ACCESS_MASK and SID

typedef DWORD ACCESS_MASK;

这个类型组合标志了一个或者多个访问类型。

SID(The security identifier)

  这是一个变长的数据结构,用于唯一的标志用户或者群组。这个结构不能被直接编辑,需要用系统API函数来创建、修改,具体应用如下:

前一阵子,有网友向我抱怨。他说自己在本机建立了一个共享内存,然后用B/S架构的浏览器端来访问这块内存,结果总是访问成功,返回错误是没有权限。

的确,B/S程序,其插件运行在浏览器中,账户是guest,当然没有权限访问身为内核对象的本机共享内存。不过,如果你在创建内核对象时重新设置了它的访问控制列表(DACL),那么就能让它被你所允许的任何账户访问。很神奇,不是吗?

下面我通过创建一个在Windows2000下不会被杀死的计事本程序,向各位展示这个技术:

void Test()
{
?printf("本程序將创建一个不可被杀死的记事本!\n");
?
?PSID pEveryoneSID??????? = NULL; // everyone群组SID
?PSID pAdminSID?????????? = NULL; // 本机系统管理员群组SID
?EXPLICIT_ACCESS?????????? ea[3]; // ACE內容
?PACL pProcessACL???????? = NULL; // 进程的DACL
?PSECURITY_DESCRIPTOR pSD = NULL; // 进程的SD
?SECURITY_ATTRIBUTES?? saProcess; // 进程SA

?DWORD dwRet;
?
?// 以下創建SID
?// S-1-1-0
?SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY;
?SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY;
?if (!AllocateAndInitializeSid(&SIDAuthWorld, 1, SECURITY_WORLD_RID,
??0, 0, 0, 0, 0, 0, 0, &pEveryoneSID))
?{
??printf("AllocateAndInitializeSid failed! EveryoneSID\n");
??goto Err;
?}
?
?// S-1-5-32-0x220
?if (!AllocateAndInitializeSid(&SIDAuthNT, 1, SECURITY_BUILTIN_DOMAIN_RID,
??DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &pAdminSID))
?{
??printf("AllocateAndInitializeSid failed! AdminSID\n");
??goto Err;
?}

?// S-1-5-32-0x1F4
?PSID pAdminuUserSID;
?if (!AllocateAndInitializeSid(&SIDAuthNT, 1, SECURITY_BUILTIN_DOMAIN_RID,
??DOMAIN_USER_RID_ADMIN, 0, 0, 0, 0, 0, 0, &pAdminuUserSID))
?{
??printf("AllocateAndInitializeSid failed! pAdminuUserSID\n");
??goto Err;
?}

?// 填充外部访问组
?ZeroMemory(&ea, 2 * sizeof(EXPLICIT_ACCESS));
?// S-1-1-0,禁止关闭进程和修改参数
?ea[0].grfAccessPermissions = PROCESS_TERMINATE|PROCESS_SET_INFORMATION;
?ea[0].grfAccessMode = GRANT_ACCESS;
?ea[0].grfInheritance= NO_INHERITANCE;
?ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
?ea[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
?ea[0].Trustee.ptstrName? = (LPTSTR) pEveryoneSID;

?// S-1-5-32-0x220,禁止关闭进程和修改参数
?ea[1].grfAccessPermissions = PROCESS_TERMINATE|PROCESS_SET_INFORMATION;
?ea[1].grfAccessMode = GRANT_ACCESS;
?ea[1].grfInheritance= NO_INHERITANCE;
?ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
?ea[1].Trustee.TrusteeType = TRUSTEE_IS_GROUP;
?ea[1].Trustee.ptstrName? = (LPTSTR) pAdminSID;

?// S-1-5-32-0x1F4,禁止关闭进程和修改参数
?ea[2].grfAccessPermissions = PROCESS_TERMINATE|PROCESS_SET_INFORMATION;
?ea[2].grfAccessMode = GRANT_ACCESS;
?ea[2].grfInheritance= NO_INHERITANCE;
?ea[2].Trustee.TrusteeForm = TRUSTEE_IS_SID;
?ea[2].Trustee.TrusteeType = TRUSTEE_IS_USER;
?ea[2].Trustee.ptstrName? = (LPTSTR) pAdminuUserSID;


?// 创建并填充ACL
?dwRet = SetEntriesInAcl(3, ea, NULL, &pProcessACL);
?if (dwRet != ERROR_SUCCESS)
?{
??printf("SetEntriesInAcl failed!\nCode = %d", dwRet);
??goto CleanUp;
?}

?// 创建并初始化SD
?pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR,
??SECURITY_DESCRIPTOR_MIN_LENGTH);
?if (pSD == NULL)
?{
??printf( "LocalAlloc failed!\n");
??goto Err;
?}
?if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION))
?{?
??printf( "InitializeSecurityDescriptor failed!\n");
??goto Err;
?}

?// 添加ACL到SD中去
?if (!SetSecurityDescriptorDacl(pSD,
??????? TRUE,???? // fDaclPresent flag??
??????? pProcessACL,
??????? FALSE))?? // not a default DACL
?{?
??printf( "SetSecurityDescriptorDacl failed!");
??goto Err;
?}

?// 设置SA
?saProcess.nLength = sizeof(SECURITY_ATTRIBUTES);
?saProcess.lpSecurityDescriptor = pSD;
?saProcess.bInheritHandle = FALSE;

?// 运行进程并等待其正常结束
?PROCESS_INFORMATION ProcessInfo;
?STARTUPINFO StartupInfo;
?ZeroMemory(&StartupInfo, sizeof(StartupInfo));
?StartupInfo.cb = sizeof(StartupInfo);
?if (CreateProcess("c:\\winnt\\notepad.exe", NULL,
??&saProcess, NULL, FALSE, 0, NULL,
??NULL, &StartupInfo, &ProcessInfo))
?{
??WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
??CloseHandle(ProcessInfo.hThread);
??CloseHandle(ProcessInfo.hProcess);
?}?
?else
?{
??printf("CreateProcess failed!\n");
??goto Err;
?}
?
// Clean up
CleanUp:
?printf("Exiting...\n");

?if (pEveryoneSID != NULL)
?{
??FreeSid(pEveryoneSID);
?}
?if (pAdminSID != NULL)
?{
??FreeSid(pAdminSID);
?}
?if (pProcessACL != NULL)
?{
??LocalFree(pProcessACL);
?}
?if (pSD != NULL)
?{
??LocalFree(pSD);
?}
?
?printf("Success!\n");
?return;
// Error process
Err:
?DWORD dwErr;
?dwErr = GetLastError();
?printf("Code = %d \n", dwErr);

?goto CleanUp;
}

分享到:
评论

相关推荐

    藏经阁-An-ACE-Up-The-Sleeve-Designing-Active-Directory-DACL-Backdoo

    在 Active Directory 中,DACL(Discretionary Access Control List)是一种访问控制机制,用于控制对象的访问权限。DACL 由多个 ACE(Access Control Entry)组成,每个 ACE 定义了一个用户或组对对象的访问权限。...

    关于Windows安全权限的学习.doc

    2. **DACL (Discretionary Access Control List)**:这是一个可选的存取控制列表,用于定义哪些用户或用户组可以访问某个对象及其具体的访问权限。当一个进程尝试访问某个对象时,系统会根据DACL中的规则来确定该...

    Windows Security Introduction Windows Security Introduction

    - **Discretionary Access Control List (DACL)**:定义允许或拒绝访问的对象列表。 ### 访问令牌 访问令牌存储了进程的安全上下文,包括用户的身份、权限和组成员资格。它决定了进程可以执行哪些操作。例如,`...

    aa.rar_注册表权限

    这个函数需要`SECURITY_INFORMATION`结构来指定要设置的安全信息类型,如DACL(Discretionary Access Control List,自定义访问控制列表)或SACL(System Access Control List,系统访问控制列表)。以下是一个简单...

    宁盾打印机网络准入:MAB认证+DACL权限管控.docx

    宁盾打印机网络准入:MAB认证+DACL权限管控.docx宁盾打印机网络准入:MAB认证+DACL权限管控.docx宁盾打印机网络准入:MAB认证+DACL权限管控.docx宁盾打印机网络准入:MAB认证+DACL权限管控.docx宁盾打印机网络准入:...

    宁盾打印机网络准入:MAB认证+DACL权限管控.pdf

    宁盾打印机网络准入:MAB认证+DACL权限管控.pdf宁盾打印机网络准入:MAB认证+DACL权限管控.pdf宁盾打印机网络准入:MAB认证+DACL权限管控.pdf宁盾打印机网络准入:MAB认证+DACL权限管控.pdf宁盾打印机网络准入:MAB...

    网络安全实验

    Lock-and-Key 是一种基于动态访问控制列表(Dynamic Access Control List, DACL)的技术,它允许网络管理员通过TACACS+服务器或其他认证方式来动态地管理路由器上的访问控制列表(ACL)。这种机制能够提高网络的安全性和...

    THM Windows权限提升中滥用服务错误配置,不安全的服务权限

    接下来,我们讨论服务的访问控制列表(DACL,Discretionary Access Control List)。DACL是Windows权限模型的一部分,用于定义谁可以访问一个对象(例如,服务)以及他们可以执行的操作。如果一个服务的DACL设置不当...

    C# 动态设置是否允许运行注册表,实际上应该是是否允许修改注册表,注册表当然要运行了,要不然系统要崩溃的,一般来说,注册表的键值是不能随便改的,像有些优化软件都有禁止修改注册表的选项,以确保Windows设置不被破坏,那么本代码就实现了这个小功能,仅供参阅。

    // 修改 DACL(Discretionary Access Control List) var acl = new Native.ACL(); // 添加或移除权限,这里简化为只设置管理员权限 if (allowModify) { // 添加管理员权限 // ... } else { // 移除管理...

    Delphi 基础档案权限建立的源码

    在Windows中,文件权限主要通过访问控制列表(Access Control List, ACL)来实现,它包含了对文件或目录的一系列访问规则。这些规则由访问控制项(Access Control Entry, ACE)组成,每个ACE定义了一个特定的安全...

    域渗透之ACL攻击.pdf

    访问控制列表(ACL,Access Control List)是Windows操作系统,尤其是活动目录(AD,Active Directory)中实现访问控制的核心机制。它定义了哪些用户或组能够对特定对象进行何种级别的访问。在AD环境中,ACL主要用于...

    计算机网络管理第四章

    其中,访问控制通过安全描述符实现,包括DACL(Discretionary Access Control List)和SACL(System Access Control List),并支持对象继承以确保安全策略的统一实施。用户身份验证则依赖于访问令牌和安全标识符...

    NewSID(光学习一下代码就可以了,没看清楚介绍别运行)

    These other computers effectively appear to have been through the same install process, and are immediately available for use. While this method saves hours of work and hassle over other rollout ...

    VC.net添加或删除文件权限的实例代码.rar

    2. **解析安全描述符**:安全描述符包含了 DACL(Discretionary Access Control List),这是一个包含ACEs的列表。我们可以通过`GetSecurityDescriptorDacl`函数来获取DACL。 3. **创建新的ACE**:为了添加或删除...

    注册表权限添加任何人权限

    在上述代码中,我们首先打开了注册表键,然后创建了一个新的安全描述符并设置其 DACL( discretionary access control list)。接着,我们添加了一个 ACE,赋予 Everyone 组读取和写入权限。最后,我们使用 `...

    VC.net为文件增加或删除文件权限

    这涉及到Windows操作系统中的访问控制列表(Access Control List, ACL)和访问控制条目(Access Control Entry, ACE)。本篇文章将深入探讨如何使用C++编程语言在VC++.net环境下为文件增加或删除文件权限。 首先,...

    NTFS 文件系统及NTFS权限应用原则

    NTFS的权限管理基于访问控制列表(Access Control List, ACL),分为随机访问控制列表(DACL)和系统访问控制列表(SACL)。DACL存储了用户或组对文件或文件夹的访问权限,用于控制访问;SACL则记录了对象的审计设置...

    理解Windows文件和注册表权限.pdf

    在Windows Server 2008以及更新的系统中,ACL可以分为两类:DACL(Discretionary Access Control Lists)和SACL(System Access Control Lists)。DACL用于控制对资源的访问权限,而SACL用于监视和记录访问尝试。...

    VBSCript之GenerateSDDL函数(权限设置)

    最后,创建一个安全描述符(SecurityDescriptor)实例,并将之前创建的信任对象设置为所有者,将访问控制条目作为DACL(Discretionary Access Control List)数组中的一员,并设置控制标志(ControlFlags)为SET_...

    常见的几种物联网终端身份认证及安全准入场景.pdf

    首先,实现所有终端的可视化接入和分类,然后对IoT设备实施MAB(Machine Authentication Based,基于机器的认证)和静态ACL(Access Control List,访问控制列表)策略,以防止IP/MAC伪造。同时,通过“终端类型”...

Global site tag (gtag.js) - Google Analytics