XWorm Part 1 - Unraveling a Steganography-Based Downloader

malwaretrace.net · Jared G. · 9 months ago · research
quality 7/10 · good
0 net
XWorm Part 1 - Unraveling a Steganography-Based Downloader Contents XWorm Part 1 - Unraveling a Steganography-Based Downloader Overview Today, we’ll analyze a sample tagged as XWorm, sourced from Malware Bazaar, with a SHA-256 hash of 0fd706ebd884e6678f5d0c73c42d7ee05dcddd53963cf53542d5a8084ea82ad1 . This sample will be referred to as the first stage. According to a recent AnyRun report 1 , XWorm is a remote access trojan (RAT) sold as a service, capable of exfiltrating files, stealing various application credentials, and maintaining remote access. It also states that XWorm is commonly delivered in multi-stage attacks, starting with phishing emails. Technical Analysis Stage 1 The first stage is a JScript file employing junk code, junk delimiter strings, and string concatenation for obfuscation. figure 1 - obfuscated stage 1 downloader This can be trivially deobfuscated using a text editor like Sublime Text to replace the delimiter string defined on line 79 with an empty string, followed by replacing the below regular expression with an empty string to clean up string concatenation. 1 ";[\s\n]+[a-z]+\s\+=\s" After further deobfuscation and variable renaming, the below downloader is identified, which reaches out to a URL, checks for a status code of 200 , then executes the HTTP response as code through use of an immediately invoked function expression 2 (IIFE). figure 2 - deobfuscated stage 1 downloader script Stage 2 The next stage is further JScript with obfuscation identical to stage 1. Repeating previous deobfuscation steps, we observe use of PowerShell to execute another stage seen in figure 3 . This is responsible for executing the PowerShell script in figure 4 . figure 3 - stage 2 downloader script figure 4 - PowerShell script invoked by stage 2 downloader script After some code beautifying using CyberChef and variable renaming, we can see it loads an image hosted on “Internet Archive” into memory as a byte array. figure 5 - PowerShell code responsible for loading image into memory figure 6 - universe themed image hosted on Internet Archive Once loaded into memory, the array is scanned for hard-coded bitmap magic bytes 3 42 4D . Once found, the index position of the byte sequence start is stored in variable $bitmap_begin . figure 7 - code responsible for locating bitmap embedded in image Starting at $bitmap_begin , the remaining image bytes are stored in a memory buffer, used to construct a .NET Bitmap object . It then loops through each pixel and loads their RGB byte values into variable $byte_list . figure 8 - code responsible for image manipulation From the newly created byte list, a .NET assembly is loaded where method ClassLibrary1.Home::VAI() is invoked. figure 9 - extraction and execution of .NET assembly embedded within bitmap Dynamic PE Extration Now having an understanding of its functionality, we can dump the assembly using a dynamic approach by replacing lines 55 and onwards with the following and executing the script. 1 [ System.IO.File ]:: WriteAllBytes ( "assembly.mal" , $dotnet_assembly ); Static PE Extraction Alternatively, we can leverage the Pillow Python library 4 to work with the image data and extract the embedded PE. The referenced blog on looping through pixel data with Python 5 was helpful during development. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 import sys import os from PIL import Image # take image as input polyglot = sys . argv [ 1 ] with open ( polyglot , " rb " ) as f : image_bytes = f . read () # convert image to byte array image_byte_array = bytearray ( image_bytes ) size = len ( image_byte_array ) # find bitmap start bitmap_start = image_byte_array . find ( b " \x42\x4D\x72\x6E\x37\x00\x00\x00\x00\x00\x36\x00\x00\x00\x28\x00\x00\x00\x64\x00\x00\x00\x4D\x2F\x00\x00\x01\x00\x18\x00\x00\x00\x00\x00\x3C\x6E\x37\x00\xC4\x0E\x00\x00\xC4\x0E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 " ) # extract bitmap based on start location extracted_bitmap = image_byte_array [ slice ( bitmap_start , size )] # temporarily write bitmap to disk # (the Image module only handles file paths) with open ( " bitmap.tmp " , " wb " ) as f : f . write ( extracted_bitmap ) try : img = Image . open ( " bitmap.tmp " ) except FileNotFoundError : print ( " Error: temporary bitmap file not found " ) width , height = img . size # get dimensions image = img . convert ( " RGB " ) # read image using RGB mode byte_list = [] # define ouput byte list # extract each pixel's RGB byte values for y in range ( height ): for x in range ( width ): r , g , b = image . getpixel (( x , y )) byte_list . append ( r ) byte_list . append ( g ) byte_list . append ( b ) # bitmap cleanup img . close () image . close () os . remove ( " bitmap.tmp " ) # extract assembly assembly_len = int . from_bytes ( byte_list [: 4 ], byteorder = " little " ) extracted_assembly = bytes ( byte_list [ 4 : assembly_len ]) # write assembly to file with open ( " extracted_assembly.mal " , " wb " ) as f : f . write ( extracted_assembly ) Until next time! See you in part two , where we will analyze the extracted .NET assembly. All hashes from the below IOC table will be available for download on MalShare . IOCs Type IOC Stage 1 Downloader SHA-256 0fd706ebd884e6678f5d0c73c42d7ee05dcddd53963cf53542d5a8084ea82ad1 Stage 1 Downloader User-Agent MyCustomAgent/1.0 Stage 2 URL hxxp[://]deadpoolstart[.]lovestoblog[.]com/arquivo_fb2497d842454850a250bf600d899709[.]txt Stage 2 Downloader SHA-256 ad25fffedad9a82f6c55c70c62c391025e74c743a8698c08d45f716b154f86da Image SHA-256 89959ad7b1ac18bbd1e850f05ab0b5fce164596bce0f1f8aafb70ebd1bbcf900 Image URL hxxps[://]archive[.]org/download/universe-1733359315202-8750/universe-1733359315202-8750[.]jpg References and Resources https://any.run/malware-trends/xworm/  ↩︎ https://developer.mozilla.org/en-US/docs/Glossary/IIFE  ↩︎ https://en.wikipedia.org/wiki/List_of_file_signatures  ↩︎ https://pillow.readthedocs.io/en/stable/  ↩︎ https://www.nemoquiz.com/python/loop-through-pixel-data/  ↩︎ Malware Analysis x-worm xworm polyglot rat deobfuscation script This post is licensed under CC BY 4.0 by the author. Share