kerberos协议

kerberos协议中的角色与简单流程

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

在kerberos协议之中主要是有三个角色存在:

  • Client(用户):发出访问服务的角色
  • Server(服务):提供服务的角色
  • KDC(Key Distribution Center)密钥分发中心:分发密钥的角色

在一个域林之中,KDC服务默认会安装在域控之中,而client和server是域内的用户或者服务。在kerberos认证过程中client是否有权限访问server的服务就由KDC发放的票据决定

简化的Kerberos认证流程图

名词概念

AD(Account Datebase):账户数据库

Master Key: 用户密码的一种hash值

Ticket(票据):域网络对象相互访问的凭证

TGT(Ticket Granting Ticket 票据授予票据):用于向KDC获取服务票据的凭证

TGS(Silver Ticket 服务票据):用于向Server请求服务的凭证

Authentication Service(身份认证服务):认证Client 的身份,并为其发放TGT的服务,是KDC的一部分

Ticket Granting Service(票据发放服务):检验Client发来的TGT,并为其生成某个Server的TGS,是KDC的一部分。

  1. AS_REQ(认证服务请求):Client向KDC发送AS_REQ,请求的凭据是Client的hash(这个hash是根据输入的密码生成的)加密的时间戳。
  2. AS_REP(认证服务响应):KDC向发出AS_REQ的Client发出响应,去如果认证成功就返回一个TGT
  3. TGS_REQ(票据发放服务请求):Client凭借TGT向KDC发送对某一Server的TGS_REQ
  4. TGS_REP(票据发放服务响应):KDC验证TGT,如果验证正确就根据请求的服务返回对应的TGS,不管是否有权向访问Server
  5. AP_REQ(服务请求):Client凭借TGS向Server发起服务请求
  6. AP_REP(服务响应):Server验证TGS,如果验证正确就向KDC询问,Client是否有权限获得服务,如果有就返回响应

AS_REQ

数据包结构拆解

Kerberos
    Record Mark: 294 bytes
        0... .... .... .... .... .... .... .... = Reserved: Not set
        .000 0000 0000 0000 0000 0001 0010 0110 = Record Length: 294
    as-req
        pvno: 5
        msg-type: krb-as-req (10)
        padata: 2 items
            PA-DATA PA-ENC-TIMESTAMP
                padata-type: kRB5-PADATA-ENC-TIMESTAMP (2)
                    padata-value: 3041a003020112a23a04384e3857102e1da38ea37695b42c…
                        etype: eTYPE-AES256-CTS-HMAC-SHA1-96 (18)
                        cipher: 4e3857102e1da38ea37695b42cc877f2dfbc29a67c6c8f21…
            PA-DATA PA-PAC-REQUEST
                padata-type: kRB5-PADATA-PA-PAC-REQUEST (128)
                    padata-value: 3005a0030101ff
                        include-pac: True
        req-body
            Padding: 0
            kdc-options: 40810010
                0... .... = reserved: False
                .1.. .... = forwardable: True
                ..0. .... = forwarded: False
                ...0 .... = proxiable: False
                .... 0... = proxy: False
                .... .0.. = allow-postdate: False
                .... ..0. = postdated: False
                .... ...0 = unused7: False
                1... .... = renewable: True
                .0.. .... = unused9: False
                ..0. .... = unused10: False
                ...0 .... = opt-hardware-auth: False
                .... 0... = unused12: False
                .... .0.. = unused13: False
                .... ..0. = constrained-delegation: False
                .... ...1 = canonicalize: True
                0... .... = request-anonymous: False
                .0.. .... = unused17: False
                ..0. .... = unused18: False
                ...0 .... = unused19: False
                .... 0... = unused20: False
                .... .0.. = unused21: False
                .... ..0. = unused22: False
                .... ...0 = unused23: False
                0... .... = unused24: False
                .0.. .... = unused25: False
                ..0. .... = disable-transited-check: False
                ...1 .... = renewable-ok: True
                .... 0... = enc-tkt-in-skey: False
                .... .0.. = unused29: False
                .... ..0. = renew: False
                .... ...0 = validate: False
            cname
                name-type: kRB5-NT-PRINCIPAL (1)
                cname-string: 1 item
                    CNameString: testuser
            realm: HACKE
            sname
                name-type: kRB5-NT-SRV-INST (2)
                sname-string: 2 items
                    SNameString: krbtgt
                    SNameString: HACKE
            till: 2037-09-13 02:48:05 (UTC)
            rtime: 2037-09-13 02:48:05 (UTC)
            nonce: 19228112
            etype: 6 items
                ENCTYPE: eTYPE-AES256-CTS-HMAC-SHA1-96 (18)
                ENCTYPE: eTYPE-AES128-CTS-HMAC-SHA1-96 (17)
                ENCTYPE: eTYPE-ARCFOUR-HMAC-MD5 (23)
                ENCTYPE: eTYPE-ARCFOUR-HMAC-MD5-56 (24)
                ENCTYPE: eTYPE-ARCFOUR-HMAC-OLD-EXP (-135)
                ENCTYPE: eTYPE-DES-CBC-MD5 (3)
            addresses: 1 item WIN10-X64-TEST<20>
                HostAddress WIN10-X64-TEST<20>
                    addr-type: nETBIOS (20)
                    NetBIOS Name: WIN10-X64-TEST<20> (Server service)
  • pvno

