Cerbero Suite 4.8 is out!

This time it took a bit longer, because we were busy with the release of our Cerbero Engine.

The main news of this release is that we rewrote our Rich-Text Format (RTF) parser to handle more anti-malware tricks and we exposed the entire parser to Python.

We have also updated the YARA engine to its latest version and fixed a bug in the ELF Carbon loader.

This is the complete list of news:

– improved RTF parsing
– improved JBIG2 decoding
– various improvements
– exposed RTF classes to Python
– updated YARA to 4.1.1
– fixed bug in Carbon ELF loader
– fixed some bugs

Happy hacking!

Cerbero Suite 4.7 is out!

This version of Cerbero Suite comes with a variety of improvements:

  • We have greatly improved macOS support and squashed all the bugs we could find.
  • We have improved the hex editor: it can now open folders and on Windows it can edit logical drives, physical disks and the memory of processes.
  • We have further improved the native UI for Ghidra.
  • We have improved the ARM64 support in our Carbon disassembler.
  • We have improved the entropy view.
  • We have improved system integration on Windows and macOS and theme support.

This is the full list of news for version 4.7:

added open folder to hex editor
added open drive/disk to hex editor on Windows
added open process to hex editor on Windows
added system settings
improved native Ghidra UI
improved ARM64 disassembly
improved entropy view
– small improvements to the GZ format support
improved theme support
fixed Ghidra Native UI execution on macOS
fixed UI glitches on macOS
– fixed some bugs

Hex Editor

It is now possible to open an entire folder in the hex editor, either by context menu, command line or UI.

Furthermore, on Windows it is also possible to edit logical drives, physical disks and the memory of processes.

Logical drives:

Physical disks:

Processes:

Improved native UI for Ghidra

Now, when launching the native UI for Ghidra, the Java UI is automatically minimized (configurable from the settings). You can create and delete functions, and we try to keep the function list view updated without having to do a manual refresh. You can switch back to the Java UI from the native UI and you can also launch an additional native UI directly from the native UI.

Improved Carbon ARM64 support

We have improved ARM64 support in our Carbon disassembler in order to recognize additional multi-instruction jump patterns.

Improved entropy view

We have improved our entropy view making it dependent from the parent view and enabling clicks on it. When you click somewhere on the plot it will bring you to the point in the hex editor of the entropy you want to inspect.

System Settings

On both Windows and macOS it’s now possible to configure the integration of Cerbero Suite with the Explorer/Finder context menu.

Up until now, on Windows it was possible to configure the integration with Explorer only during the setup and not at a granular level.

Windows:

macOS:

You can now access the tools of Cerbero Suite directly from the context menu of Finder:

Improved theme support

Since on macOS the native system style may result in cluttered UIs, we have introduced an additional theme called “Fusion”. It comes with the same colors as the default theme, but with a different style for widgets.

Default theme on macOS:

Fusion theme:

If we see that our users prefer this theme, we might make it the default one on macOS.

Improved macOS support

Apart from adding system integration and improving theme support for macOS, we have also squashed all the macOS bugs we could find. We fixed some UI glitches and a bug which affected the launch of the native Ghidra UI on macOS. The UI experience on macOS should be a smooth one now!

Cerbero Suite 4.6 is out!

This is the complete list of news for version 4.6:

– added XLSX/XLSM format support
– added formula view to spreadsheet workspace
– added export table as text action
+ improved Silicon Excel Emulator
+ updated Sleigh decompiler

In order to demonstrate the use of the newly introduced formula view, here is a 50-seconds analysis of an obfuscated XLSX Excel malware:

Happy hacking!

Video: 3-Minutes Self-Decrypting Excel Malware Analysis

The script below shows how to brute-force the decryption of the code. It is not necessary, as in the video we calculate the correct value of the W86 cell manually, but the snippet might be useful for future samples.

from Pro.SiliconSpreadsheet import *
from Pro.UI import proContext

