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

This Tools is not run for Ex2010 ? #108

Closed
rezatbahtera opened this issue Mar 7, 2021 · 26 comments
Closed

This Tools is not run for Ex2010 ? #108

rezatbahtera opened this issue Mar 7, 2021 · 26 comments
Assignees

Comments

@rezatbahtera
Copy link

Unable TO find type [PS Credential]: make sure that the assembly containing this step loaded
image

@bill-long
Copy link
Member

Hmm... this was working on 2010 initially. Investigating.

@bill-long bill-long self-assigned this Mar 7, 2021
@bill-long
Copy link
Member

It's definitely broken when running locally on 2010, and there are several changes needed to get it working due to the older version of PowerShell.

One option is to Enable-PSRemoting on 2010 and then run it from somewhere else, using the -ComputerName parameter to point it to the 2010 server. That does work.

Another option is to run the blog commands manually on 2010.

Keep in mind that the script is of limited use on 2010 even in a fully working state. The commands from the blog post search several folders that don't exist on 2010. I think the goal for this script will be to run the tests we can, remotely, against 2010, and fail gracefully where the tests don't apply to 2010.

@dinonovak
Copy link

Confirming SBS 2011 when run locally is throwing the same error.
Please fix as this is the only server in infrastructure so no remote option possible.

@mahmoudshoaala
Copy link

mahmoudshoaala commented Mar 7, 2021

Try to bind the $credential function with = get-credential "domain\username", you know you need at least PS Version 4.0.

@Wizzdk
Copy link

Wizzdk commented Mar 8, 2021

Check if your shortcut to "Exchange Management Shell" includes "-version 2.0" in the parameters.
If so, remove this and try again.
Exchange Management Shell

@JeremyTBradshaw
Copy link

The script should start with #Requires -Version 4 to prevent people trying to use it in the wrong version of PowerShell.

@bill-long
Copy link
Member

bill-long commented Mar 8, 2021

You can also remove the PSCredential requirement if that's the blocker. I haven't seen a case where we need to pass credentials. Just delete this line:

[pscredential]

Or change it to some other data type:

[string]

However, when I do that on my 2010 machine I immediately run into other issues.

@live-motion
Copy link

I change [pscredential] to [string] and got it:

[PS] D:\Downloads>.\Test-ProxyLogon.ps1 -OutPath .\logs
cmdlet Write-Progress at command pipeline position 1
Supply values for the following parameters:
(Type !? for Help.)
Status:

@bill-long
Copy link
Member

For the "Status:" prompt, you can change every Write-Progress command in the script so that it has a -Status parameter. For example, change:

Write-Progress -Activity "Checking for CVE-2021-26855 in the HttpProxy logs"

To:

Write-Progress -Activity "Checking for CVE-2021-26855 in the HttpProxy logs" -Status "Checking"

However, after you fix that you are going to run into another issue... This series of issues is why there isn't an update that makes this work locally on 2010 yet. We're looking into it again today.

@jakewalkeruct
Copy link

jakewalkeruct commented Mar 8, 2021

Running Exchange 2010 on Windows Server 2008 R2 (I know it's EOL, we are decom'ing soon). I upgraded the installed version of PS to 5.1 and reran the script. Instead of getting the [pscredential] error now, I get this instead:

