Active Directory域-ACL相关安全研究

Active Directory域-ACL相关安全研究

转载请注明出处:https://youngrichog.github.io/

描述

从攻击者的角度进行ACL相关安全研究,主要从ACL基础、ACL解析、ACL枚举、ACL利用、ACL自动化攻击、ACL防御几个角度,可能会有不准确和不正确的地方。

ACL基础

ACL

什么是ACL(Access Control List)?

ACL是访问控制列表,用于定义谁可以访问哪些对象,这些设置称为访问控制项(ACE),ACL分为DACL和SACL,DACL主要记录访问权限的相关内容,SACL主要记录访问对象日志。DACL可以大致理解为A->B、B-A,意为谁对我有权限,我对谁有权限。有关于ACL的详细内容,可以参考微软文档。

当进程尝试访问安全对象时,系统将检查该对象的DACL中的ACE,以确定是否授予对该对象的访问权限。如果对象没有DACL,则系统将授予所有人完全访问权限。如果对象的DACL没有ACE,则系统将拒绝所有尝试访问该对象的尝试,因为DACL不允许任何访问权限。系统依次检查ACE,直到找到一个或多个允许所有请求的访问权限的ACE,或者直到拒绝任何请求的访问权限为止。

我觉得这个很有意思,贴出来方便看 :-)

https://docs.microsoft.com/en-us/windows/win32/secauthz/access-control-lists

ACL场景

1

安全描述符(Security Descriptors)

这里我们关注点放到DACL中的ACE,以便理解是如何存储复杂的ACL访问控制关系。

2

ACE的结构分为:

3

type:主要说明是什么类型的ACE

flags:主要是设置一些标识符

rights:主要说明是什么权限,可读?可写?等等

object_guid:主要说明对象的guid值

inherit_object_guid:主要说明继承对象的guid值

sid:主要说明对象的sid值

resource_attribute:主要说明数据类型,是一个可选项

那么现在来看一条ACE,就能清楚的了解ACE

OA;;RP;46a9b11d-60ae-405a-b7e8-ff8a58d456d2;;S-1-5-32-560

OA=type,flags没有设置,RP=权限,46a9b11d-60ae-405a-b7e8-ff8a58d456d2=object_guid,inherit_object_guid没有设置,S-1-5-32-560=sid,resource_attribute没有设置

那么每个属性的意思是什么呢?这个就涉及到ACL解析

ACL解析

每个属性的意思在微软官方都有明确的定义,这样我们就可以解析出这条ACE是什么意思

ace_type

ACE type string Constant in Sddl.h AceType value
“A” SDDL_ACCESS_ALLOWED ACCESS_ALLOWED_ACE_TYPE
“D” SDDL_ACCESS_DENIED ACCESS_DENIED_ACE_TYPE
“OA” SDDL_OBJECT_ACCESS_ALLOWED ACCESS_ALLOWED_OBJECT_ACE_TYPE
“OD” SDDL_OBJECT_ACCESS_DENIED ACCESS_DENIED_OBJECT_ACE_TYPE
“AU” SDDL_AUDIT SYSTEM_AUDIT_ACE_TYPE
“AL” SDDL_ALARM SYSTEM_ALARM_ACE_TYPE
“OU” SDDL_OBJECT_AUDIT SYSTEM_AUDIT_OBJECT_ACE_TYPE
“OL” SDDL_OBJECT_ALARM SYSTEM_ALARM_OBJECT_ACE_TYPE
“ML” SDDL_MANDATORY_LABEL SYSTEM_MANDATORY_LABEL_ACE_TYPE
“XA” SDDL_CALLBACK_ACCESS_ALLOWED ACCESS_ALLOWED_CALLBACK_ACE_TYPEWindows Vista and Windows Server 2003: Not available.
“XD” SDDL_CALLBACK_ACCESS_DENIED ACCESS_DENIED_CALLBACK_ACE_TYPEWindows Vista and Windows Server 2003: Not available.
“RA” SDDL_RESOURCE_ATTRIBUTE SYSTEM_RESOURCE_ATTRIBUTE_ACE_TYPEWindows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista and Windows Server 2003: Not available.
“SP” SDDL_SCOPED_POLICY_ID SYSTEM_SCOPED_POLICY_ID_ACE_TYPEWindows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista and Windows Server 2003: Not available.
“XU” SDDL_CALLBACK_AUDIT SYSTEM_AUDIT_CALLBACK_ACE_TYPEWindows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista and Windows Server 2003: Not available.
“ZA” SDDL_CALLBACK_OBJECT_ACCESS_ALLOWED ACCESS_ALLOWED_CALLBACK_ACE_TYPEWindows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista and Windows Server 2003: Not available.

