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

Implement kpasswd #1189

Closed
wants to merge 3 commits into from
Closed

Implement kpasswd #1189

wants to merge 3 commits into from

Conversation

Alef-Burzmali
Copy link
Contributor

@Alef-Burzmali Alef-Burzmali commented Oct 16, 2021

Implement the Kerberos Change Password and Set Password protocols.
It fixes the second request of #1156.

As it is a completely different protocol than what smbpasswd.py is using, with different properties and constraints, I have created a new example script. It may be possible to merge the two, let me know if you would prefer it that way.

It differs from #1177 because it is not using SamrUnicodeChangePasswordUser2 to change the password, but the Kerberos Change Password protocol.

@mubix
Copy link
Contributor

mubix commented Nov 3, 2021

Seems to be not working correctly when using the KRB5CCNAME

root@ubuntu:~/impacket/examples# python3 kpasswd.py -ts -newpass 'ASDqwe123' SITTINGDUCK.INFO/uberuser
Impacket v0.9.25.dev1+20211027.123255.1dad8f7f - Copyright 2021 SecureAuth Corporation

[2021-11-03 02:57:56] [*] Current password not given: will use KRB5CCNAME
[2021-11-03 02:57:56] [*] Changing the password of \
Traceback (most recent call last):
  File "kpasswd.py", line 141, in <module>
    kpasswd.changePassword(newPassword)
  File "kpasswd.py", line 59, in changePassword
    changePassword(self.username, self.domain, newPassword, self.oldPassword, self.oldPwdHashLM, self.oldPwdHashNT, self.aesKey, kdcHost=self.kdcHost)
  File "/usr/local/lib/python3.8/dist-packages/impacket-0.9.25.dev1+20211027.123255.1dad8f7f-py3.8.egg/impacket/krb5/kpasswd.py", line 278, in changePassword
    setPassword(clientName, domain, None, None, *args, **kwargs)
  File "/usr/local/lib/python3.8/dist-packages/impacket-0.9.25.dev1+20211027.123255.1dad8f7f-py3.8.egg/impacket/krb5/kpasswd.py", line 289, in setPassword
    userName = Principal(clientName, type=PrincipalNameType.NT_PRINCIPAL.value)
  File "/usr/local/lib/python3.8/dist-packages/impacket-0.9.25.dev1+20211027.123255.1dad8f7f-py3.8.egg/impacket/krb5/types.py", line 90, in __init__
    raise KerberosException("invalid principal syntax")
impacket.krb5.types.KerberosException: invalid principal syntax

Klist:

root@ubuntu:~/impacket/examples# klist
Ticket cache: FILE:/tmp/krb5cc_0
Default principal: uberuser@SITTINGDUCK.INFO

Valid starting     Expires            Service principal
11/03/21 02:24:45  11/03/21 12:24:45  krbtgt/SITTINGDUCK.INFO@SITTINGDUCK.INFO
        renew until 11/04/21 02:24:43

@mubix
Copy link
Contributor

mubix commented Nov 3, 2021

Figured out the issue, target in the help needs to be updated:

positional arguments:
  target                [[domain/]username[:password]]

Where as the examples give an actual host for a target:

#       kpasswd.py contoso.local/j.doe:'Passw0rd!'@DC1 -newpass 'N3wPassw0rd!'

@Alef-Burzmali
Copy link
Contributor Author

Thanks for noticing that. The DC could be an optional parameter (it was originally but I changed to parse_target instead of parse_credentials, causing the bug). However, I think it is better to be coherent with smbpasswd parameters.

Implement the Kerberos Change Password and Set Password protocols.
The authentication uses Kerberos (cleartext password, hash or TGT).
The new password must be specified in cleartext and password policies
are enforced.
@Alef-Burzmali
Copy link
Contributor Author

Rebasing to latest master as this PR received some attention for CVE-2022-32744

@0xdeaddood 0xdeaddood added the in review This issue or pull request is being analyzed label Jan 18, 2023
@alexisbalbachan
Copy link
Contributor

We should wait for #1177 to be merged before reviewing this pull request.

@Alef-Burzmali
Copy link
Contributor Author

#1177 does not implement the same protocol. It uses SamrChangePasswordUser, with Kerberos autentication, whereas my PR implements the kpasswd protocol.

Some additional info here on the different protocols. Mine is 3. and 4., #1177 is 1.

@darkoperator
Copy link

fingers crossed to see this one added

@Alef-Burzmali
Copy link
Contributor Author

Is there anything more I can do to help with the review of this PR, since it has been assigned?

@anadrianmanrique
Copy link
Contributor

Hello, sorry for the delayed response. Despite #1177 (which has to be merged), we are thinking to integrate all the PRs related to password change/reset (#1304, #1207, and this one) into one example like changepaswd.py or similar.
Let us know your opinions on that. thanks!

@Alef-Burzmali
Copy link
Contributor Author

Alef-Burzmali commented May 14, 2023

Hello,
Thanks for the answer!

If I understand correctly all these PR, we have:

It would make sense from an exploitation perspective to regroup all of these similar features in the same script. However, from an example code perspective, the script would be harder to understand if not planned correctly, especially because we would mix 3 different transport protocols. Up to you to decide if you prefer focusing on "ease of use for attackers" or "clarity of example scripts for developers".

If you want to go ahead on a single "changepasswd.py" script that merge all these PR, I'd be happy to give it a try in a new PR if no one is already working on it. I'd suggest an interface like this one:

usage: changepasswd.py [-h] [-ts] [-debug] (-newpass NEWPASS | -newhashes LMHASH:NTHASH) [-hashes LMHASH:NTHASH] [-no-pass] [-k] [-aesKey hex key] [-altuser ALTUSER] [-altpass ALTPASS] [-althash ALTHASH]
                       [-protocol {smb-samr,rpc-samr,kpasswd}] [-reset] [-dc-ip ip address]
                       target

Change or reset password over different protocols.

positional arguments:
  target                [[domain/]username[:password]@]<targetName or address>

options:
  -h, --help            show this help message and exit
  -ts                   adds timestamp to every logging output
  -debug                turn DEBUG output ON
  -newpass NEWPASS      new password
  -newhashes LMHASH:NTHASH
                        new NTLM hashes, format is LMHASH:NTHASH

Authentication (target user changing their password):
  -hashes LMHASH:NTHASH
                        NTLM hashes, format is LMHASH:NTHASH
  -no-pass              Don't ask for password (useful for -k)
  -k                    Use Kerberos authentication. Grabs credentials from ccache file (KRB5CCNAME) based on target parameters. If valid credentials cannot be found, it will use the ones specified in the command line
  -aesKey hex key       AES key to use for Kerberos Authentication (128 or 256 bits)

Authentication (optional, privileged user performing the change):
  -altuser ALTUSER      Alternative username
  -altpass ALTPASS      Alternative password
  -althash ALTHASH      Alternative NT hash

Method of operations:
  -protocol {smb-samr,rpc-samr,kpasswd}
                        Protocol to use for password change/reset
  -reset, -admin        Try to reset the password with privileges (may bypass some password policies)

Connection:
  -dc-ip ip address     IP Address of the domain controller. If omitted it will use the domain part (FQDN) specified in the target parameter

Examples:
  SAMR protocol over SMB transport to change passwords (like smbpasswd.py, -protocol smb-samr is implied)
    changepasswd.py j.doe@192.168.1.11
    changepasswd.py contoso.local/j.doe@DC1 -hashes :fc525c9683e8fe067095ba2ddc971889
    changepasswd.py -protocol smb-samr contoso.local/j.doe:'Passw0rd!'@DC1 -newpass 'N3wPassw0rd!'
    changepasswd.py contoso.local/j.doe:'Passw0rd!'@DC1 -newhashes :126502da14a98b58f2c319b81b3a49cb
    changepasswd.py contoso.local/j.doe@DC1 -newhashes :126502da14a98b58f2c319b81b3a49cb -k -no-pass

  SAMR protocol over SMB transport to reset passwords (like smbpasswd.py, -protocol smb-samr is implied)
    changepasswd.py contoso.local/j.doe:'Passw0rd!'@DC1 -newpass 'N3wPassw0rd!' -altuser administrator -altpass 'Adm1nPassw0rd!'
    changepasswd.py -protocol smb-samr contoso.local/j.doe:'Passw0rd!'@DC1 -newhashes :126502da14a98b58f2c319b81b3a49cb -altuser CONTOSO/administrator -altpass 'Adm1nPassw0rd!' -reset
    changepasswd.py SRV01/administrator:'Passw0rd!'@10.10.13.37 -newhashes :126502da14a98b58f2c319b81b3a49cb -altuser CONTOSO/SrvAdm -althash 6fe945ead39a7a6a2091001d98a913ab -reset
    changepasswd.py SRV01/administrator:'Passw0rd!'@10.10.13.37 -newhashes :126502da14a98b58f2c319b81b3a49cb -altuser CONTOSO/DomAdm -k -no-pass -reset

  SAMR protocol over MS-RPC transport to change passwords
    changepasswd.py -protocol rpc-samr contoso.local/j.doe:'Passw0rd!'@DC1 -newpass 'N3wPassw0rd!'
    changepasswd.py -protocol rpc-samr contoso.local/j.doe@DC1 -newhashes :126502da14a98b58f2c319b81b3a49cb -k

  SAMR protocol over MS-RPC transport to reset passwords
    changepasswd.py -protocol rpc-samr contoso.local/j.doe@DC1 -newpass 'N3wPassw0rd!' -altuser CONTOSO/SrvAdm -althash 6fe945ead39a7a6a2091001d98a913ab -reset
    changepasswd.py -protocol rpc-samr contoso.local/j.doe@DC1 -newhashes :126502da14a98b58f2c319b81b3a49cb -altuser CONTOSO/SrvAdm -k -reset

  Kerberos Change Password protocol (like kpasswd) (-newhashes is not supported)
    changepasswd.py -protocol kpasswd contoso.local/j.doe:'Passw0rd!'@DC1 -newpass 'N3wPassw0rd!' -k

  Kerberos Reset Password protocol (like kpasswd) (-newhashes is not supported)
    changepasswd.py -protocol kpasswd contoso.local/j.doe@DC1 -newpass 'N3wPassw0rd!' -altuser CONTOSO/SrvAdm -k -reset

@anadrianmanrique
Copy link
Contributor

Wow that's really great and helpful feedback! We haven't started merging those PRs yet
Thank you!

Cherry-picked from branch changepasswd (PR fortra#1559)

Add the possibility to request a TGT for another SPN
Request a TGT with the kadmin/changepw SPN
Apply black and flake8 formatting
@Alef-Burzmali
Copy link
Contributor Author

As #1559 was merged and is a superset of this PR, I am closing this one.

@0xdeaddood 0xdeaddood removed the in review This issue or pull request is being analyzed label Jul 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants