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

PSScript Analyzer fixes #179

Merged
merged 9 commits into from
Dec 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: Lint
on: pull_request

jobs:
install-invoke:
name: Install Invoke-Atomic
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@v2
- name: Run lint checks
shell: pwsh
run: |
Install-Module -Name PSScriptAnalyzer -Force
Invoke-ScriptAnalyzer -Recurse ./ -Settings ./PSScriptAnalyzerSettings.psd1 -Fix
- name: Check whether there are any file changes
shell: bash
run: |
git diff --exit-code
14 changes: 7 additions & 7 deletions Invoke-AtomicRedTeam.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@
PowerShellVersion = '5.0'

# Modules that must be imported into the global environment prior to importing this module
RequiredModules = @('powershell-yaml')
RequiredModules = @('powershell-yaml')

# Script files (.ps1) that are run in the caller's environment prior to importing this module.
# AtomicClassSchema.ps1 needs to be present in the caller's scope in order for the built-in classes to surface properly.
ScriptsToProcess = @('Private\AtomicClassSchema.ps1','Public\config.ps1')
ScriptsToProcess = @('Private\AtomicClassSchema.ps1', 'Public\config.ps1')

# Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export.
FunctionsToExport = @(
Expand All @@ -53,26 +53,26 @@
# Variables to export from this module
VariablesToExport = '*'

NestedModules = @(
NestedModules = @(
"Public\Default-ExecutionLogger.psm1",
"Public\Attire-ExecutionLogger.psm1",
"Public\Syslog-ExecutionLogger.psm1",
"Public\WinEvent-ExecutionLogger.psm1"
)
)

# Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell.
PrivateData = @{

PSData = @{

# Tags applied to this module. These help with module discovery in online galleries.
Tags = @('Security', 'Defense')
Tags = @('Security', 'Defense')

# A URL to the license for this module.
LicenseUri = 'https://github.com/redcanaryco/invoke-atomicredteam/blob/master/LICENSE.txt'
LicenseUri = 'https://github.com/redcanaryco/invoke-atomicredteam/blob/master/LICENSE.txt'

# A URL to the main website for this project.
ProjectUri = 'https://github.com/redcanaryco/invoke-atomicredteam'
ProjectUri = 'https://github.com/redcanaryco/invoke-atomicredteam'

# A URL to an icon representing this module.
# IconUri = ''
Expand Down
5 changes: 5 additions & 0 deletions PSScriptAnalyzerSettings.psd1
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# PSScriptAnalyzerSettings.psd1
@{
ExcludeRules=@('PSUseSingularNouns',
'PSAvoidUsingWriteHost')
}
4 changes: 2 additions & 2 deletions Private/AtomicClassSchema.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class AtomicExecutorBase {
[Bool] $elevation_required

# Implemented to facilitate improved PS object display
[String] ToString(){
[String] ToString() {
return $this.Name
}
}
Expand Down Expand Up @@ -43,7 +43,7 @@ class AtomicTest {
[AtomicExecutorBase] $executor

# Implemented to facilitate improved PS object display
[String] ToString(){
[String] ToString() {
return $this.name
}
}
Expand Down
4 changes: 2 additions & 2 deletions Private/Get-PrereqExecutor.ps1
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
function Get-PrereqExecutor ($test) {
if ($nul -eq $test.dependency_executor_name) { $executor = $test.executor.name }
function Get-PrereqExecutor ($test) {
if ($nul -eq $test.dependency_executor_name) { $executor = $test.executor.name }
else { $executor = $test.dependency_executor_name }
$executor
}
15 changes: 8 additions & 7 deletions Private/Get-TargetInfo.ps1
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
function Get-TargetInfo($Session) {
function Get-TargetInfo($Session) {
$tmpDir = "$env:TEMP\"
$isElevated = $false
$targetHostname = hostname
Expand All @@ -10,14 +10,15 @@ function Get-TargetInfo($Session) {
$targetHostname = hostname
$targetUser = whoami
if ($IsLinux) { $targetPlatform = "linux" }
elseif ($IsMacOS) { $targetPlatform = "macos" }
else { # windows
elseif ($IsMacOS) { $targetPlatform = "macos" }
else {
# windows
$tmpDir = "$env:TEMP\"
$isElevated = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
}
if ($IsLinux -or $IsMacOS) {
$isElevated = $false
$privid = id -u
$privid = id -u
if ($privid -eq 0) { $isElevated = $true }
}
$targetPlatform, $isElevated, $tmpDir, $targetHostname, $targetUser
Expand All @@ -28,15 +29,15 @@ function Get-TargetInfo($Session) {
if ($IsLinux -or $IsMacOS) {
$tmpDir = "/tmp/"
$isElevated = $false
$privid = id -u
$privid = id -u
if ($privid -eq 0) { $isElevated = $true }
if ($IsMacOS) { $targetPlatform = "macos" }
}
else {
$targetPlatform = "windows"
$isElevated = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
}

}
$targetPlatform, $isElevated, $tmpDir, $targetHostname, $targetUser
}
}
2 changes: 1 addition & 1 deletion Private/Invoke-CheckPrereqs.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ function Invoke-CheckPrereqs ($test, $isElevated, $executionPlatform, $customInp
foreach ($dep in $test.dependencies) {
$executor = Get-PrereqExecutor $test
$final_command = Merge-InputArgs $dep.prereq_command $test $customInputArgs $PathToAtomicsFolder
if($executor -ne "powershell") { $final_command = ($final_Command.trim()).Replace("`n", " && ") }
if ($executor -ne "powershell") { $final_command = ($final_Command.trim()).Replace("`n", " && ") }
$res = Invoke-ExecuteCommand $final_command $executor $executionPlatform $TimeoutSeconds $session
$description = Merge-InputArgs $dep.description $test $customInputArgs $PathToAtomicsFolder
if ($res.ExitCode -ne 0) {
Expand Down
45 changes: 23 additions & 22 deletions Private/Invoke-ExecuteCommand.ps1
Original file line number Diff line number Diff line change
@@ -1,52 +1,53 @@
function Invoke-ExecuteCommand ($finalCommand, $executor, $executionPlatform, $TimeoutSeconds, $session = $null, $interactive) {
function Invoke-ExecuteCommand ($finalCommand, $executor, $executionPlatform, $TimeoutSeconds, $session = $null, $interactive) {
$null = @(
if ($null -eq $finalCommand) { return 0 }
$finalCommand = $finalCommand.trim()
Write-Verbose -Message 'Invoking Atomic Tests using defined executor'
if ($executor -eq "command_prompt" -or $executor -eq "sh" -or $executor -eq "bash") {
$execPrefix = "-c"
$execExe = $executor
if ($executor -eq "command_prompt") {
$execPrefix = "/c";
$execExe = "cmd.exe";
$execCommand = $finalCommand -replace "`n", " & "
$arguments = $execPrefix,"$execCommand"
}
if ($executor -eq "command_prompt") {
$execPrefix = "/c";
$execExe = "cmd.exe";
$execCommand = $finalCommand -replace "`n", " & "
$arguments = $execPrefix, "$execCommand"
}
else {
$finalCommand = $finalCommand -replace "[\\](?!;)", "`\$&"
$finalCommand = $finalCommand -replace "[`"]", "`\$&"
$execCommand = $finalCommand -replace "(?<!;)\n", "; "
$arguments = "$execPrefix `"$execCommand`""
$finalCommand = $finalCommand -replace "[\\](?!;)", "`\$&"
$finalCommand = $finalCommand -replace "[`"]", "`\$&"
$execCommand = $finalCommand -replace "(?<!;)\n", "; "
$arguments = "$execPrefix `"$execCommand`""

}
}
elseif ($executor -eq "powershell") {
$execCommand = $finalCommand -replace "`"", "`\`"`""
if ($session) {
if ($executionPlatform -eq "windows") {
$execExe = "powershell.exe"
$execExe = "powershell.exe"
}
else {
$execExe = "pwsh"
$execExe = "pwsh"
}
}
else {
$execExe = "powershell.exe"; if ($IsLinux -or $IsMacOS) { $execExe = "pwsh" }
}
if ($execExe -eq "pwsh"){
if ($execExe -eq "pwsh") {
$arguments = "-Command $execCommand"
}else{
}
else {
$arguments = "& {$execCommand}"
}
}
else {
Write-Warning -Message "Unable to generate or execute the command line properly. Unknown executor"
return [PSCustomObject]@{
StandardOutput = ""
ErrorOutput = ""
ExitCode = -1
IsTimeOut = $false
}
StandardOutput = ""
ErrorOutput = ""
ExitCode = -1
IsTimeOut = $false
}
}

# Write-Host -ForegroundColor Magenta "$execExe $arguments"
Expand All @@ -56,7 +57,7 @@ function Invoke-ExecuteCommand ($finalCommand, $executor, $executionPlatform, $T
$fp2 = Join-Path $scriptParentPath "Invoke-KillProcessTree.ps1"
invoke-command -Session $session -FilePath $fp
invoke-command -Session $session -FilePath $fp2
$res = invoke-command -Session $session -ScriptBlock { Invoke-Process -filename $Using:execExe -Arguments $Using:arguments -TimeoutSeconds $Using:TimeoutSeconds -stdoutFile "art-out.txt" -stderrFile "art-err.txt" }
$res = invoke-command -Session $session -ScriptBlock { Invoke-Process -filename $Using:execExe -Arguments $Using:arguments -TimeoutSeconds $Using:TimeoutSeconds -stdoutFile "art-out.txt" -stderrFile "art-err.txt" }
}
else {
if ($interactive) {
Expand All @@ -67,7 +68,7 @@ function Invoke-ExecuteCommand ($finalCommand, $executor, $executionPlatform, $T
else {
# Local execution that DO NOT contain interactive prompts
# In this situation, capture the stdout/stderr for Invoke-AtomicTest to send to the caller
$res = Invoke-Process -filename $execExe -Arguments $arguments -TimeoutSeconds $TimeoutSeconds -stdoutFile "art-out.txt" -stderrFile "art-err.txt"
$res = Invoke-Process -filename $execExe -Arguments $arguments -TimeoutSeconds $TimeoutSeconds -stdoutFile "art-out.txt" -stderrFile "art-err.txt"
}
}
)
Expand Down
Loading
Loading