What We Do
How We Do
Resources
Company
Partners
Get Started
Blog

The Case of LummaC2 v4.0

BY eSentire Threat Response Unit (TRU)

September 7, 2023 | 11 MINS READ

Attacks/Breaches

Threat Intelligence

Threat Response Unit

TRU Positive/Bulletin

Want to learn more on how to achieve Cyber Resilience?

TALK TO AN EXPERT

Adversaries don’t work 9-5 and neither do we. At eSentire, our 24/7 SOCs are staffed with Elite Threat Hunters and Cyber Analysts who hunt, investigate, contain and respond to threats within minutes.

We have discovered some of the most dangerous threats and nation state attacks in our space – including the Kaseya MSP breach and the more_eggs malware.

Our Security Operations Centers are supported with Threat Intelligence, Tactical Threat Response and Advanced Threat Analytics driven by our Threat Response Unit – the TRU team.

In TRU Positives, eSentire’s Threat Response Unit (TRU) provides a summary of a recent threat investigation. We outline how we responded to the confirmed threat and what recommendations we have going forward.

Here’s the latest from our TRU Team…

What did we find?

Since the beginning of August 2023, the eSentire Threat Response Unit (TRU) has observed 5 cases of Lumma Stealer infections across manufacturing, retail, and business industries.

The infostealer was delivered via drive-by downloads disguised as fake installers such as Chrome and Edge browser installers. and some of them were distributed via PrivateLoader (a loader known to drop malware such as Redline, DCRat, and RaccoonStealer in the past).

eSentire TRU recently published a TRU Positive on LummaC2 delivering Amadey and PrivateLoader; you can access the article here.

Lumma Stealer, also known as LummaC2, first appeared on Russian-speaking forums at the end of 2022. The stealer is written in C++, and the build size is approximately 150-396 KB. The pricing for the stealer is divided into three categories:

Figure 1: Stealer advertisement on Russian speaking forums


The stealer features a non-resident loader that is capable of delivering additional payloads via EXE, DLL, and PowerShell:

Figure 2: Non-resident loader


Some other notable features of the stealer include:

Figure 3: Pop-up message if the build is not crypted

Technical Analysis

From the previous versions of the stealer (the sample we observed in June, MD5: a4e04604c178fe4fd19996b4d48b8885), as an obfuscation method, the stealer appends strings such as “576xe” to the data.

Figure 4: String obfuscation for previous versions of LummaC2


But with the latest versions (version 4.0), the stealer obfuscates the strings with an XOR algorithm. It converts the hexadecimal characters in the string into the decimal value. The first four bytes of the byte array of the string are used as the XOR key. Each subsequent byte in the array is XORed with the mentioned four bytes in a cyclic manner. The decryption is shown algorithm is shown in the screenshot below.

Figure 5: LummaC2 decryption algorithm


We implemented the string decrypter for LummaC2 in Python, which you can access here.

Figure 6: String decrypter implementation in Python


The stealer uses MurmurHash2 hashing algorithm to resolve the APIs, in our example the seed is 0x20. The API hashing function is obfuscated with control flow flattening as the rest of the code (Figure 8).

Figure 7: Snippet of code with control flow flattening


Figure 8: API hashing function


We wrote the script to produce the hash values based on the seed for each API call within the DLL library found in the stealer.

C2 Communication

Upon the initial infection, the stealer retrieves the configuration from the C2 (/c2conf). @Jane_0sint provided insights on decrypting the configuration using the first 32-byte of the base64-encoded string as the key. That means that the crypto wallet extensions, applications, and list of browsers are not embedded in the stealer build anymore compared to previous versions of the stealer.

Here is the example of the decrypted configuration retrieved from C2 (JSON format):