OA:ACCESS_ALLOWED_OBJECT_ACE_TYPE

ace_flags

ACE flags string Constant in Sddl.h AceFlag value
“CI” SDDL_CONTAINER_INHERIT CONTAINER_INHERIT_ACE
“OI” SDDL_OBJECT_INHERIT OBJECT_INHERIT_ACE
“NP” SDDL_NO_PROPAGATE NO_PROPAGATE_INHERIT_ACE
“IO” SDDL_INHERIT_ONLY INHERIT_ONLY_ACE
“ID” SDDL_INHERITED INHERITED_ACE
“SA” SDDL_AUDIT_SUCCESS SUCCESSFUL_ACCESS_ACE_FLAG
“FA” SDDL_AUDIT_FAILURE FAILED_ACCESS_ACE_FLAG

ace_rights

Access rights string Constant in Sddl.h Access right value
“RP” SDDL_READ_PROPERTY ADS_RIGHT_DS_READ_PROP
“WP” SDDL_WRITE_PROPERTY ADS_RIGHT_DS_WRITE_PROP
“CC” SDDL_CREATE_CHILD ADS_RIGHT_DS_CREATE_CHILD
“DC” SDDL_DELETE_CHILD ADS_RIGHT_DS_DELETE_CHILD
“LC” SDDL_LIST_CHILDREN ADS_RIGHT_ACTRL_DS_LIST
“SW” SDDL_SELF_WRITE ADS_RIGHT_DS_SELF
“LO” SDDL_LIST_OBJECT ADS_RIGHT_DS_LIST_OBJECT
“DT” SDDL_DELETE_TREE ADS_RIGHT_DS_DELETE_TREE
“CR” SDDL_CONTROL_ACCESS ADS_RIGHT_DS_CONTROL_ACCESS

RP:ADS_RIGHT_DS_READ_PROP

object_guid

由于guid太多了,这里我就不列出来了

46a9b11d-60ae-405a-b7e8-ff8a58d456d2:tokenGroupsGlobalAndUniversal

4

sid

由于这个sid是内置的,可以直接找到什么意思

S-1-5-32-560:Builtin\Windows Authorization Access Group

通过解析,已经知道了该条ace的含义 :-)

ace详细的内容:

https://docs.microsoft.com/en-us/windows/win32/secauthz/ace-strings

内置sid:

https://support.microsoft.com/en-us/help/243330/well-known-security-identifiers-in-windows-operating-systems

guid:
https://docs.microsoft.com/en-us/windows/win32/adschema/attributes-all

https://docs.microsoft.com/en-us/windows/win32/adschema/extended-rights

ACL枚举

已经了解了如何去进行ACL解析,接下来就是如何进行ACL枚举,通过ACL枚举,可以清楚的知道”谁对我有权限,我对谁有权限”。域中的ACL是存储在LDAP的nTSecurityDescriptor属性中,那么只需要读取该属性,然后进行解析,便可完成。

任何经过域身份认证的用户都可以通过LDAP进行枚举,那么连接到LDAP,然后进行读取

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#! /usr/bin/env python3
# -*- cofing:utf-8 -*-

import ldap3
from ldap3 import Server,Connection,SIMPLE,SYNC,ALL,NTLM,MODIFY_ADD,MODIFY_ADD,MODIFY_REPLACE

def ldap_query(c):
search_filter = '({search_filter})'.format(search_filter='cn=test')
print(search_filter)
search_scope = 'SUBTREE'
c.search('dc=domain,dc=local',search_filter,search_scope,attributes=['sn','nTSecurityDescriptor'])
entry = c.entries[0]

print(entry.nTSecurityDescriptor.values)

def main():
s = Server('ldap://ip',get_info=ALL)
c = Connection(s,user='domain\\user',password='******',authentication=None)
if not c.bind():
print('bind failed...')
else:
ldap_query(c)
print('ok...')

if __name__ == '__main__':
main()

发现无法读取到test对象的nTSecurityDescriptor属性的值,这是为什么?然后开始研究,通过全局目录(Global Catalog) 去读取,失败:-(,通过域管账户(Domain Admins)去读取,成功:-),难道是权限的原因吗?普通域用户无法读取?

