KRB_AP_ERR_MODIFIED w/ msDS-SupportedEncryptionTypes AES128 but not w/ AES256

Michael B Allen ioplex at gmail.com
Thu May 16 23:04:06 EDT 2024


Hi,

I have Windows client / server progs that exercise AcceptSecurityContext /
InitializeSecurityContext.
I'm studying SSPI behavior by running through the many variations in
package, enctype, mutual, qop, ... etc.
I have all of this working in Java too (from scratch, not
sun.security.kerberos) and eventually I'm going to get into IAKERB.
But for now this post is strictly Windows to Windows.

Anyway, I found a case that doesn't work and I'm trying to understand why.
It's probably unimportant and I'm just being ocd but whatev.

Short Explanation of Failure:

If the acceptor account has msDS-SupportedEncryptionTypes with AES256, it
works.

If the Computer account acting as the acceptor has
msDS-SupportedEncryptionTypes with AES128 only, AcceptSecurityContext emits
a KRB_ERROR token with KRB_AP_ERR_MODIFIED.

The Internet claims that KRB_AP_ERR_MODIFIED is emitted if ASC could not
decrypt the ticket but the password is definitely correct [1].

Long Explanation of Failure:

What follows is logging output from my client / server progs for the
working and non-working cases.

Note: AcquireCredentialsHandle is using a SEC_WINNT_AUTH_IDENTITY with
domain/user/password so the Computer account machine the progs are running
on should not be a factor.

--8<--
The following AES256 test case works.

ACCEPTOR ACCOUNT ATTRIBUTES:
  sAMAccountName: TsspiCompAes256$
  msDS-SupportedEncryptionTypes: [16] // AES256
  servicePrincipalName: [HOST/TsspiCompAes256.gema.corp]
  userAccountControl: 0x11000 // WORKSTATION_TRUST_ACCOUNT |
DONT_EXPIRE_PASSWD
ASC FLAGS: INTEG, MUTUAL, REPLAY, SEQUENCE
RESULT: SEC_E_OK

accept() success: 10.11.12.13:52669
socket_input_pstream_read: 1965
CMD_CTX_ACCEPT
struct hashmap:
  str_t [18]: "acceptor.acctname" = str_t [27]: "TsspiCompAes256$@GEMA.CORP"
  str_t [15]: "tsspi.pkg.name" = str_t [9]: "Kerberos"
  str_t [18]: "acceptor.password" = str_t [33]: "<snip>"
  str_t [10]: "targetSpn" = str_t [31]: "HOST/TsspiCompAes256.gema.corp"
  str_t [19]: "initiator.acctname" = str_t [18]: "devwin1 at GEMA.CORP"
  str_t [19]: "initiator.password" = str_t [12]: "<snip>"
  str_t [12]: "tsspi.flags" = str_t [3]: "46"
  str_t [12]: "tsspi.token" = uint8_t [1640]: 60 82 06 64 06 09 2a 86 48 ...
EnumerateSecurityPackagesA: 9 packages:
  Negotiate: fCapabilities=0x00883bb3 cbMaxToken=48256
  NegoExtender: fCapabilities=0x00913913 cbMaxToken=12000
  Kerberos: fCapabilities=0x028f3bbf cbMaxToken=48000
  NTLM: fCapabilities=0x02882b37 cbMaxToken=2888
  TSSSP: fCapabilities=0x00810230 cbMaxToken=13000
  pku2u: fCapabilities=0x00a11113 cbMaxToken=12000
  WDigest: fCapabilities=0x00800304 cbMaxToken=4096
  Schannel: fCapabilities=0x004107b3 cbMaxToken=24576
  Microsoft Unified Security Protocol Provider: fCapabilities=0x004107b3
cbMaxToken=24576
AcquireCredentialsHandle(SECPKG_CRED_INBOUND) success
QueryCredentialsAttributes success:
  acctname: TsspiCompAes256$@GEMA.CORP
  expires: Forever
inSecBuffer[0]: SECBUFFER_TOKEN: 0x0668 1640
fContextReq:
  ASC_REQ_CONNECTION
  ASC_REQ_EXTENDED_ERROR
  ASC_REQ_INTEGRITY
  ASC_REQ_MUTUAL_AUTH
  ASC_REQ_REPLAY_DETECT
  ASC_REQ_SEQUENCE_DETECT
AcceptSecurityContext: SEC_E_OK
fContextAttr:
  ASC_RET_CONNECTION
  ASC_RET_EXTENDED_ERROR
  ASC_RET_INTEGRITY
  ASC_RET_MUTUAL_AUTH
  ASC_RET_REPLAY_DETECT
  ASC_RET_SEQUENCE_DETECT
outSecBuffer: SECBUFFER_TOKEN: 0x009b 155

--8<--
The following test case fails w/ KRB_AP_ERR_MODIFIED.
The only difference between this and the working case is
msDS-SupportedEncryptionTypes is AES128 only.