{
    "v": 1,
    "c": [
        {
            "t": 0,
            "p": "%userprofile%",
            "m": "*.txt",
            "z": "Important Files/Profile",
            "d": 1
        },
        {
            "t": 0,
            "p": "%userprofile%",
            "m": "*key*",
            "z": "Important Files/Profile",
            "d": 1
        },
        {
            "t": 0,
            "p": "%userprofile%",
            "m": "*bitcoin*",
            "z": "Important Files/Profile",
            "d": 3
        },
        {
            "t": 0,
            "p": "%userprofile%",
            "m": "*binance*",
            "z": "Important Files/Profile",
            "d": 3
        },
        {
            "t": 0,
            "p": "%userprofile%",
            "m": "*exodus*",
            "z": "Important Files/Profile",
            "d": 3
        },
        {
            "t": 0,
            "p": "%userprofile%",
            "m": "*coinbase*",
            "z": "Important Files/Profile",
            "d": 3
        },
        {
            "t": 0,
            "p": "%userprofile%",
            "m": "*wallet*",
            "z": "Important Files/Profile",
            "d": 3
        },
        {
            "t": 0,
            "p": "%userprofile%",
            "m": "*seed*",
            "z": "Important Files/Profile",
            "d": 3
        },
        {
            "t": 0,
            "p": "%userprofile%",
            "m": "*pass*",
            "z": "Important Files/Profile",
            "d": 3
        },
        {
            "t": 0,
            "p": "%userprofile%",
            "m": "*ledger*",
            "z": "Important Files/Profile",
            "d": 3
        },
        {
            "t": 0,
            "p": "%userprofile%",
            "m": "*trezor*",
            "z": "Important Files/Profile",
            "d": 3
        },
        {
            "t": 0,
            "p": "%userprofile%",
            "m": "*metamask*",
            "z": "Important Files/Profile",
            "d": 3
        },
        {
            "t": 0,
            "p": "%userprofile%",
            "m": "*crypto*",
            "z": "Important Files/Profile",
            "d": 1
        },
        {
            "t": 0,
            "p": "%appdata%\\Binance",
            "m": "app-store.json",
            "z": "Wallets/Binance",
            "d": 1
        },
        {
            "t": 0,
            "p": "%appdata%\\Binance",
            "m": ".finger-print.fp",
            "z": "Wallets/Binance",
            "d": 1
        },
        {
            "t": 0,
            "p": "%appdata%\\Binance",
            "m": "simple-storage.json",
            "z": "Wallets/Binance",
            "d": 1
        },
        {
            "t": 0,
            "p": "%appdata%\\Electrum\\wallets",
            "m": "*",
            "z": "Wallets/Electrum",
            "d": 1
        },
        {
            "t": 0,
            "p": "%appdata%\\Ethereum",
            "m": "keystore",
            "z": "Wallets/Ethereum",
            "d": 1
        },
        {
            "t": 0,
            "p": "%appdata%\\Exodus\\exodus.wallet",
            "m": "*",
            "z": "Wallets/Exodus",
            "d": 2
        },
        {
            "t": 0,
            "p": "%appdata%\\Ledger Live",
            "m": "*",
            "z": "Wallets/Ledger Live",
            "d": 2
        },
        {
            "t": 0,
            "p": "%appdata%\\atomic\\Local Storage\\leveldb",
            "m": "*",
            "z": "Wallets/Atomic",
            "d": 2
        },
        {
            "t": 0,
            "p": "%localappdata%\\Coinomi\\Coinomi\\wallets",
            "m": "*",
            "z": "Wallets/Coinomi",
            "d": 2
        },
        {
            "t": 0,
            "p": "%appdata%\\Authy Desktop\\Local Storage\\leveldb",
            "m": "*",
            "z": "Wallets/Authy Desktop",
            "d": 2
        },
        {
            "t": 0,
            "p": "%appdata%\\Bitcoin\\wallets",
            "m": "*",
            "z": "Wallets/Bitcoin core",
            "d": 2
        },
        {
            "t": 0,
            "p": "%appdata%\\com.liberty.jaxx\\IndexedDB",
            "m": "*.leveldb",
            "z": "Wallets/JAXX New Version",
            "d": 2
        },
        {
            "t": 0,
            "p": "%appdata%\\Electrum\\wallets",
            "m": "*",
            "z": "Wallets/Electrum",
            "d": 2
        },
        {
            "t": 0,
            "p": "%appdata%\\AnyDesk",
            "m": "*.conf",
            "z": "Applications/AnyDesk",
            "d": 2
        },
        {
            "t": 0,
            "p": "%appdata%\\FileZilla",
            "m": "recentservers.xml",
            "z": "Applications/FileZilla",
            "d": 2
        },
        {
            "t": 0,
            "p": "%appdata%\\FileZilla",
            "m": "sitemanager.xml",
            "z": "Applications/FileZilla",
            "d": 2
        },
        {
            "t": 0,
            "p": "%userprofile%",
            "m": "*.kbdx",
            "z": "Applications/KeePass",
            "d": 2
        },
        {
            "t": 0,
            "p": "%programfiles%\\Steam",
            "m": "ssfn*",
            "z": "Applications/Steam",
            "d": 2
        },
        {
            "t": 0,
            "p": "%programfiles%\\Steam\\config",
            "m": "*",
            "z": "Applications/Steam/config",
            "d": 2
        },
        {
            "t": 0,
            "p": "%appdata%\\Telegram Desktop",
            "m": "*s",
            "z": "Applications/Telegram",
            "d": 2
        },
        {
            "t": 1,
            "e": [
                {
                    "en": "ejbalbakoplchlghecdalmeeeajnimhm",
                    "ez": "MetaMask"
                },
                {
                    "en": "nkbihfbeogaeaoehlefnkodbefgpgknn",
                    "ez": "MetaMask"
                },
                {
                    "en": "egjidjbpglichdcondbcbdnbeeppgdph",
                    "ez": "Trust Wallet"
                },
                {
                    "en": "ibnejdfjmmkpcnlpebklmnkoeoihofec",
                    "ez": "TronLink"
                },
                {
                    "en": "fnjhmkhhmkbjkkabndcnnogagogbneec",
                    "ez": "Ronin Wallet"
                },
                {
                    "en": "fhbohimaelbohpjbbldcngcnapndodjp",
                    "ez": "Binance Chain Wallet"
                },
                {
                    "en": "ffnbelfdoeiohenkjibnmadjiehjhajb",
                    "ez": "Yoroi"
                },
                {
                    "en": "jbdaocneiiinmjbjlgalhcelgbejmnid",
                    "ez": "Nifty"
                },
                {
                    "en": "afbcbjpbpfadlkmhmclhkeeodmamcflc",
                    "ez": "Math"
                },
                {
                    "en": "hnfanknocfeofbddgcijnmhnfnkdnaad",
                    "ez": "Coinbase"
                },
                {
                    "en": "hpglfhgfnhbgpjdenjgmdgoeiappafln",
                    "ez": "Guarda"
                },
                {
                    "en": "blnieiiffboillknjnepogjhkgnoapac",
                    "ez": "EQUA"
                },
                {
                    "en": "cjelfplplebdjjenllpjcblmjkfcffne",
                    "ez": "Jaxx Liberty"
                },
                {
                    "en": "fihkakfobkmkjojpchpfgcmhfjnmnfpi",
                    "ez": "BitApp"
                },
                {
                    "en": "kncchdigobghenbbaddojjnnaogfppfj",
                    "ez": "iWlt"
                },
                {
                    "en": "kkpllkodjeloidieedojogacfhpaihoh",
                    "ez": "EnKrypt"
                },
                {
                    "en": "amkmjjmmflddogmhpjloimipbofnfjih",
                    "ez": "Wombat"
                },
                {
                    "en": "nlbmnnijcnlegkjjpcfjclmcfggfefdm",
                    "ez": "MEW CX"
                },
                {
                    "en": "nanjmdknhkinifnkgdcggcfnhdaammmj",
                    "ez": "Guild"
                },
                {
                    "en": "nkddgncdjgjfcddamfgcmfnlhccnimig",
                    "ez": "Saturn"
                },
                {
                    "en": "cphhlgmgameodnhkjdmkpanlelnlohao",
                    "ez": "NeoLine"
                },
                {
                    "en": "nhnkbkgjikgcigadomkphalanndcapjk",
                    "ez": "Clover"
                },
                {
                    "en": "kpfopkelmapcoipemfendmdcghnegimn",
                    "ez": "Liquality"
                },
                {
                    "en": "aiifbnbfobpmeekipheeijimdpnlpgpp",
                    "ez": "Terra Station"
                },
                {
                    "en": "dmkamcknogkgcdfhhbddcghachkejeap",
                    "ez": "Keplr"
                },
                {
                    "en": "fhmfendgdocmcbmfikdcogofphimnkno",
                    "ez": "Sollet"
                },
                {
                    "en": "cnmamaachppnkjgnildpdmkaakejnhae",
                    "ez": "Auro"
                },
                {
                    "en": "jojhfeoedkpkglbfimdfabpdfjaoolaf",
                    "ez": "Polymesh"
                },
                {
                    "en": "flpiciilemghbmfalicajoolhkkenfe",
                    "ez": "ICONex"
                },
                {
                    "en": "nknhiehlklippafakaeklbeglecifhad",
                    "ez": "Nabox"
                },
                {
                    "en": "hcflpincpppdclinealmandijcmnkbgn",
                    "ez": "KHC"
                },
                {
                    "en": "ookjlbkiijinhpmnjffcofjonbfbgaoc",
                    "ez": "Temple"
                },
                {
                    "en": "mnfifefkajgofkcjkemidiaecocnkjeh",
                    "ez": "TezBox"
                },
                {
                    "en": "lodccjjbdhfakaekdiahmedfbieldgik",
                    "ez": "DAppPlay"
                },
                {
                    "en": "ijmpgkjfkbfhoebgogflfebnmejmfbm",
                    "ez": "BitClip"
                },
                {
                    "en": "lkcjlnjfpbikmcmbachjpdbijejflpcm",
                    "ez": "Steem Keychain"
                },
                {
                    "en": "onofpnbbkehpmmoabgpcpmigafmmnjh",
                    "ez": "Nash Extension"
                },
                {
                    "en": "bcopgchhojmggmffilplmbdicgaihlkp",
                    "ez": "Hycon Lite Client"
                },
                {
                    "en": "klnaejjgbibmhlephnhpmaofohgkpgkd",
                    "ez": "ZilPay"
                },
                {
                    "en": "aeachknmefphepccionboohckonoeemg",
                    "ez": "Coin98"
                },
                {
                    "en": "bhghoamapcdpbohphigoooaddinpkbai",
                    "ez": "Authenticator"
                },
                {
                    "en": "dkdedlpgdmmkkfjabffeganieamfklkm",
                    "ez": "Cyano"
                },
                {
                    "en": "nlgbhdfgdhgbiamfdfmbikcdghidoadd",
                    "ez": "Byone"
                },
                {
                    "en": "infeboajgfhgbjpjbeppbkgnabfdkdaf",
                    "ez": "OneKey"
                },
                {
                    "en": "cihmoadaighcejopammfbmddcmdekcje",
                    "ez": "Leaf"
                },
                {
                    "en": "gaedmjdfmmahhbjefcbgaolhhanlaolb",
                    "ez": "Authy"
                },
                {
                    "en": "oeljdldpnmdbchonielidgobddfffla",
                    "ez": "EOS Authenticator"
                },
                {
                    "en": "ilgcnhelpchnceeipipijaljkblbcob",
                    "ez": "GAuth Authenticator"
                },
                {
                    "en": "imloifkgjagghnncjkhggdhalmcnfklk",
                    "ez": "Trezor Password Manager"
                },
                {
                    "en": "bfnaelmomeimhlpmgjnjophhpkkoljpa",
                    "ez": "Phantom"
                },
                {
                    "en": "ppbibelpcjmhbdihakflkdcoccbgbkpo",
                    "ez": "UniSat"
                }
            ],
            "n": [
                {
                    "p": "%localappdata%\\Google\\Chrome\\User Data",
                    "z": "Chrome"
                },
                {
                    "p": "%localappdata%\\Chromium\\User Data",
                    "z": "Chromium"
                },
                {
                    "p": "%localappdata%\\Microsoft\\Edge\\User Data",
                    "z": "Edge"
                },
                {
                    "p": "%localappdata%\\Kometa\\User Data",
                    "z": "Kometa"
                },
                {
                    "p": "%appdata%\\Opera Software\\Opera Stable",
                    "z": "Opera Stable"
                },
                {
                    "p": "%appdata%\\Opera Software\\Opera GX Stable",
                    "z": "Opera GX Stable"
                },
                {
                    "p": "%appdata%\\Opera Software\\Opera Neon\\User Data",
                    "z": "Opera Neon"
                },
                {
                    "p": "%localappdata%\\BraveSoftware\\Brave-Browser\\User Data",
                    "z": "Brave Software"
                },
                {
                    "p": "%localappdata%\\Comodo\\Dragon\\User Data",
                    "z": "Comodo"
                },
                {
                    "p": "%localappdata%\\CocCoc\\Browser\\User Data",
                    "z": "CocCoc"
                }
            ]
        },
        {
            "t": 2,
            "p": "%appdata%\\Mozilla\\Firefox\\Profiles",
            "z": "Mozilla Firefox"
        }
    ]
}

