[ << ALL_FEED ]

Again CFG

More in Malware

  • This is Siemens...

    Recently, our colleagues from the Positive Industrial Expertise Center discovered a curious Windows sample on MalwareBazaar.…

  • Anti-antivirus

    Recently, we came across an APK with an intriguing and trust-inspiring name: «Антивирус ФСБ.apk». After installing…

  • .exe .docm .xlsm

    .exe .docm .xlsm Malicious files with these extensions are most often found in corporate network traffic.…

  • Operation Chewbacca

    At the end of June, the PT ESC team, during incident investigations, discovered a new group…

  • Your Zimbra server is at risk

    Recently, our PT ESC IR team encountered a new attack by ransomware groups on Zimbra mail…

CFG again 👋

A common task when extracting malware configurations at scale is obtaining function boundaries and references. The most typical example is string decryption functions, since often only the input arguments containing the encrypted buffer differ.

Such functionality is a basic part of analysis tools like IDA, Binary Ninja, and others, but for our needs they are overkill and not always convenient for embedding into a project.

🤔 Next, angr comes to mind. Let’s try building a CFG with it:

io_wrapper = BytesIO(code)
proj = angr.Project(
        io_wrapper,
        main_opts={
            "backend": "blob",
            "arch": "x86",  
            "base_addr": imagebase,
        },
        auto_load_libs=False,
    )

cfg = proj.analyses.CFGFast(
    cross_references=True,
    normalize=True,
)

After a few experiments, it becomes clear that speed is not its strong suit: analyzing a test buffer took an average of 45 seconds.

⏰ In our case, speed is important, so after some googling, we find the SMDA project and decide to experiment with it. First, we initialize the config, immediately disabling unnecessary features and setting analysis time and size limits:

config = SmdaConfig()
config.CALCULATE_HASHING = False
config.CALCULATE_SCC = False
# having a valid prologue is enough
config.CONFIDENCE_THRESHOLD = 0.29
config.MAX_IMAGE_SIZE = 5 * 2 ** 20 #
config.TIMEOUT = 60

Let’s run the analysis and check the results. The library allows setting an arbitrary base address, which is extremely convenient when working with images from dumps:

dism = Disassembler(config=config, backend="intel")
report = dism.disassembleBuffer(file_content=code, base_addr=imagebase, bitness=32)
if report.status == "ok":
    report.initCodeXrefs()

If the analysis is successful, the report will contain information about functions, their basic blocks, instructions within blocks, and references between functions. You can retrieve all of this as follows:

for smda_func in report.getFunctions():
    if smda_func.blocks:
        for block_instructions in smda_func.blocks.values():
            for smda_isnn in block_instructions:
                print(f"{smda_func.offset} | {smda_isnn.detailed}")

    for smda_out_ref in smda_func.getCodeOutrefs():
        print(f"{smda_func.offset} | Out ref {smda_out_ref.to_func}")

    for smda_in_ref in smda_func.getCodeInrefs():
        print(f"{smda_func.offset} | In ref {smda_in_ref.from_func}")

👀 Example output for one of the functions:

c749b0 | <CsInsn 0xc749b0 [ff742408]: push dword ptr [esp + 8]>
c749b0 | <CsInsn 0xc749b4 [ff742408]: push dword ptr [esp + 8]>
c749b0 | <CsInsn 0xc749b8 [e893feffff]: call 0xc74850>
c749b0 | <CsInsn 0xc749bd [83c408]: add esp, 8>
c749b0 | <CsInsn 0xc749c0 [89c1]: mov ecx, eax>
c749b0 | <CsInsn 0xc749c2 [31c0]: xor eax, eax>
c749b0 | <CsInsn 0xc749c4 [85c9]: test ecx, ecx>
c749b0 | <CsInsn 0xc749c6 [7409]: je 0xc749d1>
c749b0 | <CsInsn 0xc749c8 [83790402]: cmp dword ptr [ecx + 4], 2>
c749b0 | <CsInsn 0xc749cc [7503]: jne 0xc749d1>
c749b0 | <CsInsn 0xc749ce [8b4108]: mov eax, dword ptr [ecx + 8]>
c749b0 | <CsInsn 0xc749d1 [c3]: ret >
c749b0 | Out ref 0xc749b8 (0xc749b0) -> 0xc74850 (0xc74850)

Measuring the analysis time, we get a result of about 1 second, which is a good indicator and suitable for use at scale.

✍️ To summarize: SMDA is a fast and convenient tool if the task is only to obtain a CFG and references. For other types of black magic analysis, heavier tools like angr are more suitable.

#tip #reverse #malware
@ptescalator (X, Max)

More from global_author

More from global_author

More in Malware

  • This is Siemens...

    Recently, our colleagues from the Positive Industrial Expertise Center discovered a curious Windows sample on MalwareBazaar.…

  • Anti-antivirus

    Recently, we came across an APK with an intriguing and trust-inspiring name: «Антивирус ФСБ.apk». After installing…

  • .exe .docm .xlsm

    .exe .docm .xlsm Malicious files with these extensions are most often found in corporate network traffic.…

  • Operation Chewbacca

    At the end of June, the PT ESC team, during incident investigations, discovered a new group…

  • Your Zimbra server is at risk

    Recently, our PT ESC IR team encountered a new attack by ransomware groups on Zimbra mail…