在内网渗透中,域一直是一个关键角色,在现实情况中,如果能够获得域控的权限,便可以接管域内所有机器。而在域渗透中,Kerberos是最常用的,是整个域的基础认证协议,这里简单的介绍Kerberos协议及其部分攻击方式。
本文Kerberos协议内容参考自北辰知识星球居多,这里强推北辰师傅的知识星球,内网知识很详细。
Kerberos是一种计算机网络授权协议,用于在非安全网络中,对个人通信以安全的手段进行身份认证。该协议以希腊神话中的角色Kerberos命名,它在希腊神话中是指守护地狱大门的一只三头神犬,之所以使用此名,是因为Kerberos协议需要三方共同参与才能完成第一认证。
对于Kerberos认证,我们简单理解的话可以分为三个部分:
1、用户(Client)
2、服务器(Server)
3、密钥分发中心(Key Distribution Center,KDC)
对这三部分的具体解释如下
1、Client:需要访问服务的客户端,Kerberos客户端是需要访问资源的用户进行操作的应用程序,当Kerberos客户端在进行访问资源之前都会进行请求身份认证。
2、Server:提供访问服务的服务端,Kerberos服务端是提供被访问和请求的服务,客户端都有唯一的SPN(服务主体名称)。
3、KDC:密钥分发中心,KDC是一种提供认证服务的网络服务,其服务账户为krbtgt
,KDC会负责颁发加密令牌(Ticket),并且对客户端的身份进行验证。
KDC作为活动目录域服务的一部分运行在每个域控制器DC上
。
在KDC中又需要分为两个部分:Authentication Server(AS,身份验证服务)
和Ticket Granting Server(TGS,票据授予服务)
。
(1)Authentication Server
作为认证服务器是Kerberos分发中心(KDC)的核心组件,其主要作用是验证用户的身份,在Windows Active Directory
域环境中,Authentication Server
通常是由域控制器DC角色来实现的。
(2)Ticket Granting Server
作为票据授权服务器也是Kerberos分发中心(KDC)的核心组件,其主要负责接收客户端的请求并且用于访问特定服务器的服务票据Service Ticket(ST)
,在Windows Active Directory
域环境中,Ticket Granting Server
通常也是由域控制器DC角色来实现的。
Kerberos会使用TCP/UDP
的88端口进行身份验证和票据授予,使用TCP/UDP
的464端口号进行Kerberos KpassWd(密码重置)
。
在讲解Kerberos认证之前,我们还需要介绍一个账户,即krbtgt
账户。
Krbtgt账户是Windows中的一个内置账户,在创建活动目录时系统自动创建,其作用是KDC的服务账户,每个域都有一个唯一的Krbtgt账户,与域名称相同,并存储在Active Directory数据库中。krbtgt账户的密码是由域控制器DC系统自动随机生成的,在AD域中以HTLM hash的形式存储,可以简单理解为一个不能登录的账户。
在了解整个Kerberos认证流程前,必须要了解一个Kerberos协议中的重要概念:TGT,即Ticket-Granting Ticket
,它是用于在Kerberos认证过程中获取服务票据(Service Ticket
)的票据,可以理解为TGT就是认证服务器(AS)生成的一张门票,可以让Client通过Kerberos服务获得其他服务的权限。
首先Client
会向KDC(Kerberos服务)发送请求,希望获取访问Server的权限,当Kerberos收到该请求后,会先判断Client是否为可信主机,如果可信,AS认证服务器就会返回TGT给Client。
1、Client向KDC发送Authenticator1
,其中的内容为通过Client密码Hash加密的时间戳、Client ID、网络地址、加密类型等内容。Client对用户口令执行散列运算转换为HTLM散列,该散列值(用户密钥)称为Client和KDC共享的长期密钥。所以这里的KRB_AS_REQ
为Client执行散列运算加密一个时间戳,然后发送给身份认证服务(KDC-AS)。
2、KDC收到Authenticator1(验证程序1)
的信息后,会进行身份验证服务(KDC-AS)
进行解密时间戳,若解密(KDC-AS检查用户身份)成功,则会创建服务票据授予票据(TGT),并向本地LSA(Local Security Authority)
请求生成一个特殊的数据PAC,这个PAC包含了各种授权信息、附加凭据信息、配置文件等,此将表示Client获得了某个特定用户的口令。
这里的身份验证服务(KDC-AS)会向Client发送两条信息,一个是SessionKeya-KDC(短期会话密钥)
,该密钥用于Client向KDC发起后续的请求,该消息是经过Client的长期密钥加密,其中该短期会话密钥仅适用于Client和KDC之间。另一个是服务票据授予票据(TGT)
,包含了有关用户信息、时间、组成员等信息,其中TGT票据使用KDC的krbtgt密钥进行加密,PAC使用krbtgt进行签名。所以这里的KRB_AS_REP
为KDC-AS
向Client发送一个响应包,该响应包包含服务器使用的加密票据,用于后续通信的会话密钥。
综上,我们可以对KRB_AS_REQ
和KRB_AS_REP
的过程精简如下
KRB_AS_REQ: Client通过密码Hash加密时间戳将各类详细信息发送给AS认证服务,此操作即为发送KRB_AS_REQ。
KRB_AS_REP:KDC-AS收到KRB_AS_REQ信息后进行解密时间戳验证身份,当身份验证成功时,则创建服务票据授予票据(TGT)、SessionKeya-KDC等信息继续发送给Client,这一步就是KRB_AS_REQ。
整个交互过程Client就是为了获取TGT以及Login Session Key
存储于本地,Client使用自身hash解密login Session key
后获得原始数据,便于下一步通信。
Client获取TGT服务票据后,会继续向KDC发送请求,请求目的是希望获得Server的访问权限,当Kerberos服务收到请求包后,会通过Client发送消息中的TGT服务票据来判断Client是否拥有访问Server的权限,如果拥有访问权限则会返回给CLient访问Server的Ticket Granting Server(TGS)
,当Client拥有了TGS票据,就可以在后续的访问Server中,无需在通过KDC作为中间人进行协商。
具体协商过程如下:
1、Client使用KDC-AS返回的SessionKeya-KDC(短期会话密钥)
来创建一个特定服务的请求,该请求是Client使用了As返回的SessionKeya-KDC(短期会话密钥)
构建访问特定服务的请求,再将KDC-AS返回的TGT票据授予票据连同创建特定服务的请求一起发送给KDC-TGS。所以这里的KRB_TGS_REQ
为Client将TGT票据和需要访问的服务请求发送给KDC-TGS。
2、KDC-TGS收到TGT票据和服务请求之后,会先解密TGT信息和服务请求,KDC-TGS会对TGT票据进行校验检查,如果DC可以通过校验和检查,那么会认为该TGT票据有效,此时TGT中的数据会被复制,然后创建TGS的服务票据ST(Service Ticket),再将该服务票据ST返回给Client。
这里的KDC-TGS发送一个服务票据ST,包含了两个部分。
(1)远程服务器的部分,包含了请求用户的组成员资格、时间戳、用于客户端的远程服务器之间通信的会话密钥,使用远程服务器和KDC共享的长期密钥(Long Term Key)加密该部分;
(2)客户端部分,包含了KRB_AS_REP返回包的Sessionkeya-kDC(短期会话密钥)
加密这部分消息生成的会话密钥。所以这里的KRB_TGS_REP
为KDC-TGS向Client发送一个响应包,该响应包中包含了Client访问Server的服务票据ST。
综上,KRB_TGS_REQ
与KRB_TGS_REP
的协商过程就是Client
与KDC-TGS
票据授予服务器之间的交互,其过程可以精简如下
1、KRB_TGS_REQ:Client通过KRB_AS_REP获得的TGT票据、Login Session Key后,创建访问特定服务请求发送给TGS票据授予服务器,此即发送KRB_TGS_REQ。
2、KRB_TGS_REP:KDC-TGS收到KRB_TGS_REQ信息后会先解密TGT信息和服务请求,同时对TGT票据进行校验,通过校验后就会创建TGS的服务票据ST(Service Ticket),然后KDC-TGS将信息发送给Client,此即KRB_TGS_REP
这一整个交互过程,Client的目的是为了获取服务票据ST,便于请求所需的服务。
当Client收到KDC-TGS发过来的服务票据(ST)之后,就会根据服务票据ST向Server发起服务请求,当Server收到相关数据的请求包后,会先解密服务票据ST的信息,同时验证对方身份,如果验证成功,Server会对Client提供相应的服务。
具体如下
1、Client收到服务票据Service Ticket(ST)之后,会使用缓存的Login Session Key
解密enc-part
解密获得Service Session Key
,将Authenticator
和时间戳提取出来,并使用Service Session Key
进行加密,最后在请求服务时将服务票据ST和Service Session Key
加密后的Authenticator
时间戳信息发给Server,所以这里的KRB_AP_REQ
为Client将服务票据ST和加密后的信息发送给Server
。
2、Server接收到Client服务请求之后,使用Service key
解密TGS的Ticket的enc-part
,获取Service Session key
,再通过Service Session Key
解密authentication
后对authentication
信息进行验证,通过后返回新的时间戳信息,Client通过Service Session Key
解密返回的时间戳进行验证,通过则会对Client提供相应的服务。所以这里的KRB_AP_REP(Kerberos Authentication Protocol Application Reply)
用于响应Client的请求,完成Kerberos认证协议的身份验证流程。
综上,KRB_AP_REQ
与KRB_AP_REP
的协商过程实际上是Client
与Server
之间的交互,其过程可精简如下
1、KRB_AP_REQ: Client通过KRB_TGS_REP得到的服务票据ST之后,解密其中的enc-part得到Service Session Key,再次利用时间戳加密Service Session Key,最后将服务票据ST和加密后的信息发送给Server,此操作即发送KRB_AP_REQ。
2、KRB_AP_REP: Server收到KRB_AP_REQ之后会解密相关信息,获得Service Session Key再进行验证,验证通过后Server向Client发送服务请求,此操作即发送KRB_AP_REP
当机器不在域中时,可以通过Kerberos协议的AS_AEQ工作原理来进行枚举域内账号,由于用户名存在跟不存在的报错不一致,导致可以进行用户相关枚举。
Kerberos服务所在端口为88端口,采用tcp连接,所以通过88端口来探测。其次是用户名登录存在三种状态,根据不同状态可以判断其是否存在。
1、KDC_ERR_PREAUTH_REQUIRED-需要额外的预认证(启用)
2、KDC_ERR_CLIENT_REVOKED-客户端凭证已被吊销(禁用)
3、KDC_ERR_C_PRINCIPAL_UNKNOWN-在Kerberos数据库中找不到客户端(不存在)
使用示例如下:
常见的工具是kerbrute,用法如下
kerbrute_windows_amd64.exe userenum --dc 192.168.183.130 -d demo.com user.txt
--dc 为域控IP
-d 为域名
user.txt 为爆破字典
密码喷洒攻击是指对其他用户进行密码爆破,类似暴力破解。简单的说就是我们对域内多个账号进行统一密码爆破,这样可以避免一个账号多次登录错误而被禁止登录的情况。
可以利用上方进行用户枚举的工具进行密码喷洒攻击,具体如下
kerbrute_windows_amd64.exe passwordspray --dc 192.168.183.130 -d demo.com user.txt Qq123456
# --dc 为域控IP
-d 为域名
user.txt 为爆破成功的用户名
Qq123456 为固定密码
可以看出成功爆破出一个账户。
也可以利用其他工具,例如利用工具为DomainPasswordSpray.ps1
,链接如下
https://github.com/dafthack/DomainPasswordSpray
默认情况下它将利用LDAP从域中导出用户列表,然后扣掉被锁定的用户,再用固定密码进行密码喷洒。
使用此工具的条件是需要具有域权限用户
具体用法如下,收集用户列表
powershell -exec bypass
Import-Module .\DomainPasswordSpray.ps1
Get-DomainUserList -Domain 域名 -RemoveDisabled -RemovePotentialLockouts | Out-File -Encoding ascii userlist.txt
固定密码爆破域