jborean93 / pypsrp

PowerShell Remoting Protocol for Python
MIT License
328 stars 49 forks source link

Connecting to Exchange online with protected account #117

Closed vletoux closed 3 years ago

vletoux commented 3 years ago

I'm working in a company and I'm not an admin that can do what I want. I'm trying to automate the "Get-MessageTrace" but from a tool named TheHive used for incident response. My goal is to get the emails associated to a reported email.

For security reasons, the tenant is protected by MFA. I've requested a service account secured by a certificate, but in the meantime, I'm working on making Get-MessageTrace working on linux.

The official api endpoint for accessing the report is not working with modern auth: https://reports.office365.com/ecp/reportingwebservice/reporting.svc/MessageTrace

So I found out how to do it with powhershell:

Install-Module -Name ExchangeOnlineManagement -Scope CurrentUser
Connect-ExchangeOnline -UserPrincipalName xxxx@yyyy.onmicrosoft.com
Get-MessageTrace

But the problem is that I have to put the login / password in a webpage, and it's not working on a command line only.

Until I found this article: https://www.michev.info/Blog/Post/2997/connecting-to-exchange-online-powershell-via-client-secret-flow which split my problem in 2 parts: 1) get the token 2) open the session.

In short, you can get the token by intercepting Connect-ExchangeOnline with a proxy, then creating the remote powershell session: image The trick is that the OAuth token is sent to O365 by using a special account OAuthUser@<your tenantid> with the password being the OAuth token.

I then tried to reuse that exact same token by using pypsrp Here is the code I used (based on other support request I saw github)

wsman = WSMan("outlook.office365.com", port=443, ssl=True, auth="basic", encryption="auto", path="PowerShell-LiveId?BasicAuthToOAuthConversion=true", proxy="127.0.0.1:8888", cert_validation=False,
              username="OAuthUser@<your tenant id>", password="Bearer " + token)

with RunspacePool(wsman, configuration_name="Microsoft.Exchange") as pool:

image

With the loggin activated, as described on github, I saw this error message: pypsrp.exceptions.WSManFaultError: Received a WSManFault message. (Code: 2150858843, Machine: outlook.office365.com, Reason: The request for the Windows Remote Shell with ShellId 1886A617-95D8-4A29-A69B-36E83F6FAF85 failed because the shell was not found on the server. Possible causes are: the specified ShellId is incorrect or the shell no longer exists on the server. Provide the correct ShellId or create a new shell and retry the operation.)

I saw previous issues on github related to a warning that added Microsoft, but this doesn't seems to be the case here.

The code is crashing when creating the "pool". I see on the proxy a 200 code request, followed by a 500 code one.

Help welcomed

vletoux commented 3 years ago

If this can help

