0x00 前言
看了灵腾实验室大佬的文章受益匪浅 复现了一下大佬的文章手法 记录下来分享一下
kerberos篇将从四个方面来阐述kerberos协议,分别是kerberos的两个基础认证模块ASREQ & ASREP,TGSREQ & TGSREP。以及微软扩展的两个认证模块S4U和PAC。这篇文章是kerberos篇的第一篇文章ASREQ& ASREP。

82709-u540drytt7k.png

0x01 kerberos 协议概述
Kerberos是一种由MIT(麻省理工大学)提出的一种网络身份验证协议。它旨在通过使用密钥加密技术为客户端/服务器应用程序提供强身份验证。

在Kerberos协议中主要是有三个角色的存在:

访问服务的Client(以下表述为Client 或者用户)
提供服务的Server(以下表述为服务)
KDC(Key Distribution Center)密钥分发中心 kerberos 测试工具介绍

其中KDC服务默认会安装在一个域的域控中,而Client和Server为域内的用户或者是服务,如HTTP服务,SQL服务。在Kerberos中Client是否有权限访问Server端的服务由KDC发放的票据来决定。

kerberos的简化认证认证过程如下图

50248-s7vam1s65a7.png

1.ASREQ: Client向KDC发起ASREQ,请求凭据是Client hash加密的时间戳
2.AS_REP: KDC使用Client hash进行解密,如果结果正确就返回用krbtgt hash加密的TGT票据,TGT里面包含PAC,PAC包含Client的sid,Client所在的组。
3.TGSREQ: Client凭借TGT票据向KDC发起针对特定服务的TGSREQ请求
4.TGS_REP: KDC使用krbtgt hash进行解密,如果结果正确,就返回用服务hash 加密的TGS票据(这一步不管用户有没有访问服务的权限,只要TGT正确,就返回TGS票据)
5.AP_REQ: Client拿着TGS票据去请求服务
6.AP_REP: 服务使用自己的hash解密TGS票据。如果解密正确,就拿着PAC去KDC那边问Client有没有访问权限,域控解密PAC。获取Client的sid,以及所在的组,再根据该服务的ACL,判断Client是否有访问服务的权限。

0x02 kerberos 测试工具
配置kerberos发包工具

46887-2hkppfeae34.png

点击修改配置,支持明文密码以及hash

44799-pwryyx4gm0k.png

不得不说十分好用 配合起来理解相当好

0x03 AS_REQ
用户向KDC发起ASREQ,请求凭据是用户 hash加密的时间戳。请求凭据放在PADATA里面。详情见以下每个字段的详细介绍。

1. pvno
kerberos 版本号

2. msg-type
请求类型,ASREQ对应的就是KRBAS_REQ(0x0a)

3. PA_DATA
主要是一些认证信息。一个列表,包含若干个认证消息用于认证,我们也可以Authenticator。每个认证消息有type和value。
type主要有以下一些

NONE = 0,
TGS_REQ = 1,
AP_REQ = 1,
ENC_TIMESTAMP = 2,
PW_SALT = 3,
ENC_UNIX_TIME = 5,
SANDIA_SECUREID = 6,
SESAME = 7,
OSF_DCE = 8,
CYBERSAFE_SECUREID = 9,
AFS3_SALT = 10,
ETYPE_INFO = 11,
SAM_CHALLENGE = 12,
SAM_RESPONSE = 13,
PK_AS_REQ_19 = 14,
PK_AS_REP_19 = 15,
PK_AS_REQ_WIN = 15,
PK_AS_REQ = 16,
PK_AS_REP = 17,
PA_PK_OCSP_RESPONSE = 18,
ETYPE_INFO2 = 19,
USE_SPECIFIED_KVNO = 20,
SVR_REFERRAL_INFO = 20,
SAM_REDIRECT = 21,
GET_FROM_TYPED_DATA = 22,
SAM_ETYPE_INFO = 23,
SERVER_REFERRAL = 25,
TD_KRB_PRINCIPAL = 102,
PK_TD_TRUSTED_CERTIFIERS = 104,
PK_TD_CERTIFICATE_INDEX = 105,
TD_APP_DEFINED_ERROR = 106,
TD_REQ_NONCE = 107,
TD_REQ_SEQ = 108,
PA_PAC_REQUEST = 128,
S4U2SELF = 129,
PA_PAC_OPTIONS = 167,
PK_AS_09_BINDING = 132,
CLIENT_CANONICALIZED = 133