经过研究发现:非特权账户无法访问SACL,导致读取不到SACL返回空值

去参考了一些国外的工具,其中代码的一部分引发我的思考🤔

1
2
# Set SD flags to only query for DACL
controls = security_descriptor_control(sdflags=0x04)

要选择ntSecurityDescriptor,因为你需要使用LDAP_SERVER_SD_FLAGS_OID服务器控件与值7表示要在安全描述符减去SACL的所有部分非特权帐户。默认值(包括SACL)似乎是导致该属性不被返回的原因,因为大多数非特权帐户将无法访问SACL,并且由于此AD似乎只是不返回任何内容。

根据这些分析,我们只需要把枚举SACL的部分ban掉就可以了,设置为:LDAP_SERVER_SD_FLAGS_OID为0x04

Bit flag name and value Portion of security descriptor to retrieve/update
OWNER_SECURITY_INFORMATION (OSI)0x1 Owner identifier of the object.
GROUP_SECURITY_INFORMATION (GSI)0x2 Primary group identifier.
DACL_SECURITY_INFORMATION (DSI)0x4 Discretionary access control list (DACL) of the object.
SACL_SECURITY_INFORMATION (SSI)0x8 System access control list (SACL) of the object.

https://gist.github.com/dirkjanm/a2087c27888a15410b4622009c7f2d41

https://github.com/fox-it/aclpwn.py/blob/master/aclpwn/exploitation.py

http://www.harmj0y.net/blog/redteaming/a-guide-to-attacking-domain-trusts/

https://stackoverflow.com/questions/40771503/selecting-the-ad-ntsecuritydescriptor-attribute-as-a-non-admin

http://cn.voidcc.com/question/p-xxdskkma-nh.html

接下来修改我们的代码,便可以实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#! /usr/bin/env python3
# -*- cofing:utf-8 -*-

import ldap3,argparse,getpass
from ldap3 import Server,Connection,SIMPLE,SYNC,ALL,NTLM,MODIFY_ADD,MODIFY_ADD,MODIFY_REPLACE
from ldap3.protocol.microsoft import security_descriptor_control

def ldap_query(c):
search_filter = '({search_filter})'.format(search_filter='cn=test')
controls = security_descriptor_control(sdflags=0x04)
print(search_filter)
search_scope = 'SUBTREE'
c.search('dc=domain,dc=local',search_filter,search_scope,attributes=['sn','nTSecurityDescriptor'],controls=controls)
entry = c.entries[0]

print(entry.nTSecurityDescriptor.values)

def main():
s = Server('ldap://ip',get_info=ALL)
c = Connection(s,user='domain\\user',password='*******',authentication=None)
if not c.bind():
print('bind failed...')
else:
ldap_query(c)
print('ok...')

if __name__ == '__main__':
main()

成功:-)

ACL利用

可以参考Powerview,这里就不在说明了。例如:Set-DomainUserPassword,Set-DomainObject等等

https://powersploit.readthedocs.io/en/latest/Recon/

ACL自动化利用

这里我简单的看了下BloodHound的一些功能,膜拜!

Collection Method API Call Default Targets Stealth Targets
Session NetSessionEnum All Computers Domain Controllers + “Share Servers”
LocalGroup Modified NetLocalGroupGetMembers All Computers GPO Files
Group Ldap All User,Group, and Computer Objects All User,Group, and Computer Objects
Trusts DsEnumerateDomainTrusts NETAPI32 All Domain and TrustedDomain objects All Domain and TrustedDomain objects
LoggedOn NetWkstaUserEnum NETAPI32 + Remote Registry All Computers Domain Controllers + “Share Servers”
ACL Ldap All user, group, computer, and domain objects All user, group, computer, and domain objects
ObjectProps Ldap All user and computer objects All user and computer objects

5

类似的ACL自动化攻击工具还有很多,例如:aclpwn

如果感兴趣可以深入探索下 :-)

ACL防御

关于ACL防御,感觉是一个很复杂的活,在域中存在各种交叉的权限。

不过我这里有一个想法,和域攻击相关的技术都要涉及到LDAP,那么如果监控LDAP,是否可以进行防御?🤔

希望有兴趣的朋友可以交流下

最后

为什么要这样做呢?

规划最短攻击路径,减少横向移动

后续还会继续更新该文,让文章更细致一些

Respect

Microsoft

BloodHound

dirkjanm

harmj0y