前言
理论上来说,Kerberos协议在大学密码学这门课里已经学的差不多了,但我作为信安科班生密码学的课全是水过去的,最近打了下内网渗透的靶场,发现Kerberos协议在内网渗透中确实发挥了极大的作用,因此这里专门开个文章讲讲Kerberos协议以及它的利用。
概念
Kerberos 是一种网络认证协议,其设计目标是通过密钥系统为客户机 / 服务器应用程序提供强大的认证服务。该认证过程的实现不依赖于主机操作系统的认证,无需基于主机地址的信任,不要求网络上所有主机的物理安全,并假定网络上传送的数据包可以被任意地读取、修改和插入数据。在以上情况下, Kerberos 作为一种可信任的第三方认证服务,是通过传统的密码技术(如:共享密钥)执行认证服务的。
借用一位大师傅的话:”Kerberos协议要解决的实际上就是一个身份认证的问题,顾名思义,当一个客户机去访问一个服务器的某服务时,服务器如何判断该客户机是否有权限来访问本服务器上的服务,同时保证在该过程中的通讯内容即便被拦截或者被篡改也不影响整个通讯的安全性。”
kerberos协议中一些名词:
Client:访问服务的客户机
Server:提供服务的服务器
KDC(Key Distribution Center):密钥分发中心
KDC中分成两个部分:Authentication Service和Ticket Granting Service
(1)Authentication Service(AS):身份验证服务器
AS的作用就是验证Client端的身份,验证通过之后,AS就会给TGT票据(Ticket Granting Ticket)给Client
(2)Ticket Granting Service(TGS):票据授予服务器
TGS的作用是通过AS发送给Client的TGT换取访问Server端的ST(Server Ticket)给Client.
(3)Ticket-granting cookie(TGC):存放用户身份认证凭证的cookie,在浏览器和CAS Server间通讯时使用,是CAS Server用来明确用户身份的凭证。TGT封装了TGC值以及此Cookie值对应的用户信息.
(4)Ticket-granting ticket(TGT):TGT对象的ID就是TGC的值,在服务器端,通过TGC查询TGT.
(5)SEerver Ticket(ST):ST服务票据,由TGS服务发布.
Active Directory(AD):活动目录,充当集中存储库并存储与Active Directory 用户、计算机、服务器和组织内的其他资源等对象相关的所有数据
Domain Controller(DC):域控制器
Kerberos认证协议是基于票据的一种认证方式。在域环境中,KDC服务部署在控制器DC上,而Client和Server为域内的用户或者是服务,而在Kerberos中Client是否有权限访问Server端的服务由KDC发放的票据来决定。
过程
kerberos认证过程如下:
1. AS_Req
当域内某个用户访问域内某个服务时,于是输入用户名和密码,本机的kerberos服务会向KDC的AS认证服务发送一个AS-REQ认证请求,该请求包中包含:请求的用户名、客户端主机名、加密类型和Authenticator(用户NTLM hash加密的时间戳)以及一些其他信息。
利用
这个第一个过程就会出现几种常用的域渗透攻击方式:
1.HASH传递(PTH)
这个阶段我们使用的是用户NTLM hash加密的时间戳作为Authenticator,所以我们无需破解密钥明文就可以通过hash伪造用户身份发起请求,这也是哈希传递攻击出现的根本原因。
2.域内用户枚举
在as-req阶段,请求包cname对应的值是用户名,当用户状态不同时,比如用户存在且启用、用户存在但禁用、用户不存在,不同的状态返回包的提示都是不同的,因此可以进行枚举。
3.密码喷洒
当用户名存在,密码正确或者错误的时候,返回包也不一样,因此可以进行用户名密码爆破。在内网里域管理者为了方便可能会用相同的密码对服务器进行配置,因此拿到一个有效密码可以在内网里喷洒试试,说不定就能拿下好几台内网服务器。
4.AS-REP Roasting
这个之前打靶场提到过,当关闭了预身份验证后(该属性默认是没关的),此时向域控制器的88端口发送AS_REQ请求,此时域控不会进行任何验证就将TGT和该用户Hash加密的Login Session Key 返回,我们在本地就可以对获取到的用户Hash加密的Session-Key进行离线破解,甚至获得该用户的明文口令
2.AS_Rep
KDC接受到请求后,会先通过AD活动目录查询该用户的密码Hash,然后AS会使用Client_hash对请求包中的Authenticator进行解密,解密成功且时间戳范围在五分钟内则返回用krbtgt用户(Windows域中的默认管理员账户,密码无法登录且随机生成)hash加密的TGT票据,TGT里面包含PAC,PAC包含Client的sid、Client所在的组。除此之外AS会生成一个临时秘钥Login session key,并使用用户(之前发请求那个用户)NTLM-Hash加密Login session key作为响应包的一部分内容。
利用
黄金票据
这里有内网里绝对绕不开的黄金、白银票据中的黄金票据,这个东西是什么呢,试想一下,如果我们拥有了krbtgt用户的hash,那我们就可以给我们自己签发任意用户的TGT票据,跳过AS验证,利用条件:
1.域名称
2.域的SID 值
3.域的KRBTGT账户NTLM密码哈希
4.伪造用户名
3.TGS-Req
这个阶段里我们客户端获得了TGT和Login session key。然后用自己的密码NTLM hash解密后可以获得原始的Login Session Key,然后会在本地缓存此TGT和原始的Login session key。如果现在要访问某个服务,就可以凭借TGT票据向TGS发起针对特定服务的TGS_REQ请求(微软引入了两个扩展自协议S4u2self和S4u2Proxy,但在委派的时候才用得到,后面再提)
4.TGS_Rep
收到tgs-req后,TGS会首先检查自身是否存在客户端所请求的服务,如果存在则会使用krbtgt用户的NTLM Hash解密TGT并得到Login session key,然后用Login session key解密解密Authenticator,如果解密成功,且验证时间戳在范围内。TGT时间戳未过期,原始地址与TGT中保存的地址相同,则成功验证了对方的身份,然后会生成一个用Login session key加密后的用于确保客户端服务器之间通讯安全的server-session -key,并且生成用Server_Hash加密的TGS票据。(这一步不管用户有没有访问服务的权限,只要TGT正确,就返回TGS票据)
利用
白银票据
在TGS_REP中ticket里的encpart是使用服务的hash进行加密的,如果我们拥有服务的hash,就可以给我们自己签发任意用户的TGS票据,这个票据也被称为白银票据,与黄金票据相比,白银票据只能访问特定访问,并且伪造的白银票据没有带有有效KDC签名的PAC。如果将目标主机配置为验证KDC PAC签名,则银票将不起作用。利用条件:
1.域名
2.域sid
3.目标服务FQDN
4.服务名
5.服务账号的NTML HASH
6.伪造的用户名
5.AP_Req
前四个过程本质上是对用户身份的验证,验证结束Client和KDC的通信就结束了,后面是和Server进行通信,收到TGS_REP后用户获得了TGS票据,想要访问某个服务,则需要拿着TGS票据去请求服务。
6.AP_Rep
服务使用自己的Server_Hash解密TGS票据。如果解密正确,就拿着PAC去KDC那边问Client有没有访问权限,域控解密PAC。获取Client的sid,以及所在的组,再根据该服务的ACL,判断Client是否有访问服务的权限,至此kerberos认证过程便完成了
PAC
原始的kerberos认证过程有一个很大的问题,那就是TGS_Rep这一步,无论用户是否拥有对应服务的访问权限,只要验证用户身份通过都会返回TGS票据,这导致后续过程里用户可以直接拿着TGS票据访问任何服务了,因此这个认证只解决了身份验证的问题,没有解决权限验证的问题。
为此微软引入了PAC,在AS_Req这个过程里,用户验证成功返回krbtgt hash加密的TGT票据,TGT里面包含PAC,而PAC中包含用户的sid,用户所在的组。在后续TGS_Req的过程里,KDC会验证TGT中的PAC的签名,判断PAC是否被篡改,如果PAC完好,则重新构造新的PAC放在TGS票据中,到最后一步AP_Rep这里,服务会拿着PAC去KDC那边询问用户有没有访问权限,KDC解密PAC。获取用户的sid,以及所在的组,再判断用户是否有访问服务的权限,有访问权限就允许用户访问。
PAC对于用户和服务全程都是不可见的,只有KDC能制作和查看PAC,这也确保了PAC的安全性。当然从这里我们就能看出来为什么白银票据是有局限性的了,上面我们提到过伪造的白银票据没有带有有效KDC签名的PAC,如果将目标主机配置为验证KDC PAC签名,则银票将不起作用,因为即使我们拥有Server_Hash也没法伪造有效KDC签名的PAC,毕竟PAC的整个过程无论对于用户还是服务都是不可见,只有KDC那里才能签发。
利用
MS14-068
在小于2012R2且没有打KB3011780的域控中存在该漏洞,导致任意用户都可以把自己提权到域控级别。因为老版本的验证过程允许任何签名算法,因此我们只需要把PAC进行md5就可以生成新的校验和。这也就意味着我们可以随意更改PAC的内容,之后再用md5生成一个服务检验和以及KDC校验和。
委派
委派主要发生在TGS-Req与TGS-Rep阶段,在Windows 2000 Server首次发布Active Directory时,Microsoft必须提供一种简单的机制来支持用户通过Kerberos向Web Server进行身份验证并需要代表该用户更新后端数据库服务器上的记录的方案。这通常称为“Kerberos双跳问题”,并且要求进行委派,以便Web Server在修改数据库记录时模拟用户。需要注意的一点是接受委派的用户只能是服务账户或者计算机用户。
简单来说,假设现在有三个对象,分别是用户A(hostA)、服务B(hostB)、服务C(hostC),这时用户A想要使用hostB上的服务B,这个功能需要让主机hostB上的服务B访问主机HostC上的服务C中专属于用户A的部分才能完成,因此需要主机hostB上的服务B就需要代表用户A去访问hostC上的服务C,这个过程就被称为委派。简而言之,即用户A委派主机hostB上的服务代表自己去访问了主机hostC上的服务C,当然委派可以被理解成一种权限,需要域控那边提前配置。
委派大概被分成三种,分别是非约束性委派、约束性委派和基于资源的约束性委派(RBCD),我们一种一种来讲。
非约束性委派
在域控上配置主机hostB的委派属性如下图所示
看配置顾名思义,任何用户都可以委派主机hostB代替自己去访问任何服务。比如某个用户委托Win2012$
去访问某个服务,那么这个用户会将 TGT(在TGS里面)发送到Win2012$
并缓存到LSASS中,以方便以后使用。 然后Win2012$
模拟用户去请求某个服务,配置了非约束委派的用户的userAccountControl
属性有个FLAG位 TrustedForDelegation
。(域控机器账户默认配置非约束性委派)。流程为:
1、服务1向KDC请求用户的可转发票据TGT
2、服务1使用TGT向KDC申请服务2票据TGS
利用
诱使高权限用户访问机器
当域管理员使用net use等远程访问命令,模拟域控管理员访问WIN7主机,设置了非约束性委派的主机可以抓取到域控管理员的TGT。
利用条件:
1、需要Administrator权限
2、域内主机的机器账户开启非约束委派
3、高权限用户远程访问
mimikatz.exe "privilege::debug" "sekurlsa::tickets /export" "exit"
然后使用kerberos::ptt
导入票据即可伪造
mimikatz.exe "kerberos::ptt [0;4bbb6]-2-0-60a10000-Administrator@krbtgt-HACKME.COM.kirbi" "exit"
约束委派
配置如下:
如果hostB被配置了如上图所示的约束性委派,那么这时候主机hostB就可以被任意用户委派去访问LISI计算机上的cifs服务,虽然这里限制了访问的服务类型与主机,但不能限制谁能对主机hostB进行委派。
微软在这里引入了Kerberos协议扩展,也就是之前提到过的S4U2Self
和S4U2Proxy
。配置它后,约束委派将限制指定服务器可以代表用户执行的服务。这需要域管理员特权(其实严谨一点是SeEnableDelegation
特权,该特权很敏感,通常仅授予域管理员)才能为服务配置域帐户,并且将帐户限制为单个域。
这是为了在用户以不使用 Kerberos 的方式对服务进行身份验证的情况下使用。
S4U2self
协议(协议转换)允许服务代表任意用户请求访问自身服务的ST服务票据。这使得服务可以获得用户的授权(可转发的用户TGS票据),然后将其用于后期的认证(主要是后期的s4u2proxy)。S4U2proxy
协议允许服务在已取得ST服务票据下代表任意用户获取另一个服务的服务票据。
当用户以其他方式(如NTLM认证,基于表单的认证等方式)与服务器进行认证后,用户是无法向服务器提供请求该服务的服务票据TGS的,因而服务器也无法进一步使用S4U2Proxy协议请求访问服务B。
S4U2Self协议便是解决该问题的方案,被设置为TrustedToAuthForDelegation
的服务能够调用S4U2Self向认证服务器为任意用户请求访问自身的可转发的服务票据,此后,便可通过S4U2Proxy使用这张TGS向域控制器请求访问B的票据
配置了约束委派的用户的userAccountControl
属性有个FLAG位TrustedToAuthForDelegation
。除此之外,还有一个msDS-AllowedToDelegateTo
属性位,用于配置对哪个SPN进行委派。过程即:收到用户的请求之后,首先代表用户获得针对服务自身的可转发的kerberos服务票据(S4U2SELF
),拿着这个票据向KDC请求访问特定服务的可转发的TGS(S4U2PROXY
),并且代表用户访问特定服务,而且只能访问该特定服务。
具体步骤为:
1、服务1使用自己的hash向KDC申请一个TGT票据,注意在KDC-Options里面选择FORWARDABLE标志位,这样的话请求的TGT票据就是可转发的TGT票据。
2、服务1代表用户申请一个获得针对服务1自身的kerberos服务票据(这一步就是S4U2SELF),这一步生成的TGS票据是可转发的TGS票据。
3、服务1可以使用来自用户的授权(在S4U2SELF阶段获得的可转发的TGS),然后用该TGS(放在AddtionTicket里面)向KDC请求访问服务2的TGS
利用
使用机器账户已存在的TGT票据
约束性委派攻击的关键就是获得可转发的服务票据TGS,而约束性委派在向KDC申请可转发TGS时,需要提供可转发的TGT(自身的hash申请的)。获取根据约束性委派的执行过程可知,只要控制配置约束性委派服务的机器,并获得了它的密码,那么我们就可以劫持这台主机的kerberos请求过程,最终获得任意用户权限的ticket
# 导出票据
mimikatz.exe "privilege::debug" "sekurlsa::logonpasswords" "exit"
# 使用Rubeus申请服务票据
.\Rubeus.exe asktgt /user:MSSQLSERVER$ /rc4:NTLM哈希 /domain:xiaorang.lab /dc:DC.xiaorang.lab /nowrap
# 注入票据
.\Rubeus.exe s4u /impersonateuser:Administrator /msdsspn:CIFS/DC.xiaorang.lab /dc:DC.xiaorang.lab /ptt /ticket:你上面抓到的服务票据
# 访问
dir \\DC.xiaorang.lab\c$
基于资源的约束性委派(RBCD)
基于资源的约束委派允许资源配置受信任的帐户委派给他们。基于资源的约束委派不需要通过具备
SeEnableDelegationPrivilege
权限的域管理员进行修改,而是将设置属性的权限给了服务资源本身,资源本身可以为自己配置资源委派信任关系,资源本身决定可以信任谁。
以从Service A到Service B的委派作为例子,传统的约束性委派需要域管理员将Service A的 msDS-AllowedToDelegateTo
属性指定为Service B,而在基于资源的约束性委派中无需域管理员参加,只需要在Service B上把msDS-AllowedToActOnBehalfOfOtherIdentity
属性设置为Service A即可完成委派。配置RBCD的关键在于设置msDS-AllowedToActOnBehalfOfOtherIdentity
属性,一般而言拥有设置权限的用户为:
- 将主机加入域的用户 (机器账户中会有一个 msDS-CreatorSID 属性, 使用非域管账户加入域时才会显示)
- Account Operators (能修改任意域内非域控机器的委派属性)
- NT AUTHORITY\SELF (该主机的机器账户)
利用
本地提权
如果我们现在已经获取到一个域账户bob,其具备机器win2019的属性修改的权限,那我们就可以获取win2019的管理员权限
攻击步骤:
1、利用bob域用户创建一个机器账户test(每个域用户默认可以创建10个)
2、然后修改win2019的msDS-AllowedToActOnBehalfOfOtherIdentity
为新创建的机器用户的sid
3、利用该机器账户的凭证通过S4U协议伪造Administrator用户委派至目标主机的ST票据, 实现本地提权/横向移动
变种黄金票据
在获取到域控权限后,可以对krbtgt用户设置委派属性,以实现维持权限的目的,类似与一个变种的黄金票据
新一代Kerberos攻击
陇剑的时候和其他师傅交流发现内网里的Kerberos攻击除了常见的黄金白银票据,现在还新出了蓝宝石票据和钻石票据,这里简单补充一下。
常规的后渗透思路里,票据攻击常用于域内横向,最常见的就是黄金票据和白银票据,前面已经提过了,白银票据局限性是最大的,只能访问指定服务,并且目标主机不能开启验证KDC PAC签名,因为白银票据伪造不了这玩意儿;而黄金票据在如今很容易被识别,因为一旦KDC服务收到TGT/ST,并且在SIEM中收到日志,现在的安全设备就能检测出来。
钻石票据
与黄金票据相似,黄金票据和钻石票据都需要Krbgtg密钥,不同之处在于,黄金票据是利用krbtgt用户的hash直接伪造新的TGT,而钻石票据攻击请求普通票证、解密 PAC、修改、重新计算签名并再次加密,生成与合法 PAC 高度相似的 PAC。利用条件:
1、域krbtgt的hash
2、当前域用户的账号密码
3、域名
4、域控的名称
过程就抄找个文章了,本地没有域环境:新一代Kerberos攻击 | 钻石票据与蓝宝石票据
首先用mimikatz获取krgtgt的aes256密钥
shell mimikatz.exe "privilege::debug" "lsadump::dcsync /domain:de1ay.com /user:krbtgt" "exit"
假设我们现在知道:
krbkey:42e65a58c000dab8d353b1ff2bee93383f27f0966767afa8c1f32fc51122d118
user:mssql
password:1qaz@WSX
domain:de1ay.com
dc:dc.de1ay.com
ticketuser:administrator
接下来可以用Rubeus进行钻石票据攻击
shell Rubeus.exe diamond /krbkey:42e65a58c000dab8d353b1ff2bee93383f27f0966767afa8c1f32fc51122d118 /user:mssql /password:1qaz@WSX /enctype:aes /domain:de1ay.com /dc:dc.de1ay.com /ticketuser:administrator /ptt /nowrap
然后可以获取ticket.kirbi
shell Rubeus.exe asktgs /ticket:ticket.kirbi的内容 /service:cifs/dc.de1ay.com /ptt /nowrap
然后即可用低权限机器访问域控
这里其实也可以看出来钻石票据利用的本质了,前面提到过,windows引入PAC是为了判断用户有没有访问权限,理论上应该只有KDC能制作和查看PAC,对用户和服务器都透明,这里我们劫持了这个过程给自己修改PAC增加了高权限,所以在对TGT影响较小的情况下实现了提权,较为隐蔽。
蓝宝石票据
蓝宝石票据和钻石票据相似,票据不是伪造的,而是基于正常请求后得到的合法票据。区别只在于PAC的修改方式,钻石票据修改了合法的PAC,在蓝宝石票据里通过S4U2self+u2u实现,与钻石票据相似,生成的票据是合法元素的集合,并遵循标准票据请求,这使得它成为最难检测的银/金票据变体。
由于钻石票据会动态修改PAC来包含任意组ID,理论上来说某些软件或许能检测出PAC值与实际AD关系之间的差异(例如PAC指示用户属于某些组),虽然事实上这样并不可行。而蓝宝石票据通过在票据中包含合法强大用户的PAC来以更隐秘的方式获取类似票据的替代方案,因此PAC中的内容与AD中的内容之间将不再有任何差异。
在某些特定场景中,S4U2self和U2U可以组合,在这种情况下,这两种机制在其请求中包含的标志和结构被组合。这允许
- 操作来自无 SPN 帐户的 RBCD 攻击
- 进行unPAC-the hash攻击
- 检索并解密任何帐户的PAC,可以用来获得蓝宝石票据。
接下来使用的工具是https://github.com/ShutdownRepo/impacket/blob/sapphire-tickets/examples/ticketer.py 假设我们知道
domain admin:snapattack
domain:snapattcker.labs
user:vgullible
pass:Passw0rd1
aesKey:fec5d... ....
domain-sid:S-1-5 ... ...
DC:arrakis.snapattack.labs
python3 ticketer.py -request -impersonate 'snapattack' -domain 'snapattack.labs' -user 'vgullible' -password 'Passw0rd1' -aesKey 'fec5d... ....' -domain-sid 'S-1-5-21-... ...' 'snapattcker'
export KRB5CCNAME=snapattcker.cache
python3 psexec.py snapattack.labs/snapattack@arrakis.snapattack.labs cmd.exe -k debug -n
然后即可接管域控
域信息搜集工具BloodHound
bloodhound是最知名的域内信息搜集工具之一,它可以使用可视化图形显示域环境中的关系,让攻击者识别高度复杂的攻击路径。
kali安装bloodhound:
sudo apt-get install bloodhound
安装完成后启动neo4j:
sudo neo4j console
接着访问http://localhost:7474/browser/,User默认 neo4j,Password默认 neo4j,连接成功后就会提示创建新密码,出现下图即证明启动成功。
接下来在终端输入bloodhound命令会弹出网页,输入对应的账号密码即可成功登录bloodhound
参考
https://dar1in9s.github.io/categories/%E5%86%85%E7%BD%91%E6%B8%97%E9%80%8F/
http://www.taodudu.cc/news/show-6193984.html?action=onClick
http://www.hackdig.com/08/hack-1065506.htm
https://cn-sec.com/archives/1172625.html
https://www.thehacker.recipes/ad/movement/kerberos/forged-tickets/sapphire