From ba8a37c625e498937733bd32ee1cbb48ebd4da36 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 12 Nov 2024 20:11:28 +0000 Subject: [PATCH] PS: Add more injetion sinks and type models. --- .../ql/lib/semmle/code/powershell/Frameworks.qll | 3 +++ .../semmle/code/powershell/dataflow/FlowSummary.qll | 3 +++ .../EngineIntrinsics.qll | 12 ++++++++++++ .../model.yml | 12 ++++++++++++ .../PowerShell.qll | 12 ++++++++++++ .../SystemManagementAutomationPowerShell/model.yml | 13 +++++++++++++ .../Runspaces.qll | 12 ++++++++++++ .../SystemManagementAutomationRunspaces/model.yml | 13 +++++++++++++ .../SystemManagementAutomationScriptBlock/model.yml | 6 ++++++ .../frameworks/SystemNetSockets/model.yml | 8 ++++---- .../security/CommandInjectionCustomizations.qll | 9 +++++++++ 11 files changed, 99 insertions(+), 4 deletions(-) create mode 100644 powershell/ql/lib/semmle/code/powershell/frameworks/SystemManagementAutomationEngineIntrinsics/EngineIntrinsics.qll create mode 100644 powershell/ql/lib/semmle/code/powershell/frameworks/SystemManagementAutomationEngineIntrinsics/model.yml create mode 100644 powershell/ql/lib/semmle/code/powershell/frameworks/SystemManagementAutomationPowerShell/PowerShell.qll create mode 100644 powershell/ql/lib/semmle/code/powershell/frameworks/SystemManagementAutomationPowerShell/model.yml create mode 100644 powershell/ql/lib/semmle/code/powershell/frameworks/SystemManagementAutomationRunspaces/Runspaces.qll create mode 100644 powershell/ql/lib/semmle/code/powershell/frameworks/SystemManagementAutomationRunspaces/model.yml create mode 100644 powershell/ql/lib/semmle/code/powershell/frameworks/SystemManagementAutomationScriptBlock/model.yml diff --git a/powershell/ql/lib/semmle/code/powershell/Frameworks.qll b/powershell/ql/lib/semmle/code/powershell/Frameworks.qll index 19c46aa64da..8d69ab9b32c 100644 --- a/powershell/ql/lib/semmle/code/powershell/Frameworks.qll +++ b/powershell/ql/lib/semmle/code/powershell/Frameworks.qll @@ -2,3 +2,6 @@ * Helper file that imports all framework modeling. */ +import semmle.code.powershell.frameworks.SystemManagementAutomationRunspaces.Runspaces +import semmle.code.powershell.frameworks.SystemManagementAutomationPowerShell.PowerShell +import semmle.code.powershell.frameworks.SystemManagementAutomationEngineIntrinsics.EngineIntrinsics diff --git a/powershell/ql/lib/semmle/code/powershell/dataflow/FlowSummary.qll b/powershell/ql/lib/semmle/code/powershell/dataflow/FlowSummary.qll index 65b446a9ea0..0f236704fef 100644 --- a/powershell/ql/lib/semmle/code/powershell/dataflow/FlowSummary.qll +++ b/powershell/ql/lib/semmle/code/powershell/dataflow/FlowSummary.qll @@ -13,6 +13,9 @@ private import internal.DataFlowPrivate private module Summaries { private import semmle.code.powershell.Frameworks private import semmle.code.powershell.frameworks.data.ModelsAsData + import RunspaceFactory + import PowerShell + import EngineIntrinsics } /** A callable with a flow summary, identified by a unique string. */ diff --git a/powershell/ql/lib/semmle/code/powershell/frameworks/SystemManagementAutomationEngineIntrinsics/EngineIntrinsics.qll b/powershell/ql/lib/semmle/code/powershell/frameworks/SystemManagementAutomationEngineIntrinsics/EngineIntrinsics.qll new file mode 100644 index 00000000000..9f856f28949 --- /dev/null +++ b/powershell/ql/lib/semmle/code/powershell/frameworks/SystemManagementAutomationEngineIntrinsics/EngineIntrinsics.qll @@ -0,0 +1,12 @@ +import powershell +import semmle.code.powershell.frameworks.data.internal.ApiGraphModels +private import semmle.code.powershell.dataflow.internal.DataFlowPublic as DataFlow + +module EngineIntrinsics { + private class EngineIntrinsicsGlobalEntry extends ModelInput::TypeModel { + override DataFlow::Node getASource(string type) { + type = "System.Management.Automation.EngineIntrinsics" and + result.asExpr().getExpr().(VarReadAccess).getUserPath().toLowerCase() = "executioncontext" + } + } +} diff --git a/powershell/ql/lib/semmle/code/powershell/frameworks/SystemManagementAutomationEngineIntrinsics/model.yml b/powershell/ql/lib/semmle/code/powershell/frameworks/SystemManagementAutomationEngineIntrinsics/model.yml new file mode 100644 index 00000000000..6364b97ab82 --- /dev/null +++ b/powershell/ql/lib/semmle/code/powershell/frameworks/SystemManagementAutomationEngineIntrinsics/model.yml @@ -0,0 +1,12 @@ +extensions: + - addsTo: + pack: microsoft-sdl/powershell-all + extensible: sinkModel + data: + - ["System.Management.Automation.CommandInvocationIntrinsics", "Method[ExpandString].Argument[0]", "command-injection"] + + - addsTo: + pack: microsoft-sdl/powershell-all + extensible: typeModel + data: + - ["System.Management.Automation.CommandInvocationIntrinsics","System.Management.Automation.EngineIntrinsics","Member[InvokeCommand]"] \ No newline at end of file diff --git a/powershell/ql/lib/semmle/code/powershell/frameworks/SystemManagementAutomationPowerShell/PowerShell.qll b/powershell/ql/lib/semmle/code/powershell/frameworks/SystemManagementAutomationPowerShell/PowerShell.qll new file mode 100644 index 00000000000..a3b606cb9ed --- /dev/null +++ b/powershell/ql/lib/semmle/code/powershell/frameworks/SystemManagementAutomationPowerShell/PowerShell.qll @@ -0,0 +1,12 @@ +import powershell +import semmle.code.powershell.frameworks.data.internal.ApiGraphModels +private import semmle.code.powershell.dataflow.internal.DataFlowPublic as DataFlow + +module PowerShell { + private class PowerShellGlobalEntry extends ModelInput::TypeModel { + override DataFlow::Node getASource(string type) { + type = "System.Management.Automation.PowerShell!" and + result.asExpr().getExpr().(TypeNameExpr).getName().toLowerCase() = "powershell" + } + } +} diff --git a/powershell/ql/lib/semmle/code/powershell/frameworks/SystemManagementAutomationPowerShell/model.yml b/powershell/ql/lib/semmle/code/powershell/frameworks/SystemManagementAutomationPowerShell/model.yml new file mode 100644 index 00000000000..ca3e8b546cb --- /dev/null +++ b/powershell/ql/lib/semmle/code/powershell/frameworks/SystemManagementAutomationPowerShell/model.yml @@ -0,0 +1,13 @@ +extensions: + - addsTo: + pack: microsoft-sdl/powershell-all + extensible: sinkModel + data: + - ["System.Management.Automation.PowerShell", "Method[AddScript].Argument[0]", "command-injection"] + - ["System.Management.Automation.ScriptBlock!", "Method[Create].Argument[0]", "command-injection"] + + - addsTo: + pack: microsoft-sdl/powershell-all + extensible: typeModel + data: + - ["System.Management.Automation.PowerShell","System.Management.Automation.PowerShell!","Method[Create].ReturnValue"] \ No newline at end of file diff --git a/powershell/ql/lib/semmle/code/powershell/frameworks/SystemManagementAutomationRunspaces/Runspaces.qll b/powershell/ql/lib/semmle/code/powershell/frameworks/SystemManagementAutomationRunspaces/Runspaces.qll new file mode 100644 index 00000000000..fd4e6e9c6f3 --- /dev/null +++ b/powershell/ql/lib/semmle/code/powershell/frameworks/SystemManagementAutomationRunspaces/Runspaces.qll @@ -0,0 +1,12 @@ +import powershell +import semmle.code.powershell.frameworks.data.internal.ApiGraphModels +private import semmle.code.powershell.dataflow.internal.DataFlowPublic as DataFlow + +module RunspaceFactory { + private class RunspaceFactoryGlobalEntry extends ModelInput::TypeModel { + override DataFlow::Node getASource(string type) { + type = "System.Management.Automation.Runspaces.RunspaceFactory!" and + result.asExpr().getExpr().(TypeNameExpr).getName().toLowerCase() = "runspacefactory" + } + } +} diff --git a/powershell/ql/lib/semmle/code/powershell/frameworks/SystemManagementAutomationRunspaces/model.yml b/powershell/ql/lib/semmle/code/powershell/frameworks/SystemManagementAutomationRunspaces/model.yml new file mode 100644 index 00000000000..721d41c3d64 --- /dev/null +++ b/powershell/ql/lib/semmle/code/powershell/frameworks/SystemManagementAutomationRunspaces/model.yml @@ -0,0 +1,13 @@ +extensions: + - addsTo: + pack: microsoft-sdl/powershell-all + extensible: sinkModel + data: + - ["System.Management.Automation.Runspaces.Runspace", "Method[CreateNestedPipeline].Argument[0]", "command-injection"] + - ["System.Management.Automation.Runspaces.Runspace", "Method[CreatePipeline].Argument[0]", "command-injection"] + + - addsTo: + pack: microsoft-sdl/powershell-all + extensible: typeModel + data: + - ["System.Management.Automation.Runspaces.Runspace","System.Management.Automation.Runspaces.RunspaceFactory!","Method[CreateRunspace].ReturnValue"] \ No newline at end of file diff --git a/powershell/ql/lib/semmle/code/powershell/frameworks/SystemManagementAutomationScriptBlock/model.yml b/powershell/ql/lib/semmle/code/powershell/frameworks/SystemManagementAutomationScriptBlock/model.yml new file mode 100644 index 00000000000..df9abac9d24 --- /dev/null +++ b/powershell/ql/lib/semmle/code/powershell/frameworks/SystemManagementAutomationScriptBlock/model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: microsoft-sdl/powershell-all + extensible: sinkModel + data: + - ["System.Management.Automation.ScriptBlock!", "Method[Create].Argument[0]", "command-injection"] diff --git a/powershell/ql/lib/semmle/code/powershell/frameworks/SystemNetSockets/model.yml b/powershell/ql/lib/semmle/code/powershell/frameworks/SystemNetSockets/model.yml index 196d6838ce2..572a8872a61 100644 --- a/powershell/ql/lib/semmle/code/powershell/frameworks/SystemNetSockets/model.yml +++ b/powershell/ql/lib/semmle/code/powershell/frameworks/SystemNetSockets/model.yml @@ -3,7 +3,7 @@ extensions: pack: microsoft-sdl/powershell-all extensible: sourceModel data: - - ["System.Net.Sockets.TcpClient", "Instance.Method[GetStream].ReturnValue", "remote"] - - ["System.Net.Sockets.UpdClient", "Instance.Method[EndReceive].ReturnValue", "remote"] - - ["System.Net.Sockets.UpdClient", "Instance.Method[Receive].ReturnValue", "remote"] - - ["System.Net.Sockets.UpdClient", "Instance.Method[ReceiveAsync].ReturnValue", "remote"] \ No newline at end of file + - ["System.Net.Sockets.TcpClient", "Method[GetStream].ReturnValue", "remote"] + - ["System.Net.Sockets.UpdClient", "Method[EndReceive].ReturnValue", "remote"] + - ["System.Net.Sockets.UpdClient", "Method[Receive].ReturnValue", "remote"] + - ["System.Net.Sockets.UpdClient", "Method[ReceiveAsync].ReturnValue", "remote"] \ No newline at end of file diff --git a/powershell/ql/lib/semmle/code/powershell/security/CommandInjectionCustomizations.qll b/powershell/ql/lib/semmle/code/powershell/security/CommandInjectionCustomizations.qll index 30c7d6fdb43..1623941fb82 100644 --- a/powershell/ql/lib/semmle/code/powershell/security/CommandInjectionCustomizations.qll +++ b/powershell/ql/lib/semmle/code/powershell/security/CommandInjectionCustomizations.qll @@ -48,6 +48,15 @@ module CommandInjection { } } + class AddTypeSink extends Sink { + AddTypeSink() { + exists(DataFlow::CallNode call | + call.getName() = "Add-Type" and + call.getAnArgument() = this + ) + } + } + private class ExternalCommandInjectionSink extends Sink { ExternalCommandInjectionSink() { this = ModelOutput::getASinkNode("command-injection").asSink()