• 内网渗透测试 | Kerberos协议及其部分攻击手法


    前言

    在内网渗透中,域一直是一个关键角色,在现实情况中,如果能够获得域控的权限,便可以接管域内所有机器。而在域渗透中,Kerberos是最常用的,是整个域的基础认证协议,这里简单的介绍Kerberos协议及其部分攻击方式。

    本文Kerberos协议内容参考自北辰知识星球居多,这里强推北辰师傅的知识星球,内网知识很详细。

    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(密码重置)

    image-20231111100502858

    在讲解Kerberos认证之前,我们还需要介绍一个账户,即krbtgt账户。

    Krbtgt账户是Windows中的一个内置账户,在创建活动目录时系统自动创建,其作用是KDC的服务账户,每个域都有一个唯一的Krbtgt账户,与域名称相同,并存储在Active Directory数据库中。krbtgt账户的密码是由域控制器DC系统自动随机生成的,在AD域中以HTLM hash的形式存储,可以简单理解为一个不能登录的账户。

    image-20231111140349493

    Kerberos认证流程

    image-20231111140737477

    在了解整个Kerberos认证流程前,必须要了解一个Kerberos协议中的重要概念:TGT,即Ticket-Granting Ticket,它是用于在Kerberos认证过程中获取服务票据(Service Ticket)的票据,可以理解为TGT就是认证服务器(AS)生成的一张门票,可以让Client通过Kerberos服务获得其他服务的权限。

    KRB_AS_REQ与KRB_AS_REP协商过程

    首先Client会向KDC(Kerberos服务)发送请求,希望获取访问Server的权限,当Kerberos收到该请求后,会先判断Client是否为可信主机,如果可信,AS认证服务器就会返回TGT给Client。

    image-20231111143946838

    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_REPKDC-AS向Client发送一个响应包,该响应包包含服务器使用的加密票据,用于后续通信的会话密钥。

    综上,我们可以对KRB_AS_REQKRB_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后获得原始数据,便于下一步通信。

    KRB_TGS_REQ与KRB_TGS_REP协商

    image-20231111144430461

    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_REQKRB_TGS_REP的协商过程就是ClientKDC-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,便于请求所需的服务。

    KRB_AP_REQ与KRB_AP_REP协商过程

    image-20231111151041015

    当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_REQKRB_AP_REP的协商过程实际上是ClientServer之间的交互,其过程可精简如下

    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
    

    AS_REQ & AS_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 为爆破字典
    

    image-20231116154731399

    密码喷洒攻击

    密码喷洒攻击是指对其他用户进行密码爆破,类似暴力破解。简单的说就是我们对域内多个账号进行统一密码爆破,这样可以避免一个账号多次登录错误而被禁止登录的情况。

    可以利用上方进行用户枚举的工具进行密码喷洒攻击,具体如下

    kerbrute_windows_amd64.exe passwordspray --dc 192.168.183.130 -d demo.com user.txt Qq123456
    # --dc 为域控IP
      -d 为域名
      user.txt 为爆破成功的用户名
      Qq123456 为固定密码
    

    image-20231116161013269

    可以看出成功爆破出一个账户。

    也可以利用其他工具,例如利用工具为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
    

    固定密码爆破域

  • 相关阅读:
    Grandle安装配置使用
    SAE J3016路面机动车驾驶自动化系统相关术语的分类和定义(2021中文版-全文)
    天拓四方分享:智能装备制造厂商如何利用远程运维提升用户设备价值
    ARM64 linux并发与同步之经典自旋锁
    【蓝桥杯选拔赛真题30】python开关灯 青少年组蓝桥杯python 选拔赛STEMA比赛真题解析
    gcc/g++使用格式+各种选项,预处理/编译(分析树,编译优化,生成目标代码)/汇编/链接过程(函数库,动态链接)
    JavaScript工具函数大全
    My Ninety-second - 最长重复子数列 - By Nicolas
    Visual Studio2019碰到的几个问题(续)
    字符驱动开发
  • 原文地址:https://www.freebuf.com/articles/network/384457.html