AS2Go.psm1
|
################################################################################ ###### ##### ###### Description ##### ###### ##### ################################################################################ <# AS2Go is an acronym for Attack Scenario To Go. AS2Go is written in PowerShell and goes along the cyber kill chain, with stops at Password Spray, Reconnaissance, Privilege Escalation, Sensitive Data Access & Exfiltration and Domain Compromise. The basic idea of AS2Go My goal is to create expressive and representative Microsoft Defender for Endpoint & Identity alerts or rather Microsoft 365 Defender & Microsoft Sentinel incidents. Within my current role in the Semperis Breach Preparedness and Response team, an additional goal of AS2Go is to increase awareness of how easy it is to abuse a vulnerability or misconfiguration to compromise the entire Active Directory. #> ##Requires -RunAsAdministrator $Script:DateFormatLog = "yyyy-MM-dd HH:mm:ss.fff" $Script:DateFormatSA = "yyyy-MM-dd HH:mm:ss" $Script:WinVersion = [System.Environment]::OSVersion.Version.ToString() $ASModulePath = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent $ASModuleTopPath = Split-Path -Path $ASModulePath -Parent $ASModuleName = $MyInvocation.MyCommand.ScriptBlock.Module.Name $ASModuleManifest = (Test-ModuleManifest -Path $(join-path $ASModulePath -ChildPath "\$ASModuleName.psd1")) $ASModuleLastUpdate = $ASModuleManifest.PrivateData.PSData.LastUpdate $Script:ASModuleLog = "$ASModulePath\$ASModuleName.log" $Script:ConfigFile = "$ASModulePath\$ASModuleName.json" $Script:DefautExportFolder = Join-Path -Path $ASModuleTopPath -ChildPath "Export" $Script:DefautImportFolder = Join-Path -Path $ASModuleTopPath -ChildPath "Import" $Script:DefautExfiltrationFolder = Join-Path -Path $ASModulePath -ChildPath "Exfiltration" $Script:DefautCleanUpFolder = Join-Path -Path $ASModulePath -ChildPath "CleanUp" $Script:ASTools = Join-Path -Path $ASModulePath -ChildPath "Tools" $Script:ASPhases = Join-Path -Path $ASModulePath -ChildPath "Phases" $Script:ASSetup = Join-Path -Path $ASModulePath -ChildPath "LabSetup" $Global:PathPSCertutil = Join-Path -Path $Script:ASSetup -ChildPath "PSCertutil\PSCertutil.psd1" $Global:PathADCSGoat = Join-Path -Path $Script:ASSetup -ChildPath "ADCSGoat\ADCSGoat.psd1" $Script:AllDomainsDetails = @() $Script:DoaminTypes = @{} $Script:ADCS = @{} [bool]$Script:PoSH7 = $false If ($PSVersionTable.PSVersion.Major -ge 7) { $Script:PoSH7 = $true # --- Global header color for all Format-Table outputs --- $PSStyle.Formatting.TableHeader = "`e[90m" # DarkGray #Cyan → "e[96m" #White → "e[97m" } $Script:FGCIInfo = [System.ConsoleColor]::Magenta # Additional info / side details $Script:FGCMInfo = [System.ConsoleColor]::Yellow # Main info (instead of Yellow → modern, easy to read) $Script:FGCSInfo = [System.ConsoleColor]::DarkGray # Secondary info / less important $Script:FGCCommand = [System.ConsoleColor]::White # Commands / executions $Script:FGCQuestion = [System.ConsoleColor]::Cyan $Script:FGCInput = [System.ConsoleColor]::Cyan $Script:FGCQuestion2 = [System.ConsoleColor]::Cyan # Questions / user input $Script:FGCHighLight = [System.ConsoleColor]::Magenta # Clear highlight text $Script:FGCWarning = [System.ConsoleColor]::Cyan # Warnings (classic Yellow) $Script:FGCError = [System.ConsoleColor]::Red # Errors (bright red tone, more visible) $global:BDSecurePass = "" $global:BDUser = "" $global:BDCred = "" $fgcS = "DarkGray" # Switch - DarkGray $fgcC = "Yellow" # Command $fgcV = "Cyan" # Value $fgcF = "White" $fgcH = "Yellow" $fgcR = "Green" #result $fgcG = "Gray" $Script:ConsoleBGColor = [System.ConsoleColor]::Black $Script:ConsoleFGColor = [System.ConsoleColor]::Gray $Script:fgcS = "DarkGray" # Switch - DarkGray $Script:fgcC = "Yellow" # Command $Script:fgcV = "White" # Value"DarkCyan" # Value Blue or Cyan $Script:fgcF = "White" # Foreground Color $Script:fgcR = "Green" # Result $Script:fgcHeader = [System.ConsoleColor]::DarkGray $Script:Yes = "Y" $Script:No = "N" $Script:EnableLogging = $false $PublishedRiskyTemplates = New-Object System.Collections.ArrayList $Script:AllDomainsDetails = New-Object System.Collections.ArrayList $exit = "x" #$yes = "Y" #$no = "N" $PtH = "H" $PtT = "T" $PtC = "C" $KrA = "K" $CfM = "M" $Script:GoldenTicket = "GT" $Script:InitialStart = "Start" $Script:PrivledgeAccount = $no #$tmp = "$ASModulePath\AS2Go.tmp" $Script:RUBEUS = Join-Path -Path $Script:ASTools -ChildPath "Rubeus.exe" $Script:Phase04 = "Brute Force Or Pw Spray" $Script:Phase05 = "User Account Compromised" $Script:Phase06 = "Reconnaissance" $Script:Phase07 = "Privilege Escalation" $Script:Phase08 = "Priviledge Account Compromised" $Script:Phase09 = "Reconnaissance with Priviledge Account" $Script:Phase10 = "Access Sensitive Data" $Script:Phase11 = "Exfiltrate Data" $Script:Phase12 = "Domain Compromised" $Script:Phase25 = "Misconfigured Certificate Template Attack (ESC1)" $Script:Phase27 = "Kerberoasting Attack" $Script:Phase50 = "COMPLETE" $Script:GroupEA = @() $Script:GroupSA = @() $Script:GroupPUG = @() $Script:GroupDA = @() $Script:GroupDNSA = @() $Script:BestDCs = @{} $Script:DCsPerDomain = @{} $Script:departments = ( # Finance @{ Name = "Finance & Accounting" Positions = @( "Finance Manager", "Senior Accountant", "Accountant", "Financial Analyst", "Accounts Payable Clerk", "Accounts Receivable Clerk" ) }, # Human Resources @{ Name = "Human Resources" Positions = @( "HR Manager", "HR Business Partner", "HR Administrator", "Recruiter", "People Operations Specialist" ) }, # Sales @{ Name = "Sales" Positions = @( "Sales Manager", "Account Executive", "Sales Representative", "Business Development Manager", "Sales Operations Analyst" ) }, # Marketing @{ Name = "Marketing" Positions = @( "Marketing Manager", "Digital Marketing Specialist", "Content Manager", "SEO Specialist", "Marketing Coordinator" ) }, # Engineering / R&D @{ Name = "Engineering" Positions = @( "Engineering Manager", "Software Engineer", "Senior Software Engineer", "Systems Engineer", "DevOps Engineer" ) }, # IT @{ Name = "Information Technology" Positions = @( "IT Manager", "Systems Administrator (Tier 0)", "Cloud Engineer", "Network Engineer", "IT Support Specialist (Tier 1)" ) }, # Security @{ Name = "Cyber Security" Positions = @( "Security Manager", "Security Engineer", "SOC Analyst", "Incident Response Analyst", "IAM Specialist" ) }, # Consulting / Professional Services @{ Name = "Consulting" Positions = @( "Consulting Manager", "Senior Consultant", "Consultant", "Solution Architect" ) }, # Data & Analytics @{ Name = "Data & Analytics" Positions = @( "Data Analyst", "Senior Data Analyst", "Data Engineer", "Business Intelligence Analyst" ) }, # AI / Automation @{ Name = "AI & Automation" Positions = @( "AI Engineer", "Machine Learning Engineer", "Automation Engineer", "AI Solutions Architect" ) }, # Operations @{ Name = "Operations" Positions = @( "Operations Manager", "Business Operations Analyst", "Process Manager", "Service Delivery Manager" ) }, # Procurement @{ Name = "Procurement & Purchasing" Positions = @( "Procurement Manager", "Purchasing Specialist", "Buyer", "Vendor Manager" ) }, # Legal & Compliance @{ Name = "Legal & Compliance" Positions = @( "Legal Counsel", "Compliance Manager", "Compliance Officer", "Risk Analyst" ) } ) ########################################################################## Set-Alias Pause Invoke-NextStep -Force $ScriptDir = New-Object System.Collections.ArrayList if (Test-Path("$ASModulePath\Private")) { $PrivatePath = '{0}\Private\*.ps1' -f $ASModulePath [VOID]$ScriptDir.Add($PrivatePath) } if (Test-Path("$ASModulePath\Public")) { $PublicPath = '{0}\Public\*.ps1' -f $ASModulePath [VOID]$ScriptDir.Add($PublicPath) } if (Test-Path("$ASModulePath\Script")) { $ScriptPath = '{0}\Script\*.ps1' -f $ASModulePath [VOID]$ScriptDir.Add($ScriptPath) } $Scripts = Get-ChildItem -Path $ScriptDir | Select-Object -ExpandProperty FullName # Load all scripts in the module foreach ($Script in $Scripts) { . $Script } #$SearchRecursive = $true $SearchRootOnly = $false $PublicScriptBlock = [ScriptBlock]::Create((Get-ChildItem -Path $PublicPath | Get-Content | Out-String)) $PublicFunctionAsts = $PublicScriptBlock.Ast.FindAll({ $args[0] -is [System.Management.Automation.Language.FunctionDefinitionAst] }, $SearchRootOnly) $PublicFunctions = $PublicFunctionAsts.Name # Export all functions including alias if ($PublicFunctions) { foreach ($Function in $PublicFunctions) { $Alias = @() #Check if function has an alias $AliasFunc = $PublicFunctionAsts | Where-Object { $_.Name -eq $Function -and $_.Body.ParamBlock -and $_.Body.ParamBlock.Attributes } | Select-Object -First 1 #Check if an alias was found, if it did save the alias name if ($AliasFunc) { $Alias = $AliasFunc.Body.ParamBlock.Attributes | Where-Object { $_.TypeName.Name -eq 'Alias' } | ForEach-Object { $_.PositionalArguments.Value } | Where-Object { $_ } } #If alias exist export function wiht alias if ($Alias) { Export-ModuleMember -Function $Function -Alias $Alias } else { Export-ModuleMember -Function $Function } } } $logo = @' █████╗ ███████╗██████╗ ██████╗ ██╔══██╗██╔════╝╚════██╗██╔════╝ ███████║███████╗ █████╔╝██║ ███╗ █████╗ ██╔══██║╚════██║██╔═══╝ ██║ ██║ ██ ██║ ██║ ██║███████║███████╗╚██████╔╝ █████║ ╚═╝ ╚═╝╚══════╝╚══════╝ ╚═════╝ ╚════╝ '@ -split "`n" Write-Host "`n" $logo | ForEach-Object { $line = $_ -replace '█', '█' Write-Host $line -ForegroundColor DarkYellow -BackgroundColor Black } Write-Host "`n" Write-Host " Description: $($ASModuleManifest.Description) " -ForegroundColor Gray Write-Host " Author: $($ASModuleManifest.CompanyName) | Version: $($ASModuleManifest.Version) | Last Update: $ASModuleLastUpdate | Copyright: $($ASModuleManifest.Copyright)" -ForegroundColor Gray Write-Host "`n get-command " -NoNewline -ForegroundColor DarkYellow Write-Host "-Module " -ForegroundColor DarkGray -NoNewline Write-Host "'AS2Go'`n`n" -ForegroundColor DarkCyan $host.ui.RawUI.WindowTitle = "$ASModuleName - $($ASModuleManifest.Version)" |