Comments (26)
The script should start with #Requires -Version 4
to prevent people trying to use it in the wrong version of PowerShell.
from css-exchange.
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:
from css-exchange.
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.
from css-exchange.
Check if your shortcut to "Exchange Management Shell" includes "-version 2.0" in the parameters.
If so, remove this and try again.
from css-exchange.
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.
from css-exchange.
@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*" }
from css-exchange.
Hmm... this was working on 2010 initially. Investigating.
from css-exchange.
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.
from css-exchange.
Try to bind the $credential function with = get-credential "domain\username", you know you need at least PS Version 4.0.
from css-exchange.
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.
from css-exchange.
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:
from css-exchange.
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.
from css-exchange.
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
- CategoryInfo : PermissionDenied: (C:\Windows\temp\XCCache:String) [Get-ChildItem], UnauthorizedAccessEx
Any ideas?
from css-exchange.
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 #153
- change the param type to
[object]
and perform type-checking in the function body
from css-exchange.
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.
from css-exchange.
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.
from css-exchange.
@wonderwilly That means there's no sign of CVE-2021-26857 exploitation, at least as far back as your Application log goes.
from css-exchange.
@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
from css-exchange.
@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?
from css-exchange.
@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.
from css-exchange.
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?
from css-exchange.
@bill-long Thanks! I appreciate all your efforts and support.
from css-exchange.
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.
from css-exchange.
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
from css-exchange.
I love that approach. I'll experiment with it today.
from css-exchange.
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/ ?
from css-exchange.
Related Issues (20)
- [Issue] - HealthChecker documentation issue regarding HTML report HOT 3
- [Issue] - Health Checker - IIS Information showing NULL Certificate with more detail
- microsoft-exchange-client-access-server-information-disclosure HOT 2
- [Work Item] Don't show TLS 1.3 settings on unsupported OS HOT 1
- [Issue] Confirm-ProxyServer does not work on Powershell 7
- [Issue] Invoke-WebRequestWithProxyDetection fails on PowerShell 7 when -OutFile is not specified
- [Issue] - Health Checker - feature request - UnifiedContent temp path check HOT 5
- [Issue] - Health Checker - Credential Guard Check Still Not Functioning As Expected HOT 7
- [Issue] - Health Checker - Credential Guard Detection HOT 4
- VSSTester [Issue] HOT 15
- Error running script with -CreateAzurerApplication when account has MFA enabled HOT 7
- [Issue] SourceSideValidations - Cannot process argument transformation on parameter 'Identity'. Cannot convert the "DB01_16" value of type "Deserialized.Microsoft.Exchange.Data.Directory.ADObjectId" to type "Microsoft.Exchange.Configuration.Tasks.DatabaseIdParameter" HOT 1
- Show script version before update
- [Work Item] MSQM Updated Guidance
- [Work Item] New code formatter check to detect domains that have not been approved by CELA
- Health Checker - Add additional context for services that are not running
- [Issue] Update-Engines overwrites the files on 2nd run
- [Issue] Health Checker - Get-LocalGroupMember failing to execute
- [Issue] Health Checker - Get-SecurityCve-2022-21978 parameter ExchangeWellKnownSecurityGroups is null
- [Issue]ExPerfWiz adds counters incorrectly to datacollector HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from css-exchange.