在AS_REQ阶段主要用到的有两个

PAPACREQUEST
这个是启用PAC支持的扩展。PAC(Privilege Attribute Certificate)并不在原生的kerberos里面,是微软引进的扩展。
详细的内容之后将有一篇文章详细介绍PAC。PAC包含在ASREQ的响应body(ASREP)。
这里的value对应的是include=true或者include=false(KDC根据include的值来判断返回的票据中是否携带PAC)。

ENC_TIMESTAMP
这个是预认证,就是用用户hash加密时间戳,作为value 发送给AS服务器。
然后AS服务器那边有用户hash,使用用户hash进行解密,获得时间戳,如果能解密,且时间戳在一定的范围内,则证明认证通过

00855-svko93up0e.png

4. REQ_BODY
kdc-options 一些flag 字段

VALIDATE = 0x00000001,
RENEW = 0x00000002,
UNUSED29 = 0x00000004,
ENCTKTINSKEY = 0x00000008,
RENEWABLEOK = 0x00000010,
DISABLETRANSITEDCHECK = 0x00000020,
UNUSED16 = 0x0000FFC0,
CANONICALIZE = 0x00010000,
CNAMEINADDLTKT = 0x00020000,
OK_AS_DELEGATE = 0x00040000,
UNUSED12 = 0x00080000,
OPTHARDWAREAUTH = 0x00100000,
PREAUTHENT = 0x00200000,
INITIAL = 0x00400000,
RENEWABLE = 0x00800000,
UNUSED7 = 0x01000000,
POSTDATED = 0x02000000,
ALLOWPOSTDATE = 0x04000000,
PROXY = 0x08000000,
PROXIABLE = 0x10000000,
FORWARDED = 0x20000000,
FORWARDABLE = 0x40000000,
RESERVED = 0x80000000

60453-68t7uqq9j0q.png

cname
PrincipalName 类型。PrincipalName包含type和value。

KRBNTPRINCIPAL = 1 means just the name of the principal 如daizhibin
KRBNTSRV_INST = 2 service and other unique instance (krbtgt) 如krbtgt,cifs
KRBNTENTERPRISE_PRINCIPAL = 10 如 user@domain.com
在AS_REQ里面cname 是请求的用户,这个用户名存在和不存在,返回的包有差异,可以用于枚举域内用户名。详情见相关的安全问题>用户名枚举

sname
PrincipalName 类型

在ASREQ里面sname是krbtgt,类型是KRBNTSRVINST

nonce
随机生成的一个数kekeo/mimikatz nonce是12381973,rubeus nonce是1818848256,这个也可以用来作为特征检测工具。

realm
域名

till
到期时间,rubeus和kekeo都是20370913024805Z,这个可以作为特征来检测工具。

from
发送时间

etype
加密类型,有

des_cbc_crc = 1,
des_cbc_md4 = 2,
des_cbc_md5 = 3,
des3_cbc_md5 = 5,
des3_cbc_sha1 = 7,
dsaWithSHA1_CmsOID = 9,
md5WithRSAEncryption_CmsOID = 10,
sha1WithRSAEncryption_CmsOID = 11,
rc2CBC_EnvOID = 12,
rsaEncryption_EnvOID = 13,
rsaES_OAEP_ENV_OID = 14,
des_ede3_cbc_Env_OID = 15,
des3_cbc_sha1_kd = 16,
aes128_cts_hmac_sha1 = 17,
aes256_cts_hmac_sha1 = 18,
rc4_hmac = 23, 选取rc4
rc4_hmac_exp = 24,
subkey_keymaterial = 65

这个地方要注意的是如果在配置里面选择用hash(不是plaintext)的话,hash的加密类型,要跟etype一样。因为KDC是按照etype类型选择用户对应加密方式的hash,如果是选择明文(plaintext),那么client 会按照etype里面的加密方式将明文加密成hash。

21759-w161dfalyld.png

pvno: kerberos版本号,这里为5
msg-type: 消息类型, AS_REQ 对应的是 krb-as-req(10)
padata:主要是一些认证信息,每个认证消息有type和value。
  PADA PA-PAC-REQUEST:这个是启用PAC支持的扩展。PAC(Privilege Attribute Certificate)并不在原生的kerberos里面,是微软引进的扩展。PAC包含在响应包AS_REP中。这里的value对应的值为True或False,KDC根据include的值来确定返回的票据中是否需要携带PAC。
    padata-type: padata类型,这里是 kRB5-PADATA-PA-PAC-REQUEST(128)
      padata-vaule: padata的值
        include-pac: 是否包含PAC,这里为True
    PADA PA-ENC-TIMESTAMP:这个是预认证,就是用用户hash加密时间戳,作为value发送给AS服务器。然后AS服务器那边有用户hash,使用用户hash进行解密,获得时间戳,如果能解密,且时间戳在一定的范围内,则证明认证通过。由于是用用户密码Hash加密的,所以也就造成了可以利用哈希传递攻击
    padata-type: padata类型,这里是 kRB5-PADATA-ENC-TIMESTAMP(2)
      padata-vaule: padata的值
        etype:  加密类型,这里是 eTYPE-AES256-CTS-HMAC-SHA1-96(18)
        cipher: 密钥
req-body:请求body
    padding:填充,这里为0
    kdc-options:用于与KDC约定一些选项设置
    cname:客户端用户名,这个用户名存在和不存在,返回的包有差异,可以用于枚举域内用户名。PrincipalName类型,包含type和Value
      name-type:名字类型,这里是 KRB5-NT-PRINCIPAL(1)
      cnmae-string:名字,也就是请求的用户名
        CNameString: 请求的用户名,这里为 kevin
    realm:域名,这里为 kevin.com
    sname:服务端用户名,PrincipalName类型,包含type和Value。在AS-REQ里面snames krbtgt
      name-type:名字类型,这里是 KRB5-NT-SRV-INST(2)
      sname-string: krbtgt用户的信息,这里有2个items
        SNameString: 这里是krbtgt用户名
        SNameString: 这里是域名 kevin.com
    till:到期时间,rubeus和kekeo都是20370913104805z,这个可以作为特征来检测工具。
    rtime:也是到期时间
    nonce:随机生成的一个数。kekeo/mimikatz nonce是12381973,rubeus nonce是1818848256,这个也可以用来作为特征检测工具。
    etype:加密类型,这里有1个items
      ENCTYPE: eTYPE-ARCFOUR-HMAC-MD5(23)

0x04 AS_REP
KDC使用用户 hash进行解密,如果结果正确返回用krbtgt hash加密的TGT票据,TGT里面包含PAC,PAC包含用户的sid,用户所在的组。

58670-1y56mrdpvmf.png

1. msg-type
ASREQ的响应body对应的就是KRBAS_REP(0x0b)

2. crealm
域名

3. cname
用户名

4. ticket
这个ticket用于TGSREQ的认证。是加密的,用户不可读取里面的内容。在ASREQ请求里面是,是使用krbtgt的hash进行加密的,因此如果我们拥有krbtgt的hash就可以自己制作一个ticket,既黄金票据。

5. enc_part
这部分是可以解密的,key是用户hash,解密后得到Encryptionkey,Encryptionkey里面最重要的字段是session key,作为下阶段的认证密钥。

50451-7lyffmftljr.png

pvno:kerberos版本号,这里为5
msg-type:消息类型,AS_REP对应的是 krb-as-rep(11)
crealm:域名
cname:请求的用户名
  name-type: 用户名类型,这里是 kRB5-NT-PRINCIPAL(1)
  cname-string: 1item
    CNameString: kevin
ticket:TGT认购权证
  tkt-vno: TGT版本号,这里为5
  realm: 域名,这里是 KEVIN.COM
  sname:
    name-type: KRB5-NT-SRV-INST(2)
    sname-string: 2items
      SNameString: krbtgt
      SNameString: kevin.com
  enc-part: 这部分是用krbtgt的密码Hash加密的。因此如果我们拥有krbtgt的hash就可以自己制作一个ticket,这就造成了黄金票据攻击
    etype: eTYPE-AES256-CTS-HMAC-SHA1-96(18)
    kvno: 版本号,这里为2
    cipher:密钥
enc-part:这部分是用用户密码Hash加密的。里面最重要的字段是Login session key,作为下阶段的认证密钥。
  etype: eTYPE-AES256-CTS-HMAC-SHA1-96(18)
  kvno: 版本号,这里为3
  cipher:密钥