Import-Csv : Cannot validate argument on parameter 'Path'. The argument is null or empty. Provide an argument that is
not null or empty, and then try the command again.
At C:\XXXX\HAFNIUM Test Scipts\Test-ProxyLogon.ps1:122 char:63

  • ... $fileResults = @(Import-Csv -Path $_ -ErrorA ...
  •                                                            ~~
    
    • CategoryInfo : InvalidData: (:) [Import-Csv], ParameterBindingValidationException
    • FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.ImportCsvCommand

Get-ChildItem : Access to the path 'C:\Windows\temp\XCCache' is denied.
At C:\XXXX\HAFNIUM Test Scipts\Test-ProxyLogon.ps1:166 char:39

  • ... h ($file in Get-ChildItem -Recurse -Path "$env:WINDIR\temp\lsass.*dmp ...
  •             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    • CategoryInfo : PermissionDenied: (C:\Windows\temp\XCCache:String) [Get-ChildItem], UnauthorizedAccessEx
      ception
    • FullyQualifiedErrorId : DirUnauthorizedAccessError,Microsoft.PowerShell.Commands.GetChildItemCommand

Any ideas?

@bill-long
Copy link
Member

I've been trying to get this working on Exchange 2010 today. However, after some discussions, we've decided not to support running the script on 2010.

The main reason for this is that Exchange 2010 is only vulnerable to CVE-2021-26857. That means only one of the commands from the blog applies to 2010:

Get-EventLog -LogName Application -Source "MSExchange Unified Messaging" -EntryType Error | Where-Object { $_.Message -like "*System.InvalidCastException*" }

None of the other checks have any value on Exchange 2010, so the script isn't doing much for you. There's a longer explanation regarding 2010 here:

https://techcommunity.microsoft.com/t5/exchange-team-blog/released-march-2021-exchange-server-security-updates/bc-p/2190541/highlight/true#M29790

@fsackur
Copy link

fsackur commented Mar 9, 2021

Hi! Thanks for the work on this repo.

Requiring PSv4 is a serious breaking change. I'm sure a lot of thought went in that I don't see, but - on the surface - it's a puzzling decision. I have thousands of wildly heterogenous boxes. I still have many paying customers on PSv2, for my sins! I don't expect you to support PSv2 in this day and age, but jumping past PSv3 should be a considered move. PSv3 is where the language hit maturity. Excepting classes and DSC, it's basically only syntax sugar between 3 and 6.

AFAICS, the use of [pscredential] in no way requires PSv4. Perhaps this is symptomatic of some other issue, possibly relating to how the Exchange Management Shell works. I'm running this script without touching the EMS, in a general-purpose automation framework. @mahmoudshoaala I'd be interested to see your repro. I suspect you have some other issue going on.

Here's the part I don't see. IIUC, you've merged #153 in order to handle a bug in a parameter at https://github.com/microsoft/CSS-Exchange/blob/58cc16f/Security/Test-ProxyLogon.ps1#L67 that isn't in use.

Based on that, my recommendation and request is:

  • roll back Require version 4 #153
  • change the param type to [object] and perform type-checking in the function body

@fsackur
Copy link

fsackur commented Mar 9, 2021

The real issue is the way the code has been packaged into a single file. Many of us don't want "output" as a sequence of write-host commands. That's a real backwards step - if I want to parse text, I have plenty of crappy vendor tools to waste my time on. We do structured data in powershell.

I would be willing to PR something that remains a single runnable file, but exports the functions so that it can be consumed by automation frameworks. That would give users the choice between write-host or objects.

If I do this, it will be a time burden for me and the reviewers, and it would carry some level of risk, so let me know if this would be helpful!

In the meantime, I NEVER want to be copy-pasting code from version control, so I have the following snippet, which gives me flexibility to pull changes in my repo from this repo. I offer it in case anyone else has the same problem:

# replace as appropriate
$MSScriptPath = "./CSS-Exchange/Test-ProxyLogon.ps1"

# Use the built-in parser - this requires PSv3. PSv2 has similar functionality through a different class
# This captures the code definition in an object that represents how the engine parses script - an Abstract Syntax Tree
#requires -Version 3
[System.Management.Automation.Language.Token[]]$Tokens = @()
[System.Management.Automation.Language.ParseError[]]$Errors = @()
$MSScriptAst = [System.Management.Automation.Language.Parser]::ParseFile(
    $MSScriptPath,
    [ref]$Tokens,
    [ref]$Errors
)
$FunctionAst = $MsScriptAst.Find({$args[0].Name -eq "Test-ExchangeProxyLogon"}, $false)

# Now we have the definition of the useful script
$FunctionDefinition = $FunctionAst.Extent.Text

# Load the function definition into scope
$FunctionDefinition | Invoke-Expression


$MSOutput = Test-ExchangeProxyLogon

If anyone still needs to support PSv2, ping me, I'll dig out something that'll work for your use case too.

@wonderwilly
Copy link

Hello everybody and thanks to all who are trying to help!!

We are running an Exchange 2010 on Server 2008 R2 Standard and we have already installed the Update Rollup 32 (KB5000978).

We need to run this old Exchange server for less than one year before we can move to O365.

We read this thread an understood that for Exchange 2010 the only thing to proof is this commands:

Get-EventLog -LogName Application -Source "MSExchange Unified Messaging" -EntryType Error | Where-Object { $_.Message -like "*System.InvalidCastException*" }

When pasting this command to the Exchange Management Shell it returns that it did not found any accordance.
-----> Does that mean that our Exchange seems not to be attacked?

Thanks to all.

@bill-long
Copy link
Member

@wonderwilly That means there's no sign of CVE-2021-26857 exploitation, at least as far back as your Application log goes.

@greenstreak20
Copy link

@bill-long Following is the resultant output. Just to confirm "No matches found" is the expected result for NO exploitation of CVE-2021-26857 as far back as the application log goes?

[PS] C:\Windows\system32>Get-EventLog -LogName Application -Source "MSExchange Unified Messaging" -EntryType Error | Whe
re-Object { $_.Message -like "System.InvalidCastException" }
Get-EventLog : No matches found
At line:1 char:13

  • Get-EventLog <<<< -LogName Application -Source "MSExchange Unified Messaging" -EntryType Error | Where-Object { $_.M
    essage -like "System.InvalidCastException" }
    • CategoryInfo : ObjectNotFound: (:) [Get-EventLog], ArgumentException
    • FullyQualifiedErrorId : GetEventLogNoEntriesFound,Microsoft.PowerShell.Commands.GetEventLogCommand

@bill-long
Copy link
Member

@fsackur If you're not on at least Powershell 4, I assume that means you're on Exchange 2010? In which case, why not just run the event log search, which does already return objects? That's the only test that applies to 2010. Or am I misunderstanding the use case?

And yeah, as you can see by the code, we initially had the script returning objects, but due to the friction with users who don't really PowerShell, we compromised and made it work like a normal script. With some minor modifications you can then dot-source it and call Test-ExchangeProxyLogon directly. Can you point me to an example script where the inner cmdlets are exportable while you can still use it as a script?

@bill-long
Copy link
Member

bill-long commented Mar 9, 2021

@greenstreak20 Correct. It's annoying that it throws an error like something went wrong, but that's the normal result of finding no matches.

Edit: You can add -ErrorAction SilentlyContinue to the Get-EventLog command to suppress the error. If you're on a system that supports Get-WinEvent, you can copy/paste the command from the script, which is a bit faster than Get-EventLog.

@wonderwilly
Copy link

Thank you @bill-long !!

@wonderwilly That means there's no sign of CVE-2021-26857 exploitation, at least as far back as your Application log goes.

When filtering the Windows servers event log for Exchange, the logs go back to 2014 when the server was installed. Seems the logs were never been deletet/cleared.

Should/could we do any thing more to proof for already happend infiltrations?

And could we do anything more than installing the MS update rollup 32? For example create some firewall blocks for certain (source) IPs and ports?

@greenstreak20
Copy link

@bill-long Thanks! I appreciate all your efforts and support.

@fsackur
Copy link

fsackur commented Mar 9, 2021

Re PS version:

@bill-long your question highlights my lack of product knowledge - I'm going off what the exchange team told me, but that was a metting with the managers, not the engineers!

I value having a universal entrypoint across versions. There's at least some SBS 2011 in our fleet, and my dataset is imperfect. It's a big timesaver to run the same tooling and just get the results.

To keep perspective: worrying about the finer points of PS versions is not the main issue this week! I'm OK if I've logged the comment and it is not addressed. The AST snippet I commented is one of several possible workarounds.

If you like though, my offer still stands to do a PR that replaces the hard #requires with a function body test for the problematic line.

@fsackur
Copy link

fsackur commented Mar 9, 2021

Re export, here's a possibility, let me know if you'd liek this rpesented as a PR:

[CmdletBinding(DefaultParameterSetName = 'AsScript')]
param (
    [Parameter(ParameterSetName = 'AsScript', ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
    [string[]]
    $ComputerName,

    # ...OutPath and DisplayOnly also set to AsScript paramset

    [Parameter(ParameterSetName = 'AsModule')]
    [switch]
    $Export     # Possible to inspect call stack and set this automatically if user ran Import-Module... perhaps
)

process {

    function Test-ExchangeProxyLogon {
        # ...etc...
    }

    function Write-ProxyLogonReport {
        # ...etc...
    }

    if ($Export)
    {
        Set-Item function:global:Test-ExchangeProxyLogon (Get-Command Test-ExchangeProxyLogon)
        Set-Item function:global:Write-ProxyLogonReport (Get-Command Write-ProxyLogonReport)
    }
    else
    {
        if ($DisplayOnly) {
            # ...etc...
        }
    }
}

In use:

C:\githubdata\microsoft-CSS-Exchange  main ⇣ 13* ?1 
❯ gcm *proxylogon*

C:\githubdata\microsoft-CSS-Exchange  main ⇣ 13* ?1 
❯ .\Security\Untitled-1.ps1 -Export

C:\githubdata\microsoft-CSS-Exchange  main ⇣ 13* ?1 
❯ gcm *proxylogon*

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Function        Test-ExchangeProxyLogon
Function        Write-ProxyLogonReport

If we did this, I could drop the AST hack

@bill-long
Copy link
Member

I love that approach. I'll experiment with it today.

@bill-long
Copy link
Member

This is in the release that just went up. Note:

  • Version requirement dropped to 3.
  • We now refer to PSCredential by its full name. This is supposed to work in older versions of PowerShell, but I can't test it myself.
  • You can export the functions as shown above.

However, there is a breaking change for anyone who was using the functions directly already. The shape of the Cve26855 report object has changed. It now contains two things:

Hits - contains the old data, just the hits from the files.
FileList - full name of files containing hits, for collection or further investigation.

@ProBackup-nl
Copy link

ProBackup-nl commented Mar 19, 2021

Another option is to run the blog commands manually on 2010.

Which blog? https://www.microsoft.com/security/blog/2021/03/02/hafnium-targeting-exchange-servers/ ?

@bill-long
Copy link
Member

@ProBackup-nl All the tests in this script are based on this blog post:

https://www.microsoft.com/security/blog/2021/03/02/hafnium-targeting-exchange-servers/

Of the four vulnerabilities mentioned there, only CVE-2021-26857 applies to Exchange 2010. The command the blog shows to check for evidence of exploitation of that vulnerability is:

Get-EventLog -LogName Application -Source "MSExchange Unified Messaging" -EntryType Error | Where-Object { $_.Message -like "*System.InvalidCastException*" }

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

No branches or pull requests