ACCEPTOR ACCOUNT ATTRIBUTES:
  sAMAccountName=TsspiCompAes128$
  msDS-SupportedEncryptionTypes=[8] // AES128

servicePrincipalName=[HOST/TsspiCompAes128.gema.corp,tsspi/TsspiCompAes128.gema.corp]
  userAccountControl: 0x11000 // WORKSTATION_TRUST_ACCOUNT |
DONT_EXPIRE_PASSWD
ASC FLAGS: INTEG, MUTUAL, REPLAY, SEQUENCE
RESULT: KRB_ERROR out token with KRB_AP_ERR_MODIFIED

accept() success: 10.11.12.13:52660
socket_input_pstream_read: 1933
CMD_CTX_ACCEPT
struct hashmap:
  str_t [18]: "acceptor.acctname" = str_t [27]: "TsspiCompAes128$@GEMA.CORP"
  str_t [15]: "tsspi.pkg.name" = str_t [9]: "Kerberos"
  str_t [18]: "acceptor.password" = str_t [33]: "<snip>"
  str_t [10]: "targetSpn" = str_t [31]: "HOST/TsspiCompAes128.gema.corp"
  str_t [19]: "initiator.acctname" = str_t [18]: "devwin1 at GEMA.CORP"
  str_t [19]: "initiator.password" = str_t [12]: "<snip>"
  str_t [12]: "tsspi.flags" = str_t [3]: "46"
  str_t [12]: "tsspi.token" = uint8_t [1608]: 60 82 06 44 06 09 2a 86 48 ...
EnumerateSecurityPackagesA: 9 packages:
  Negotiate: fCapabilities=0x00883bb3 cbMaxToken=48256
  NegoExtender: fCapabilities=0x00913913 cbMaxToken=12000
  Kerberos: fCapabilities=0x028f3bbf cbMaxToken=48000
  NTLM: fCapabilities=0x02882b37 cbMaxToken=2888
  TSSSP: fCapabilities=0x00810230 cbMaxToken=13000
  pku2u: fCapabilities=0x00a11113 cbMaxToken=12000
  WDigest: fCapabilities=0x00800304 cbMaxToken=4096
  Schannel: fCapabilities=0x004107b3 cbMaxToken=24576
  Microsoft Unified Security Protocol Provider: fCapabilities=0x004107b3
cbMaxToken=24576
AcquireCredentialsHandle(SECPKG_CRED_INBOUND) success
QueryCredentialsAttributes success:
  acctname: TsspiCompAes128$@GEMA.CORP
  expires: Forever
inSecBuffer[0]: SECBUFFER_TOKEN: 0x0648 1608
 fContextReq:
  ASC_REQ_CONNECTION
  ASC_REQ_EXTENDED_ERROR
  ASC_REQ_INTEGRITY
  ASC_REQ_MUTUAL_AUTH
  ASC_REQ_REPLAY_DETECT
  ASC_REQ_SEQUENCE_DETECT
AcceptSecurityContext: SEC_I_CONTINUE_NEEDED
fContextAttr:
  ASC_RET_EXTENDED_ERROR
outSecBuffer: SECBUFFER_TOKEN: 0x0068 104
00000:  60 66 06 09 2a 86 48 86 f7 12 01 02 02 03 00 7e  |`f..*.H........~|
00010:  57 30 55 a0 03 02 01 05 a1 03 02 01 1e a4 11 18  |W0U.............|
00020:  0f 32 30 32 34 30 35 31 37 30 31 32 31 30 35 5a  |.20240517012105Z|
00030:  a5 05 02 03 05 46 24 a6 03 02 01 29 a9 0b 1b 09  |.....F$....)....|
00040:  4d 45 47 41 2e 43 4f 52 50 aa 1d 30 1b a0 03 02  |GEMA.CORP..0....|
00050:  01 01 a1 14 30 12 1b 10 54 73 73 70 69 43 6f 6d  |....0...TsspiCom|
00060:  70 41 65 73 31 32 38 24                          |pAes128$        |

The error buried in this KRB_ERROR is 0x29 KRB_AP_ERR_MODIFIED.
At 0x37 is tagnum a6 which is error_code, len 03, tag 02 is integer, len
01, value 0x29 is KRB_AP_ERR_MODIFIED.

KDC is plain Windows Server 2016.
Server prog is running on plain Windows Server 2016 domain member.
Client prog is running on same server under same session / user (hmmm...).

Packet captures look normal.
The failed case client gets an AES256 TGT and then an AES128 ticket as
expected.
[1] There is an AS-{REQ,REP} for the acceptor account which is slightly
unexpected (and fails if I sabotage the password so the password is
correct).

So does anyone know why using AES128 results in KRB_AP_ERR_MODIFIED?

Mike

-- 
Michael B Allen
Java AD DS Integration
https://www.ioplex.com/


More information about the Kerberos mailing list