Anomaly scanner

Malcat features a powerful anomaly scanner which leverage all Malcat’s analyses in order to highlight suspicious items in the file. It is present in all Full & Pro versions of Malcat.

What are anomalies?

Anomalies are small heuristics computed by python functions located in data/anomalies. These functions make use of Malcat’s python Analysis object (analysis) to inspect the file under all angles. Each found anomaly in the file is tagged and its locations are reported in the Summary view (see below).

../_images/summary_anomalies.png

The anomaly screen in the summary view

Each anomaly heuristic is represented by a python Anomaly class featuring a scan function. One Anomaly instance is responsible for locating one particular type of anomaly. Here is an example of anomaly, that you can find in data/anomalies/xref.py:

class UnreferencedImports(Anomaly):
    """More than half of the imports are not referenced, it could mean that the APIs are just decoys, or that the file is packed"""
    level = Anomaly.ODD
    category = "imports"

    def scan(self, malcat):
        notref = []
        referenced = 0
        for s in malcat.syms:
            if s.type != bindings.Symbol.IMPORT:
                continue
            if s.address not in malcat.xref:
                notref.append((s.address, len(s)))
            else:
                referenced += 1
        if len(notref) > referenced:
            # tag every non-referenced import
            yield from iter(notref)

And here is another one specifiy to the PE format:

class SectionTableAfterFirstSection(Anomaly):
    """The section table is located after the first section's physical address"""
    level = Anomaly.WARNING
    category = "headers"
    filetype = "PE"

    def scan(self, malcat):
        first_nonzero_region_offset = len(malcat.file)
        for r in malcat.map:
            if r.phys_size and r.phys:
                first_nonzero_region_offset = min(first_nonzero_region_offset, r.phys)
        sections = malcat.struct.Sections
        if sections.offset >= first_nonzero_region_offset:
            # this is odd, tag the whole section table as the anomaly
            yield sections.address, sections.size

Despite being written in python, the anomaly scanner runs relatively fast, since most of the work has already be done by Malcat’s C++ Analysis engine (doc in progress).

Warning

While some of the anomalies may seem quite expressive and strong, we discourage their use as standalone malware detector. They have been mainly designed to help the human analyst get faster to the point, not to have a perfect detection rate.

Found anomalies are displayed in the Summary view and are additionnaly available to scripts through the Anomalies (analysis.anomalies) object.

Write your own anomaly

Writing

Once you have setup a User data directory, you can start creating new anomalies by creating a python file under <user data dir>/anomalies/. Note that you can also add anomalies directly under <malcat install dir>/data/anomalies, but you take the risk that they get overwritten with the next Malcat’s update.

Once you have your python file ready, writing a new anomaly is as simple as adding an python class inheriting from Anomaly and featuring a scan function to the file. The scan function take as parameter a Analysis object (analysis) object which is well documented.

We plan to write a beginner-friendly tutorial addressing anomaly creation very soon. In the meantime, you can get some inspiration by looking at Malcat’s 200+ List of anomalies.

Testing

As for all hackable things in Malcat, you can test your anomaly directly from within the user interface by hitting Ctrl+R or selecting Analysis ‣ Reanalyse current file from the menu. The anomaly list will be reloaded and rerun.

If you have an error in your code, you will see an exclamation mark in Malcat’s status bar. Hover the mouse over the exclamation mark, or look at the Console window (F8) to see the error in detail. Fix it, hit Ctrl+R and have a look at the result. It is that simple!