0x05 导出的票据
凭据里面最核心的东西是session-key和加密的ticket。

正常我们用工具生成的凭据是.ccache和.kirbi后缀的,用mimikatz,kekeo,rubeus生成的凭据是以.kirbi后缀的。impacket 生成的凭据的后缀是.ccache。两种票据主要包含的都是session-key和加密的ticket,因此可以相互转化。

0x06 相关的安全问题
1. pass the key
在连接配置的时候允许使用hash进行认证,而不是只有账号密码才能认证。

50436-ewyvaah8o2f.png

就是由于在进行认证的时候,是用用户hash加密时间戳,即使在使用密码进行登录的情况下,也是先把密码加密成hash,再进行认证。因此在只有用户hash,没有明文密码的情况下也是可以进行认证的。不管是rubeus还是impacket里面的相关脚本都是支持直接使用hash进行认证。

其中,如果hash的ntlm hash,然后加密方式是rc4,这种就算做是pass the hash,(即使我们没有抓取到明文密码也可以尝试利用hash进行传递)

如果是hash是aes key(使用sekurlsa::ekeys导出来),就算是pass the key。在很多地方,不支持rc4加密方式的时候,使用pass the key不失为一种好方法。利用获得到的AES256或AES128进行Key攻击。

2. 用户名枚举
看以下几种情况
用户名存在,密码错误的情况下

23813-z149vqvf0e.png

用户名不存在的情况下

01256-ehixc3qsv2o.png

通过这个比较就可以写脚本改变cname的值进行用户名枚举。在域内没有域账号的情况下进行用户名枚举,在有账号的情况的下通过LDAP查询就行。如果有域内机器的system权限,那那台机器也是个域账户,账户名是机器名$.

可以使用Kerbrute工具,python脚本pyKerbrute

3. Password Spraying
在已有用户名的时候,可以尝试爆破密码。
密码正确的情况下:

27636-u4jjkt43q3i.png

密码错误的情况下:

73241-nd9tnrp2shl.png

这个时候就可以进行密码爆破了,但是在实践中,许多渗透测试人员和攻击者通常都会使用一种被称为“密码喷洒(Password Spraying)”的技术来进行测试和攻击。对密码进行喷洒式的攻击,这个叫法很形象,因为它属于自动化密码猜测的一种。这种针对所有用户的自动密码猜测通常是为了避免帐户被锁定,因为针对同一个用户的连续密码猜测会导致帐户被锁定。所以只有对所有用户同时执行特定的密码登录尝试,才能增加破解的概率,消除帐户被锁定的概率。普通的爆破就是用户名固定,爆破密码,但是密码喷洒,是用固定的密码去跑用户名。

可以用Kerbrute工具,ADPwdSpray.py脚本,powershell脚本工具DomainPasswordSpray

97667-g4unupo68xl.png

4. AS-REPRoasting
对于域用户,如果设置了选项”Do not require Kerberos preauthentication”,此时向域控制器的88端口发送ASREQ请求,对收到的ASREP内容(enc-part底下的ciper,因为这部分是使用用户hash加密session-key,我们通过进行离线爆破就可以获得用户hash)重新组合,能够拼接成”Kerberos 5 AS-REP etype 23”(18200)的格式,接下来可以使用hashcat对其破解,最终获得该用户的明文口令

47620-mjgqbjziab.png

63684-c13ilo8036l.png

可以看到事件ID为4768的TGT请求已生成日志

29154-1ou6pp1kegh.png

Rubeus.exe asreproast /format:john /outfile:hash.txt //将提取到的hash存储到一个txt中 存储格式为john可以爆破的格式

96368-7mgnk0xqa9.png

将hash.txt拿去破解即可

47783-wzr4srx6km.png

5. 黄金票据
在AS_REP里面的ticket的encpart是使用krbtgt的hash进行加密的,如果我们拥有krbtgt的hash,就可以给我们自己签发任意用户的TGT票据,这个票据也被称为黄金票据。

85415-3gh39jg5bpq.png

参考文献:
https://www.anquanke.com/post/id/190261
https://blog.csdn.net/qq_36119192/article/details/104731625


本文由 wulaoban 创作,采用 知识共享署名 3.0,可自由转载、引用,但需署名作者且注明文章出处。

还不快抢沙发

添加新评论