fix(powershell): sec deny powershell encoding bypass via iex injection.
This commit is contained in:
parent
6e6293e596
commit
a75ed069f4
2 changed files with 46 additions and 0 deletions
|
|
@ -95,6 +95,14 @@ var (
|
||||||
regexp.MustCompile(`\bssh\b.*@`),
|
regexp.MustCompile(`\bssh\b.*@`),
|
||||||
regexp.MustCompile(`\beval\b`),
|
regexp.MustCompile(`\beval\b`),
|
||||||
regexp.MustCompile(`\bsource\s+.*\.sh\b`),
|
regexp.MustCompile(`\bsource\s+.*\.sh\b`),
|
||||||
|
// PowerShell encoding bypass: [Text.Encoding] used to construct command strings.
|
||||||
|
regexp.MustCompile(`\[text\.encoding\]`),
|
||||||
|
// PowerShell -EncodedCommand flag (base64-encoded command).
|
||||||
|
regexp.MustCompile(`-encodedcommand`),
|
||||||
|
// .GetString called on byte array to decode commands.
|
||||||
|
regexp.MustCompile(`\.getstring\(\[byte\[\]`),
|
||||||
|
// FromBase64String used in command construction chain.
|
||||||
|
regexp.MustCompile(`frombase64string\(`),
|
||||||
}
|
}
|
||||||
|
|
||||||
// absolutePathPattern matches absolute file paths in commands (Unix and Windows).
|
// absolutePathPattern matches absolute file paths in commands (Unix and Windows).
|
||||||
|
|
|
||||||
|
|
@ -703,6 +703,44 @@ func TestShellTool_URLBypassPrevented(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestShellTool_PowerShellEncodingBypass verifies that PowerShell encoding bypass techniques are blocked.
|
||||||
|
func TestShellTool_PowerShellEncodingBypass(t *testing.T) {
|
||||||
|
tool, err := NewExecTool("", false)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
// Commands using [Text.Encoding] to construct a command string at runtime.
|
||||||
|
encodingBypassCommands := []string{
|
||||||
|
`[Text.Encoding]::ASCII.GetString([byte[]](0x6c,0x73,0x20,0x7e))`,
|
||||||
|
`[Text.Encoding]::ASCII.GetString([byte[]](0x69,0x65,0x78))`,
|
||||||
|
`[System.Text.Encoding]::ASCII.GetString([byte[]](0x69,0x65,0x78))`,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, cmd := range encodingBypassCommands {
|
||||||
|
result := tool.Execute(ctx, map[string]any{"action": "run", "command": cmd})
|
||||||
|
if !result.IsError {
|
||||||
|
t.Errorf("expected [Text.Encoding] bypass to be blocked: %s", cmd)
|
||||||
|
}
|
||||||
|
if !strings.Contains(result.ForLLM, "blocked") && !strings.Contains(result.ForUser, "blocked") {
|
||||||
|
t.Errorf("expected 'blocked' message for %s, got: %s", cmd, result.ForLLM)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Commands using PowerShell's -EncodedCommand flag (base64).
|
||||||
|
encodedCommands := []string{
|
||||||
|
`powershell -NoProfile -NonInteractive -EncodedCommand SQBFAHIAaABlAGwAbAAvAC8A`,
|
||||||
|
`pwsh -EncodedCommand aWV4`,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, cmd := range encodedCommands {
|
||||||
|
result := tool.Execute(ctx, map[string]any{"action": "run", "command": cmd})
|
||||||
|
if !result.IsError {
|
||||||
|
t.Errorf("expected -EncodedCommand to be blocked: %s", cmd)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestShellTool_Background_ReturnsImmediately(t *testing.T) {
|
func TestShellTool_Background_ReturnsImmediately(t *testing.T) {
|
||||||
tool, err := NewExecTool("", false)
|
tool, err := NewExecTool("", false)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue