作者:daiker@360RedTeam
0x00 前言
这两篇文章主要是讲windows 域内的权限访问控制,这是上篇,主要有ACL,ACE相关的一些基础概念的介绍。
0x01 windows 访问控制模型
在 Active Directory 中设置权限,其方式与在文件中设置权限的方式几乎相同。权限控制都是使用windows 访问控制模型。这里简单提一下windows 访问控制模型。
windows 访问控制模型是由两部分组成。
● 访问令牌(Access Token)包含用户的标识(User SID,Group SIDS),以及特权列表。
● 安全描述符(security identifiers)。被访问的安全对象的相关安全信息。
这里的安全对象包括但不限于
● NTFS卷上的文件和目录
● 注册表项
● 网络共享
● 服务
● Active Directory对象
● 进程等等
由于这个系列都是讲域相关的。所以这篇文章的安全对象我们特指Active Directory对象。也就是AD 树上的每个条目。
如下图所示。
在域里面用户的身份上用sid 来表示而不是用用户名来查看,我们可以通过查看用户属性objectsid来查看一个用户的sid。
大体的流程是。当对象A来访问B的时候,A会出示自己的Access Token,然后包含自己的用户sid,自己所在的组的sid,以及特权列表。B这个安全对象,有自己的ACL。
● B首先判断是不是需要特权才能访问,如果需要特权,则查看A的Access Token看有没有那个特权。
● B通过A的Access Token,来判断A的用户 sid以及组sids,跟自己的ACL做比对,来判断是否让A进行访问。关于ACL的更多细节,将在下一节具体阐述。
0x02 ACL 简介
1. ACL 简介
在前面说过,B通过A的Access Token,来判断A的用户 sid以及组sids,跟自己的ACL做比对,来判断是否让A进行访问。接下来详细介绍ACL。
ACL主要有两个作用
-
- 权限访问控制
- ● 一个用户能不能访问安全对象
- 日志记录功能
- ● 访问成功与否
根据ACL的两个作用。ACL包含DACL和SACL。
- DACL
DACL起到的作用是权限访问控制,也就是判断一个用户能不能访问安全对象。DACL 由若干条ACE构成。如下图所示,权限项目里面是一条又一条的ACE。
那DACL 是怎么判断用户能否访问呢。
我们来举个例子。
SRM对acl的解析是
- 明确定义的DENYACE。
- 明确定义的ALLOWACE
- 继承的DENYACE。
- 继承的ALLOWACE。
在不考虑特权的情况底下。情况如下。
● 当A 访问安全对象D的时候
D 查看A的用户sid,以及组sids。首先到第二条(因为DENY优先于第一条的allow)进行匹配,没匹配上,然后到第一条ACE进行判断。允许sid 为50 的对象进行访问。A的用户sid 为50,因此允许A 对象访问。
● 当B 访问安全对象D的时候
D 查看B的用户sid,以及组sids。首先到第二条进行匹配,拒绝sid 为13的对象访问,发现B 的其中一个组sid 为13,拒绝B访问。
● 当C 访问安全对象D的时候
D 查看C的用户sid,以及组sids。首先到第二条ACE进行判断。没匹配上,然后匹配第一条,又没匹配上,因此拒绝C访问。
当每条ACE都没匹配上的时候,是拒绝访问的。因此值得注意的是,这里有两种情况
● (1) ACE 条目的数量为0 的情况这种情况底下,有DACL,但是ACE条目的数量为0,是不允许任何用户访问的
● (2) 没有DACL的情况这种情况,是允许任何用户访问的。
- SACL
SACL的作用是记录访问成功与否,SACL也是由一条一条的ACE构成,每条ACE的内容是某个用户访问成功/失败 某个权限。当访问跟满足这条ACE的时候就会被记录下来。
2. ACE 简介
DACL 是由一条条的ACE构成。SACL也是由一条条的ACE构成,在这里我们只关心DACL的ACE。
在上面我们的举例里面,一条DACL的可能是这样。允许sid 为50 的用户访问。
这个是为了简单得描述。其实一条ACE的内容量远不止于此。可以把一条ACE归纳为四个方面。
● 谁对你有权限
● 是允许还是拒绝
● 有什么权限
● 这个权限能不能被继承
允许sid 为50 的用户访问。这个表述其实就解决了前面两个。谁对你有权限,是允许还是拒绝。
接下来我们主要来讲下后面两个
(1) 有什么权限
前面说能访问吗,其实是很笼统的说法。关于权限,大致可以划分为三个大的权限。
● 通用权限就是对这个条目的通用权限,通用读,通用写等。
● 对某个属性的权限一个条目包含若干个属性,通用属性是对整个条目的权限。域内的ACL同时也支持某个属性的权限。
● 扩展权限全面说的都是读写执行权限,但是域内的安全对象相对较为复杂,读写执行权限是不够用的,域内的ACL也支持扩展权限,比如强制更改密码。
(2) 这个权限能不能被继承
如上图所示,如果我们将权限作用作用于OU=IT,如果设置这个权限能够继承的话,那这个权限能够作用于CN=it-1。
3. SDDL 简介
● 存储位置 nTSecurityDescriptor
● 存储格式 SDDL(Security Descriptor Definition Language)
利用adfind 查看某个属性的ACL
AdFind.exe -b "CN=PC-JACK-0DAY,CN=Computers,DC=0day,DC=org" nTSecurityDescriptor -rawsddl
我们可以看到这一串看起来十分复杂的就是SDDL。看起来十分难以理解,接下来就让我们具体来分析一下。
SDDL 可以可以大致划分为一下四个部分。
O:DA ——> ower G:DU -->Primary Group D: (A;CIID;GW;;;S-1-5-21-1812960810-2335050734-3517558805-1103) (OA;;WP;bf967950-0de6-11d0-a285-00aa003049e2;bf967a86-0de6-11d0-a285-00aa003049e2;S-1-5-21-1812960810-2335050734-3517558805-1133) S: (OU;CIIOIDSA;WP;f30e3bbe-9ff0-11d1-b603-0000f80367c1;bf967aa5-0de6-11d0-a285-00aa003049e2;WD)(OU;CIIOIDSA;WP;f30e3bbf-9ff0-11d1-b603-0000f80367c1;bf967aa5-0de6-11d0-a285-00aa003049e2;WD)
其中O代表这条ACL的所有者
G表示primary group,Windows 通常忽略此参数(这是为了 POSIX 兼容性,但它现在已经退化了)
然后剩下的两个部分就是DACL和SACL,都是由一条一条的ACE构成(在SDDL里面一个括号代表一条ACE),这里侧重点说的是DACL的ACE。
先看第一个例子。
(A;CIID;GW;;;S-1-5-21-1812960810-2335050734-3517558805-1103)
我们前面说过,DACL的ACE的作用主要可以分为
(1) 通用权限
然后我们将ACE拆开。
( A; ACE类型(允许/拒绝/审核) CI; ACE标志(继承和审核设置) GW; 权限(增量权限列表) ; 对象类型(GUID) ; 继承的对象类型(GUID) S-1-5-21-1812960810-2335050734-3517558805-1103 受托人SID )
可以看到
● 谁对你有权限sid 为 S-1-5-21-1812960810-2335050734-3517558805-1103的用户
● 是允许还是拒绝根据ACE类型可以看到是允许
● 有什么权限GW 表示是通用权限
● 这个权限能不能被继承CI 表示权限可以被继承
关于这些值的解释可以看https://clan8blog.wordpress.com/2016/08/08/sddl-explained/
(2) 扩展权限
上面代表的是通用权限的情况,但是还有对某个属性的权限,以及扩展权限两种。看下面一个例子。
(
OA; ACE类型(允许/拒绝/审核)
; ACE标志(继承和审核设置)
CR; 权限(增量权限列表)
00299570-246d-11d0-a768-00aa006e0529; 对象类型(GUID)
; 继承的对象类型(GUID)
S-1-5-21-1812960810-2335050734-3517558805-1178 受托人SID
)
这个是扩展权限的,相较于通用权限,对某个属性的权限,以及扩展权限这两种权限的话,
我们可以看到主要是多了个GUID(00299570-246d-11d0-a768-00aa006e0529),我们查下这个GUID(00299570-246d-11d0-a768-00aa006e0529)是强制更改密码,因此这个权限是扩展权限,强制更改密码。
对于某个具体属性的权限或者扩展权限,是哪个属性或者是哪个扩展权限,体现在对象类型里面,类型是GUID。
对于扩展权限,都存储在CN=Extended-Rights,CN=Configuration,DC=test,DC=local里面,具体在rightsGuid这个属性里面,是字符串属性
如果我们已知GUID查询扩展权限的名字,可以通过这样查询
adfind -b "CN=Extended-Rights,CN=Configuration,DC=test,DC=local" -f "rightsGuid=00299570-246d-11d0-a768-00aa006e0529" name
(3) 对某个属性的权限
对哪个属性的权限,也是用GUID 体现出来的,之前我们说过,所有属性的都存储在结构分区里面,可以以此作为查询
如果我们已知GUID要查询属性的名字,可以通过这样查询
adfind -schema -f "schemaIDGUID={{GUID:BF9679C0-0DE6-11D0-A285-00AA003049E2}}" -binenc name
但是SDDL的可阅读性实在太差了,Adfind 可以更方便阅读一点。
AdFind.exe -b "CN=PC-JACK-0DAY,CN=Computers,DC=0day,DC=org" nTSecurityDescriptor -sddl
AdFind.exe -b "CN=PC-JACK-0DAY,CN=Computers,DC=0day,DC=org" nTSecurityDescriptor -sddl+++(+阅读,越容易阅读,最高三个+)
4. 利用adfind 过滤 ACL
如果想用adfind 过滤ACL的话,我们可以使用-sddlfilter,语法如下
-sddlfilter ;;;;;
后面跟的参数对应的是ace条目相应的参数,值得注意的是,过滤的格式跟输出的格式要保持一致。
如果-rawsddl ,最后一个参数是sid,这个时候用-sddlfilter进行过滤,最后一个参数就要用sid的形式。
如果是-sddl+++,最后一个参数已经解析后账号名,这个时候用-sddlfilter进行过滤,最后一个参数就要用账号名的形式。
下面举几个例子
- 查找某个对象在域内的ACL权限
AdFind.exe -s subtree -b "DC=test,DC=local" nTSecurityDescriptor -sddl+++ -sddlfilter ;;;;;"TEST\DC2016$" -recmute
- 查找更改一个对象的马上到!S-AllowedToActOnBehalfOfOtherIdentity的权限
AdFind.exe -s subtree -b "DC=test,DC=local" nTSecurityDescriptor -sddl++ -sddlfilter ;;;"msDS-AllowedToActOnBehalfOfOtherIdentity";; -recmute
- 查找域内具备dcync 权限的用户
对域对象只需要具备一下这两个权限,就有dcsync的权限。
'DS-Replication-Get-Changes' = 1131f6aa-9c07-11d1-f79f-00c04fc2dcd2
'DS-Replication-Get-Changes-All' = 1131f6ad-9c07-11d1-f79f-00c04fc2dcd2
开始进行搜索