kerberos版本号

  • msg-type

windows消息类型,AS_REQ的自然是krb-as-req

  • padata(pre-authentication data 预认证数据)

是一些认证信息,是一个列表,内部有若干个认证消息,每一个认证消息有type和value。

具体可看:Kerberos PA-DATA

  • req-body

    • kdc-options

    这是一些KDC的option开启情况,属于一种标识位。 mit文档

    • cname

    这是Client的主机名,采用的是PrincipalName 类型和string类型的组合。sname也是采用这种格式

    PrincipalName 类型

    KRB_NT_PRINCIPAL 用户主体名称类型

    KRB_NT_SRV-INST 服务和其他唯一实例(krbtgt)的名称类型

    KRB_NT_SRV_HST 服务主机名称为实例名的名称类型

    KRB_NT_SRV_XHST 服务与主机作为剩余组件名称类型

    KRB_NT_UID 唯一ID名称类型

    KRB_NT_UNKNOWN 未知名称类型

    • realm

    服务端域名

    • sname

    这是是服务端的身份和所属域,注意在AS_REQ中服务端指的是提供AS的KDC,所以正常的sname-string字段的值就应该是krbtgt和其所属域.

    • till

    到期时间

    • etype

    加密类型,在请求报文之中每个有加密的数据都有一个etype字段对应,KDC就是从这段数据中加密方式,来从AD之中选择对应的hash来进行身份验证

    • addresses

    地址相关信息@

KDC接收AS_REQ的行为

两个重要的padata(pre-authentication data 预认证数据)

PA-ENC-TIMESTAMP

这个预认证数据是Client用自己的Master key加密时间戳得到的一串字符, AS拿到这个段数据之后就会根据etype去AD里面寻找对应的用户hash(用户名取自cname),并使用这个hash解密时间戳, 如果解密成功, 并且时间戳在一定范围之内,则这个预认证数据通过.

PA-PAC-REQUEST

这个预认证数据是关于微软的一个扩展---PAC, 这个扩展的基本作用就是为kerberos添加"权限认证"的能力. 开启这项扩展,AS完成时间戳的认证之后就会将PAC(内部包涵Client的sid和所在组)放TGT的认证数据之中, 一起返回给Client, PAC关系到之后Server判断Client是否有权限访问服务

AS_REP

拆解数据包

Kerberos
    Record Mark: 1550 bytes
        0... .... .... .... .... .... .... .... = Reserved: Not set
        .000 0000 0000 0000 0000 0110 0000 1110 = Record Length: 1550
    as-rep
        pvno: 5
        msg-type: krb-as-rep (11)
        padata: 1 item
            PA-DATA PA-ENCTYPE-INFO2
                padata-type: kRB5-PADATA-ETYPE-INFO2 (19)
                    padata-value: 3020301ea003020112a1171b154841434b452e544553544c…
                        ETYPE-INFO2-ENTRY
                            etype: eTYPE-AES256-CTS-HMAC-SHA1-96 (18)
                            salt: HACKE.TESTLABtestuser
        crealm: HACKE.TESTLAB
        cname
            name-type: kRB5-NT-PRINCIPAL (1)
            cname-string: 1 item
                CNameString: testuser
        ticket
            tkt-vno: 5
            realm: HACKE.TESTLAB
            sname
                name-type: kRB5-NT-SRV-INST (2)
                sname-string: 2 items
                    SNameString: krbtgt
                    SNameString: HACKE.TESTLAB
            enc-part
                etype: eTYPE-AES256-CTS-HMAC-SHA1-96 (18)
                kvno: 2
                cipher: 07b5d35de5b1ac006b831ff508a5ced14a010563418fd736…
        enc-part
            etype: eTYPE-AES256-CTS-HMAC-SHA1-96 (18)
            kvno: 4
            cipher: 70246fe54be2b6395f20dc6845b970d16bb3319ab304e3bb…

主要关注与AS_REQ不同的点

  • ticket

    这就是AS派发的TGT票据,内部所有密文的密钥都是krbtgtNTLM hash,如果能拿到krbtgtNTLM hash我们既可以伪造TGT,这就是黄金票据

    • tkt-vno

      票据版本

    • realm

      派发票据的KDC的所属域

    • sname

      派发票据的角色再KDC的身份,一般是kbrtgt

    • enc-part

      使用kbrtgtNTLM hash作为密钥生成的TGT主体

  • enc-part

    这部分是使用Client的hash为key加密Session key得到的,主要用于作为下阶段(TGS阶段)的认证密钥。

AS阶段的安全问题

用户名枚举

在AS认证截断,用户名存在和密码错误的响应报文错误码不同,

  • 用户名不存在的响应错误码是6:KDC_ERR_C_PRINCIPAL_UNKNOWN 未知的主机名

  • 密码错误,用户名存在的响应错误码是24:KDC_ERR_PREAUTH_PAILED 预认证失败

通过这个比较AS_REP里的错误码就可实行 用户名枚举 .

黄金票据

AS_ERP里的tikcet的encpart是使用kbrtgtNTLM hashkey加密而成的,所以只要拿到了kbrtgtNTLM hash就可以伪造TGT,这个伪造出来的票据就叫做 黄金票据

TGS_REQ

拆解数据包