v = proContext().findView("Analysis [selfdecrxls]")
if v.isValid():
    view = SiliconSpreadsheetWorkspaceView(v)
    emu = view.getExcelEmulator()
    formula = """CHAR(A1-W86)&CHAR(A2-W86)&CHAR(A3-W86)&CHAR(A5-W86)&CHAR(A6-W86)&CHAR(A7-W86)&CHAR(A8-W86)&CHAR(A9-W86)&CHAR(A11-W86)&CHAR(A12-W86)&CHAR(A13-W86)&CHAR(A14-W86)&CHAR(A16-W86)&CHAR(A17-W86)&CHAR(A18-W86)&CHAR(A19-W86)&CHAR(A20-W86)&CHAR(A22-W86)&CHAR(A23-W86)&CHAR(A24-W86)&CHAR(A25-W86)&CHAR(A27-W86)&CHAR(A28-W86)&CHAR(A29-W86)&CHAR(A30-W86)&CHAR(A32-W86)&CHAR(A33-W86)&CHAR(A34-W86)&CHAR(A35-W86)&CHAR(A36-W86)&CHAR(A38-W86)&CHAR(A39-W86)&CHAR(A40-W86)&CHAR(A41-W86)&CHAR(A42-W86)&CHAR(A44-W86)&CHAR(A45-W86)&CHAR(A46-W86)&CHAR(A47-W86)&CHAR(A48-W86)"""
    cell_index = SiliconSpreadsheetUtil.cellIndex("'rZVUfQRQoV'!W86")
    ws = emu.getWorkspace()
    sheet = ws.getSheet(ws.sheetIndexFromName(cell_index.sheet))
    for i in range(1, 270):       
        sheet.addCell(cell_index.column, cell_index.row, SiliconSpreadsheetValueType_Number, str(i))
        res = emu.evaluate(formula, cell_index)
        print(str(i) + ":", res.getValue())
else:
    print("error: couldn't find view")

Video: 1.5-Minutes QakBot Excel Malware Analysis (2nd sample)

The script extends the Silicon Excel Emulator by implementing th “FORMULA” function:

from Pro.SiliconSpreadsheet import *
from Pro.UI import proContext

class EmulatorHelper(SiliconExcelEmulatorHelper):

    def __init__(self):
        super(EmulatorHelper, self).__init__()
        
    def evaluateFunction(self, emu, ctx, opts, depth, e):
        function_name = e.toString()
        if function_name == "FORMULA":
            if emu.expectedArguments(e, 2, 2):
                ve = emu.argToValue(ctx, opts, depth, e, 0)
                v = emu.valueToSpreadsheetValue(ve)
                idxstr = emu.argToValue(ctx, 0, depth, e, 1).toString()
                idx = SiliconSpreadsheetUtil.cellIndex(idxstr)
                print("FORMULA:", idxstr, "=", emu.valueToString(ve))
                # add the cell to the sheet
                ws = emu.getWorkspace()
                sheet_idx = ws.sheetIndexFromName(idx.sheet if idx.sheet else ctx.idx.sheet)
                sheet = ws.getSheet(sheet_idx)
                sheet.addCell(idx.column, idx.row, v.type, v.value)
                return SiliconExcelEmulatorValue(SiliconSpreadsheetValueType_Null, 0)
        return SiliconExcelEmulatorValue()

v = proContext().findView("Analysis [qakbot_xls_2]")
if v.isValid():
    view = SiliconSpreadsheetWorkspaceView(v)
    helper = EmulatorHelper()
    emu = view.getExcelEmulator()
    emu.setHelper(helper)
else:
    print("error: couldn't find view")

Video: 2-Minutes QakBot Excel Malware Analysis

The script extends the Silicon Excel Emulator by implementing the “NOW” and “FORMULA.FILL” functions:

from Pro.SiliconSpreadsheet import *
from Pro.UI import proContext

class EmulatorHelper(SiliconExcelEmulatorHelper):

    def __init__(self):
        super(EmulatorHelper, self).__init__()
        
    def evaluateFunction(self, emu, ctx, opts, depth, e):
        function_name = e.toString()
        if function_name == "FORMULA.FILL":
            if emu.expectedArguments(e, 2, 2):
                ve = emu.argToValue(ctx, opts, depth, e, 0)
                v = emu.valueToSpreadsheetValue(ve)
                idxstr = emu.argToValue(ctx, 0, depth, e, 1).toString()
                idx = SiliconSpreadsheetUtil.cellIndex(idxstr)
                print("FORMULA.FILL:", idxstr, "=", emu.valueToString(ve))
                # add the cell to the sheet
                ws = emu.getWorkspace()
                sheet_idx = ws.sheetIndexFromName(idx.sheet if idx.sheet else ctx.idx.sheet)
                sheet = ws.getSheet(sheet_idx)
                sheet.addCell(idx.column, idx.row, v.type, v.value)
                return SiliconExcelEmulatorValue(SiliconSpreadsheetValueType_Null, 0)
        elif function_name == "NOW":
            return SiliconExcelEmulatorValue(SiliconSpreadsheetValueType_Number, "44249.708602")
        return SiliconExcelEmulatorValue()

v = proContext().findView("Analysis [qakbot_xls_0]")
if v.isValid():
    view = SiliconSpreadsheetWorkspaceView(v)
    helper = EmulatorHelper()
    emu = view.getExcelEmulator()
    emu.setHelper(helper)
else:
    print("error: couldn't find view")

Cerbero Suite 4.5 is out!

Because of some bureaucratic slowdowns this release took longer than usual. On the upside, it comes packed with news!