We wrote the configuration retrieval script in Python, which you can access here. You can also access the configuration extractor for the builder here.

Figure 9: Output of the configuration extractor script


Example of additional data obtained from C2: lid=KjGtqi--VIKKY&j=e799236f7a828928688bbd10d343328e&ver=4.0, where the lid is the LummaC2 ID, the value “VIKKY” is likely the build ID assigned and the stealer version (ver=). The logs are exfiltrated over the ZIP archive, as shown in the screenshot below (/c2sock).

Figure 10: Exfiltrated logs


Figure 11: Log formatting (System.txt)


Figure 12: Function responsible for collecting system information and parsing it to the System.txt file


Figure 13: The contents of the ZIP archive (Source: Dark2Web)

What did we do?

What can you learn from this TRU positive?

Recommendations from our Threat Response Unit (TRU):

Protecting against information stealers requires a multi-layered defense approach to defend endpoints from malware and detect or block unauthorized login activity against applications and remote access services. Therefore, we recommend:

Indicators of Compromise

Name

Indicators

C2

gservice-node[.]io

C2

gstatic-node[.]io

C2

balancelag[.]xyz

C2

doorblu[.]xyz

Payload

c9094685ae4851fd5a5b886b73c7b07efd9b47ea0bdae3f823d035cf1b3b9e48

Payload

3bf4b365d61c1e9807d20e71375627450b8fea1635cb6ddb85f2956e8f6b3ec3

Payload

a9c7c4df7e39b8bc7b03b7d4053066d26154bc76c3e261fff84f2339d44a474e

Payload

b803e8d9da6efe7b0220f654c7afb784d21dc222afd4a4e41396e74f861cbf30

Yara

rule LummaC2 {

    meta:
        author = "RussianPanda"
        description = "LummaC2 Detection"

    strings:
        $p1="lid=%s&j=%s&ver"
        $p2= {89 ca 83 e2 03 8a 54 14 08 32 54 0d 04}

    condition:
        all of them and filesize <= 500KB
}

Reference

eSentire Threat Response Unit (TRU)
eSentire Threat Response Unit (TRU)

The eSentire Threat Response Unit (TRU) is an industry-leading threat research team committed to helping your organization become more resilient. TRU is an elite team of threat hunters and researchers that supports our 24/7 Security Operations Centers (SOCs), builds threat detection models across the eSentire XDR Cloud Platform, and works as an extension of your security team to continuously improve our Managed Detection and Response service. By providing complete visibility across your attack surface and performing global threat sweeps and proactive hypothesis-driven threat hunts augmented by original threat research, we are laser-focused on defending your organization against known and unknown threats.

Read the Latest from eSentire