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)"