fortra / impacket

Impacket is a collection of Python classes for working with network protocols.
https://www.coresecurity.com
Other
13.49k stars 3.57k forks source link

Feature Request - Kerberos support for SMBPasswd.py #1156

Closed mubix closed 1 year ago

mubix commented 3 years ago

It would be very awesome to support kerberos (if possible) for password changes.

mubix commented 3 years ago

I tried this in smbclient.py and got STATUS_WRONG_PASSWORD even though, as you can see I logged in just fine.

# ./smbclient.py -k -no-pass bob@dc1.sittingduck.info
Impacket v0.9.24.dev1+20210906.175840.50c76958 - Copyright 2021 SecureAuth Corporation

Type help for list of commands
# password
New Password:
[-] SAMR SessionError: code: 0xc000006a - STATUS_WRONG_PASSWORD - When trying to update a password, this return status indicates that the value provided as the current password is not correct
ShutdownRepo commented 3 years ago

Logging in is not the issue here. Here's what @p0dalirius and I can tell you about this.

When attempting a password change, the SamrUnicodeChangePasswordUser2 method is invoked by smbclient.py. This method requires multiple arguments including the OldNtOwfPasswordEncryptedWithNewNt which is the old user's password hash. When you authenticated using kerberos, you used -no-pass so that smbclient.py doesn't ask you the user password, resulting in an empty "oldpassword" variable.

The following should work. It uses Kerberos pass-the-cache AND uses the user password supplied for the password change to work.

$ export KRB5CCNAME=user1.ccache
$ ./smbclient.py -k -debug "lab.local"/"user1":"oldPassword123"@"dc01"
Impacket v0.9.23 - Copyright 2021 SecureAuth Corporation

[+] Impacket Library Installation Path: /usr/local/lib/python2.7/dist-packages/impacket-0.9.23-py2.7.egg/impacket
[+] Using Kerberos Cache: user1.ccache
[+] SPN CIFS/DC01@LAB.LOCAL not found in cache
[+] AnySPN is True, looking for another suitable SPN
[+] Returning cached credential for KRBTGT/LAB.LOCAL@LAB.LOCAL
[+] Using TGT from cache
[+] Trying to connect to KDC at 192.168.2.1
Type help for list of commands
# password
New Password:
# exit

Regarding smbpasswd.py, supporting Kerberos would still require users to have knowledge of the old user password, or password hash. Still, @p0dalirius and I are working on a PR to add Kerberos support.

On a side note: obtaining knowledge of the actual user hash from a Kerberos/PKINIT authentication could be done via an UnPAC-the-Hash attack.

p0dalirius commented 3 years ago

We checked with @ShutdownRepo, and it is not possible to perform a password change with SamrUnicodeChangePasswordUser2 using Kerberos when the current password is expired (STATUS_PASSWORD_EXPIRED), since the bypass relies on a null session, which cannot be obtained through Kerberos.

However we submitted a pull request to smbpasswd.py and it is now possible to authenticate using Kerberos (only when password is not expired).

Here is a demo:

image

mpgn commented 3 years ago

I see cme I press thumb up

mubix commented 3 years ago

If you use changepw instead of SamrUnicodeChangePasswordUser2 you can set the password without the need of the old password when you have a valid kerberos ticket - see here:

I realize this would fall outside of the "smb" part of smbpasswd.py so it might be worth a kpasswd.py ? but personally it would be more convenient in my opinion to have it in a single example script.

Alef-Burzmali commented 3 years ago

You may be interested in #1189. I have preferred to create a new script (kpasswd) because the two protocols and implementations are very different.

gabrielg5 commented 1 year ago

Merged in master @ https://github.com/fortra/impacket/pull/1559