Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Executing code on LOCAL exchange server #47

Closed
goooroooX opened this issue Aug 23, 2019 · 8 comments · Fixed by #78
Closed

Executing code on LOCAL exchange server #47

goooroooX opened this issue Aug 23, 2019 · 8 comments · Fixed by #78

Comments

@goooroooX
Copy link

Hi! I'm trying to implement following PS code with pypsrp for the local Exchange server:

$Session = (New-PSSession -configurationname Microsoft.Exchange -connectionURI http://exchange-srv.acme.com/PowerShell)
Import-PSSession $Session
Search-AdminAuditLog -StartDate '07-17-2019 09:00:00' -EndDate '07-18-2019 11:00:00'

PS code works fine, but not pypsrp version:

from pypsrp.powershell import PowerShell, RunspacePool
from pypsrp.wsman import WSMan

wsman = WSMan(server="exchange-srv.acme.com", port=5985, path="wsman", username="DOMAIN\\user", password="password", ssl=False, auth="kerberos", cert_validation=False)

with RunspacePool(wsman, configuration_name="Microsoft.Exchange") as pool:
    ps = PowerShell(pool)
    ps.add_script("Search-AdminAuditLog -StartDate '07-17-2019 09:00:00' -EndDate '07-18-2019 11:00:00'")
    output = ps.invoke()
    print output

The code above return resource exception:

pypsrp.exceptions.WSManFaultError: Received a WSManFault message. (Code: 2150858811, Machine: srv-scn-cas1.scnsoft.com, Reason: The WS-Management service cannot process the request. The resource URI (http://schemas.microsoft.com/powershell/Microsoft.Exchange) was not found in the WS-Management catalog. The catalog contains the metadata that describes resources, or logical endpoints.)

When changing "path" to "powershell", I got 404:

HTTP Error 404. The requested resource is not found.

Can anyone help to identify the problem?
Thank you in advance!

NOTE: issue duplicate is here.

@jborean93
Copy link
Owner

That's interesting, based on your PowerShell snipped I would assume you would need to have path="PowerShell" but you are saying that is returning a 404? I don't believe URLs are case sensitive but maybe try it in the exact case you are specifying.

To truly figure out what is happening I would have to see a Wireshark capture of the first WSMan message that your PowerShell code generates. This would show the full URI it is connected to as well as the WSMan Shell Create message which is where the ConfigurationName is used. The trouble is that this would be encrypted so you need to disable the encryption checks on both the client and the server for this to be useful.

Anyway let's first try setting path="PowerShell" to rule out it being case sensitive.

@goooroooX
Copy link
Author

"PowerShell" makes the same 404. Unfortunately I cannot disable encryption on a server. Any other suggestions how can I debug it?

@jborean93
Copy link
Owner

Darn it was worth a try.

Any other suggestions how can I debug it?

There's not too much else you can do but this is worth a shot;

  • Capture the traffic in WireShark and see the URI endpoint your actual PowerShell snippet is hitting
    • This will help determine the full URI that pypsrp should be using and to confirm what endpoint PowerShell is actually using
  • Use a HTTPS endpoint and something like Fiddler in between to see the plaintext without disabling the actual encryption checks
    • It is possible to do this but is a bit complicated

I had a look at the code for New-PSSession and it lines up with what I expect. Using -ConnectionURI means the URI you specify is used explicitly and -ConfigurationName is just appended to http://schemas.microsoft.com/powershell/ which is what pypsrp is doing.

There might be some event logs in Windows when using PowerShell itself but I'm honestly not sure what there is for the client side remote powershell operations. Maybe running your New-PSSession and Import-PSSession cmdlets with the -Verbose parameter and see if it returns any good info

@goooroooX
Copy link
Author

Thank you for assistance. I will comment on this issue if I will be able to handle this problem.

@goooroooX
Copy link
Author

I was unable to find a direct way to utilize "Microsoft.Exchange" configuration with pypsrp, but the code below works fine for my purpose. It's ugly but works.

from pypsrp.powershell import PowerShell, RunspacePool
from pypsrp.wsman import WSMan

USER = "DOMAIN\\user"
PASS = "password"

wsman = WSMan(server="exchange-srv.acme.com", port=5985, username=USER, password=PASS, ssl=False, auth="kerberos", cert_validation=False)

script = """
    $username = "%s"
    $password = ConvertTo-SecureString "%s" -AsPlainText -Force
    $UserCredential = new-object -typename System.Management.Automation.PSCredential -argumentlist $username, $password
    $Session = (New-PSSession -configurationname Microsoft.Exchange -connectionURI http://exchange-srv.acme.com/PowerShell -Authentication Kerberos -Credential $UserCredential)
    Import-PSSession $Session
    Search-AdminAuditLog -StartDate '08-28-2019 09:00:00' -EndDate '08-28-2019 12:00:00' | Out-String
    """ % (USER, PASS)

with RunspacePool(wsman) as pool:
    ps = PowerShell(pool)
    ps.add_script(script)
    output = ps.invoke()
    print "=============================================="
    if ps.had_errors:
        print("ERROR:\n%s" % "\n".join([str(s) for s in ps.streams.error]))
    else:
        print("OUTPUT:\n%s" % "\n".join([str(s) for s in output]))
        print("DEBUG:\n%s" % "\n".join([str(s) for s in ps.streams.debug]))
        print("VERBOSE:\n%s" % "\n".join([str(s) for s in ps.streams.verbose]))
    print "=============================================="

@olivier-monaco
Copy link

Hi,

Exchange Remote Management is available throught IIS. You need to use port 443 and path PowerShell. Example:

    wsman = WSMan(
        server=server,
        auth="kerberos",
        ssl=True,
        cert_validation=False,
        username=user,
        password=password,
        path='PowerShell',
        port=443
    )

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

This worked fine for me with (very old) Exchange 2010 but no more with recent Exchange.

@jborean93
Copy link
Owner

Sorry it took so long but this has been fixed with #78. Yo have to make sure you set path='PowerShell' and port=80 in the WSMan object and use the configuration_name="Microsoft.Exchange as shown above.

@goooroooX
Copy link
Author

Thank you for information.
Most likely I will not update my existing code, as it was tested and now working in production.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants