Malcat is first and foremost a static analysis tool aimed at inspectin malicious programs. Since malicious binaries often come obfuscated, it is often needed to decrypt, decompress and manipulate data in the program in order to uncover the most interesting parts of the malware. You would be surprised how fast and how far you can go with a purely static approach in malware analysis.
Malcat embeds more than 60 algorithms than you can use inside The transform dialog in order to deobfuscate arbitrary data buffers in the analyzed data. And since these algorithms (aka transforms) are written in Python, it is very easy to Writing your own transform operation!
In this chapter, we will see how to make the best use of the The transform dialog and see how you can extend Malcat by writing your own python transforms.
The simplest way to transform data in Malcat is by Selecting any arbitrary data range from within the Hexadecimal view or the Structure/text view and hit Ctrl+T. You can alternatively use the menu: . You will then be greated by the transform dialog shown below:
If you are familiar with the excellent CyberChef website, the interface should look somewhat familiar to you. If not, you can get an idea of its work flow by reading the rest of this chapter.
The transform dialog is a modeless window: it means you can continue to use Malcat’s UI while it is open. This is convenient if you need to copy/paste decryption keys found inside the program for instance.
On the left, you have the list of available transform operations, taken from both Malcat’s Data directory structure and the User data directory. You can search/filter the list using the search box on the top left corner of the dialog. You can add new operations to the transform chain (middle panel) by either:
double-clicking the name of an operation: it will be appended to the end of the chain
drag and dropping the name of operation at the position of your choice inside the chain
Each transform has a small help text than can be consulted either in the info field (bottom left) or by hovering the ? icon of the corresponding block. If this is not enough, you can consult the python code directly by clicking on the View/edit python file button located at the bottom of the left panel: the code will be displayed inside Malcat’s python editor. Transforms defined in Malcat’s
data/transforms directory can only be viewed (the python editor will be read-only). Transform defined in the User data directory on the contrary can be edited and saved.
Each operation have an arbitrary amount of parameters than you can modify directly from within the middle panel using standard GUI controls. If Auto preview is checked (the default), every parameter change will trigger a new evaluation of the transform chain (after a few milliseconds).
You can disable this behavior by unchecking the Auto preview option located at the top of the dialog. This can be useful if you want to decrypt large amount of data using CPU-intensive operations: having the whole transform chain applied for every small change can then be more annoying than useful.
The color of each operation block gives you information on the status of the corresponding operation:
a blue panel means the operation is either disabled or has not been run yet
a green panel means the operation was successful
a red panel means the operation has thrown an exception. Details about the exception can be found in the output window (bottom right)
If everything went right, the output window will display a preview of the result as an hexadecimal dump. If you are happy with the preview, you can either:
Click on In place to replace your selection with the result of the transform chain. Note that this is only possible if the result is smaller or of the same size as the initial input. If the result is smaller, the selection will be padded with null bytes.
Transforms are similar to other edits from a UI perspective. You can undo your changes to the file using Ctrl-Z if you wish so.
Click on New file to open the result as a new file in Malcat. Note that you can Switch between files to go back and forth between the result and your initial file.
And that’s it. Feel free to experiment with the system. If you wish to create your own transform operations, proceed to the next chapter.
A recent addition to Malcat is the ability to transform text from within the Source code / pure text viewer. It works for either pure-text files or script decompilation, and is pretty handy if you are facing source-code obfuscation. If you select any text in this view and then hit Ctrl+T (or use the transform button in the Source code / pure text viewer’s toolbar), you will be greeted with the same transform dialog. But since you are modifying text (and not bytes), there are a few minor differences to keep in mind:
You will only be able to transform text in place: the selected text inside the Source code / pure text viewer will simply be replaced by the result of your transformed text
Your input (aka the selected text) will be encoded to bytes using UTF-8 before being fed to the transform chain
At the end of the transform chain, the output will be converted back to text using UTF-8. If your transform chain did not produce UTF-8 text, an error will be risen
Beside this three limitations, you’ll have access to the complete list of transform operators. Don’t hesitate to Contact us if you have any feedback on this feature: it is still in beta and we are happy to improve it as needed.
Malcat has a lot of Customisation options, and transforms are no exception. Using python, it is very easy to add your own transform as you will see below.
If you do not find what you want in Malcat’s embedded transform operators, the easiest way is to use the custom user code operator. This is a simple operator that let you write your own transformation in python using Malcat’s integrated python editor:
For small one-shot operations, this is the way to go. But if you want to program something you’ll be able to reuse in the future, you are better off creating a custom operator.
If you have setup a User data directory, you can create python (.py) files in the
transforms/ subdirectory of the user directory. These files will be imported dynamically every time the transform dialog is shown. Each python file in this directory can contain one or more transform operators. A transform operator is simply defined as a class inheriting
Each transform operator must respect the following constraints:
It needs to have a
categoryclass variable (string): this will tell Malcat in which folder to put your new transform operator. Try to reuse an existing folder if it fits. If you leave it blank, your transform will be put at the root of the operators tree.
It needs to have a
nameclass variable (string): this will be the name of your operator inside the transform dialog.
It needs to implement a
The first parameter of this method (after
self) is fixed and will be the input buffer (type:
It can accept an arbitrary amount of additional Parameters. Each parameter needs to be annotated with a type and a default value
It needs to return either a
bytearrayobject: this will be the output of your transform operator
And that’s it! Malcat will take care of the rest and automatically create the GUI elements for your transform using python introspection. You can find below an small example shipped with Malcat: the bzip2 compression operator:
from transforms.base import Transform import bz2 class Bzip2Compress(Transform): # documentation/ help text shown in the transform dialog: """ Compress a stream using bzip2 level: compression level between 1 and 9 """ category = "compress" # <-- will be put under this folder in the transform dialog name = "bz2 compress" # <-- name shown in the transform dialog # the only method you have to implement is run(): def run(self, data:bytes, level:int=9): if level < 1 or level > 9: raise ValueError("Invalid level value") return bz2.compress(data, level)
As said above, the
run() method can accept an arbitrary number of parameters after the fixed
data input parameter. There are a two rules to follow though:
Parameter must be annotated with their type
A default value must be given
Malcat will then use this information in order to create the corresponding UI controls, following the rules below:
Text box accepting decimal or hexadecimal numbers
Text box accepting either hexadecimal bytes (
A Choice control to chose from a fixed list of enum values
A python code editor (only used for the user code operations, cf. Using the user code transform)
An example with
enum parameters is given below:
from transforms.base import * from Cryptodome.Cipher import AES, Blowfish, DES, DES3 from Cryptodome.Util import Padding class AesDecrypt(Transform): """ AES cipher decryption """ category = "crypto (block)" name = "aes decrypt" def run(self, data:bytes, mode:("ecb","cbc","cfb")="ecb", key:bytes=b"aaaaaaaaaaaaaaaa", iv:bytes=b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", unpad:bool=False): if mode == "ecb": decryptor = AES.new(key, AES.MODE_ECB) elif mode == "cbc": decryptor = AES.new(key, AES.MODE_CBC, iv=iv) elif mode == "cfb": decryptor = AES.new(key, AES.MODE_CFB, iv=iv) data = decryptor.decrypt(data) if unpad: data = Padding.unpad(data, 16) return data
To test your newly created transform operator, just use it in Malcat! Every time the transform dialog is shown, all python modules are dynamically reloaded. So if you need to test your new code, just reopen the transform dialog.
And even better, if you modify your python code using the Edit python file button located at the bottom of the left panel, you won’t even need to close the transform dialog: the module will be reloaded immediately.