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

Review of NTLM reflection attack over network #451

Closed
remi-cc opened this issue May 14, 2018 · 26 comments
Closed

Review of NTLM reflection attack over network #451

remi-cc opened this issue May 14, 2018 · 26 comments

Comments

@remi-cc
Copy link

remi-cc commented May 14, 2018

HI all,

I'm a little bit confused of what are the options for a reflection attack (NTLM auth back to the victim which is different from a general relay attack) on an up-to-date W10 host.
Let me explain what i have understand :

  • SMB NTLM auth reflect back to SMB is patched since 2008 (MS08-068)
  • NTLM auth reflect back to SMB (like HTTP => SMB) is patched since 2016. This was the goal of Hot Potato by @breenmachine
  • DCOM DCE (via BITS) to RPC endpoint (TCP port 135) is still working (RottenPotato by @breenmachine or lonelypotato by @decoder-it)
    Ok, but demo of these attacks is always done on the victim's host (loopback @ip). Well, my questions are:
  • Is it possible to manage these reflection attack (or another) over the local network on an fully update W10 host?
  • Does Impacket implement these attacks ?
    I know that @asolino and @dirkjanm discussed about it in an 2 years old issue (NTLMRelayX SMB->MSSQL Failure #188 (comment)) but conclusion was quite unclear for me.

Regards,

Rémi

@remi-cc remi-cc changed the title Review of NTLM reflect back attack over network Review of NTLM reflection attack over network May 14, 2018
@dirkjanm
Copy link
Contributor

What I know about this:

  • Relaying back to the same machine over the network is patched for all protocols. I'll do some more tests this week to confirm this, but I'm pretty sure it won't work anymore.
  • Same-machine NTLM authentication is quite a bit different than network NTLM authentication. I personally haven't researched this, so I'm not sure if this is still possible or patched, but it can't be compared with authentication over the network (it uses different fields for example in the NTLM packets).
  • Relaying back to the same machine is supported by impacket, but as mentioned above it isn't likely to work on patched hosts.

@decoder-it
Copy link

Well, for the "rotten" part it is possible to split the various components (rpc end point mapper and dedicated listener - the one who listens by default on port 6666 ) but why would you need that?

@breenmachine
Copy link

"NTLM auth reflect back to SMB (like HTTP => SMB) is patched since 2016" <- I don't think this is actually true. It's been a while since I've looked at this, but I don't think this is how they patched the original Potato exploit. From what I remember from the testing I did after the patch, HTTP=>SMB on the same machine with an AD account still worked.

@decoder-it
Copy link

As far as I know, only SMB->SMB reflect back is patched.

@decoder-it
Copy link

I think the issue still persists if you enable WPAD and LLMNR

@remi-cc
Copy link
Author

remi-cc commented May 14, 2018

Well, thanks for your replies.
Here the keypoints i have noticed from the discussion above about reflection attack :

  • SMB => SMB is patched, everybody agrees
  • HTTP=>SMB, there is differents point of view
    => @dirkjanm thinks that every reflection cross-protocol attack over the network is patched but he will check this week (thank to you to share yours results).
    => @breenmachine think that this attack still works (but need an AD account for the victim).
    => @decoder-it think that this attack still works (but need to enable WPAD and LLMNR).
    => @breenmachine and @decoder-it, do you have time to manage some trials with your ideas? Because i made some with WPAD and LLMNR and i didn't succeed in the HTTP =>SMB attack (WPAD and LLMNR was enabled, but it was a local account).
  • @decoder-it thinks that is possible to split the various components of RottenPotato (rpc end point mapper and dedicated listener)
    => it would be interesting to do so, but @dirkjanm thinks that the authentication over the network is different from same-machine NTLM authentication (it uses apparently different fields in the NTLM packets). @decoder-it, do you have time to modify your code and manage a trial?

@asolino
Copy link
Collaborator

asolino commented May 14, 2018

Great discussion guys. I'm also hesitating all the scenarios that were patched so looking forward to seeing the results.

it would be interesting to do so, but @dirkjanm thinks that the authentication over the network is different from same-machine NTLM authentication (it uses apparently different fields in the NTLM packets).

Here's some data that could be useful to understand that scenario.

@decoder-it
Copy link

@remi-cc , some time ago I did a test splitting the "lonelypoato" in two parts, the rpc end point client (connecting to port 135 on a different host ) and the custom listener on localhost and as far as rememeber it worked.

@remi-cc
Copy link
Author

remi-cc commented May 14, 2018

@decoder-it, thanks for your remembers. If i well understand, you are talking about relay attack but not a reflection attack. Can you process another trial with custom listener on another host in the same local network, reflecting NTLM on the victim RPC end point?
The key point in this scenario is : ok, how can we force victim to make a DCOM BITS request to our rogue custom listener? Well, as far as i remember, some windows services use BITS DCOM (like WSUS or Win update). If you are inside the local network, you should wait few time to poison theses services in order to receive to your custom listener a request from theses services, didn't you?

@dirkjanm
Copy link
Contributor

Just did some tests:

  • HTTP -> SMB
    • Windows 10 1803: Fail
    • Server 2016 1607: Fail
    • Server 2012R2 (Exchange server): Success
    • Server 2012R2 (Domain controller): Fail
  • HTTP -> LDAP
    • Server 2016 1607: Fail
    • Server 2012R2 (Domain controller): Fail
  • HTTP -> HTTP
    • Server 2012R2 (Exchange server): Success
  • SMB -> LDAP (though it is in impossible attack type due to signing incompatibilities)
    • Server 2016 1607: Fail
    • Server 2012R2 (Domain controller): Fail
  • HTTP -> IMAP
    • Server 2012R2 (Exchange server): Success
  • HTTP -> SMTP
    • Server 2012R2 (Exchange server): Success

So cross-protocol reflection seems definitely patched in Server 2016 / Windows 10 (which share the same codebase). I'm confused about the Server 2012R2 results, with my Exchange server (latest May 2018 patches installed) allowing cross-protocol relaying but my Server 2012R2 DC not allowing it.

@breenmachine
Copy link

breenmachine commented May 14, 2018 via email

@dirkjanm
Copy link
Contributor

I'll test it with SMB signing disabled but there is a difference between authentication not being accepted and the attack not working. For example my Server 2016 DC (signing enabled) accepts authentication from a different host just fine, but attacks won't work:

user@localhost:~/impacket$ ntlmrelayx.py -t smb://192.168.222.113
[*] Servers started, waiting for connections
[*] HTTPD: Received connection from 192.168.222.55, attacking target smb://192.168.222.113
[*] HTTPD: Client requested path: /kyojtd65bs
[*] HTTPD: Client requested path: /kyojtd65bs
[*] Authenticating against smb://192.168.222.113 as TESTSEGMENT\testuser SUCCEED
[-] SMB SessionError: STATUS_ACCESS_DENIED({Access Denied} A process has requested access to an object but has not been granted those access rights.)

@dirkjanm
Copy link
Contributor

Just disabled SMB signing on the S2012 DC, rebooted, verified with nmap SMB signing is disabled. Did not change the results, relaying to the same host still does not work.

@remi-cc
Copy link
Author

remi-cc commented May 14, 2018

Thank @dirkjanm for yours results, very usefull. My opinion :

  • DC (2012 or 2016) must require SMB signing but this is not the case (by default) for workstation or server. I verified on my WIN10 laptop and SMB signing is not required (HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\LanmanServer\Parameters\requiresecuritysignature set to 0).
  • With MS16-075 which patched CVE-2016-3225, i think that SMB cross-protocol reflection attack is not possible, that's why i don't understand your result with 2012R2 exchange server. @dirkjanm, can you check if MS16-075 (3164038) is installed on your exchange server?
  • best option now for fully update station is to focus on cross-protocol reflection attack without SMB, like DCOM / RPC protocol (or maybe HTTP / RPC ?). Great, this is the purpose of RottenPotato for the first option.
    => @breenmachine and @decoder-it, i can't wait to see your results if you want to try to split your custom server on a network host.

PS : i found an another usefull link from MS about SMB : https://blogs.msdn.microsoft.com/openspecification/2017/05/26/smb-2-and-smb-3-security-in-windows-10-the-anatomy-of-signing-and-cryptographic-keys/

@dirkjanm
Copy link
Contributor

I just tried HTTP->SMB on a new Server 2012 server as well, did not work (both with local and domain accounts).
I'm guessing my Exchange server is just missing a patch for some reason or falling back to old behaviour because of some configuration. I can't find the patch KB3164038 in the install history on that server, but with all the replacement patches it might still be installed.

@asolino
Copy link
Collaborator

asolino commented Jul 4, 2018

Thanks for the info guys, very useful, I referenced it at a recent blogpost I wrote. Closing this one now, feel free to keep including any extra data that could be useful to better understand these scenarios.

@asolino asolino closed this as completed Jul 4, 2018
@existXFx
Copy link

@dirkjanm In HTTP->SMB, whether all clients that send http requests use the WinHTTP library?
I think even if microsoft fixed HTTP->SMB reflection, a http client that implements ntlm authentication itself(not WinHTTP) may still be able to do it.

@rskvp93
Copy link

rskvp93 commented Jan 14, 2019

@dirkjanm There is a vulnerability of exchange server that use HTTP->HTTP (EWS) NTLM replay attack.
Detail: https://www.zerodayinitiative.com/blog/2018/12/19/an-insincere-form-of-flattery-impersonating-users-on-microsoft-exchange

Exchange set the registry HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\DisableLoopbackCheck = 1 by default.

Microsoft fix this vulnerablity by remove that registry key. So enable loopback check.

I don't understand the purpose of that key. Does anyone know it, please?

@existXFx
Copy link

existXFx commented Jan 14, 2019

@rskvp93 If this value does not exist or is dword 0, Windows will check if the ntlm type3 message cache in memory is the same as the other type3 messages sent to this machine. If the same, Windows will think that someone is trying to make an ntlm reflection attack.
In this ews vulnerability, Microsoft can block ntlm reflection attacks by deleting this key, but this can't block ntlm relay attack, which will pass credentials to other machines.

@lean0x2F
Copy link

lean0x2F commented Jan 23, 2019

Disclaimer: @asolino, sorry to hijack this issue, I'm trying to learn more about these kind of attacks and the EWS vulnreability is a nice excuse. If this question doesn't belong here please feel free to delete my comment.

What I'm seeing in the Exchange vulnerability is that the HTTP -> HTTP reflection is in fact a local authentication, not a relay of signed challenges by the same machine (classic reflection), which is weird given that this is authentication over the network, not via loopback.

When the EWS server receives the relayed NTLM_NEGOTIATE from the attacker, it answers with 0x00004000 flag set (Negotiate Local Auth) because the NTLM_NEGOTIATE domain and workstation security buffers match the ones from the server. In this case, challenge is not required to be answered by the client, signing is ignored, and the client simply has to populate the SSPI handle and send an empty NTLM_AUTHENTICATE. I have seen this behaviour on both Exchange 2016 and Exchange 2010 SP2.

For example:

Type 1:

$echo -n "TlRMTVNTUAABAAAAB7IIogQABAAwAAAACAAIACgAAAAKADk4AAAAD0VYQ0hBTkdFTEFCTw==" | python ntlmdecoder.py
Found NTLMSSP header
Msg Type: 1 (Request)
Domain: 'LABO' [4c41424f] (4b @48)
Workstation: 'EXCHANGE' [45584348414e4745] (8b @40)
OS Ver: '??98????'
Flags: 0x-5df74df9 ["Negotiate Unicode", "Negotiate OEM", "Request Target", "Negotiate NTLM", "Negotiate Domain Supplied", "Negotiate Workstation Supplied", "Negotiate Always Sign", "Negotiate NTLM2 Key", "unknown", "Negotiate 128", "Negotiate 56"]

Type 2:

echo -n "TlRMTVNTUAACAAAACAAIADgAAAAFwomiGlu+trbPFcwAxi5rJAIAAIoAigBAAAAACgA5OAAAAA9MAEEAQgBPAAIACABMAEEAQgBPAAEAEABFAFgAQwBIAEEATgBHAEUABAAUAGwAYQBiAG8ALgBsAG8AYwBhAGwAAwAmAEUAWABDAEgAQQBOAEcARQAuAGwAYQBiAG8ALgBsAG8AYwBhAGwABQAUAGwAYQBiAG8ALgBsAG8AYwBhAGwABwAIAHTDhXNIs9QBAAAAAA==" | python ntlmdecoder.py 
Found NTLMSSP header
Msg Type: 2 (Challenge)
Target Name: u'LABO' [4c00410042004f00] (8b @56)
Challenge: 0xcc15cfb6b6be5b1a
Context: '' [] (-14848b @548) alloc: 27438
Target: [block] (138b @64)
    AD domain name (2): LABO
    Server name (1): EXCHANGE
    DNS domain name (4): labo.local
    FQDN (3): EXCHANGE.labo.local
    Parent DNS domain (5): labo.local
    Server Timestamp (7): tÅsH��
OS Ver: '??98????'
Flags: 0x-5d763dfb ["Negotiate Unicode", "Request Target", "Negotiate NTLM", "Negotiate Local Call", "Negotiate Always Sign", "Target Type Domain", "Negotiate NTLM2 Key", "Negotiate Target Info", "unknown", "Negotiate 128", "Negotiate 56"]

Type 3:

$echo -n "TlRMTVNTUAADAAAAAAAAAFgAAAAAAAAAWAAAAAAAAABYAAAAAAAAAFgAAAAAAAAAWAAAAAAAAABYAAAABcKIogoAOTgAAAAP7t5IygWBHiLYy2DKYbZLYg==" | python ntlmdecoder.py
Found NTLMSSP header
Msg Type: 3 (Response)
LM Resp: '' [] (0b @88)
NTLM Resp: '' [] (0b @88)
Target Name: '' [] (0b @88)
User Name: '' [] (0b @88)
Host Name: '' [] (0b @88)
Session Key: '' [] (0b @88)
OS Ver: '??98????'
Flags: 0x-5d773dfb ["Negotiate Unicode", "Request Target", "Negotiate NTLM", "Negotiate Local Call", "Negotiate Always Sign", "Negotiate NTLM2 Key", "Negotiate Target Info", "unknown", "Negotiate 128", "Negotiate 56"]

My questions are:

  1. Is this normal HTTP -> HTTP reflection behaviour? If that's the case, can it be extrapolated to other protocols in order to force a local authentication over network?
  2. DisableLoopbackCheck seems to be a protection against reflection attacks, but I don't see any mention to local authentication. @existXFx, when you mention "ntlm type3 message cache in memory" are you referring to the SSPI handle?

Thank you

@existXFx
Copy link

existXFx commented Feb 3, 2019

@lean0x2F For your first question, I don't think this is a normal http-> http reflection behavior.

The 0x00004000 flag is set by the server. After receiving this flag, the client usually chooses to send null credentials (at least I know that java will do this), but that doesn't mean the client can successfully authenticate to the server, which I think depends on how the server handles it.

As for whether it can be extralated to other protocols, I think it is not possible (in most cases). If I really understand what you mean, let me give you an example: in http->smb reflection, specify the client as the java client, the service is the windows smb service, in the test, the smb service sets the 0x00004000 flag, java sends a null credential, and the smb service returns a login failure.

For the second question, my answer comes from Microsoft's description of the patch ms08-068. You can find it Here. In fact, I don't know. I am trying to do some reverse engineering, which takes some time.

@decoder-it
Copy link

Regarding the Local Auth. I know it is negotiated by the server and the client. If local auth is possible, the client sends his wokstation and domain name in the type 1 message and if the server agrees , he sets the Negotiate Local Call flag. Again if the client agrees , the type 3 message is empty and local auth via security buffers will take place. My question is: is it possible to trick the client/server to force local auth?

@existXFx
Copy link

existXFx commented Feb 4, 2019

@decoder-it @lean0x2F Interesting ideas, but at the moment I don't think this is possible in most cases. This is not based on some rigorous reasons, just my personal opinion, because I did not find any way to force the server to perform local auth. The Local Auth flag is set by the server, but even if it is set in the test, the server may not recognize the null credentials sent by the client.

I will continue to study your thoughts. If there are any new discoveries, please let me know.

@decoder-it
Copy link

I did some tests because my idea was trying to bypass the "OXID resolver" fix MS implemented in latest version of win 10 & server 2019. In order to get the rotten/juicy potato work (local aurh NTLM reflection), I need to set a remote address for the RPC server and then rdirect it back to my machine listening on a non standard port. I "forged" the NTLM type 1 2 3 packets but the aximum I obtained was a token from ANONYMOUS user (https://decoder.cloud/2018/10/29/no-more-rotten-juicy-potato/)

@martingalloar
Copy link
Contributor

As this thread keeps serving (at least to me) as some sort of inspiration for new variants and techniques, wanted to leave this excellent piece from @decoder-it on the saga: https://labs.sentinelone.com/relaying-potatoes-dce-rpc-ntlm-relay-eop/ . Kudos @decoder-it and Antonio!

@decoder-it
Copy link

Thanks! we just managed to get i work outside session 0 too

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

No branches or pull requests

9 participants