GSS unwrap fails using RC4 session key instead of subkey
Michael B Allen
ioplex at gmail.com
Thu May 8 00:10:51 EDT 2025
On Wed, May 7, 2025 at 5:59 PM Greg Hudson <ghudson at mit.edu> wrote:
> OR
> the acceptor subkey has a different enctype from the initiator subkey
>
Ah! Thanks for the detailed answer.
I think I figured out the problem.
TLDR; My acceptor does not "Negotiated enctype" to aes256-cts and so the
MITK initiator uses the Authenticator subkey (nevermind about the session
key being used, I must have been looking at the Authenticator subkey).
However, I think I found a minor difference between Windows Kerberos and
MITK ...
Long version:
If I run the gss-client to my acceptor with an RC4 service, I get output
like [heavily pruned]:
gdb ${GSS_CLIENT} -ex 'break make_seal_token_v1' -ex "run -port 8443 -nm
-user user1 at BUSI.CORP -pass 'Pas\$word' as5api.busi.corp
'HTTP at as5api.busi.corp' 'Hello, World!'"
ASIDE: The gdb issue was because the password had a $ symbol which needs to
be escaped in the gdb run parameters string.
Generated subkey for TGS request: aes256-cts/CBD2
etypes requested in TGS request: aes256-cts, aes128-cts, aes256-sha2,
aes128-sha2, des3-cbc-sha1, rc4-hmac, camellia128-cts, camellia256-cts
TGS reply is for user1 at BUSI.CORP -> HTTP/as5api.busi.corp at BUSI.CORP with
session key rc4-hmac/8152
Creating authenticator for user1 at BUSI.CORP -> HTTP/as5api.busi.corp@,
seqnum 7969486, subkey rc4-hmac/9579, session key rc4-hmac/8152
Read AP-REP, time 1746669048.152087, subkey rc4-hmac/387E, seqnum 334043650
Notice how my acceptor returned an rc4-hmac AS-REP subkey.
Breakpoint 1, make_seal_token_v1 (context=0x40c3f0, enc=0x413770,
seq=0x410b50, seq..._gss_oid_array>) at k5seal.c:80
80 unsigned int conflen=0, tmsglen, tlen, msglen;
(gdb) p *(krb5_key)enc
$1 = {keyblock = {magic = -1760647421, enctype = 23, length = 16, contents
= 0x40d0c0 "\311R\237\211\v\353V\334No\316t\024", <incomplete sequence
\351\246>},
refcount = 1, derived = 0x0, cache = 0x0}
(gdb) x/16bx 0x40d0c0
0x40d0c0: 0xc9 0x52 0x9f 0x89 0x0b 0xeb 0x56 0xdc
0x40d0c8: 0x4e 0x6f 0xce 0x74 0x14 0x1f 0xe9 0xa6
So the session key used starts with C952.
Meanwhile ... my acceptor logs the following:
AcceptStepState: GssContextToken {
mech: KRB5 (1.2.840.113554.1.2.2)
Krb5InnerContextToken {
tokId: 0x0001
ApReq {
ap-options: 0x20000000
ticket: Ticket {
sname: HTTP/as5api.busi.corp at BUSI.CORP
enc-part: (23)0B36A2...
}
authenticator: (23)5DA124...
}
}
}
AcceptStepState: EncTicketPart {
flags: 0x40A10000
key: (23)EE19E3...
cname: user1 at BUSI.CORP
transited: (1)
authtime: 20250508015048Z
starttime: 20250508015048Z
endtime: 20250508115048Z
renew-till: 20250515015048Z
authorization-data: (1)798
}
AcceptStepState: Authenticator {
cname: user1 at BUSI.CORP
cksum: Checksum8003 {
channelBindings: 00000000000000000000000000000000
gssflags: 0x00000136
GSS_C_DELEG_FLAG
Y GSS_C_MUTUAL_FLAG
Y GSS_C_REPLAY_FLAG
GSS_C_SEQUENCE_FLAG
Y GSS_C_CONF_FLAG
Y GSS_C_INTEG_FLAG
Y 0x0100
GSS_C_DCE_STYLE
GSS_C_IDENTIFY_FLAG
GSS_C_EXTENDED_ERROR_FLAG
}
cusec: 152087
ctime: 20250508015048Z
subkey: (23)C9529F...
seq-number: 7969486
authorization-data: (1)34
}
AcceptStepState: EncAPRepPart {
ctime: 20250508015048Z
cusec: 152087
subkey: (23)54DDA9...
seq-number: 334043650
}
AcceptStepState: GssContextToken {
mech: KRB5 (1.2.840.113554.1.2.2)
Krb5InnerContextToken {
tokId: 0x0002
ApRep {
enc-part: (23)9BB121...
}
}
}
Rc4 unwrap: key:
00000: C9 52 9F 89 0B EB 56 DC 4E 6F CE 74 14 1F E9 A6 |ÉR...ëVÜNoÎt..é¦|
MTGS: unwrap: start=45,db=45,di=45,de=59,frame=0,tailspace=0
00000: 48 65 6C 6C 6F 2C 20 57 6F 72 6C 64 21 01 |Hello, World!. |
Indeed C952 is the Authenticator subkey.
I hacked my acceptor in this case to use the Authenticator subkey whereas
normally it uses the AP-REP subkey and unwrap() fails w/ checksum failure.
-
If I run the MITK gss-client against the MITK gss-server, I get output like
[heavily pruned]:
Starting program: /ioplex/krb5-1.21.1/src/appl/gss-sample/gss-client -port
8443 -nm -user user1 at BUSI.CORP -pass 'Pas$word' rky9as1.busi.corp
'HTTP at rky9as1.busi.corp' 'Hello, World!'
Selected etype info: etype aes256-cts, salt "BUSI.CORPdev", params ""
AS key obtained for encrypted timestamp: aes256-cts/49BF
Selected etype info: etype aes256-cts, salt "BUSI.CORPdev", params ""
AS key determined by preauth: aes256-cts/49BF
Decrypted AS reply; session key is: aes256-cts/5A73
Generated subkey for TGS request: aes256-cts/97B5
etypes requested in TGS request: aes256-cts, aes128-cts, aes256-sha2,
aes128-sha2, des3-cbc-sha1, rc4-hmac, camellia128-cts, camellia256-cts
TGS reply is for user1 at BUSI.CORP -> HTTP/rky9as1.busi.corp at BUSI.CORP with
session key rc4-hmac/0FC8
Creating authenticator for user1 at BUSI.CORP -> HTTP/rky9as1.busi.corp@,
seqnum 854939001, subkey rc4-hmac/7A54, session key rc4-hmac/0FC8
Read AP-REP, time 1746669951.877933, subkey aes256-cts/7F1F, seqnum
1042191560
Notice how the MITK acceptor returns an aes256-cts AP-REP subkey.
Meanwhile ... the MITK acceptor logs the following:
Decrypted AP-REQ with server principal HTTP/rky9as1.busi.corp at BUSI.CORP:
rc4-hmac/C6A3
AP-REQ ticket: user1 at BUSI.CORP -> HTTP/rky9as1.busi.corp at BUSI.CORP, session
key rc4-hmac/0FC8
Negotiated enctype based on authenticator: aes256-cts
Authenticator contains subkey: rc4-hmac/7A54
Creating AP-REP, time 1746669951.877933, subkey aes256-cts/7F1F, seqnum
1042191560
Sending accept_sec_context token (size=152):
The MITK acceptor "Negotiated enctype" to aes256-cts and thus, because "the
acceptor subkey has a different enctype from the initiator subkey" the MITK
initiator uses the AP-REP subkey.
-
If I run the Windows SSPI initiator to my acceptor (don't have code to do
Windows SSPI to MITK gss-server), I get the following:
AcceptStepState: GssContextToken {
mech: KRB5 (1.2.840.113554.1.2.2)
Krb5InnerContextToken {
tokId: 0x0001
ApReq {
ap-options: 0x20000000
ticket: Ticket {
sname: HOST/TsspiCompRc4.mega.corp at MEGA.CORP
enc-part: (23)1DF8CE...
}
authenticator: (23)860718...
}
}
}
AcceptStepState: EncTicketPart {
flags: 0x40A10000
key: (23)D5C724...
cname: TsspiUser5 at MEGA.CORP
transited: (1)
authtime: 20250508025530Z
starttime: 20250508025530Z
endtime: 20250508125530Z
renew-till: 20250515025530Z
authorization-data: (1)750,(1)67
}
AcceptStepState: Authenticator {
cname: TsspiUser6 at MEGA.CORP
cksum: Checksum8003 {
channelBindings: 00000000000000000000000000000000
gssflags: 0x0000402E
GSS_C_DELEG_FLAG
Y GSS_C_MUTUAL_FLAG
Y GSS_C_REPLAY_FLAG
Y GSS_C_SEQUENCE_FLAG
GSS_C_CONF_FLAG
Y GSS_C_INTEG_FLAG
GSS_C_DCE_STYLE
GSS_C_IDENTIFY_FLAG
Y GSS_C_EXTENDED_ERROR_FLAG
}
cusec: 8264
ctime: 20250508025900Z
subkey: (23)9C4977...
seq-number: 781048158
authorization-data: (1)127
}
AcceptStepState: EncAPRepPart {
ctime: 20250508025900Z
cusec: 8264
subkey: (23)36662C...
seq-number: 703851114
}
AcceptStepState: GssContextToken {
mech: KRB5 (1.2.840.113554.1.2.2)
Krb5InnerContextToken {
tokId: 0x0002
ApRep {
enc-part: (23)17EE50...
}
}
}
This is with my acceptor just unconditionally using the AP-REP subkey which
works with the Windows SSPI initiator and unwrap() is successful.
So the SSPI initiator does not appear to use the Authenticator subkey if
the enctypes are the same.
I guess this isn't much of a problem since it would only occur if the
acceptor doesn't properly "Negotiated enctype" to aes256-cts.
But technically this would be a difference in behavior between Windows SSPI
and MIT Kerberos.
Mike
--
Michael B Allen
Java AD DS Integration
https://www.ioplex.com/ <http://www.ioplex.com/>
More information about the Kerberos
mailing list