In 2021 several dangerous and widely exploited vulnerabilities for Microsoft Exchange servers have been published. This repository provides scripts to scan for
- CVE-2021-26855: The SSRF vulnerability which is the entry point for the ProxyLogon exploit chain.
- CVE-2021-34473: The pre-auth path confusion which is the entry point for the ProxyShell exploit chain.
- CVE-2021-33766: The ProxyToken vulnerability which enables an unauthenticated attacker to perform configuration actions on mailboxes belonging to arbitrary users.
For this vulnerability we use the same logic as Microsoft's official
nmap
script,
but in a Python3 implementation.
This script was inspired by Kevin Beaumont's nmap
script,
but again, we re-implemented it in Python3. This is basically a GET
request to a certain URL which classifies servers as vulnerable if
they respond with an HTTP status code 302 Found
and as patched
in case 400 Bad Request
is returned. However, we found several
Exchange servers which responded with other codes (mainly 401 Unauthorized
), so we added code to determine the version of
the Exchange server in two ways:
- Trying to parse it from the
X-OWA-Version
header in requests to/autodiscover/autodiscover.xml
as described here - As the
X-OWA-Version
header is only present since the July 2021 updates, so as a backup strategy for older servers, the script requests/owa/
and tries to parse the version from the returned HTML. This was inpired by theget_exchange_version
function in https://github.com/cert-lv/CVE-2020-0688/blob/master/lib.py
Checking for CVE-2021-33677 a.k.a. ProxyToken is currently very rudimentary: It actually just tries to determine the version of the Microsoft Exchange server. As ProxyToken was fixed in the July 2021 Security Updates, any Exchange servers running Exchange 2013, 2016, or 2019 with a patch level prior to that are considered vulnerable.
The main script to run is scan.py
:
$ python3 scan.py --help
usage: scan.py [-h] [--method METHOD] [--timeout TIMEOUT] [--scheme {https://,http://}] [--path PATH] [--threads THREADS] [--patched PATCHED]
[--unknown UNKNOWN] [--debug]
{cve-2021-26855,cve-2021-34473,cve-2021-33766} hostlist results
positional arguments:
{cve-2021-26855,cve-2021-34473,cve-2021-33766}
The CVE number to scan for.
hostlist List of IPs/hostnames to scan. One IP/hostname per line
results CSV file to write vulnerable hosts to. Format: "ip","timestamp","exchange_version_number",exchange_version_name"
optional arguments:
-h, --help show this help message and exit
--method METHOD The HTTP method to use. Default: "GET"
--timeout TIMEOUT The timeout to use for requests in seconds. Default: 2
--scheme {https://,http://}
Scheme of the request, i.e. "http://" or "https://".
--path PATH The path on the webserver.
--threads THREADS Max number of parallel requests. Default: 300
--patched PATCHED File to write patched hosts to.
--unknown UNKNOWN File to write hosts to whose status is not known (e.g. not an Exchange, OWA not active).
--debug Print debug information.
An example run to scan all hosts in hosts.txt
for CVE-2021-34473
with default method, timeout, and number of threads:
$ python3 scan.py --path '/autodiscover/autodiscover.json?@test.com/owa/?&Email=autodiscover/autodiscover.json%3F@test.com' \
--scheme 'https://' \
--patched $(date -Id)-patched.txt \
--unknown $(date -Id)-unknown.txt \
CVE-2021-34473 exchange-ips-at.txt $(date -Id)-vulnerable.txt
Example results for patched servers:
"mx0.example.com","2021-09-01T00:00:00+00:00","15.2.858.15","Exchange Server 2019 CU9 Jul21SU"
"198.51.100.58","2021-09-01T00:00:00+00:00","15.1.2308.14","Exchange Server 2016 CU21 Jul21SU"
"198.51.100.142","2021-09-01T00:00:00+00:00","15.1.2308.14","Exchange Server 2016 CU21 Jul21SU"
"198.51.100.35","2021-09-01T00:00:00+00:00","15.1.2308.14","Exchange Server 2016 CU21 Jul21SU"
"198.51.100.144","2021-09-01T00:00:00+00:00","15.1.2308.14","Exchange Server 2016 CU21 Jul21SU"
"198.51.100.61","2021-09-01T00:00:00+00:00","15.0.1473","Exchange Server 2013 CU22"
"exchange.example.com","2021-09-01T00:00:00+00:00","15.2.922","Exchange Server 2019 CU10"
"198.51.100.92","2021-09-01T00:00:00+00:00","15.0.1497.23","Exchange Server 2013 CU23 Jul21SU"
"198.51.100.183","2021-09-01T00:00:00+00:00","15.1.2308.14","Exchange Server 2016 CU21 Jul21SU"
"198.51.100.136","2021-09-01T00:00:00+00:00","15.0.1497.23","Exchange Server 2013 CU23 Jul21SU"
This project is partially funded by the CEF framework