Message 1: request: <s:Envelope xmlns:rsp="http://schemas.microsoft.com/wbem/wsman/1/windows/shell" xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsman="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd" xmlns:wsmv="http://schemas.microsoft.com/wbem/wsman/1/wsman.xsd"><s:Header><wsa:Action s:mustUnderstand="true">http://schemas.xmlsoap.org/ws/2004/09/transfer/Create</wsa:Action><wsmv:DataLocale s:mustUnderstand="false" xml:lang="en-US" /><wsman:Locale s:mustUnderstand="false" xml:lang="en-US" /><wsman:MaxEnvelopeSize s:mustUnderstand="true">153600</wsman:MaxEnvelopeSize><wsa:MessageID>uuid:B8D50CE1-43D5-44A4-AFD2-43CDC72F0C78</wsa:MessageID><wsman:OperationTimeout>PT20S</wsman:OperationTimeout><wsa:ReplyTo><wsa:Address s:mustUnderstand="true">http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:Address></wsa:ReplyTo><wsman:ResourceURI s:mustUnderstand="true">http://schemas.microsoft.com/powershell/Microsoft.Exchange</wsman:ResourceURI><wsmv:SessionId s:mustUnderstand="false">uuid:94B3CA7E-D7C3-4BEB-9E24-02E9C217C6C6</wsmv:SessionId><wsa:To>https://outlook.office365.com:443/PowerShell-LiveId?BasicAuthToOAuthConversion=true</wsa:To><wsman:OptionSet s:mustUnderstand="true"><wsman:Option MustComply="true" Name="protocolversion">2.3</wsman:Option></wsman:OptionSet></s:Header><s:Body><rsp:Shell ShellId="A815A18A-F9A6-4830-996F-71BF85C65029"><rsp:InputStreams>stdin pr</rsp:InputStreams><rsp:OutputStreams>stdout</rsp:OutputStreams><creationXml xmlns="http://schemas.microsoft.com/powershell">AAAAAAAAAAEAAAAAAAAAAAMAAADHAgAAAAIAAQCKoRWopvkwSJlvcb+FxlApAAAAAAAAAAAAAAAAAAAAADxPYmogUmVmSWQ9IjAiPjxNUz48VmVyc2lvbiBOPSJwcm90b2NvbHZlcnNpb24iPjIuMzwvVmVyc2lvbj48VmVyc2lvbiBOPSJQU1ZlcnNpb24iPjIuMDwvVmVyc2lvbj48VmVyc2lvbiBOPSJTZXJpYWxpemF0aW9uVmVyc2lvbiI+MS4xLjAuMTwvVmVyc2lvbj48L01TPjwvT2JqPgAAAAAAAAACAAAAAAAAAAADAAAC/QIAAAAEAAEAiqEVqKb5MEiZb3G/hcZQKQAAAAAAAAAAAAAAAAAAAAA8T2JqIFJlZklkPSIwIj48TVM+PEkzMiBOPSJNaW5SdW5zcGFjZXMiPjE8L0kzMj48STMyIE49Ik1heFJ1bnNwYWNlcyI+MTwvSTMyPjxPYmogUmVmSWQ9IjEiIE49IlBTVGhyZWFkT3B0aW9ucyI+PFROIFJlZklkPSIwIj48VD5TeXN0ZW0uTWFuYWdlbWVudC5BdXRvbWF0aW9uLlJ1bnNwYWNlcy5QU1RocmVhZE9wdGlvbnM8L1Q+PFQ+U3lzdGVtLkVudW08L1Q+PFQ+U3lzdGVtLlZhbHVlVHlwZTwvVD48VD5TeXN0ZW0uT2JqZWN0PC9UPjwvVE4+PFRvU3RyaW5nPkRlZmF1bHQ8L1RvU3RyaW5nPjxJMzI+MDwvSTMyPjwvT2JqPjxPYmogUmVmSWQ9IjIiIE49IkFwYXJ0bWVudFN0YXRlIj48VE4gUmVmSWQ9IjEiPjxUPlN5c3RlbS5NYW5hZ2VtZW50LkF1dG9tYXRpb24uUnVuc3BhY2VzLkFwYXJ0bWVudFN0YXRlPC9UPjxUPlN5c3RlbS5FbnVtPC9UPjxUPlN5c3RlbS5WYWx1ZVR5cGU8L1Q+PFQ+U3lzdGVtLk9iamVjdDwvVD48L1ROPjxUb1N0cmluZz5VTktOT1dOPC9Ub1N0cmluZz48STMyPjI8L0kzMj48L09iaj48T2JqIFJlZklkPSIzIiBOPSJIb3N0SW5mbyI+PE1TPjxCIE49Il9pc0hvc3ROdWxsIj50cnVlPC9CPjxCIE49Il9pc0hvc3RVSU51bGwiPnRydWU8L0I+PEIgTj0iX2lzSG9zdFJhd1VJTnVsbCI+dHJ1ZTwvQj48QiBOPSJfdXNlUnVuc3BhY2VIb3N0Ij50cnVlPC9CPjwvTVM+PC9PYmo+PE5pbCBOPSJBcHBsaWNhdGlvbkFyZ3VtZW50cyIgLz48L01TPjwvT2JqPg==</creationXml></rsp:Shell></s:Body></s:Envelope> response: <s:Envelope xml:lang="en-US" xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:x="http://schemas.xmlsoap.org/ws/2004/09/transfer" xmlns:w="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd" xmlns:rsp="http://schemas.microsoft.com/wbem/wsman/1/windows/shell" xmlns:p="http://schemas.microsoft.com/wbem/wsman/1/wsman.xsd"><s:Header><a:Action>http://schemas.xmlsoap.org/ws/2004/09/transfer/CreateResponse</a:Action><a:MessageID>uuid:0433185E-AD94-4486-8588-360C42522328</a:MessageID><a:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:To><a:RelatesTo>uuid:B8D50CE1-43D5-44A4-AFD2-43CDC72F0C78</a:RelatesTo></s:Header><s:Body><x:ResourceCreated><a:Address>https://outlook.office365.com:443/PowerShell-LiveId?BasicAuthToOAuthConversion=true</a:Address><a:ReferenceParameters><w:ResourceURI>http://schemas.microsoft.com/powershell/Microsoft.Exchange</w:ResourceURI><w:SelectorSet><w:Selector Name="ShellId">1886A617-95D8-4A29-A69B-36E83F6FAF85</w:Selector></w:SelectorSet></a:ReferenceParameters></x:ResourceCreated><rsp:Shell xmlns:rsp="http://schemas.microsoft.com/wbem/wsman/1/windows/shell"><rsp:ShellId>1886A617-95D8-4A29-A69B-36E83F6FAF85</rsp:ShellId><rsp:ResourceUri>http://schemas.microsoft.com/powershell/Microsoft.Exchange</rsp:ResourceUri><rsp:Owner>s-1-5-21-1055359317-2347530276-3947479235-28792284</rsp:Owner><rsp:ClientIP>2603:10a6:102:1fb::21</rsp:ClientIP><rsp:IdleTimeOut>PT900.000S</rsp:IdleTimeOut><rsp:InputStreams>stdin pr</rsp:InputStreams><rsp:OutputStreams>stdout</rsp:OutputStreams><rsp:ShellRunTime>P0DT0H0M0S</rsp:ShellRunTime><rsp:ShellInactivity>P0DT0H0M0S</rsp:ShellInactivity></rsp:Shell></s:Body></s:Envelope>

Message 2: request <s:Envelope xmlns:rsp="http://schemas.microsoft.com/wbem/wsman/1/windows/shell" xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsman="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd" xmlns:wsmv="http://schemas.microsoft.com/wbem/wsman/1/wsman.xsd"><s:Header><wsa:Action s:mustUnderstand="true">http://schemas.microsoft.com/wbem/wsman/1/windows/shell/Receive</wsa:Action><wsmv:DataLocale s:mustUnderstand="false" xml:lang="en-US" /><wsman:Locale s:mustUnderstand="false" xml:lang="en-US" /><wsman:MaxEnvelopeSize s:mustUnderstand="true">153600</wsman:MaxEnvelopeSize><wsa:MessageID>uuid:415F4A8E-FFF9-4BC1-9D34-6A76CCBE727B</wsa:MessageID><wsman:OperationTimeout>PT20S</wsman:OperationTimeout><wsa:ReplyTo><wsa:Address s:mustUnderstand="true">http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:Address></wsa:ReplyTo><wsman:ResourceURI s:mustUnderstand="true">http://schemas.microsoft.com/powershell/Microsoft.Exchange</wsman:ResourceURI><wsmv:SessionId s:mustUnderstand="false">uuid:94B3CA7E-D7C3-4BEB-9E24-02E9C217C6C6</wsmv:SessionId><wsa:To>https://outlook.office365.com:443/PowerShell-LiveId?BasicAuthToOAuthConversion=true</wsa:To><wsman:OptionSet s:mustUnderstand="true"><wsman:Option Name="WSMAN_CMDSHELL_OPTION_KEEPALIVE">True</wsman:Option></wsman:OptionSet><wsman:SelectorSet><wsman:Selector Name="ShellId">1886A617-95D8-4A29-A69B-36E83F6FAF85</wsman:Selector></wsman:SelectorSet></s:Header><s:Body><rsp:Receive><rsp:DesiredStream>stdout</rsp:DesiredStream></rsp:Receive></s:Body></s:Envelope> response <s:Envelope xml:lang="en-US" xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:x="http://schemas.xmlsoap.org/ws/2004/09/transfer" xmlns:e="http://schemas.xmlsoap.org/ws/2004/08/eventing" xmlns:n="http://schemas.xmlsoap.org/ws/2004/09/enumeration" xmlns:w="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd" xmlns:p="http://schemas.microsoft.com/wbem/wsman/1/wsman.xsd"><s:Header><a:Action>http://schemas.dmtf.org/wbem/wsman/1/wsman/fault</a:Action><a:MessageID>uuid:A0C77440-F7D3-4CE4-B723-7977CCED8115</a:MessageID><a:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:To><a:RelatesTo>uuid:415F4A8E-FFF9-4BC1-9D34-6A76CCBE727B</a:RelatesTo></s:Header><s:Body><s:Fault><s:Code><s:Value>s:Sender</s:Value><s:Subcode><s:Value>w:InvalidSelectors</s:Value></s:Subcode></s:Code><s:Reason><s:Text xml:lang="en-US">The WS-Management service cannot process the request because the request contained invalid selectors for the resource. </s:Text></s:Reason><s:Detail><w:FaultDetail>http://schemas.dmtf.org/wbem/wsman/1/wsman/faultDetail/UnexpectedSelectors</w:FaultDetail><f:WSManFault xmlns:f="http://schemas.microsoft.com/wbem/wsman/1/wsmanfault" Code="2150858843" Machine="outlook.office365.com"><f:Message>The request for the Windows Remote Shell with ShellId 1886A617-95D8-4A29-A69B-36E83F6FAF85 failed because the shell was not found on the server. Possible causes are: the specified ShellId is incorrect or the shell no longer exists on the server. Provide the correct ShellId or create a new shell and retry the operation. </f:Message></f:WSManFault></s:Detail></s:Fault></s:Body></s:Envelope>

vletoux commented 3 years ago

On my opinion, what's most probably the problem, we can see a set-cookie at the response of message 1. The cookie is not reused on message 2 image image

while on the ps remote session that is working, the cookie is set: image

We can see also that the sessionID=OAuthUser@tenantId is added to the url

vletoux commented 3 years ago

ok, found the problem.

Short version: typed PowerShell-LiveI instead of PowerShell-LiveID (final d in lowercase vs uppercase) As a consequence, the cookie lib doesn't match the url because there is a case sensitive comparison. But the Windows url is case insensitive.

Suggested fix: add a warning if the returned url is the same, but with a different case.