AlphaBlend Campaign Part 2

in reverseengineering •  29 days ago

This post continues the analysis of the AlphaBlend campaign. I’d like to thank everyone for all the fantastic feedback. One goal I have is to always show my work, and I think my elementary school math teachers would be proud. In the last post, I noted that a structured exception handler is used to prevent easy debugging. This is an old technique, but I’ve found that much of the information about circumventing this technique is hard to follow. Below is a step-by-step process for circumvention using x64dbg. Additionally, I noted that there is an odd string “Actx “ that appears during debugging. I’ve found how it is used, but I don’t yet know why.

A structured exception handler (SEH) is used by software to “do something” if a particular exception is raised. It lives in register fs at fs:[0]. Malware can set a custom handler that then runs when a particular exception is raised. Then the malware does something that causes the exception to be raised. Then the custom handler with the malicious code is run. The lab rat I’m working with poses an interesting challenge for the standard SEH circumvention technique of setting a software or hardware breakpoint on the handler. It doesn’t work, or I’m doing it wrong. However, if one follows the handler pointer and sets a memory breakpoint in the memory map of x64dbg, one is able to debug the code in the handler.

Memory Map.png

Set Breakpoint.png

With the breakpoint set, go over to the list of breakpoints and disable it so it stays out of the way until you need it. Next, set an exception breakpoint on EXCEPTION_ACCESS_VIOLATION and proceed to the exception breakpoint. Finally, enable the memory breakpoint and step into the exception.

Breakpoints.png

In the following screenshot of Hopper Disassembler, I’ve identified the function where the SEH is setup. I renamed it set_SEH to make it clear. If anyone knows a better way to mark this in Hopper, please let me know.

Set SEH in Hopper.png

There are two very important instructions in this function: SEH save and SEH init. The code between them, I think, is the configuration of the SEH. Here is a look at the same stretch of code in the debugger.

SEH Setup.png

These two instructions provide a nice bit of code to build a YARA rule on. I went on a search for previous research on this topic and found a pair of rules written by @NaxoneZ. AlphaBlend uses a different register in the init mov instruction, so I built on those rules and developed a pair of new rules that cover both observed instruction patterns. I also added a set of tags to the rules that make their incorporation into MITRE ATT&CK easier. That ruleset is found in the appendix in both standard format and plyara format.

Next, we examine the interesting string “Actx “ I noticed in the last post. I located where the string is originally loaded. Arrow 1 is where the string ecx+4 is moved to the ebx register. This address is located in the main, benign Setup.exe thread. The next instruction moves the pointer to InterlockCompareExchange to the edi register.

Actx.png

Arrow 3 is the set of input parameters for InterlockCompareExchange: 0, “Actx “, and an address in the malicious DLL. This stretch of code includes a comparison that can cause sleep to occur (arrow 2). This is important to note so that it can be patched to disable the sleep if needed later on. I am not sure if this is important yet, but sleep can be poisonous to sandbox analysis. Knowing where it happens can allow you to patch it out in an automated way. This lets future samples run in Cuckoo Sandbox easier.

We’ve seen two potential anti-analysis defenses used by AlphaBlend. I hope this has helped you understand how to find them. If you have any questions or suggestions, please leave comments below.

Appendix

[
    {
        "condition_terms": [
            "uint16",
            "(",
            "0",
            ")",
            "==",
            "0x5A4D",
            "and",
            "uint32",
            "(",
            "uint32",
            "(",
            "0x3C",
            ")",
            ")",
            "==",
            "0x00004550"
        ],
        "raw_condition": "condition:\n        uint16(0) == 0x5A4D and uint32(uint32(0x3C)) == 0x00004550\n",
        "rule_name": "WindowsPE",
        "scopes": [
            "private"
        ],
        "start_line": 1,
        "stop_line": 5
    },
    {
        "condition_terms": [
            "WindowsPE",
            "and",
            "$a"
        ],
        "metadata": [
            {
                "author": "Malware Utkonos"
            },
            {
                "original_author": "naxonez"
            },
            {
                "source": "https://github.com/naxonez/yaraRules/blob/master/AntiDebugging.yara"
            }
        ],
        "raw_condition": "condition:\n        WindowsPE and $a\n",
        "raw_meta": "meta:\n        author = \"Malware Utkonos\"\n        original_author = \"naxonez\"\n        source = \"https://github.com/naxonez/yaraRules/blob/master/AntiDebugging.yara\"\n    ",
        "raw_strings": "strings:\n        $a = { 64 ff 35 00 00 00 00 }\n    ",
        "rule_name": "SEH_Save",
        "start_line": 7,
        "stop_line": 17,
        "strings": [
            {
                "name": "$a",
                "type": "byte",
                "value": "{ 64 ff 35 00 00 00 00 }"
            }
        ],
        "tags": [
            "Tactic_DefensiveEvasion",
            "Technique_AntiDebugging",
            "SubTechnique_SEH"
        ]
    },
    {
        "condition_terms": [
            "WindowsPE",
            "and",
            "(",
            "$a",
            "or",
            "$b",
            ")"
        ],
        "metadata": [
            {
                "author": "Malware Utkonos"
            },
            {
                "original_author": "naxonez"
            },
            {
                "source": "https://github.com/naxonez/yaraRules/blob/master/AntiDebugging.yara"
            }
        ],
        "raw_condition": "condition:\n        WindowsPE and ($a or $b)\n",
        "raw_meta": "meta:\n        author = \"Malware Utkonos\"\n        original_author = \"naxonez\"\n        source = \"https://github.com/naxonez/yaraRules/blob/master/AntiDebugging.yara\"\n    ",
        "raw_strings": "strings:\n        $a = { 64 A3 00 00 00 00 }\n        $b = { 64 89 25 00 00 00 00 }\n    ",
        "rule_name": "SEH_Init",
        "start_line": 19,
        "stop_line": 30,
        "strings": [
            {
                "name": "$a",
                "type": "byte",
                "value": "{ 64 A3 00 00 00 00 }"
            },
            {
                "name": "$b",
                "type": "byte",
                "value": "{ 64 89 25 00 00 00 00 }"
            }
        ],
        "tags": [
            "Tactic_DefensiveEvasion",
            "Technique_AntiDebugging",
            "SubTechnique_SEH"
        ]
    }
]

YARA Rule in plyara Format

private rule WindowsPE
{
    condition:
        uint16(0) == 0x5A4D and uint32(uint32(0x3C)) == 0x00004550
}

rule SEH_Save : Tactic_DefensiveEvasion Technique_AntiDebugging SubTechnique_SEH
{
    meta:
        author = "Malware Utkonos"
        original_author = "naxonez"
        source = "https://github.com/naxonez/yaraRules/blob/master/AntiDebugging.yara"
    strings:
        $a = { 64 ff 35 00 00 00 00 }
    condition:
        WindowsPE and $a
}

rule SEH_Init : Tactic_DefensiveEvasion Technique_AntiDebugging SubTechnique_SEH
{
    meta:
        author = "Malware Utkonos"
        original_author = "naxonez"
        source = "https://github.com/naxonez/yaraRules/blob/master/AntiDebugging.yara"
    strings:
        $a = { 64 A3 00 00 00 00 }
        $b = { 64 89 25 00 00 00 00 }
    condition:
        WindowsPE and ($a or $b)
}

YARA Rule

For the people who read this far, some more music for your pleasure.

Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE STEEM!
Sort Order:  

Hello @utkonos! This is a friendly reminder that you have 3000 Partiko Points unclaimed in your Partiko account!

Partiko is a fast and beautiful mobile app for Steem, and it’s the most popular Steem mobile app out there! Download Partiko using the link below and login using SteemConnect to claim your 3000 Partiko points! You can easily convert them into Steem token!

https://partiko.app/referral/partiko