Tests/Pester.MaliciousContent.Tests.ps1
function RunRuleForCommand { param([String] $Command) $outputPath = Join-Path $env:TEMP ([IO.Path]::GetRandomFileName() + ".ps1") try { Set-Content -Path $outputPath -Value $Command Invoke-ScriptAnalyzer -Path $outputPath ` -CustomizedRulePath (Resolve-Path $PSScriptRoot\..\MaliciousContentRules.psm1) ` -ExcludeRule PS* } finally { Remove-Item $outputPath } } Describe "Tests for validating malicious content techniques" { It "Should detect dynamic method invocation" { $result = RunRuleForCommand '[Object]::("Equ" + "als")(1, 2)' $result.RuleName | Should be "MaliciousContent.DynamicMethodInvocation" } It "Should detect dynamic method invocation variable" { $result = RunRuleForCommand '$method = "Equals"; [Object]::$method(1, 2)' $result.RuleName | Should be "MaliciousContent.DynamicMethodInvocation" } It "Should detect access to [Type] via cast" { $result = RunRuleForCommand '$foo = [Type] "Object"' $result.RuleName | Should be "MaliciousContent.DynamicTypeConversion" } It "Should detect access to [Type] via -as" { $result = RunRuleForCommand '$foo = "Object" -as [Type]' $result.RuleName | Should be "MaliciousContent.DynamicTypeCast" } It "Should detect dynamic member access variable" { $result = RunRuleForCommand '$member = "CommandLine"; [Environment]::$member' $result.RuleName | Should be "MaliciousContent.DynamicMemberAccess" } It "Should detect dynamic member access" { $result = RunRuleForCommand '[Environment]::("Command" + "Line")' $result.RuleName | Should be "MaliciousContent.DynamicMemberAccess" } It "Should detect static access on a variable" { $result = RunRuleForCommand '$foo = [Environment]; $foo::CommandLine' $result.RuleName | Should be "MaliciousContent.DynamicMemberAccess" } It "Should not flag unobfuscated static access" { $result = RunRuleForCommand '[Environment]::CommandLine' $result | Should be $null } It "Should detect suspicious token" { $result = RunRuleForCommand '[System.Runtime.InteropServices.Marshal]::ReadIntPtr(0)' $result.RuleName | Should be "MaliciousContent.SuspiciousContentText" } It "Should detect suspicious token case insenstive" { $result = RunRuleForCommand '[system.runtime.interopservices.marshal]::readintptr(0)' $result.RuleName | Should be "MaliciousContent.SuspiciousContentText" } It "Should detect multiple suspicious tokens" { $results = RunRuleForCommand '[system.runtime.interopservices.marshal]::readintptr(0); Add-Type Foo' $results.Count | Should be 3 $results[0].RuleName | Should be "MaliciousContent.SuspiciousContentText" $results[0].Extent.Text | Should match "marshal" $results[1].RuleName | Should be "MaliciousContent.SuspiciousContentText" $results[1].Extent.Text | Should match "readintptr" $results[2].RuleName | Should be "MaliciousContent.SuspiciousContentText" $results[2].Extent.Text | Should match 'Add-Type' } ## Possible attacks ## We've put some non-malicious warnings on an ignore list: ## - And they do something (i.e.: insert some lines) to invalidate the whole ignore list ## - And they add some new content (maybe under the same parent?) that gets also ignored by the ignore list ## We've ignored a non-malicious type conversion (for example), but then they change it to be malicious without ## chaging the raw hit. I.e.: $type = [String]; $type.GetProperties() -> $type = [Type]; $type.GetProperties() } |