SYMBOLCOMMON_NAMEaka. SYNONYMS
win.scavenger (Back to overview)

Scavenger

aka: scavenger, SCVNGR, scvngr
VTCollection    

Scavenger is a stealthy, two-stage malware family first observed in July 2025 following a targeted supply chain attack on the NPM ecosystem. The infection began with a phishing campaign that leveraged a typo-squatted domain (npnjs.com) to impersonate the legitimate NPM login page. The adversaries abused NPM's web-based login flow—akin to device code phishing—to trick a package maintainer into generating an automation access token, which does not expire and can bypass 2FA under certain configurations.

With the stolen credentials, the attackers injected malicious payloads into several trusted NPM packages, including eslint-config-prettier, by modifying their install scripts to execute a DLL loader. This first-stage loader, compiled in Visual Studio, performs anti-VM checks, dynamic API resolution using CRC32 hashing, indirect syscalls to bypass EDR, and string decryption routines. If the environment passes these checks, it executes a second-stage infostealer that targets browser data—particularly from Chromium—such as extension state, cached content, and visited URLs.

The malware communicates with its command and control infrastructure using libcurl and XXTEA-encrypted payloads over HTTP(S), implementing challenge-response integrity checks during session initialization. Development artifacts like a leftover PDB path and operational overlaps have linked Scavenger to other campaigns, including one involving an infected BeamNG game binary, further suggesting a broader and evolving threat infrastructure.

References
2025-07-28 ⋅ Invoke RE ⋅ Josh Reynolds
Scavenger Malware Distributed via num2words PyPI Supply Chain Compromise
Scavenger
2025-07-24 ⋅ Dr.Web ⋅ Dr.Web
Gamers, get ready: scammers disguise cryptocurrency and password-stealing Scavenger trojans as cheats and mods
Scavenger
2025-07-20 ⋅ Invoke RE ⋅ cyb3rjerry, Josh Reynolds
Install Linters, Get Malware - DevSecOps Speedrun Edition
Scavenger
2025-07-20 ⋅ Invoke RE ⋅ cyb3rjerry, Josh Reynolds
Scavenger Malware Distributed via eslint-config-prettier NPM Package Supply Chain Compromise
Scavenger
2025-07-20 ⋅ Utkonos ⋅ Utkonos
Supply Chain Trojan sc_trojan_jwjf
Scavenger
Yara Rules
[TLP:WHITE] win_scavenger_auto (20260917 | Detects win.scavenger.)
rule win_scavenger_auto {

    meta:
        author = "Felix Bilstein - yara-signator at cocacoding dot com"
        date = "2026-09-17"
        version = "1"
        description = "Detects win.scavenger."
        info = "autogenerated rule brought to you by yara-signator"
        tool = "yara-signator v0.6.0"
        signator_config = "callsandjumps;datarefs;binvalue"
        malpedia_reference = "https://malpedia.caad.fkie.fraunhofer.de/details/win.scavenger"
        malpedia_rule_date = "20260916"
        malpedia_hash = "53a643781c18e08f4a50949af60172d837a0b6f6"
        malpedia_version = "20260917"
        malpedia_license = "CC BY-SA 4.0"
        malpedia_sharing = "TLP:WHITE"

    /* DISCLAIMER
     * The strings used in this rule have been automatically selected from the
     * disassembly of memory dumps and unpacked files, using YARA-Signator.
     * The code and documentation is published here:
     * https://github.com/fxb-cocacoding/yara-signator
     * As Malpedia is used as data source, please note that for a given
     * number of families, only single samples are documented.
     * This likely impacts the degree of generalization these rules will offer.
     * Take the described generation method also into consideration when you
     * apply the rules in your use cases and assign them confidence levels.
     */


    strings:
        $sequence_0 = { 4833c4 4889842400010000 488b842430010000 4889442428 488b442428 488b4010 4889442430 }
            // n = 7, score = 900
            //   4833c4               | mov                 ecx, edi
            //   4889842400010000     | mov                 eax, 0x38
            //   488b842430010000     | dec                 ebp
            //   4889442428           | test                eax, eax
            //   488b442428           | je                  0x35e
            //   488b4010             | dec                 eax
            //   4889442430           | lea                 edx, [0x72070]

        $sequence_1 = { 48898424e8000000 488b8424e8000000 48ffc0 48898424e8000000 48c744245000000000 }
            // n = 5, score = 900
            //   48898424e8000000     | or                  dword ptr [eax], eax
            //   488b8424e8000000     | xchg                dword ptr [ebx], ecx
            //   48ffc0               | or                  dword ptr [eax], eax
            //   48898424e8000000     | or                  dword ptr [eax], eax
            //   48c744245000000000     | xchg    dword ptr [ebx], ecx

        $sequence_2 = { 48ffc0 48898424f0000000 48c744244000000000 488b9424f0000000 488b8c2488000000 e8???????? }
            // n = 6, score = 900
            //   48ffc0               | dec                 eax
            //   48898424f0000000     | arpl                word ptr [ebp + 0x4f0], cx
            //   48c744244000000000     | mov    byte ptr [ebp + ecx + 0x12d40], al
            //   488b9424f0000000     | jmp                 0x1f49
            //   488b8c2488000000     | dec                 eax
            //   e8????????           |                     

        $sequence_3 = { 4883c020 4889442428 488b442440 4839442428 }
            // n = 4, score = 900
            //   4883c020             | dec                 eax
            //   4889442428           | lea                 eax, [ebp + 0x10c30]
            //   488b442440           | dec                 eax
            //   4839442428           | add                 ecx, eax

        $sequence_4 = { 730c 488b442428 4889442430 eb61 33d2 }
            // n = 5, score = 900
            //   730c                 | dec                 eax
            //   488b442428           | mov                 eax, dword ptr [ebp + 0x2d80]
            //   4889442430           | dec                 eax
            //   eb61                 | mov                 ecx, dword ptr [ebp + 0x9a8]
            //   33d2                 | movzx               eax, word ptr [eax + ecx*2]

        $sequence_5 = { 488b442448 4889442450 488b442450 4c8bc0 }
            // n = 4, score = 900
            //   488b442448           | test                dword ptr [eax + 0x4800006f], ebp
            //   4889442450           | mov                 eax, dword ptr [ebp + 0x6fa8]
            //   488b442450           | dec                 eax
            //   4c8bc0               | mov                 dword ptr [ebp + 0x75d0], eax

        $sequence_6 = { 4839442420 743a 488b442420 4889442438 }
            // n = 4, score = 900
            //   4839442420           | call                edx
            //   743a                 | test                eax, eax
            //   488b442420           | jne                 0x13db
            //   4889442438           | mov                 eax, dword ptr [esp + 0x60]

        $sequence_7 = { 488b442438 488b542478 488bc8 e8???????? 4889442440 488b442440 4889442428 }
            // n = 7, score = 900
            //   488b442438           | shr                 edx, 8
            //   488b542478           | mov                 eax, dword ptr [ecx + eax*4]
            //   488bc8               | xor                 eax, edx
            //   e8????????           |                     
            //   4889442440           | mov                 dword ptr [ebp + 0x40], eax
            //   488b442440           | dec                 eax
            //   4889442428           | mov                 eax, dword ptr [ebp + 0x2b0]

        $sequence_8 = { eb08 c744240400000000 0fb6442404 880424 0fb60424 0fb6c0 85c0 }
            // n = 7, score = 900
            //   eb08                 | mov                 eax, dword ptr [ebp + 0x338]
            //   c744240400000000     | xor                 eax, 0xffffffff
            //   0fb6442404           | mov                 dword ptr [ebp + 0x338], eax
            //   880424               | mov                 dword ptr [ebp + 0xf34], 0
            //   0fb60424             | mov                 dword ptr [ebp + 0x338], 0
            //   0fb6c0               | dec                 eax
            //   85c0                 | mov                 eax, dword ptr [ebp + 0x4798]

        $sequence_9 = { 0fb6c0 85c0 7421 488b442430 488b00 4889442410 }
            // n = 6, score = 900
            //   0fb6c0               | je                  0x1f1a
            //   85c0                 | jmp                 0x1f73
            //   7421                 | dec                 eax
            //   488b442430           | lea                 eax, [ebp + 0x10700]
            //   488b00               | vmovdqu             ymm0, ymmword ptr [eax]
            //   4889442410           | vmovdqu             ymmword ptr [ebp + 0xaa20], ymm0

    condition:
        7 of them and filesize < 2992128
}
[TLP:WHITE] win_scavenger_w0   (20250719 | Matches Scavenger DLLs related to the ones found in the Prettier NPM supply chain compromise.)
rule win_scavenger_w0 {

    meta:
        author = "Malware Utkonos"
        date = "2025-07-19"
        description = "Matches Scavenger DLLs related to the ones found in the Prettier NPM supply chain compromise."
        malpedia_reference = "https://malpedia.caad.fkie.fraunhofer.de/details/win.scavenger"
        malpedia_rule_date = "20250719"
        malpedia_hash = ""
        malpedia_version = "20250719"
        malpedia_license = "CC BY-SA 4.0"
        malpedia_sharing = "TLP:WHITE"

    strings:
        $op = { b9c4c58fcd 483bc1 75 }
            // 18000d555  b9c4c58fcd         mov     ecx, 0xcd8fc5c4
            // 18000d55a  483bc1             cmp     rax, rcx
            // 18000d55d  7514               jne     0x18000d573

    condition:
        uint16(0) == 0x5a4d and uint32(uint32(0x3c)) == 0x00004550 and $op
}
Download all Yara Rules