We have added support for the XLSB format (via pyxlsb2), so that now Cerbero Suite decompiles both XLS and XLSB formulas. Not only that, Cerbero Suite now previews spreadsheets even better than Microsoft Excel does!

But even more exciting, we have introduced the Silicon Excel Emulator to emulate Microsoft Excel formulas.

In order to emulate a formula, it’s enough to select it in the spreadsheet and to press “Ctrl+E” (or using the context menu).

While the emulator doesn’t support all the functions available in Excel, we made it extremely simple to extend it from Python. When a function is not supported, the emulator simply prints out its arguments:

warning: unimplemented function 'CALL'
    arg_0: "Shell32"
    arg_1: "ShellExecuteA"
    arg_2: "JJCCCCJ"
    arg_3: 0
    arg_4: "Open"
    arg_5: "C:\ProgramData\nCjBmqQ.exe"
    arg_6: 
    arg_7: 0
    arg_8: 0

In most cases, this is enough to understand what’s happening. When it isn’t and we need something more, we can easily hook into the emulator engine via Python and extend it:

from Pro.SiliconSpreadsheet import *
from Pro.UI import proContext

class EmulatorHelper(SiliconExcelEmulatorHelper):

    def __init__(self):
        super(EmulatorHelper, self).__init__()
        
    def evaluateFunction(self, emu, ctx, opts, depth, e):
        function_name = e.toString()
        print(function_name)
        return SiliconExcelEmulatorValue()

v = proContext().findView("Analysis [file name]")
if v.isValid():
    view = SiliconSpreadsheetWorkspaceView(v)
    helper = EmulatorHelper()
    emu = view.getExcelEmulator()
    emu.setHelper(helper)
else:
    print("error: couldn't find view")

This little snippet of Python code does nothing else than to hook the Silicon Excel Emulator being used in a spreadsheet preview and to log every function being called. We can, however, just as easily modify the behavior of a function or implement its functionality by returning a valid value. We’ll show you how to do this in future articles and videos.

The new version of Cerbero Suite comes also with other improvements. For instance, it is now possible to edit the prototype of functions in the decompiler by pressing “Y”.

And you can now edit the prototype of a function in the same way also in the native UI for Ghidra.

This is the complete list of news for version 4.5:

– added spreadsheet preview for XLS and XLSB files
– added XLSB format support
+ added Microsoft Excel macro emulator
+ added editing of function prototypes in the decompiler
+ added editing of function prototypes in the native UI for Ghidra
+ improved Ghidra native UI
– improved XLS macro decompiler
– improved XLS format support
– exposed XLS classes to Python
– exposed new cell table view to Python
– minor improvements

We’ll soon publish material to demonstrate how to reverse engineer malicious Excel documents.

Happy hacking!

Cerbero Suite 4.4 is out!

This time it took a bit longer for the release as we’re undergoing some organizational changes, but we’ll make up for it in the upcoming months!

This is the list of news for version 4.4:

added Excel macro decompiler
added word highlighting to text editor
added password brute-forcers
+ improved C++ support in the decompiler
+ improved disassembly view
– improved detection of Excel malware

Excel Macro Decompiler

The major news of this release is the addition of a decompiler for Excel macros. We’ll continue to build and improve upon this feature in the upcoming releases!

C++ Decompiler Improvements

We have improved C++ support in the decompiler. A small improvement makes the code much easier to read!

Text Editor: Word Highlighting

Cerbero Suite now provides the word highlighting feature available in the disassembly/decompiler also in the text editor. This makes the analysis of VBA macros, JavaScript and other managed languages much easier.

Password Brute-Forcers

“infected” is such an ubiquitous password for sharing Zip archives containing malware that starting with this release you don’t even have to enter it when opening a file.

We’ve also added optional common passwords dictionary-based brute-forcers as a bonus. You can activate them from the extensions page.

More is coming soon…

Happy hacking!

Video: In-Depth Obfuscated VBA Analysis

This script concatenates strings such as “a” + “b”:

from Pro.UI import *
import re

ctx = proContext()
v = ctx.getCurrentView()
if v.isValid() and v.hasSelection():
    s = v.getSelectedText().replace('" &', '" +')
    s = eval(s)
    v.setSelectedText('"' + s + '"')

This second script decrypts strings the same way as the “NobosMeik” function:

from Pro.UI import *
import base64

ctx = proContext()
v = ctx.getCurrentView()
if v.isValid() and v.hasSelection():
    s = v.getSelectedText()
    s = base64.b64decode(s)
    key = b"versache"
    s2 = bytearray(s)
    y = 0
    tire = lambda r, g: (r & ~g) | (~r & g)
    for x in range(len(s)):
        s2[x] = tire(s2[x], key[y])
        if y < len(key) - 1:
            y += 1
        else:
            y = 0
    print(s2)