Frame 40: 62 bytes on wire (496 bits), 62 bytes captured (496 bits) on interface \Device\NPF_{FBDB2B2D-DEF3-473C-87EF-787E4B606694}, id 0
Ethernet II, Src: VMware_f0:d8:2b (00:0c:29:f0:d8:2b), Dst: VMware_e6:ab:e6 (00:0c:29:e6:ab:e6)
Internet Protocol Version 4, Src: 192.168.1.2, Dst: 192.168.1.1
Transmission Control Protocol, Src Port: 49731, Dst Port: 88, Seq: 1461, Ack: 1, Len: 8
[2 Reassembled TCP Segments (1468 bytes): #39(1460), #40(8)]
Kerberos
    Record Mark: 1464 bytes
    tgs-req
        pvno: 5
        msg-type: krb-tgs-req (12)
        padata: 2 items
            PA-DATA PA-TGS-REQ
                padata-type: kRB5-PADATA-TGS-REQ (1)
                    padata-value: 6e8204f4308204f0a003020105a10302010ea20703050000…
            PA-DATA PA-PAC-OPTIONS
                padata-type: kRB5-PADATA-PAC-OPTIONS (167)
                    padata-value: 3009a00703050040000000
        req-body
            Padding: 0
            kdc-options: 40810000
                0... .... = reserved: False
                .1.. .... = forwardable: True
                ..0. .... = forwarded: False
                ...0 .... = proxiable: False
                .... 0... = proxy: False
                .... .0.. = allow-postdate: False
                .... ..0. = postdated: False
                .... ...0 = unused7: False
                1... .... = renewable: True
                .0.. .... = unused9: False
                ..0. .... = unused10: False
                ...0 .... = opt-hardware-auth: False
                .... 0... = unused12: False
                .... .0.. = unused13: False
                .... ..0. = constrained-delegation: False
                .... ...1 = canonicalize: True
                0... .... = request-anonymous: False
                .0.. .... = unused17: False
                ..0. .... = unused18: False
                ...0 .... = unused19: False
                .... 0... = unused20: False
                .... .0.. = unused21: False
                .... ..0. = unused22: False
                .... ...0 = unused23: False
                0... .... = unused24: False
                .0.. .... = unused25: False
                ..0. .... = disable-transited-check: False
                ...0 .... = renewable-ok: False
                .... 0... = enc-tkt-in-skey: False
                .... .0.. = unused29: False
                .... ..0. = renew: False
                .... ...0 = validate: False
            realm: HACKE.TESTLAB
            sname
                name-type: kRB5-NT-SRV-HST (3)
                sname-string: 2 items
                    SNameString: host
                    SNameString: win10-x64-test.hacke.testlab
            till: 2037-09-13 02:48:05 (UTC)
            nonce: 19595592
            etype: 5 items
                ENCTYPE: eTYPE-AES256-CTS-HMAC-SHA1-96 (18)
                ENCTYPE: eTYPE-AES128-CTS-HMAC-SHA1-96 (17)
                ENCTYPE: eTYPE-ARCFOUR-HMAC-MD5 (23)
                ENCTYPE: eTYPE-ARCFOUR-HMAC-MD5-56 (24)
                ENCTYPE: eTYPE-ARCFOUR-HMAC-OLD-EXP (-135)
  • msg-type

    windows消息格式,krb-tgs-req

  • padata

    这部分携带了TGS_REQ最重要的数据—TGT票据,TGT票据以ap-req的形式存放在数据包之中。KDC会校验TGT,如果正确就返回TGS票据

    这部分数据和还包含PAC和S4U2SELF,这个之后其他文章单独说

  • req-body

    格式和之前的请求报文基本一致,只是这里的sname换成了Client想要请求服务的Server的名字

TGS_REP

数据包拆解

Kerberos
    Record Mark: 1495 bytes
        0... .... .... .... .... .... .... .... = Reserved: Not set
        .000 0000 0000 0000 0000 0101 1101 0111 = Record Length: 1495
    tgs-rep
        pvno: 5
        msg-type: krb-tgs-rep (13)
        crealm: HACKE.TESTLAB
        cname
            name-type: kRB5-NT-PRINCIPAL (1)
            cname-string: 1 item
                CNameString: testuser
        ticket
            tkt-vno: 5
            realm: HACKE.TESTLAB
            sname
                name-type: kRB5-NT-SRV-HST (3)
                sname-string: 2 items
                    SNameString: host
                    SNameString: win10-x64-test.hacke.testlab
            enc-part
                etype: eTYPE-AES256-CTS-HMAC-SHA1-96 (18)
                kvno: 1
                cipher: 1fc40f7b907bea22e5606abf4f0575c113b8f5ee8d87ce4f…
        enc-part
            etype: eTYPE-AES256-CTS-HMAC-SHA1-96 (18)
            cipher: e4705cfafb271944be50c33f4576bb4b4e449357fbdbb18f…
  • msg-type

    windows消息格式,krb-tgs-rep

  • crealm

    Client所属域

  • cname

    Client的身份名

  • ticket

    这就是最终的票据,是使用Client请求服务的Server的hash作为key来加密得到的。内部包含:Server session keyClient info (Domain name\client)end time (到期时间)

  • enc-part

    这一部分是使用AS认证中得Session key为key加密成得内部有Server session key,主要用于下轮用户认证(AP阶段)
    # NTML协议

LM Hash&NTML Hash

windows内部是不保存明文密码的,只保存密码的hash值

本机的用户密码hash是放在本地的SAM文件里面,域内用户的密码hash存在域控的NTDS.DIT文件的。

windows密码hash保存模式,类似如下

Administrator:500:AAD3B435B51404EEAAD3B435B51404EE:31D6CFE0D16AE931B73C59D7E0C089C0:::

AAD3B435B51404EEAAD3B435B51404EELM hash

31D6CFE0D16AE931B73C59D7E0C089C0NTML hash

LM hash (LAN Manager Hash) 老密码

LM Hash 的算法

  1. 将用户密码转化为大写,再将转化后的密码转化成十六进制字符串,不足14字节将会使用0再末尾补全。
  2. 上一步得到的十六进制字符串分成两个7byte的部分,每部分转化成byte流,长度为56bit,长度不足的使用0在左边补齐。
  3. 再分为7bit一组,每组末尾加0,凑足8bit,重新组回两组。
  4. 上步骤得到的二组,分别作为Key对KGS!@#$%进行DES加密。
  5. 加密后的两组拼接到一起,得到最终的LM Hash

LM Hash的一些弊端

  • 密码方面的限制
    • 密码长度最大只能为14个字符
    • 密码不区分大小写
  • 加密过程中的一些漏洞
    • 如果密文的后半部分是aad3b435b51404ee,那么就意味着,这个密码的长度是小于等于7位的,密码强度大大减少
    • des密码强度并不高

NTLM hash

NTLM hash 的算法

  1. 将用户的密码转化成16进制形式
  2. 把转化成16进制的密码进行unicode编码
  3. 使用MD4摘要算法对上一步得到的unicode编码进行hash计算

NTLM hash本地的认证

当用户注销、重启、锁屏之后,windows会让winlogon显示登陆界面,接收用户的输入之后,会将将密码交付给lsass进程,这个进程会将明文密码加密成NTLM hash,再与SAM数据库里对应的用户密码做对比。

  • winlogon(Windows logon process)windows注册进程:是windows NT 用户的登陆程序,用于管理用户的登陆与退出

  • lsass( Local Security Authority Service): 用于本地安全与登陆策略

  • SAM(Security Account Manager 安全账户管理):windows采用的账户管理策略,这个策略会将本地组的用户的账户和hash加密之后保存到SAM数据库中,SAM数据库文件路径是%systemroot%\system32\config\SAM文件

NTLM 身份验证机制

NTLM 身份验证采用的是 Challenge(挑战)/Response(响应)验证机制,有三步组成:协商,质询,身份验证

客户机与服务器的交互过程示意图(域控不参加的情况)

  • 协商:Client会发送一个带有用户信息(用户名)和服务器请求的功能列表
  • 质询:Server对Client发出的协商 做出回应,返回的内容包含服务器同意并且支持的功能列表,更重要的是包含了服务器产生的challenge
  • 身份验证:Client对Server返回的质询 做出回应,使用根具输入的密码生成的NTMLM hash质询 中的challenge进行加密运算得到response,然后将response、用户名、challenge一起返回给Server

关于challenge:服务端生成的一个随机字符用于验证Client的身份,NTLM v1中为8位,NTLM v2中为16位

关于Net-NTML hash:基于用户hash经过一定算法产生的。

关于response:本质上就是一个net-NTLM hash

点击收藏 | 5 关注 | 1
  • 动动手指,沙发就是你的了!
登录 后跟帖