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场景
安全描述符(Security Descriptors)
这里我们关注点放到DACL中的ACE,以便理解是如何存储复杂的ACL访问控制关系。
ACE的结构分为:
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
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:
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 | #! /usr/bin/env python3 |
发现无法读取到test对象的nTSecurityDescriptor属性的值,这是为什么?然后开始研究,通过全局目录(Global Catalog) 去读取,失败:-(,通过域管账户(Domain Admins)去读取,成功:-),难道是权限的原因吗?普通域用户无法读取?
经过研究发现:非特权账户无法访问SACL,导致读取不到SACL返回空值
去参考了一些国外的工具,其中代码的一部分引发我的思考🤔
1 | # Set SD flags to only query for DACL |
要选择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/
http://cn.voidcc.com/question/p-xxdskkma-nh.html
接下来修改我们的代码,便可以实现
1 | #! /usr/bin/env python3 |
成功:-)
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 |
类似的ACL自动化攻击工具还有很多,例如:aclpwn
如果感兴趣可以深入探索下 :-)
ACL防御
关于ACL防御,感觉是一个很复杂的活,在域中存在各种交叉的权限。
不过我这里有一个想法,和域攻击相关的技术都要涉及到LDAP,那么如果监控LDAP,是否可以进行防御?🤔
希望有兴趣的朋友可以交流下
最后
为什么要这样做呢?
规划最短攻击路径,减少横向移动
后续还会继续更新该文,让文章更细致一些
Respect
Microsoft
BloodHound
dirkjanm
harmj0y
…