CINXE.COM

Tools — Elastic Security Labs

<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><title>Tools — 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="Tools — 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?16d2b4a32dc915f9b0c5cab89f21f1f6"/><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/category/tools"/><meta property="og:type" content="website"/><meta name="twitter:card" content="summary_large_image"/><meta name="twitter:title" content="Tools — 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?16d2b4a32dc915f9b0c5cab89f21f1f6"/><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/category/tools"/><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%2Fstixy-situations-ecsaping-your-threat-data%2Fphoto-edited-07%402x.jpg&amp;w=640&amp;q=75 640w, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fstixy-situations-ecsaping-your-threat-data%2Fphoto-edited-07%402x.jpg&amp;w=750&amp;q=75 750w, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fstixy-situations-ecsaping-your-threat-data%2Fphoto-edited-07%402x.jpg&amp;w=828&amp;q=75 828w, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fstixy-situations-ecsaping-your-threat-data%2Fphoto-edited-07%402x.jpg&amp;w=1080&amp;q=75 1080w, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fstixy-situations-ecsaping-your-threat-data%2Fphoto-edited-07%402x.jpg&amp;w=1200&amp;q=75 1200w, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fstixy-situations-ecsaping-your-threat-data%2Fphoto-edited-07%402x.jpg&amp;w=1920&amp;q=75 1920w, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fstixy-situations-ecsaping-your-threat-data%2Fphoto-edited-07%402x.jpg&amp;w=2048&amp;q=75 2048w, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fstixy-situations-ecsaping-your-threat-data%2Fphoto-edited-07%402x.jpg&amp;w=3840&amp;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-4378a3e3b84d79cd.js" defer=""></script><script src="/security-labs/_next/static/chunks/616-0b017b9cfa597392.js" defer=""></script><script src="/security-labs/_next/static/chunks/pages/category/%5Bslug%5D-4bd9f3bc8d6da08a.js" defer=""></script><script src="/security-labs/_next/static/wTIynxBm98ujmQxLsgK6X/_buildManifest.js" defer=""></script><script src="/security-labs/_next/static/wTIynxBm98ujmQxLsgK6X/_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 hover-link" 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&amp;referrer=https://www.elastic.co/security-labs/category/tools"><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&amp;tech=trial&amp;plcmt=navigation&amp;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&amp;referrer=https://www.elastic.co/security-labs/category/tools"><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-[&#x27; &#x27;] 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-[&#x27; &#x27;] 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">Category</h4><h1 class="font-bold leading-tighter text-3xl md:text-5xl">Tools</h1></div><div class="shrink-0 flex items-center space-x-4"><a href="https://www.elastic.co/security-labs/rss/categories/tools.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">9 February 2024</h4><h2 class="font-bold text-2xl md:text-4xl mb-5"><a class="hover:text-blue-400 transition" href="/security-labs/stixy-situations-ecsaping-your-threat-data">STIXy Situations: ECSaping your threat data</a></h2></div><p class="text-sm md:text-base text-zinc-400">Structured threat data is commonly formatted using STIX. To help get this data into Elasticsearch, we’re releasing a Python script that converts STIX to an ECS format to be ingested into your stack.</p></div><div class="w-full max-w-2xl"><a href="/security-labs/stixy-situations-ecsaping-your-threat-data"><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%2Fstixy-situations-ecsaping-your-threat-data%2Fphoto-edited-07%402x.jpg&amp;w=640&amp;q=75 640w, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fstixy-situations-ecsaping-your-threat-data%2Fphoto-edited-07%402x.jpg&amp;w=750&amp;q=75 750w, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fstixy-situations-ecsaping-your-threat-data%2Fphoto-edited-07%402x.jpg&amp;w=828&amp;q=75 828w, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fstixy-situations-ecsaping-your-threat-data%2Fphoto-edited-07%402x.jpg&amp;w=1080&amp;q=75 1080w, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fstixy-situations-ecsaping-your-threat-data%2Fphoto-edited-07%402x.jpg&amp;w=1200&amp;q=75 1200w, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fstixy-situations-ecsaping-your-threat-data%2Fphoto-edited-07%402x.jpg&amp;w=1920&amp;q=75 1920w, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fstixy-situations-ecsaping-your-threat-data%2Fphoto-edited-07%402x.jpg&amp;w=2048&amp;q=75 2048w, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fstixy-situations-ecsaping-your-threat-data%2Fphoto-edited-07%402x.jpg&amp;w=3840&amp;q=75 3840w" src="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fstixy-situations-ecsaping-your-threat-data%2Fphoto-edited-07%402x.jpg&amp;w=3840&amp;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/into-the-weeds-how-we-run-detonate"><div class="flex flex-col space-4"><div class="relative w-full rounded-lg overflow-hidden"><img alt="Into The Weeds: How We Run Detonate" 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%2Finto-the-weeds-how-we-run-detonate%2Fphoto-edited-02%402x.jpg&amp;w=640&amp;q=75 1x, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Finto-the-weeds-how-we-run-detonate%2Fphoto-edited-02%402x.jpg&amp;w=828&amp;q=75 2x" src="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Finto-the-weeds-how-we-run-detonate%2Fphoto-edited-02%402x.jpg&amp;w=828&amp;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 June 2023</time><h3 class="font-bold leading-tight text-xl md:text-3xl mb-2">Into The Weeds: How We Run Detonate</h3><p class="text-sm text-zinc-400">Explore the technical implementation of the Detonate system, including sandbox creation, the supporting technology, telemetry collection, and how to blow stuff up.</p></div></a><a href="/security-labs/click-click-boom-automating-protections-testing-with-detonate"><div class="flex flex-col space-4"><div class="relative w-full rounded-lg overflow-hidden"><img alt="Click, Click… Boom! Automating Protections Testing with Detonate" 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%2Fclick-click-boom-automating-protections-testing-with-detonate%2Fblog-thumb-tools-various.jpg&amp;w=640&amp;q=75 1x, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fclick-click-boom-automating-protections-testing-with-detonate%2Fblog-thumb-tools-various.jpg&amp;w=828&amp;q=75 2x" src="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fclick-click-boom-automating-protections-testing-with-detonate%2Fblog-thumb-tools-various.jpg&amp;w=828&amp;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 May 2023</time><h3 class="font-bold leading-tight text-xl md:text-3xl mb-2">Click, Click… Boom! Automating Protections Testing with Detonate</h3><p class="text-sm text-zinc-400">To automate this process and test our protections at scale, we built Detonate, a system that is used by security research engineers to measure the efficacy of our Elastic Security solution in an automated fashion.</p></div></a><a href="/security-labs/unpacking-icedid"><div class="flex flex-col space-4"><div class="relative w-full rounded-lg overflow-hidden"><img alt="Unpacking 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%2Funpacking-icedid%2Fphoto-edited-07%402x.jpg&amp;w=640&amp;q=75 1x, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Funpacking-icedid%2Fphoto-edited-07%402x.jpg&amp;w=828&amp;q=75 2x" src="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Funpacking-icedid%2Fphoto-edited-07%402x.jpg&amp;w=828&amp;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 May 2023</time><h3 class="font-bold leading-tight text-xl md:text-3xl mb-2">Unpacking ICEDID</h3><p class="text-sm text-zinc-400">ICEDID is known to pack its payloads using custom file formats and a custom encryption scheme. We are releasing a set of tools to automate the unpacking process and help analysts and the community respond to ICEDID.</p></div></a><a href="/security-labs/netwire-configuration-extractor"><div class="flex flex-col space-4"><div class="relative w-full rounded-lg overflow-hidden"><img alt="NETWIRE Configuration Extractor" 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%2Fnetwire-configuration-extractor%2Ftools-image.jpg&amp;w=640&amp;q=75 1x, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fnetwire-configuration-extractor%2Ftools-image.jpg&amp;w=828&amp;q=75 2x" src="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fnetwire-configuration-extractor%2Ftools-image.jpg&amp;w=828&amp;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 January 2023</time><h3 class="font-bold leading-tight text-xl md:text-3xl mb-2">NETWIRE Configuration Extractor</h3><p class="text-sm text-zinc-400">Python script to extract the configuration from NETWIRE samples.</p></div></a><a href="/security-labs/blister-configuration-extractor"><div class="flex flex-col space-4"><div class="relative w-full rounded-lg overflow-hidden"><img alt="BLISTER Configuration Extractor" 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-configuration-extractor%2Ftools-image.jpg&amp;w=640&amp;q=75 1x, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fblister-configuration-extractor%2Ftools-image.jpg&amp;w=828&amp;q=75 2x" src="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fblister-configuration-extractor%2Ftools-image.jpg&amp;w=828&amp;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">BLISTER Configuration Extractor</h3><p class="text-sm text-zinc-400">Python script to extract the configuration and payload from BLISTER samples.</p></div></a><a href="/security-labs/bpfdoor-configuration-extractor"><div class="flex flex-col space-4"><div class="relative w-full rounded-lg overflow-hidden"><img alt="BPFDoor Configuration Extractor" 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%2Fbpfdoor-configuration-extractor%2Ftools-image.jpg&amp;w=640&amp;q=75 1x, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fbpfdoor-configuration-extractor%2Ftools-image.jpg&amp;w=828&amp;q=75 2x" src="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fbpfdoor-configuration-extractor%2Ftools-image.jpg&amp;w=828&amp;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">BPFDoor Configuration Extractor</h3><p class="text-sm text-zinc-400">Configuration extractor to dump out hardcoded passwords with BPFDoor.</p></div></a><a href="/security-labs/bpfdoor-scanner"><div class="flex flex-col space-4"><div class="relative w-full rounded-lg overflow-hidden"><img alt="BPFDoor Scanner" 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%2Fbpfdoor-scanner%2Ftools-image.jpg&amp;w=640&amp;q=75 1x, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fbpfdoor-scanner%2Ftools-image.jpg&amp;w=828&amp;q=75 2x" src="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fbpfdoor-scanner%2Ftools-image.jpg&amp;w=828&amp;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">BPFDoor Scanner</h3><p class="text-sm text-zinc-400">Python script to identify hosts infected with the BPFDoor malware.</p></div></a><a href="/security-labs/cobalt-strike-beacon-extractor"><div class="flex flex-col space-4"><div class="relative w-full rounded-lg overflow-hidden"><img alt="Cobalt Strike Beacon Extractor" 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%2Fcobalt-strike-beacon-extractor%2Ftools-image.jpg&amp;w=640&amp;q=75 1x, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fcobalt-strike-beacon-extractor%2Ftools-image.jpg&amp;w=828&amp;q=75 2x" src="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fcobalt-strike-beacon-extractor%2Ftools-image.jpg&amp;w=828&amp;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">Cobalt Strike Beacon Extractor</h3><p class="text-sm text-zinc-400">Python script that collects Cobalt Strike memory data generated by security events from an Elasticsearch cluster, extracts the configuration from the CS beacon, and writes the data back to Elasticsearch.</p></div></a><a href="/security-labs/emotet-configuration-extractor"><div class="flex flex-col space-4"><div class="relative w-full rounded-lg overflow-hidden"><img alt="EMOTET Configuration Extractor" 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%2Femotet-configuration-extractor%2Ftools-image.jpg&amp;w=640&amp;q=75 1x, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Femotet-configuration-extractor%2Ftools-image.jpg&amp;w=828&amp;q=75 2x" src="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Femotet-configuration-extractor%2Ftools-image.jpg&amp;w=828&amp;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">EMOTET Configuration Extractor</h3><p class="text-sm text-zinc-400">Python script to extract the configuration from EMOTET samples.</p></div></a><a href="/security-labs/icedid-configuration-extractor"><div class="flex flex-col space-4"><div class="relative w-full rounded-lg overflow-hidden"><img alt="ICEDID Configuration Extractor" 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%2Ficedid-configuration-extractor%2Ftools-image.jpg&amp;w=640&amp;q=75 1x, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Ficedid-configuration-extractor%2Ftools-image.jpg&amp;w=828&amp;q=75 2x" src="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Ficedid-configuration-extractor%2Ftools-image.jpg&amp;w=828&amp;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">ICEDID Configuration Extractor</h3><p class="text-sm text-zinc-400">Python script to extract the configuration from ICEDID samples.</p></div></a><a href="/security-labs/parallax-payload-extractor"><div class="flex flex-col space-4"><div class="relative w-full rounded-lg overflow-hidden"><img alt="PARALLAX Payload Extractor" 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%2Fparallax-payload-extractor%2Ftools-image.jpg&amp;w=640&amp;q=75 1x, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fparallax-payload-extractor%2Ftools-image.jpg&amp;w=828&amp;q=75 2x" src="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fparallax-payload-extractor%2Ftools-image.jpg&amp;w=828&amp;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">PARALLAX Payload Extractor</h3><p class="text-sm text-zinc-400">Python script to extract the payload from PARALLAX samples.</p></div></a><a href="/security-labs/qbot-configuration-extractor"><div class="flex flex-col space-4"><div class="relative w-full rounded-lg overflow-hidden"><img alt="QBOT Configuration Extractor" 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-configuration-extractor%2Ftools-image.jpg&amp;w=640&amp;q=75 1x, /security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fqbot-configuration-extractor%2Ftools-image.jpg&amp;w=828&amp;q=75 2x" src="/security-labs/_next/image?url=%2Fsecurity-labs%2Fassets%2Fimages%2Fqbot-configuration-extractor%2Ftools-image.jpg&amp;w=828&amp;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">QBOT Configuration Extractor</h3><p class="text-sm text-zinc-400">Python script to extract the configuration from QBOT samples.</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&amp;utm_medium=referral&amp;utm_campaign=search-labs&amp;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>© <!-- -->2025<!-- -->. Elasticsearch B.V. All Rights Reserved.</p></div></div></footer></main></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{"title":"Tools","slug":"tools","body":{"raw":"","code":"var Component=(()=\u003e{var x=Object.create;var s=Object.defineProperty;var l=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),d=(t,n)=\u003e{for(var e in n)s(t,e,{get:n[e],enumerable:!0})},c=(t,n,e,a)=\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:!(a=l(n,r))||a.enumerable});return t};var p=(t,n,e)=\u003e(e=t!=null?x(_(t)):{},c(n||!t||!t.__esModule?s(e,\"default\",{value:t,enumerable:!0}):e,t)),M=t=\u003ec(s({},\"__esModule\",{value:!0}),t);var i=j((h,u)=\u003e{u.exports=_jsx_runtime});var X={};d(X,{default:()=\u003eF,frontmatter:()=\u003eC});var o=p(i()),C={title:\"Tools\",slug:\"tools\"};function m(t){return(0,o.jsx)(o.Fragment,{})}function D(t={}){let{wrapper:n}=t.components||{};return n?(0,o.jsx)(n,Object.assign({},t,{children:(0,o.jsx)(m,t)})):m(t)}var F=D;return M(X);})();\n;return Component;"},"_id":"categories/tools.mdx","_raw":{"sourceFilePath":"categories/tools.mdx","sourceFileName":"tools.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/tools"},"type":"Category","url":"/categories/tools","articles":[{"title":"STIXy Situations: ECSaping your threat data","slug":"stixy-situations-ecsaping-your-threat-data","date":"2024-02-09","description":"Structured threat data is commonly formatted using STIX. To help get this data into Elasticsearch, we’re releasing a Python script that converts STIX to an ECS format to be ingested into your stack.","image":"photo-edited-07@2x.jpg","subtitle":"Structured threat data is commonly formatted using STIX. To help get this data into Elasticsearch, we’re releasing a Python script that converts STIX to an ECS format to be ingested into your stack.","body":{"raw":"\n## Preamble\nOrganizations that use threat indicators or observables consume, create, and/or (ideally) publish threat data. This data can be used internally or externally as information or intelligence to inform decision-making and event prioritization.\n\nWhile there are several formats for this information to be structured into, the de facto industry standard is [Structured Threat Information Expression (STIX)](https://oasis-open.github.io/cti-documentation/stix/intro). STIX is managed by the [OASIS Cyber Threat Intelligence Technical Committee](https://www.oasis-open.org/committees/tc_home.php?wg_abbrev=cti) and enables organizations to share threat data in a standard and machine-readable format.\n\nAt Elastic, we developed the [Elastic Common Schema (ECS)](https://www.elastic.co/guide/en/ecs/current/ecs-reference.html) as a data normalization capability. “[ECS] is an open source specification, developed with support from the Elastic user community. ECS defines a common set of fields for storing event data in Elasticsearch, such as logs and metrics.” In April of 2023, [Elastic contributed ECS](https://www.elastic.co/blog/ecs-elastic-common-schema-otel-opentelemetry-announcement) to the [OpenTelemetry Semantic Conventions (OTel)](https://opentelemetry.io/docs/concepts/semantic-conventions/) as a commitment to the joint development of an open schema. \n\nThe security community shares threat data in the STIX format, so to store that data in Elasticsearch for analysis and threat detection [[1](https://www.elastic.co/guide/en/security/current/threat-intel-hash-indicator-match.html)] [[2](https://www.elastic.co/guide/en/security/current/threat-intel-ip-address-indicator-match.html)] [[3](https://www.elastic.co/guide/en/security/current/threat-intel-url-indicator-match.html)] [[4](https://www.elastic.co/guide/en/security/current/threat-intel-windows-registry-indicator-match.html)], we created a tool that converts STIX documents into ECS and outputs the threat data either as a file or directly into Elasticsearch indices. If this was a challenge for us, it was a challenge for others - therefore, we decided to release a version of the tool.\n\nThis tool uses the [Elastic License 2.0](https://www.elastic.co/licensing/elastic-license) and is available for download [here](https://github.com/elastic/labs-releases/tree/main/tools/stix-to-ecs).\n\n## Getting started\nThis project will take a STIX 2.x formatted JSON document and create an ECS version. There are three output options: STDOUT as JSON, an NDJSON file, and/or directly to an Elasticsearch cluster.\n\n### Prerequisites\nThe STIX 2 ECS project requires Python 3.10+ and the [stix2](https://pypi.org/project/stix2/), [Elasticsearch](https://pypi.org/project/elasticsearch/), and [getpass](https://pypi.org/project/getpass4/) modules.\n\nIf exporting to Elasticsearch, you will need the host information and authentication credentials. API authentication is not yet implemented.\n\n### Setup\nCreate a virtual environment and install the required prerequisites.\n\n```\ngit clone https://github.com/elastic/labs-releases.git\ncd tools/stix2ecs\npython -m venv /path/to/virtual/environments/stix2ecs\nsource /path/to/virtual/environments/stix2ecs/bin/activate\npython -m pip install -r requirements.txt\n```\n\n## Operation\nThe input is a STIX 2.x JSON document (or a folder of JSON documents); the output defaults to STDOUT, with an option to create an NDJSON file and/or send to an Elasticsearch cluster.\n\n```\nstix_to_ecs.py [-h] -i INPUT [-o OUTPUT] [-e] [--index INDEX] [--url URL] \\\n[--user USER] [-p PROVIDER] [-r]\n```\n\nBy default, the ECS file is named the same as the STIX file input but with `.ecs.ndjson` appended.\n\n### Arguments\nThe script has several arguments, the only mandatory field is `-i` for the input. By default, the script will output the NDJSON document to STDOUT.\n\n| Option | Description |\n| - | - |\n| -h | displays the help menu |\n| -i | specifies the input STIX document (mandatory) |\n| -o | specifies the output ECS document (optional) |\n| -p | defines the ECS provider field (optional) |\n| -r | recursive mode to convert multiple STIX documents (optional) |\n| -e | specifies the Elasticsearch output mode (optional) |\n| --index | defines the Elasticsearch Index, requires `-e` (optional) |\n| --url | defines the Elasticsearch URL, requires `-e` (optional) |\n| --user | defines the Elasticsearch username, requires `-e` (optional) |\n\n## Examples\nThere are two sample files located in the `test-inputs/` directory. One is from [CISA](https://www.cisa.gov/topics/cyber-threats-and-advisories/information-sharing/automated-indicator-sharing-ais) (Cybersecurity \u0026 Infrastructure Security Agency), and one is from [OpenCTI](https://github.com/OpenCTI-Platform/opencti) (an open source threat intelligence platform).\n\n### STIX file input to STDOUT\nThis will output the STIX document to STDOUT in ECS format.\n\n```\npython stix_to_ecs.py -i test-inputs/cisa_sample_stix.json | jq\n\n[\n {\n \"threat\": {\n \"indicator\": {\n \"file\": {\n \"name\": \"123.ps1\",\n \"hash\": {\n \"sha256\": \"ED5D694D561C97B4D70EFE934936286FE562ADDF7D6836F795B336D9791A5C44\"\n }\n },\n \"type\": \"file\",\n \"description\": \"Simple indicator of observable {ED5D694D561C97B4D70EFE934936286FE562ADDF7D6836F795B336D9791A5C44}\",\n \"first_seen\": \"2023-11-21T18:57:25.000Z\",\n \"provider\": \"identity--b3bca3c2-1f3d-4b54-b44f-dac42c3a8f01\",\n \"modified_at\": \"2023-11-21T18:57:25.000Z\",\n \"marking\": {\n \"tlp\": \"clear\"\n }\n }\n }\n },\n...\n```\n\n### STIX file input to ECS file output\nThis will create a folder called `ecs` in the present directory and write the ECS file there.\n\n```\npython python stix_to_ecs.py -i test-inputs/cisa_sample_stix.json -o ecs\n\ncat ecs/cisa_sample_stix.ecs.ndjson | jq\n{\n \"threat\": {\n \"indicator\": {\n \"file\": {\n \"name\": \"123.ps1\",\n \"hash\": {\n \"sha256\": \"ED5D694D561C97B4D70EFE934936286FE562ADDF7D6836F795B336D9791A5C44\"\n }\n },\n \"type\": \"file\",\n \"description\": \"Simple indicator of observable {ED5D694D561C97B4D70EFE934936286FE562ADDF7D6836F795B336D9791A5C44}\",\n \"first_seen\": \"2023-11-21T18:57:25.000Z\",\n \"provider\": \"identity--b3bca3c2-1f3d-4b54-b44f-dac42c3a8f01\",\n \"modified_at\": \"2023-11-21T18:57:25.000Z\",\n \"marking\": {\n \"tlp\": \"clear\"\n }\n }\n }\n}\n...\n```\n\n### STIX file input to ECS file output, defining the Provider field\nThe provider field is commonly a GUID in the STIX document. To make it more user-friendly, you can use the `-p` argument to define the `threat.indicator.provider` field.\n\n```\npython stix_to_ecs.py -i test-inputs/cisa_sample_stix.json -o ecs -p \"Elastic Security Labs\"\n\ncat ecs/cisa_sample_stix.ecs.ndjson | jq\n{\n \"threat\": {\n \"indicator\": {\n \"file\": {\n \"name\": \"123.ps1\",\n \"hash\": {\n \"sha256\": \"ED5D694D561C97B4D70EFE934936286FE562ADDF7D6836F795B336D9791A5C44\"\n }\n },\n \"type\": \"file\",\n \"description\": \"Simple indicator of observable {ED5D694D561C97B4D70EFE934936286FE562ADDF7D6836F795B336D9791A5C44}\",\n \"first_seen\": \"2023-11-21T18:57:25.000Z\",\n \"provider\": \"Elastic Security Labs\",\n \"modified_at\": \"2023-11-21T18:57:25.000Z\",\n \"marking\": {\n \"tlp\": \"clear\"\n }\n }\n }\n}\n...\n```\n\n### STIX directory input to ECS file outputs\nIf you have a directory of STIX documents, you can use the `-r` argument to recursively search through the directory and write the ECS documents to the output directory.\n\n```\npython stix_to_ecs.py -ri test-inputs -o ecs\n```\n\n### STIX file input to Elasticsearch output\nTo output to Elasticsearch, you can use either Elastic Cloud or a local instance. Local Elasticsearch will use port `9200` and Elastic Cloud will use port `443`. By default, a valid TLS session to Elasticsearch is required.\n\nFirst, create an index if you don't already have one. In this example, we’re creating an index called `stix2ecs`, but the index name isn’t relevant.\n\n```\ncurl -u {username} -X PUT \"https://elasticsearch:port/stix2ecs?pretty\"\n\n{\n \"acknowledged\" : true,\n \"shards_acknowledged\" : true,\n \"index\" : \"stix2ecs\"\n}\n```\n\nNext, define the Elasticsearch output options.\n\n```\npython stix_to_ecs.py -i test-inputs/cisa_sample_stix.json -e --url https://elasticsearch:port --user username --index stix2ecs\n```\n\nIf you’re storing the data in Elasticsearch for use in another platform, you can view the indicators using cURL.\n\n```\ncurl -u {username} https://elasticsearch:port/stix2ecs/_search?pretty\n\n{\n \"took\" : 2,\n \"timed_out\" : false,\n \"_shards\" : {\n \"total\" : 1,\n \"successful\" : 1,\n \"skipped\" : 0,\n \"failed\" : 0\n },\n \"hits\" : {\n \"total\" : {\n \"value\" : 3,\n \"relation\" : \"eq\"\n },\n \"max_score\" : 1.0,\n \"hits\" : [\n {\n \"_index\" : \"stix2ecs\",\n \"_id\" : \"n2lt8IwBahlUtp0hzm9i\",\n \"_score\" : 1.0,\n \"_source\" : {\n \"threat\" : {\n \"indicator\" : {\n \"file\" : {\n \"name\" : \"123.ps1\",\n \"hash\" : {\n \"sha256\" : \"ED5D694D561C97B4D70EFE934936286FE562ADDF7D6836F795B336D9791A5C44\"\n }\n },\n \"type\" : \"file\",\n \"description\" : \"Simple indicator of observable {ED5D694D561C97B4D70EFE934936286FE562ADDF7D6836F795B336D9791A5C44}\",\n \"first_seen\" : \"2023-11-21T18:57:25.000Z\",\n \"provider\" : \"identity--b3bca3c2-1f3d-4b54-b44f-dac42c3a8f01\",\n \"modified_at\" : \"2023-11-21T18:57:25.000Z\",\n \"marking\" : {\n \"tlp\" : \"clear\"\n }\n }\n }\n }\n }\n...\n```\n\nIf you’re using Kibana, you can [create a Data View](https://www.elastic.co/guide/en/kibana/current/data-views.html) for your `stix2ecs` index to view the ingested indicators. \n\n![STIX2ECS data in Kibana](/assets/images/stixy-situations-ecsaping-your-threat-data/image1.png \"STIX2ECS data in Kibana\")\n\n\nFinally, you can use this as an indicator source for [Indicator Match rules](https://www.elastic.co/guide/en/security/current/prebuilt-rule-1-0-2-threat-intel-indicator-match.html).\n\n![Indicator Match rule created with STIX2ECS data](/assets/images/stixy-situations-ecsaping-your-threat-data/image2.png \"Indicator Match rule created with STIX2ECS data\")\n\n\n## Summary\nWe hope this project helps your organization analyze and operationalize your threat data. If you’re new to the Elastic Common Schema, you can learn more about that [here](https://www.elastic.co/guide/en/ecs/current/index.html). \n\nAs always, please feel free to open an [issue](https://github.com/elastic/labs-releases/issues) with any questions, comments, concerns, or complaints. \n\n## About Elastic Security Labs\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/). \n","code":"var Component=(()=\u003e{var h=Object.create;var a=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var u=Object.getOwnPropertyNames;var m=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var y=(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})},s=(n,e,i,o)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let r of u(e))!f.call(n,r)\u0026\u0026r!==i\u0026\u0026a(n,r,{get:()=\u003ee[r],enumerable:!(o=p(e,r))||o.enumerable});return n};var g=(n,e,i)=\u003e(i=n!=null?h(m(n)):{},s(e||!n||!n.__esModule?a(i,\"default\",{value:n,enumerable:!0}):i,n)),E=n=\u003es(a({},\"__esModule\",{value:!0}),n);var l=y((v,c)=\u003e{c.exports=_jsx_runtime});var T={};w(T,{default:()=\u003eD,frontmatter:()=\u003eS});var t=g(l()),S={title:\"STIXy Situations: ECSaping your threat data\",subtitle:\"Structured threat data is commonly formatted using STIX. To help get this data into Elasticsearch, we\\u2019re releasing a Python script that converts STIX to an ECS format to be ingested into your stack.\",slug:\"stixy-situations-ecsaping-your-threat-data\",date:\"2024-02-09\",description:\"Structured threat data is commonly formatted using STIX. To help get this data into Elasticsearch, we\\u2019re releasing a Python script that converts STIX to an ECS format to be ingested into your stack.\",author:[{slug:\"cyril-francois\"},{slug:\"andrew-pease\"}],image:\"photo-edited-07@2x.jpg\",category:[{slug:\"tools\"}]};function d(n){let e=Object.assign({h2:\"h2\",p:\"p\",a:\"a\",h3:\"h3\",pre:\"pre\",code:\"code\",div:\"div\",table:\"table\",thead:\"thead\",tr:\"tr\",th:\"th\",tbody:\"tbody\",td:\"td\",img:\"img\"},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:\"Organizations that use threat indicators or observables consume, create, and/or (ideally) publish threat data. This data can be used internally or externally as information or intelligence to inform decision-making and event prioritization.\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"While there are several formats for this information to be structured into, the de facto industry standard is \",(0,t.jsx)(e.a,{href:\"https://oasis-open.github.io/cti-documentation/stix/intro\",rel:\"nofollow\",children:\"Structured Threat Information Expression (STIX)\"}),\". STIX is managed by the \",(0,t.jsx)(e.a,{href:\"https://www.oasis-open.org/committees/tc_home.php?wg_abbrev=cti\",rel:\"nofollow\",children:\"OASIS Cyber Threat Intelligence Technical Committee\"}),\" and enables organizations to share threat data in a standard and machine-readable format.\"]}),`\n`,(0,t.jsxs)(e.p,{children:[\"At Elastic, we developed the \",(0,t.jsx)(e.a,{href:\"https://www.elastic.co/guide/en/ecs/current/ecs-reference.html\",rel:\"nofollow\",children:\"Elastic Common Schema (ECS)\"}),\" as a data normalization capability. \\u201C[ECS] is an open source specification, developed with support from the Elastic user community. ECS defines a common set of fields for storing event data in Elasticsearch, such as logs and metrics.\\u201D In April of 2023, \",(0,t.jsx)(e.a,{href:\"https://www.elastic.co/blog/ecs-elastic-common-schema-otel-opentelemetry-announcement\",rel:\"nofollow\",children:\"Elastic contributed ECS\"}),\" to the \",(0,t.jsx)(e.a,{href:\"https://opentelemetry.io/docs/concepts/semantic-conventions/\",rel:\"nofollow\",children:\"OpenTelemetry Semantic Conventions (OTel)\"}),\" as a commitment to the joint development of an open schema.\"]}),`\n`,(0,t.jsxs)(e.p,{children:[\"The security community shares threat data in the STIX format, so to store that data in Elasticsearch for analysis and threat detection [\",(0,t.jsx)(e.a,{href:\"https://www.elastic.co/guide/en/security/current/threat-intel-hash-indicator-match.html\",rel:\"nofollow\",children:\"1\"}),\"] [\",(0,t.jsx)(e.a,{href:\"https://www.elastic.co/guide/en/security/current/threat-intel-ip-address-indicator-match.html\",rel:\"nofollow\",children:\"2\"}),\"] [\",(0,t.jsx)(e.a,{href:\"https://www.elastic.co/guide/en/security/current/threat-intel-url-indicator-match.html\",rel:\"nofollow\",children:\"3\"}),\"] [\",(0,t.jsx)(e.a,{href:\"https://www.elastic.co/guide/en/security/current/threat-intel-windows-registry-indicator-match.html\",rel:\"nofollow\",children:\"4\"}),\"], we created a tool that converts STIX documents into ECS and outputs the threat data either as a file or directly into Elasticsearch indices. If this was a challenge for us, it was a challenge for others - therefore, we decided to release a version of the tool.\"]}),`\n`,(0,t.jsxs)(e.p,{children:[\"This tool uses the \",(0,t.jsx)(e.a,{href:\"https://www.elastic.co/licensing/elastic-license\",rel:\"nofollow\",children:\"Elastic License 2.0\"}),\" and is available for download \",(0,t.jsx)(e.a,{href:\"https://github.com/elastic/labs-releases/tree/main/tools/stix-to-ecs\",rel:\"nofollow\",children:\"here\"}),\".\"]}),`\n`,(0,t.jsx)(e.h2,{id:\"getting-started\",children:\"Getting started\"}),`\n`,(0,t.jsx)(e.p,{children:\"This project will take a STIX 2.x formatted JSON document and create an ECS version. There are three output options: STDOUT as JSON, an NDJSON file, and/or directly to an Elasticsearch cluster.\"}),`\n`,(0,t.jsx)(e.h3,{id:\"prerequisites\",children:\"Prerequisites\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"The STIX 2 ECS project requires Python 3.10+ and the \",(0,t.jsx)(e.a,{href:\"https://pypi.org/project/stix2/\",rel:\"nofollow\",children:\"stix2\"}),\", \",(0,t.jsx)(e.a,{href:\"https://pypi.org/project/elasticsearch/\",rel:\"nofollow\",children:\"Elasticsearch\"}),\", and \",(0,t.jsx)(e.a,{href:\"https://pypi.org/project/getpass4/\",rel:\"nofollow\",children:\"getpass\"}),\" modules.\"]}),`\n`,(0,t.jsx)(e.p,{children:\"If exporting to Elasticsearch, you will need the host information and authentication credentials. API authentication is not yet implemented.\"}),`\n`,(0,t.jsx)(e.h3,{id:\"setup\",children:\"Setup\"}),`\n`,(0,t.jsx)(e.p,{children:\"Create a virtual environment and install the required prerequisites.\"}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`git clone https://github.com/elastic/labs-releases.git\ncd tools/stix2ecs\npython -m venv /path/to/virtual/environments/stix2ecs\nsource /path/to/virtual/environments/stix2ecs/bin/activate\npython -m pip install -r requirements.txt\n`})}),`\n`,(0,t.jsx)(e.h2,{id:\"operation\",children:\"Operation\"}),`\n`,(0,t.jsx)(e.p,{children:\"The input is a STIX 2.x JSON document (or a folder of JSON documents); the output defaults to STDOUT, with an option to create an NDJSON file and/or send to an Elasticsearch cluster.\"}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`stix_to_ecs.py [-h] -i INPUT [-o OUTPUT] [-e] [--index INDEX] [--url URL] \\\\\n[--user USER] [-p PROVIDER] [-r]\n`})}),`\n`,(0,t.jsxs)(e.p,{children:[\"By default, the ECS file is named the same as the STIX file input but with \",(0,t.jsx)(e.code,{children:\".ecs.ndjson\"}),\" appended.\"]}),`\n`,(0,t.jsx)(e.h3,{id:\"arguments\",children:\"Arguments\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"The script has several arguments, the only mandatory field is \",(0,t.jsx)(e.code,{children:\"-i\"}),\" for the input. By default, the script will output the NDJSON document to STDOUT.\"]}),`\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:\"Option\"}),(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:\"-h\"}),(0,t.jsx)(e.td,{children:\"displays the help menu\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"-i\"}),(0,t.jsx)(e.td,{children:\"specifies the input STIX document (mandatory)\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"-o\"}),(0,t.jsx)(e.td,{children:\"specifies the output ECS document (optional)\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"-p\"}),(0,t.jsx)(e.td,{children:\"defines the ECS provider field (optional)\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"-r\"}),(0,t.jsx)(e.td,{children:\"recursive mode to convert multiple STIX documents (optional)\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"-e\"}),(0,t.jsx)(e.td,{children:\"specifies the Elasticsearch output mode (optional)\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"--index\"}),(0,t.jsxs)(e.td,{children:[\"defines the Elasticsearch Index, requires \",(0,t.jsx)(e.code,{children:\"-e\"}),\" (optional)\"]})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"--url\"}),(0,t.jsxs)(e.td,{children:[\"defines the Elasticsearch URL, requires \",(0,t.jsx)(e.code,{children:\"-e\"}),\" (optional)\"]})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"--user\"}),(0,t.jsxs)(e.td,{children:[\"defines the Elasticsearch username, requires \",(0,t.jsx)(e.code,{children:\"-e\"}),\" (optional)\"]})]})]})]})}),`\n`,(0,t.jsx)(e.h2,{id:\"examples\",children:\"Examples\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"There are two sample files located in the \",(0,t.jsx)(e.code,{children:\"test-inputs/\"}),\" directory. One is from \",(0,t.jsx)(e.a,{href:\"https://www.cisa.gov/topics/cyber-threats-and-advisories/information-sharing/automated-indicator-sharing-ais\",rel:\"nofollow\",children:\"CISA\"}),\" (Cybersecurity \u0026 Infrastructure Security Agency), and one is from \",(0,t.jsx)(e.a,{href:\"https://github.com/OpenCTI-Platform/opencti\",rel:\"nofollow\",children:\"OpenCTI\"}),\" (an open source threat intelligence platform).\"]}),`\n`,(0,t.jsx)(e.h3,{id:\"stix-file-input-to-stdout\",children:\"STIX file input to STDOUT\"}),`\n`,(0,t.jsx)(e.p,{children:\"This will output the STIX document to STDOUT in ECS format.\"}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`python stix_to_ecs.py -i test-inputs/cisa_sample_stix.json | jq\n\n[\n {\n \"threat\": {\n \"indicator\": {\n \"file\": {\n \"name\": \"123.ps1\",\n \"hash\": {\n \"sha256\": \"ED5D694D561C97B4D70EFE934936286FE562ADDF7D6836F795B336D9791A5C44\"\n }\n },\n \"type\": \"file\",\n \"description\": \"Simple indicator of observable {ED5D694D561C97B4D70EFE934936286FE562ADDF7D6836F795B336D9791A5C44}\",\n \"first_seen\": \"2023-11-21T18:57:25.000Z\",\n \"provider\": \"identity--b3bca3c2-1f3d-4b54-b44f-dac42c3a8f01\",\n \"modified_at\": \"2023-11-21T18:57:25.000Z\",\n \"marking\": {\n \"tlp\": \"clear\"\n }\n }\n }\n },\n...\n`})}),`\n`,(0,t.jsx)(e.h3,{id:\"stix-file-input-to-ecs-file-output\",children:\"STIX file input to ECS file output\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"This will create a folder called \",(0,t.jsx)(e.code,{children:\"ecs\"}),\" in the present directory and write the ECS file there.\"]}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`python python stix_to_ecs.py -i test-inputs/cisa_sample_stix.json -o ecs\n\ncat ecs/cisa_sample_stix.ecs.ndjson | jq\n{\n \"threat\": {\n \"indicator\": {\n \"file\": {\n \"name\": \"123.ps1\",\n \"hash\": {\n \"sha256\": \"ED5D694D561C97B4D70EFE934936286FE562ADDF7D6836F795B336D9791A5C44\"\n }\n },\n \"type\": \"file\",\n \"description\": \"Simple indicator of observable {ED5D694D561C97B4D70EFE934936286FE562ADDF7D6836F795B336D9791A5C44}\",\n \"first_seen\": \"2023-11-21T18:57:25.000Z\",\n \"provider\": \"identity--b3bca3c2-1f3d-4b54-b44f-dac42c3a8f01\",\n \"modified_at\": \"2023-11-21T18:57:25.000Z\",\n \"marking\": {\n \"tlp\": \"clear\"\n }\n }\n }\n}\n...\n`})}),`\n`,(0,t.jsx)(e.h3,{id:\"stix-file-input-to-ecs-file-output-defining-the-provider-field\",children:\"STIX file input to ECS file output, defining the Provider field\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"The provider field is commonly a GUID in the STIX document. To make it more user-friendly, you can use the \",(0,t.jsx)(e.code,{children:\"-p\"}),\" argument to define the \",(0,t.jsx)(e.code,{children:\"threat.indicator.provider\"}),\" field.\"]}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`python stix_to_ecs.py -i test-inputs/cisa_sample_stix.json -o ecs -p \"Elastic Security Labs\"\n\ncat ecs/cisa_sample_stix.ecs.ndjson | jq\n{\n \"threat\": {\n \"indicator\": {\n \"file\": {\n \"name\": \"123.ps1\",\n \"hash\": {\n \"sha256\": \"ED5D694D561C97B4D70EFE934936286FE562ADDF7D6836F795B336D9791A5C44\"\n }\n },\n \"type\": \"file\",\n \"description\": \"Simple indicator of observable {ED5D694D561C97B4D70EFE934936286FE562ADDF7D6836F795B336D9791A5C44}\",\n \"first_seen\": \"2023-11-21T18:57:25.000Z\",\n \"provider\": \"Elastic Security Labs\",\n \"modified_at\": \"2023-11-21T18:57:25.000Z\",\n \"marking\": {\n \"tlp\": \"clear\"\n }\n }\n }\n}\n...\n`})}),`\n`,(0,t.jsx)(e.h3,{id:\"stix-directory-input-to-ecs-file-outputs\",children:\"STIX directory input to ECS file outputs\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"If you have a directory of STIX documents, you can use the \",(0,t.jsx)(e.code,{children:\"-r\"}),\" argument to recursively search through the directory and write the ECS documents to the output directory.\"]}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`python stix_to_ecs.py -ri test-inputs -o ecs\n`})}),`\n`,(0,t.jsx)(e.h3,{id:\"stix-file-input-to-elasticsearch-output\",children:\"STIX file input to Elasticsearch output\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"To output to Elasticsearch, you can use either Elastic Cloud or a local instance. Local Elasticsearch will use port \",(0,t.jsx)(e.code,{children:\"9200\"}),\" and Elastic Cloud will use port \",(0,t.jsx)(e.code,{children:\"443\"}),\". By default, a valid TLS session to Elasticsearch is required.\"]}),`\n`,(0,t.jsxs)(e.p,{children:[\"First, create an index if you don't already have one. In this example, we\\u2019re creating an index called \",(0,t.jsx)(e.code,{children:\"stix2ecs\"}),\", but the index name isn\\u2019t relevant.\"]}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`curl -u {username} -X PUT \"https://elasticsearch:port/stix2ecs?pretty\"\n\n{\n \"acknowledged\" : true,\n \"shards_acknowledged\" : true,\n \"index\" : \"stix2ecs\"\n}\n`})}),`\n`,(0,t.jsx)(e.p,{children:\"Next, define the Elasticsearch output options.\"}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`python stix_to_ecs.py -i test-inputs/cisa_sample_stix.json -e --url https://elasticsearch:port --user username --index stix2ecs\n`})}),`\n`,(0,t.jsx)(e.p,{children:\"If you\\u2019re storing the data in Elasticsearch for use in another platform, you can view the indicators using cURL.\"}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`curl -u {username} https://elasticsearch:port/stix2ecs/_search?pretty\n\n{\n \"took\" : 2,\n \"timed_out\" : false,\n \"_shards\" : {\n \"total\" : 1,\n \"successful\" : 1,\n \"skipped\" : 0,\n \"failed\" : 0\n },\n \"hits\" : {\n \"total\" : {\n \"value\" : 3,\n \"relation\" : \"eq\"\n },\n \"max_score\" : 1.0,\n \"hits\" : [\n {\n \"_index\" : \"stix2ecs\",\n \"_id\" : \"n2lt8IwBahlUtp0hzm9i\",\n \"_score\" : 1.0,\n \"_source\" : {\n \"threat\" : {\n \"indicator\" : {\n \"file\" : {\n \"name\" : \"123.ps1\",\n \"hash\" : {\n \"sha256\" : \"ED5D694D561C97B4D70EFE934936286FE562ADDF7D6836F795B336D9791A5C44\"\n }\n },\n \"type\" : \"file\",\n \"description\" : \"Simple indicator of observable {ED5D694D561C97B4D70EFE934936286FE562ADDF7D6836F795B336D9791A5C44}\",\n \"first_seen\" : \"2023-11-21T18:57:25.000Z\",\n \"provider\" : \"identity--b3bca3c2-1f3d-4b54-b44f-dac42c3a8f01\",\n \"modified_at\" : \"2023-11-21T18:57:25.000Z\",\n \"marking\" : {\n \"tlp\" : \"clear\"\n }\n }\n }\n }\n }\n...\n`})}),`\n`,(0,t.jsxs)(e.p,{children:[\"If you\\u2019re using Kibana, you can \",(0,t.jsx)(e.a,{href:\"https://www.elastic.co/guide/en/kibana/current/data-views.html\",rel:\"nofollow\",children:\"create a Data View\"}),\" for your \",(0,t.jsx)(e.code,{children:\"stix2ecs\"}),\" index to view the ingested indicators.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/stixy-situations-ecsaping-your-threat-data/image1.png\",alt:\"STIX2ECS data in Kibana\",title:\"STIX2ECS data in Kibana\",width:\"1440\",height:\"266\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"Finally, you can use this as an indicator source for \",(0,t.jsx)(e.a,{href:\"https://www.elastic.co/guide/en/security/current/prebuilt-rule-1-0-2-threat-intel-indicator-match.html\",rel:\"nofollow\",children:\"Indicator Match rules\"}),\".\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/stixy-situations-ecsaping-your-threat-data/image2.png\",alt:\"Indicator Match rule created with STIX2ECS data\",title:\"Indicator Match rule created with STIX2ECS data\",width:\"1440\",height:\"884\"})}),`\n`,(0,t.jsx)(e.h2,{id:\"summary\",children:\"Summary\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"We hope this project helps your organization analyze and operationalize your threat data. If you\\u2019re new to the Elastic Common Schema, you can learn more about that \",(0,t.jsx)(e.a,{href:\"https://www.elastic.co/guide/en/ecs/current/index.html\",rel:\"nofollow\",children:\"here\"}),\".\"]}),`\n`,(0,t.jsxs)(e.p,{children:[\"As always, please feel free to open an \",(0,t.jsx)(e.a,{href:\"https://github.com/elastic/labs-releases/issues\",rel:\"nofollow\",children:\"issue\"}),\" with any questions, comments, concerns, or complaints.\"]}),`\n`,(0,t.jsx)(e.h2,{id:\"about-elastic-security-labs\",children:\"About Elastic Security Labs\"}),`\n`,(0,t.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,t.jsxs)(e.p,{children:[\"Follow Elastic Security Labs on Twitter \",(0,t.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,t.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/\",rel:\"nofollow\",children:\"www.elastic.co/security-labs/\"}),\".\"]})]})}function b(n={}){let{wrapper:e}=n.components||{};return e?(0,t.jsx)(e,Object.assign({},n,{children:(0,t.jsx)(d,n)})):d(n)}var D=b;return E(T);})();\n;return Component;"},"_id":"articles/stixy-situations-ecsaping-your-threat-data.mdx","_raw":{"sourceFilePath":"articles/stixy-situations-ecsaping-your-threat-data.mdx","sourceFileName":"stixy-situations-ecsaping-your-threat-data.mdx","sourceFileDir":"articles","contentType":"mdx","flattenedPath":"articles/stixy-situations-ecsaping-your-threat-data"},"type":"Article","imageUrl":"/assets/images/stixy-situations-ecsaping-your-threat-data/photo-edited-07@2x.jpg","readingTime":"11 min read","series":"","url":"/stixy-situations-ecsaping-your-threat-data","headings":[{"level":2,"title":"Preamble","href":"#preamble"},{"level":2,"title":"Getting started","href":"#getting-started"},{"level":3,"title":"Prerequisites","href":"#prerequisites"},{"level":3,"title":"Setup","href":"#setup"},{"level":2,"title":"Operation","href":"#operation"},{"level":3,"title":"Arguments","href":"#arguments"},{"level":2,"title":"Examples","href":"#examples"},{"level":3,"title":"STIX file input to STDOUT","href":"#stix-file-input-to-stdout"},{"level":3,"title":"STIX file input to ECS file output","href":"#stix-file-input-to-ecs-file-output"},{"level":3,"title":"STIX file input to ECS file output, defining the Provider field","href":"#stix-file-input-to-ecs-file-output-defining-the-provider-field"},{"level":3,"title":"STIX directory input to ECS file outputs","href":"#stix-directory-input-to-ecs-file-outputs"},{"level":3,"title":"STIX file input to Elasticsearch output","href":"#stix-file-input-to-elasticsearch-output"},{"level":2,"title":"Summary","href":"#summary"},{"level":2,"title":"About Elastic Security Labs","href":"#about-elastic-security-labs"}],"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":"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":"Tools","slug":"tools","body":{"raw":"","code":"var Component=(()=\u003e{var x=Object.create;var s=Object.defineProperty;var l=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),d=(t,n)=\u003e{for(var e in n)s(t,e,{get:n[e],enumerable:!0})},c=(t,n,e,a)=\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:!(a=l(n,r))||a.enumerable});return t};var p=(t,n,e)=\u003e(e=t!=null?x(_(t)):{},c(n||!t||!t.__esModule?s(e,\"default\",{value:t,enumerable:!0}):e,t)),M=t=\u003ec(s({},\"__esModule\",{value:!0}),t);var i=j((h,u)=\u003e{u.exports=_jsx_runtime});var X={};d(X,{default:()=\u003eF,frontmatter:()=\u003eC});var o=p(i()),C={title:\"Tools\",slug:\"tools\"};function m(t){return(0,o.jsx)(o.Fragment,{})}function D(t={}){let{wrapper:n}=t.components||{};return n?(0,o.jsx)(n,Object.assign({},t,{children:(0,o.jsx)(m,t)})):m(t)}var F=D;return M(X);})();\n;return Component;"},"_id":"categories/tools.mdx","_raw":{"sourceFilePath":"categories/tools.mdx","sourceFileName":"tools.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/tools"},"type":"Category","url":"/categories/tools"}]},{"title":"Into The Weeds: How We Run Detonate","slug":"into-the-weeds-how-we-run-detonate","date":"2023-06-13","description":"Explore the technical implementation of the Detonate system, including sandbox creation, the supporting technology, telemetry collection, and how to blow stuff up.","image":"photo-edited-02@2x.jpg","subtitle":"A deeper dive into the technical implementations of Detonate","tags":["detonate"],"body":{"raw":"\n## Preamble\n\nIn our [first post](https://www.elastic.co/security-labs/click-click-boom-automating-protections-testing-with-detonate) in our Detonate series, we introduced the Detonate system and what we use it for at Elastic. We also discussed the benefits it provides our team when assessing the performance of our security artifacts.\n\nIn this publication, we will break down how Detonate works \u0026 dive deeper into the technical implementation. This includes how we’re able to create this sandboxed environment in practice, the technology that supports the overall pipeline, and how we submit information to and read information from the pipeline.\n\n\u003e Interested in other posts on Detonate? Check out [Part 1 - Click, Click…Boom!](https://www.elastic.co/security-labs/click-click-boom-automating-protections-testing-with-detonate) where we introduce Detonate, why we built it, explore how Detonate works, describe case studies, and discuss efficacy testing.\n\n## Architecture\n\nBelow is a high-level overview of the Detonate end-to-end architecture.\n\n![The end-to-end Detonate architecture, including how we send input to the API server, each individual worker \u0026 associated queue, cloud infrastructure details, and our Elastic data stores.](/assets/images/into-the-weeds-how-we-run-detonate/image8.png)\n\nThe overall system consists of a series of message queues and Python workers. Detonation tasks are created by an API server upon accepting a request with as little information as the sample file hash. The task then moves from queue to queue, picked up by workers that execute various operations along the way. \nThe server and workers run in a container on [Amazon ECS](https://aws.amazon.com/ecs/). The pipeline can also be brought up locally using [Docker Compose](https://docs.docker.com/compose/) for early development and feature testing.\n\n### API server\n\nThe Detonate API server is a [FastAPI](https://fastapi.tiangolo.com/) python application that accepts a variety of execution target requests: hashes of samples, native commands (in bash or Powershell, with or without arguments), and uploaded files. The server also exposes endpoints for fetching alerts and raw agent telemetry from an Elastic cluster.\n\nThe API documentation is generated [automatically](https://fastapi.tiangolo.com/advanced/extending-openapi/) by FastAPI and incorporated into our global API schema.\n\n![The schema includes varies get methods to see information about the running task.](/assets/images/into-the-weeds-how-we-run-detonate/image2.png)\n\n#### Interacting with the API server - CLI\n\nWe built a custom Python CLI (command-line interface) tool for interacting with our Detonate server. The CLI tool is built using the Python library [click](https://click.palletsprojects.com/en/8.1.x/) along with [rich](https://github.com/Textualize/rich) for a beautiful formatting experience in a terminal window. The tool is particularly useful for debugging the pipeline, as it can also be run against a local pipeline setup. The tool is installed and runs using [Poetry](https://python-poetry.org/), our preferred tool of choice for managing dependencies and running scripts.\n\n```\n❯ DETONATE_CLI_API_ROOT_URL=\"${API_ENDPOINT_URL}\" \\\n\tDETONATE_CLI_API_AUTH_HEADER=\"${API_KEY}\" \\\n\tpoetry run cli \\\n\t--hash \"${MY_FILE_HASH}\"\n```\n\n![An example of the output from the CLI tool once a hash is submitted. It shows the hash, the task ID, and where along the pipeline the process is as well as the last worker status.](/assets/images/into-the-weeds-how-we-run-detonate/image5.png)\n\n![The full output of a Hash detonation in the console. The links include references to run logs, task information, events and alerts in our Elastic clusters, and more.](/assets/images/into-the-weeds-how-we-run-detonate/image13.png)\n\n#### Interacting with the API server - Web UI\n\nInternally, we host a site called Protections Portal (written using [Elastic UI](https://elastic.github.io/eui/) components) to assist our team with research. For a more interactive experience with the Detonate API, we built a page in the Portal to interact with it. Along with submitting tasks, the Web UI allows users to see the feed of all detonations and the details of each task.\n\n![The Detonate landing page Protections Portal showing the input field for starting a detonation. Below the input is a task that is currently running.](/assets/images/into-the-weeds-how-we-run-detonate/image10.png)\n\nEach task can be expanded to see its full details. We provide the links to the data and telemetry collected during the detonation.\n\n![The UI shows the completed detonation task in the Protections Portal.](/assets/images/into-the-weeds-how-we-run-detonate/image11.png)\n\n#### Interacting with the API server - HTTP client\n\nIf our users want to customize how they interact with the Detonate API, they can also run commands using their HTTP client of choice (such as **curl** , **httpie** , etc.). This allows them to add detonations to scripts or as final steps at the end of their own workflows.\n\n### Queues\n\nThe pipeline is built on a series of queues and workers. Having very basic requirements for the message queues engine, we decided to go with [Amazon SQS](https://aws.amazon.com/sqs/). One of the many benefits of using a popular service like SQS is the availability of open-source resources and libraries we can build upon. For example, we use [softwaremill/elasticmq](https://github.com/softwaremill/elasticmq) Docker images as a queue engine when running the pipeline locally.\n\nThe queues are configured and deployed with Terraform code that covers all our production and staging infrastructure.\n\n### Workers\n\nEach worker is a Python script that acts as both a queue consumer and a queue producer. The workers are implemented in our custom mini-framework, with the boilerplate code for error handling, retries, and monitoring built-in. Our base worker is easily extended, allowing us to add new workers and evolve existing ones if additional requirements arise.\n\nFor monitoring, we use the [Elastic APM](https://www.elastic.co/observability/application-performance-monitoring) observability solution. It is incredibly powerful, giving us a view into the execution flow and making debugging pipeline issues a breeze. Below, we can see a Detonate task move between workers in the APM UI:\n\n![The Elastic Observability APM tracing page showing the execution flow of a detonation task. We are able to follow the task between each worker \u0026 queue to see where we may have issues or can add improvements.](/assets/images/into-the-weeds-how-we-run-detonate/image12.png)\n\nThese software and infrastructure components give us everything we need to perform the submission, execution, and data collection that make up a detonation.\n\n## Detonations\n\n![Caption: by Simon Lee, https://unsplash.com/photos/CKuOXoZ21a8](/assets/images/into-the-weeds-how-we-run-detonate/image3.jpg)\n\nThe pipeline can execute commands and samples in Windows, Linux, and macOS virtual machines (VMs). For Windows and Linux environments, we use VM instances in [Google Compute Engine](https://cloud.google.com/compute). With the wide selection of public images, it allows us to provision sandboxed environments with different versions of Windows, Debian, Ubuntu, CentOS, and RHEL.\n\nFor macOS environments, we use [mac1.metal instances in AWS](https://aws.amazon.com/ec2/instance-types/mac/) and an on-demand macOS VM provisioning [solution from Veertu called Anka](https://veertu.com/anka-build/). Anka gives us the ability to quickly rotate multiple macOS VMs running on the same macOS bare metal instance.\n\nDetonate is currently focused on the breadth of our OS coverage, scalability, and the collection of contextually relevant data from the pipeline. Fitting sophisticated anti-analysis countermeasures into Detonate is currently being researched and engineered.\n\n### VM provisioning\n\nIn order to keep our footprint in the VM to a minimum, we use startup scripts for provisioning. Minimizing our footprint is important because our activities within a VM are included in the events we collect, making analysis more complicated after a run. For Windows and Linux VMs, [GCP startup scripts](https://cloud.google.com/compute/docs/instances/startup-scripts) written in Powershell and bash are used to configure the system; for macOS VMs, we wrote custom bash and AppleScript scripts.\n\nThe startup scripts perform these steps:\n\n- **Configure the system**. For example, disable MS Defender, enable macros execution in MS Office, disable automatic system updates, etc.\n- **Download and install Elastic agent**. The script verifies that the agent is properly [enrolled into the Fleet Server](https://www.elastic.co/guide/en/fleet/current/fleet-overview.html) and that the policies are applied.\n- **Download and detonate a sample, or execute a set of commands**. The execution happens in a background process, while the main script collects the STDOUT / STDERR datastreams and sleeps for N seconds.\n- **Collect files from the filesystem (if needed) and upload them into the storage**. This allows us to do any additional verification or debugging once the detonation is complete.\n\nThe VM lifecycle is managed by the **start_vm** and **stop_vm** workers. Since we expect some detonations to break the startup script execution flow (e.g., in the case of ransomware), every VM has a TTL set, which allows the **stop_vm** worker to delete VMs not in use anymore.\n\nThis clean-slate approach, with the startup script used to configure everything needed for a detonation, allows us to use VM images from the vendors from Google Cloud public images catalog without any modifications!\n\n### Network configuration\n\nSome of the samples we detonate are malicious and might produce malicious traffic, such as network scans, C2 callouts, etc. In order to keep our cloud resources and our vendor’s infrastructure safe, we limit all outgoing traffic from VMs. The instances are placed in a locked-down VPC that allows outgoing connection only to a predefined list of targets. We restrict traffic flows in VPC using Google Cloud’s [routes](https://cloud.google.com/vpc/docs/routes) and [firewall rules](https://cloud.google.com/firewall/docs/firewalls), and AWS’s [security groups](https://docs.aws.amazon.com/vpc/latest/userguide/security-groups.html).\n\nWe also make use of [VPC Flow Logs](https://cloud.google.com/vpc/docs/flow-logs) in GCE. These logs allow us to see private network traffic initiated by sandbox VMs in our VPC.\n\n### Telemetry collection\n\nTo observe detonations, we use the [Elastic Agent](https://www.elastic.co/elastic-agent) with the [Elastic Defend](https://www.elastic.co/guide/en/security/current/install-endpoint.html) integration installed with all protections in “Detect” (instead of “Protect”) mode. This allows us to collect as much information from a VM as we can, while simultaneously allowing the [Elastic Security](https://www.elastic.co/security) solution to produce alerts and detections.\n\n![The policy settings in Elastic Defend integration for Detonate.](/assets/images/into-the-weeds-how-we-run-detonate/image6.png)\n\nWe cover two use cases with this architecture: we can validate protections (comparing events and alerts produced for different OS versions, agent versions, security artifacts deployed, etc) and collect telemetry for analysis (for fresh samples or novel malware) at the same time. All data collected is kept in a persistent Elastic cluster and is available for our researchers.\n\n## Running in production\n\nRecently we completed a full month of running Detonate pipeline in production, under the load of multiple data integrations, serving internal users through UI at the same time. Our record so far is 1034 detonations in a single day, and so far, we haven’t seen any scalability or reliability issues.\n\n![Data from our internal Detonate telemetry, visualized in Kibana.](/assets/images/into-the-weeds-how-we-run-detonate/image4.png)\n\nThe bulk of the submissions are Windows-specific samples, for now. We are working on increasing our coverage of Linux and macOS as well – stay tuned for the research blog posts coming soon!\n\n![Additional visualization types can help us further break down how Detonate is being used.](/assets/images/into-the-weeds-how-we-run-detonate/image7.png)\n\nWe are constantly improving our support for various file types, making sure the detonation is as close to the intended trigger behavior as possible.\n\nLooking at the detonations from the last month, we see that most of the tasks were completed in under 13 minutes (with a median of 515 seconds). This time includes task data preparation, VM provisioning and cleanup, sample execution, and post-detonation processing.\n\n![Data from our internal Detonate telemetry, generated using custom Python code.](/assets/images/into-the-weeds-how-we-run-detonate/image14.jpg)\n\nThese are still early days of the service, so it is normal to see the outliers. Since most of the time in a task is spent waiting for a VM to provision, we can improve the overall execution time by using custom VM images, pre-starting VM instances, and optimizing the startup scripts.\n\n## What's next?\n\nNow that you see how Detonate works, our next posts will dive into more detailed use cases of Detonate. We’ll go further into how these detonations turn into protecting more of our users, including right here at Elastic!\n","code":"var Component=(()=\u003e{var d=Object.create;var s=Object.defineProperty;var u=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var m=Object.getPrototypeOf,w=Object.prototype.hasOwnProperty;var g=(n,e)=\u003e()=\u003e(e||n((e={exports:{}}).exports,e),e.exports),f=(n,e)=\u003e{for(var i in e)s(n,i,{get:e[i],enumerable:!0})},r=(n,e,i,a)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let o of p(e))!w.call(n,o)\u0026\u0026o!==i\u0026\u0026s(n,o,{get:()=\u003ee[o],enumerable:!(a=u(e,o))||a.enumerable});return n};var b=(n,e,i)=\u003e(i=n!=null?d(m(n)):{},r(e||!n||!n.__esModule?s(i,\"default\",{value:n,enumerable:!0}):i,n)),v=n=\u003er(s({},\"__esModule\",{value:!0}),n);var c=g((P,l)=\u003e{l.exports=_jsx_runtime});var x={};f(x,{default:()=\u003eT,frontmatter:()=\u003ey});var t=b(c()),y={title:\"Into The Weeds: How We Run Detonate\",slug:\"into-the-weeds-how-we-run-detonate\",date:\"2023-06-13\",subtitle:\"A deeper dive into the technical implementations of Detonate\",description:\"Explore the technical implementation of the Detonate system, including sandbox creation, the supporting technology, telemetry collection, and how to blow stuff up.\",author:[{slug:\"jessica-david\"},{slug:\"sergey-polzunov\"},{slug:\"hez-carty\"}],image:\"photo-edited-02@2x.jpg\",category:[{slug:\"detection-science\"},{slug:\"tools\"},{slug:\"security-research\"}],tags:[\"detonate\"]};function h(n){let e=Object.assign({h2:\"h2\",p:\"p\",a:\"a\",blockquote:\"blockquote\",img:\"img\",br:\"br\",h3:\"h3\",h4:\"h4\",pre:\"pre\",code:\"code\",strong:\"strong\",ul:\"ul\",li:\"li\"},n.components);return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(e.h2,{id:\"preamble\",children:\"Preamble\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"In our \",(0,t.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/click-click-boom-automating-protections-testing-with-detonate\",rel:\"nofollow\",children:\"first post\"}),\" in our Detonate series, we introduced the Detonate system and what we use it for at Elastic. We also discussed the benefits it provides our team when assessing the performance of our security artifacts.\"]}),`\n`,(0,t.jsx)(e.p,{children:\"In this publication, we will break down how Detonate works \u0026 dive deeper into the technical implementation. This includes how we\\u2019re able to create this sandboxed environment in practice, the technology that supports the overall pipeline, and how we submit information to and read information from the pipeline.\"}),`\n`,(0,t.jsxs)(e.blockquote,{children:[`\n`,(0,t.jsxs)(e.p,{children:[\"Interested in other posts on Detonate? Check out \",(0,t.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/click-click-boom-automating-protections-testing-with-detonate\",rel:\"nofollow\",children:\"Part 1 - Click, Click\\u2026Boom!\"}),\" where we introduce Detonate, why we built it, explore how Detonate works, describe case studies, and discuss efficacy testing.\"]}),`\n`]}),`\n`,(0,t.jsx)(e.h2,{id:\"architecture\",children:\"Architecture\"}),`\n`,(0,t.jsx)(e.p,{children:\"Below is a high-level overview of the Detonate end-to-end architecture.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/into-the-weeds-how-we-run-detonate/image8.png\",alt:\"The end-to-end Detonate architecture, including how we send input to the API server, each individual worker \u0026 associated queue, cloud infrastructure details, and our Elastic data stores.\",width:\"1440\",height:\"768\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"The overall system consists of a series of message queues and Python workers. Detonation tasks are created by an API server upon accepting a request with as little information as the sample file hash. The task then moves from queue to queue, picked up by workers that execute various operations along the way.\",(0,t.jsx)(e.br,{}),`\n`,\"The server and workers run in a container on \",(0,t.jsx)(e.a,{href:\"https://aws.amazon.com/ecs/\",rel:\"nofollow\",children:\"Amazon ECS\"}),\". The pipeline can also be brought up locally using \",(0,t.jsx)(e.a,{href:\"https://docs.docker.com/compose/\",rel:\"nofollow\",children:\"Docker Compose\"}),\" for early development and feature testing.\"]}),`\n`,(0,t.jsx)(e.h3,{id:\"api-server\",children:\"API server\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"The Detonate API server is a \",(0,t.jsx)(e.a,{href:\"https://fastapi.tiangolo.com/\",rel:\"nofollow\",children:\"FastAPI\"}),\" python application that accepts a variety of execution target requests: hashes of samples, native commands (in bash or Powershell, with or without arguments), and uploaded files. The server also exposes endpoints for fetching alerts and raw agent telemetry from an Elastic cluster.\"]}),`\n`,(0,t.jsxs)(e.p,{children:[\"The API documentation is generated \",(0,t.jsx)(e.a,{href:\"https://fastapi.tiangolo.com/advanced/extending-openapi/\",rel:\"nofollow\",children:\"automatically\"}),\" by FastAPI and incorporated into our global API schema.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/into-the-weeds-how-we-run-detonate/image2.png\",alt:\"The schema includes varies get methods to see information about the running task.\",width:\"1440\",height:\"1081\"})}),`\n`,(0,t.jsx)(e.h4,{id:\"interacting-with-the-api-server---cli\",children:\"Interacting with the API server - CLI\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"We built a custom Python CLI (command-line interface) tool for interacting with our Detonate server. The CLI tool is built using the Python library \",(0,t.jsx)(e.a,{href:\"https://click.palletsprojects.com/en/8.1.x/\",rel:\"nofollow\",children:\"click\"}),\" along with \",(0,t.jsx)(e.a,{href:\"https://github.com/Textualize/rich\",rel:\"nofollow\",children:\"rich\"}),\" for a beautiful formatting experience in a terminal window. The tool is particularly useful for debugging the pipeline, as it can also be run against a local pipeline setup. The tool is installed and runs using \",(0,t.jsx)(e.a,{href:\"https://python-poetry.org/\",rel:\"nofollow\",children:\"Poetry\"}),\", our preferred tool of choice for managing dependencies and running scripts.\"]}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`\\u276F DETONATE_CLI_API_ROOT_URL=\"\\${API_ENDPOINT_URL}\" \\\\\n\tDETONATE_CLI_API_AUTH_HEADER=\"\\${API_KEY}\" \\\\\n\tpoetry run cli \\\\\n\t--hash \"\\${MY_FILE_HASH}\"\n`})}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/into-the-weeds-how-we-run-detonate/image5.png\",alt:\"An example of the output from the CLI tool once a hash is submitted. It shows the hash, the task ID, and where along the pipeline the process is as well as the last worker status.\",width:\"1440\",height:\"78\"})}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/into-the-weeds-how-we-run-detonate/image13.png\",alt:\"The full output of a Hash detonation in the console. The links include references to run logs, task information, events and alerts in our Elastic clusters, and more.\",width:\"1440\",height:\"903\"})}),`\n`,(0,t.jsx)(e.h4,{id:\"interacting-with-the-api-server---web-ui\",children:\"Interacting with the API server - Web UI\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"Internally, we host a site called Protections Portal (written using \",(0,t.jsx)(e.a,{href:\"https://elastic.github.io/eui/\",rel:\"nofollow\",children:\"Elastic UI\"}),\" components) to assist our team with research. For a more interactive experience with the Detonate API, we built a page in the Portal to interact with it. Along with submitting tasks, the Web UI allows users to see the feed of all detonations and the details of each task.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/into-the-weeds-how-we-run-detonate/image10.png\",alt:\"The Detonate landing page Protections Portal showing the input field for starting a detonation. Below the input is a task that is currently running.\",width:\"1440\",height:\"871\"})}),`\n`,(0,t.jsx)(e.p,{children:\"Each task can be expanded to see its full details. We provide the links to the data and telemetry collected during the detonation.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/into-the-weeds-how-we-run-detonate/image11.png\",alt:\"The UI shows the completed detonation task in the Protections Portal.\",width:\"1440\",height:\"952\"})}),`\n`,(0,t.jsx)(e.h4,{id:\"interacting-with-the-api-server---http-client\",children:\"Interacting with the API server - HTTP client\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"If our users want to customize how they interact with the Detonate API, they can also run commands using their HTTP client of choice (such as \",(0,t.jsx)(e.strong,{children:\"curl\"}),\" , \",(0,t.jsx)(e.strong,{children:\"httpie\"}),\" , etc.). This allows them to add detonations to scripts or as final steps at the end of their own workflows.\"]}),`\n`,(0,t.jsx)(e.h3,{id:\"queues\",children:\"Queues\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"The pipeline is built on a series of queues and workers. Having very basic requirements for the message queues engine, we decided to go with \",(0,t.jsx)(e.a,{href:\"https://aws.amazon.com/sqs/\",rel:\"nofollow\",children:\"Amazon SQS\"}),\". One of the many benefits of using a popular service like SQS is the availability of open-source resources and libraries we can build upon. For example, we use \",(0,t.jsx)(e.a,{href:\"https://github.com/softwaremill/elasticmq\",rel:\"nofollow\",children:\"softwaremill/elasticmq\"}),\" Docker images as a queue engine when running the pipeline locally.\"]}),`\n`,(0,t.jsx)(e.p,{children:\"The queues are configured and deployed with Terraform code that covers all our production and staging infrastructure.\"}),`\n`,(0,t.jsx)(e.h3,{id:\"workers\",children:\"Workers\"}),`\n`,(0,t.jsx)(e.p,{children:\"Each worker is a Python script that acts as both a queue consumer and a queue producer. The workers are implemented in our custom mini-framework, with the boilerplate code for error handling, retries, and monitoring built-in. Our base worker is easily extended, allowing us to add new workers and evolve existing ones if additional requirements arise.\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"For monitoring, we use the \",(0,t.jsx)(e.a,{href:\"https://www.elastic.co/observability/application-performance-monitoring\",rel:\"nofollow\",children:\"Elastic APM\"}),\" observability solution. It is incredibly powerful, giving us a view into the execution flow and making debugging pipeline issues a breeze. Below, we can see a Detonate task move between workers in the APM UI:\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/into-the-weeds-how-we-run-detonate/image12.png\",alt:\"The Elastic Observability APM tracing page showing the execution flow of a detonation task. We are able to follow the task between each worker \u0026 queue to see where we may have issues or can add improvements.\",width:\"1440\",height:\"1308\"})}),`\n`,(0,t.jsx)(e.p,{children:\"These software and infrastructure components give us everything we need to perform the submission, execution, and data collection that make up a detonation.\"}),`\n`,(0,t.jsx)(e.h2,{id:\"detonations\",children:\"Detonations\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/into-the-weeds-how-we-run-detonate/image3.jpg\",alt:\"Caption: by Simon Lee, https://unsplash.com/photos/CKuOXoZ21a8\",width:\"1440\",height:\"1440\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"The pipeline can execute commands and samples in Windows, Linux, and macOS virtual machines (VMs). For Windows and Linux environments, we use VM instances in \",(0,t.jsx)(e.a,{href:\"https://cloud.google.com/compute\",rel:\"nofollow\",children:\"Google Compute Engine\"}),\". With the wide selection of public images, it allows us to provision sandboxed environments with different versions of Windows, Debian, Ubuntu, CentOS, and RHEL.\"]}),`\n`,(0,t.jsxs)(e.p,{children:[\"For macOS environments, we use \",(0,t.jsx)(e.a,{href:\"https://aws.amazon.com/ec2/instance-types/mac/\",rel:\"nofollow\",children:\"mac1.metal instances in AWS\"}),\" and an on-demand macOS VM provisioning \",(0,t.jsx)(e.a,{href:\"https://veertu.com/anka-build/\",rel:\"nofollow\",children:\"solution from Veertu called Anka\"}),\". Anka gives us the ability to quickly rotate multiple macOS VMs running on the same macOS bare metal instance.\"]}),`\n`,(0,t.jsx)(e.p,{children:\"Detonate is currently focused on the breadth of our OS coverage, scalability, and the collection of contextually relevant data from the pipeline. Fitting sophisticated anti-analysis countermeasures into Detonate is currently being researched and engineered.\"}),`\n`,(0,t.jsx)(e.h3,{id:\"vm-provisioning\",children:\"VM provisioning\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"In order to keep our footprint in the VM to a minimum, we use startup scripts for provisioning. Minimizing our footprint is important because our activities within a VM are included in the events we collect, making analysis more complicated after a run. For Windows and Linux VMs, \",(0,t.jsx)(e.a,{href:\"https://cloud.google.com/compute/docs/instances/startup-scripts\",rel:\"nofollow\",children:\"GCP startup scripts\"}),\" written in Powershell and bash are used to configure the system; for macOS VMs, we wrote custom bash and AppleScript scripts.\"]}),`\n`,(0,t.jsx)(e.p,{children:\"The startup scripts perform these steps:\"}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.strong,{children:\"Configure the system\"}),\". For example, disable MS Defender, enable macros execution in MS Office, disable automatic system updates, etc.\"]}),`\n`,(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.strong,{children:\"Download and install Elastic agent\"}),\". The script verifies that the agent is properly \",(0,t.jsx)(e.a,{href:\"https://www.elastic.co/guide/en/fleet/current/fleet-overview.html\",rel:\"nofollow\",children:\"enrolled into the Fleet Server\"}),\" and that the policies are applied.\"]}),`\n`,(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.strong,{children:\"Download and detonate a sample, or execute a set of commands\"}),\". The execution happens in a background process, while the main script collects the STDOUT / STDERR datastreams and sleeps for N seconds.\"]}),`\n`,(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.strong,{children:\"Collect files from the filesystem (if needed) and upload them into the storage\"}),\". This allows us to do any additional verification or debugging once the detonation is complete.\"]}),`\n`]}),`\n`,(0,t.jsxs)(e.p,{children:[\"The VM lifecycle is managed by the \",(0,t.jsx)(e.strong,{children:\"start_vm\"}),\" and \",(0,t.jsx)(e.strong,{children:\"stop_vm\"}),\" workers. Since we expect some detonations to break the startup script execution flow (e.g., in the case of ransomware), every VM has a TTL set, which allows the \",(0,t.jsx)(e.strong,{children:\"stop_vm\"}),\" worker to delete VMs not in use anymore.\"]}),`\n`,(0,t.jsx)(e.p,{children:\"This clean-slate approach, with the startup script used to configure everything needed for a detonation, allows us to use VM images from the vendors from Google Cloud public images catalog without any modifications!\"}),`\n`,(0,t.jsx)(e.h3,{id:\"network-configuration\",children:\"Network configuration\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"Some of the samples we detonate are malicious and might produce malicious traffic, such as network scans, C2 callouts, etc. In order to keep our cloud resources and our vendor\\u2019s infrastructure safe, we limit all outgoing traffic from VMs. The instances are placed in a locked-down VPC that allows outgoing connection only to a predefined list of targets. We restrict traffic flows in VPC using Google Cloud\\u2019s \",(0,t.jsx)(e.a,{href:\"https://cloud.google.com/vpc/docs/routes\",rel:\"nofollow\",children:\"routes\"}),\" and \",(0,t.jsx)(e.a,{href:\"https://cloud.google.com/firewall/docs/firewalls\",rel:\"nofollow\",children:\"firewall rules\"}),\", and AWS\\u2019s \",(0,t.jsx)(e.a,{href:\"https://docs.aws.amazon.com/vpc/latest/userguide/security-groups.html\",rel:\"nofollow\",children:\"security groups\"}),\".\"]}),`\n`,(0,t.jsxs)(e.p,{children:[\"We also make use of \",(0,t.jsx)(e.a,{href:\"https://cloud.google.com/vpc/docs/flow-logs\",rel:\"nofollow\",children:\"VPC Flow Logs\"}),\" in GCE. These logs allow us to see private network traffic initiated by sandbox VMs in our VPC.\"]}),`\n`,(0,t.jsx)(e.h3,{id:\"telemetry-collection\",children:\"Telemetry collection\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"To observe detonations, we use the \",(0,t.jsx)(e.a,{href:\"https://www.elastic.co/elastic-agent\",rel:\"nofollow\",children:\"Elastic Agent\"}),\" with the \",(0,t.jsx)(e.a,{href:\"https://www.elastic.co/guide/en/security/current/install-endpoint.html\",rel:\"nofollow\",children:\"Elastic Defend\"}),\" integration installed with all protections in \\u201CDetect\\u201D (instead of \\u201CProtect\\u201D) mode. This allows us to collect as much information from a VM as we can, while simultaneously allowing the \",(0,t.jsx)(e.a,{href:\"https://www.elastic.co/security\",rel:\"nofollow\",children:\"Elastic Security\"}),\" solution to produce alerts and detections.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/into-the-weeds-how-we-run-detonate/image6.png\",alt:\"The policy settings in Elastic Defend integration for Detonate.\",width:\"1440\",height:\"1520\"})}),`\n`,(0,t.jsx)(e.p,{children:\"We cover two use cases with this architecture: we can validate protections (comparing events and alerts produced for different OS versions, agent versions, security artifacts deployed, etc) and collect telemetry for analysis (for fresh samples or novel malware) at the same time. All data collected is kept in a persistent Elastic cluster and is available for our researchers.\"}),`\n`,(0,t.jsx)(e.h2,{id:\"running-in-production\",children:\"Running in production\"}),`\n`,(0,t.jsx)(e.p,{children:\"Recently we completed a full month of running Detonate pipeline in production, under the load of multiple data integrations, serving internal users through UI at the same time. Our record so far is 1034 detonations in a single day, and so far, we haven\\u2019t seen any scalability or reliability issues.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/into-the-weeds-how-we-run-detonate/image4.png\",alt:\"Data from our internal Detonate telemetry, visualized in Kibana.\",width:\"1440\",height:\"1088\"})}),`\n`,(0,t.jsx)(e.p,{children:\"The bulk of the submissions are Windows-specific samples, for now. We are working on increasing our coverage of Linux and macOS as well \\u2013 stay tuned for the research blog posts coming soon!\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/into-the-weeds-how-we-run-detonate/image7.png\",alt:\"Additional visualization types can help us further break down how Detonate is being used.\",width:\"1440\",height:\"1088\"})}),`\n`,(0,t.jsx)(e.p,{children:\"We are constantly improving our support for various file types, making sure the detonation is as close to the intended trigger behavior as possible.\"}),`\n`,(0,t.jsx)(e.p,{children:\"Looking at the detonations from the last month, we see that most of the tasks were completed in under 13 minutes (with a median of 515 seconds). This time includes task data preparation, VM provisioning and cleanup, sample execution, and post-detonation processing.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/into-the-weeds-how-we-run-detonate/image14.jpg\",alt:\"Data from our internal Detonate telemetry, generated using custom Python code.\",width:\"1440\",height:\"953\"})}),`\n`,(0,t.jsx)(e.p,{children:\"These are still early days of the service, so it is normal to see the outliers. Since most of the time in a task is spent waiting for a VM to provision, we can improve the overall execution time by using custom VM images, pre-starting VM instances, and optimizing the startup scripts.\"}),`\n`,(0,t.jsx)(e.h2,{id:\"whats-next\",children:\"What's next?\"}),`\n`,(0,t.jsx)(e.p,{children:\"Now that you see how Detonate works, our next posts will dive into more detailed use cases of Detonate. We\\u2019ll go further into how these detonations turn into protecting more of our users, including right here at Elastic!\"})]})}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 T=k;return v(x);})();\n;return Component;"},"_id":"articles/into-the-weeds-how-we-run-detonate.mdx","_raw":{"sourceFilePath":"articles/into-the-weeds-how-we-run-detonate.mdx","sourceFileName":"into-the-weeds-how-we-run-detonate.mdx","sourceFileDir":"articles","contentType":"mdx","flattenedPath":"articles/into-the-weeds-how-we-run-detonate"},"type":"Article","imageUrl":"/assets/images/into-the-weeds-how-we-run-detonate/photo-edited-02@2x.jpg","readingTime":"10 min read","series":"","url":"/into-the-weeds-how-we-run-detonate","headings":[{"level":2,"title":"Preamble","href":"#preamble"},{"level":2,"title":"Architecture","href":"#architecture"},{"level":3,"title":"API server","href":"#api-server"},{"level":4,"title":"Interacting with the API server - CLI","href":"#interacting-with-the-api-server---cli"},{"level":4,"title":"Interacting with the API server - Web UI","href":"#interacting-with-the-api-server---web-ui"},{"level":4,"title":"Interacting with the API server - HTTP client","href":"#interacting-with-the-api-server---http-client"},{"level":3,"title":"Queues","href":"#queues"},{"level":3,"title":"Workers","href":"#workers"},{"level":2,"title":"Detonations","href":"#detonations"},{"level":3,"title":"VM provisioning","href":"#vm-provisioning"},{"level":3,"title":"Network configuration","href":"#network-configuration"},{"level":3,"title":"Telemetry collection","href":"#telemetry-collection"},{"level":2,"title":"Running in production","href":"#running-in-production"},{"level":2,"title":"What's next?","href":"#whats-next"}],"author":[{"title":"Jessica David","slug":"jessica-david","description":"Principal Data Engineer, Elastic","image":"jessica-david.jpg","body":{"raw":"","code":"var Component=(()=\u003e{var u=Object.create;var r=Object.defineProperty;var g=Object.getOwnPropertyDescriptor;var j=Object.getOwnPropertyNames;var x=Object.getPrototypeOf,l=Object.prototype.hasOwnProperty;var p=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),f=(t,e)=\u003e{for(var n in e)r(t,n,{get:e[n],enumerable:!0})},c=(t,e,n,s)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let i of j(e))!l.call(t,i)\u0026\u0026i!==n\u0026\u0026r(t,i,{get:()=\u003ee[i],enumerable:!(s=g(e,i))||s.enumerable});return t};var _=(t,e,n)=\u003e(n=t!=null?u(x(t)):{},c(e||!t||!t.__esModule?r(n,\"default\",{value:t,enumerable:!0}):n,t)),D=t=\u003ec(r({},\"__esModule\",{value:!0}),t);var d=p((X,o)=\u003e{o.exports=_jsx_runtime});var E={};f(E,{default:()=\u003eC,frontmatter:()=\u003ev});var a=_(d()),v={title:\"Jessica David\",description:\"Principal Data Engineer, Elastic\",slug:\"jessica-david\",image:\"jessica-david.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(E);})();\n;return Component;"},"_id":"authors/jessica-david.mdx","_raw":{"sourceFilePath":"authors/jessica-david.mdx","sourceFileName":"jessica-david.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/jessica-david"},"type":"Author","imageUrl":"/assets/images/authors/jessica-david.jpg","url":"/authors/jessica-david"},{"title":"Sergey Polzunov","slug":"sergey-polzunov","description":"Senior Data Security Data Engineer, Elastic","body":{"raw":"","code":"var Component=(()=\u003e{var l=Object.create;var a=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var f=Object.getPrototypeOf,p=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)a(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 x(e))!p.call(t,o)\u0026\u0026o!==n\u0026\u0026a(t,o,{get:()=\u003ee[o],enumerable:!(i=m(e,o))||i.enumerable});return t};var j=(t,e,n)=\u003e(n=t!=null?l(f(t)):{},s(e||!t||!t.__esModule?a(n,\"default\",{value:t,enumerable:!0}):n,t)),y=t=\u003es(a({},\"__esModule\",{value:!0}),t);var u=_((C,c)=\u003e{c.exports=_jsx_runtime});var v={};d(v,{default:()=\u003eS,frontmatter:()=\u003eD});var r=j(u()),D={title:\"Sergey Polzunov\",description:\"Senior Data Security Data Engineer, Elastic\",slug:\"sergey-polzunov\"};function g(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)(g,t)})):g(t)}var S=M;return y(v);})();\n;return Component;"},"_id":"authors/sergey-polzunov.mdx","_raw":{"sourceFilePath":"authors/sergey-polzunov.mdx","sourceFileName":"sergey-polzunov.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/sergey-polzunov"},"type":"Author","imageUrl":"","url":"/authors/sergey-polzunov"},{"title":"Hez Carty","slug":"hez-carty","description":"Senior Manager, Threat Intelligence Services, Elastic","body":{"raw":"","code":"var Component=(()=\u003e{var m=Object.create;var o=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var g=Object.getOwnPropertyNames;var f=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)o(t,n,{get:e[n],enumerable:!0})},i=(t,e,n,c)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of g(e))!_.call(t,a)\u0026\u0026a!==n\u0026\u0026o(t,a,{get:()=\u003ee[a],enumerable:!(c=x(e,a))||c.enumerable});return t};var p=(t,e,n)=\u003e(n=t!=null?m(f(t)):{},i(e||!t||!t.__esModule?o(n,\"default\",{value:t,enumerable:!0}):n,t)),M=t=\u003ei(o({},\"__esModule\",{value:!0}),t);var u=d((F,s)=\u003e{s.exports=_jsx_runtime});var z={};j(z,{default:()=\u003eC,frontmatter:()=\u003eh});var r=p(u()),h={title:\"Hez Carty\",description:\"Senior Manager, Threat Intelligence Services, Elastic\",slug:\"hez-carty\"};function l(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)(l,t)})):l(t)}var C=y;return M(z);})();\n;return Component;"},"_id":"authors/hez-carty.mdx","_raw":{"sourceFilePath":"authors/hez-carty.mdx","sourceFileName":"hez-carty.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/hez-carty"},"type":"Author","imageUrl":"","url":"/authors/hez-carty"}],"category":[{"title":"Detection science","slug":"detection-science","body":{"raw":"","code":"var Component=(()=\u003e{var x=Object.create;var c=Object.defineProperty;var f=Object.getOwnPropertyDescriptor;var _=Object.getOwnPropertyNames;var d=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)c(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 _(e))!g.call(t,o)\u0026\u0026o!==n\u0026\u0026c(t,o,{get:()=\u003ee[o],enumerable:!(s=f(e,o))||s.enumerable});return t};var p=(t,e,n)=\u003e(n=t!=null?x(d(t)):{},i(e||!t||!t.__esModule?c(n,\"default\",{value:t,enumerable:!0}):n,t)),D=t=\u003ei(c({},\"__esModule\",{value:!0}),t);var u=j((h,a)=\u003e{a.exports=_jsx_runtime});var X={};l(X,{default:()=\u003eF,frontmatter:()=\u003eM});var r=p(u()),M={title:\"Detection science\",slug:\"detection-science\"};function m(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)(m,t)})):m(t)}var F=C;return D(X);})();\n;return Component;"},"_id":"categories/detection-science.mdx","_raw":{"sourceFilePath":"categories/detection-science.mdx","sourceFileName":"detection-science.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/detection-science"},"type":"Category","url":"/categories/detection-science"},{"title":"Tools","slug":"tools","body":{"raw":"","code":"var Component=(()=\u003e{var x=Object.create;var s=Object.defineProperty;var l=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),d=(t,n)=\u003e{for(var e in n)s(t,e,{get:n[e],enumerable:!0})},c=(t,n,e,a)=\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:!(a=l(n,r))||a.enumerable});return t};var p=(t,n,e)=\u003e(e=t!=null?x(_(t)):{},c(n||!t||!t.__esModule?s(e,\"default\",{value:t,enumerable:!0}):e,t)),M=t=\u003ec(s({},\"__esModule\",{value:!0}),t);var i=j((h,u)=\u003e{u.exports=_jsx_runtime});var X={};d(X,{default:()=\u003eF,frontmatter:()=\u003eC});var o=p(i()),C={title:\"Tools\",slug:\"tools\"};function m(t){return(0,o.jsx)(o.Fragment,{})}function D(t={}){let{wrapper:n}=t.components||{};return n?(0,o.jsx)(n,Object.assign({},t,{children:(0,o.jsx)(m,t)})):m(t)}var F=D;return M(X);})();\n;return Component;"},"_id":"categories/tools.mdx","_raw":{"sourceFilePath":"categories/tools.mdx","sourceFileName":"tools.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/tools"},"type":"Category","url":"/categories/tools"},{"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":"Click, Click… Boom! Automating Protections Testing with Detonate","slug":"click-click-boom-automating-protections-testing-with-detonate","date":"2023-05-04","description":"To automate this process and test our protections at scale, we built Detonate, a system that is used by security research engineers to measure the efficacy of our Elastic Security solution in an automated fashion.","image":"blog-thumb-tools-various.jpg","tags":["detonate"],"body":{"raw":"\n## Preamble\n\nImagine you are an Endpoint artifact developer. After you put in the work to ensure protection against conventional shellcode injections or ransomware innovations, how do you know it actually works before you send it out into the world?\n\nFirst, you set up your end-to-end system, which involves setting up several services, the infrastructure, network configuration, and more. Then, you run some malware; the data you collect answers questions about performance and efficacy, and may be an important research resource in the future. After you spend a day testing and gathering your results, you may want to run several hundred hashes over multiple kinds of operating systems and machine types, a daunting task if done entirely manually.\n\nTo automate this process and test our protections at scale, we built Detonate, a system that is used by security research engineers to measure the efficacy of our Elastic Security solution in an automated fashion. Our goal is to have it take security researchers only a couple of clicks to test our protections against malware. (Thus: click, click… boom!)\n\nIn this series of posts, we’ll: - Introduce Detonate and why we built it - Explore how Detonate works and the technical implementation details - Describe case studies on how our teams use it at Elastic - Discuss opening our efficacy testing to the community to help the world protect their data from attack\n\nInterested in other posts on Detonate? Check out [Part 2 - Into The Weeds: How We Run Detonate](https://www.elastic.co/security-labs/into-the-weeds-how-we-run-detonate) where we break down how Detonate works and dive deeper into the technical implementation.\n\n## What is Detonate?\n\nAt a high level, Detonate runs malware and other potentially malicious software in a controlled (i.e., sandboxed) environment where the full suite of Elastic Security capabilities are enabled. Detonate accepts a file hash (usually a SHA256) and performs the following actions:\n\n- Prepares all files needed for detonation, including the malicious file\n- Provisions a virtual machine (VM) instance in a sandboxed environment, with limited connectivity to the outside world\n- Waits until file execution completes; this happens when, for example, an execution result file is found or the VM instance is stopped or older than a task timeout\n- Stops the running VM instance (if necessary) and cleans up the sandboxed environment\n- Generates an event summary based on telemetry and alerts produced during detonation\n\nThe results of these detonations are made available to the team for research and development purposes. By post-processing the logs, events, and alerts collected during detonation, we can enrich them with third-party intelligence and other sources to evaluate the efficacy of new and existing Elastic Security protection features.\n\n## What does it help us with?\n\n### Measuring Efficacy\n\nTo build the best EPP on the market, we have to continuously measure the effectiveness of our product against the latest threats. Detonate is used to execute many tens of thousands of samples every month from our data feeds. Gaps in coverage are automatically identified and used to prioritize improvements to our protections.\n\n### Supporting existing protections\n\nMany of our protections have associated artifacts (such as machine learning models and rule definitions) which receive regular updates. These updates need testing to ensure we identify and remediate regressions before they end up in a user’s environment.\n\nDetonate provides a framework and suite of tools to automate the analysis involved in this testing process. By leveraging a corpus of hashes with known good and bad software, we can validate our protections before they are deployed to users.\n\n### Threat research\n\nSome of our security researchers scour the internet daily for new and emerging threats. By giving them an easy-to-use platform to test malicious software they find in the wild, we better understand how Elastic Security defends against those threats or if we need to update our protections.\n\n### Evaluating new protections\n\nIn addition to testing existing protections, new protections run the risk of adverse interactions with our existing suite of layered capabilities. A new protection may be easily tested on its own, but tests may hide unintended interactions or conflicts with existing protections. Detonate provides a way for us to customize the configuration of the Elastic Stack and individual protections to more easily find and identify such conflicts earlier in development.\n\n## What’s next?\n\nIn this publication, we introduced Detonate \u0026 what we use it for at Elastic. We discussed the benefits it provides our team when assessing the performance of our security artifacts.\n\nNow that you know what it is, we will break down how Detonate works. In our next post, we’ll dive deeper into the technical implementation of Detonate and how we’re able to create this sandboxed environment in practice.\n","code":"var Component=(()=\u003e{var h=Object.create;var a=Object.defineProperty;var u=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var m=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var w=(n,e)=\u003e()=\u003e(e||n((e={exports:{}}).exports,e),e.exports),y=(n,e)=\u003e{for(var i in e)a(n,i,{get:e[i],enumerable:!0})},r=(n,e,i,s)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let o of p(e))!f.call(n,o)\u0026\u0026o!==i\u0026\u0026a(n,o,{get:()=\u003ee[o],enumerable:!(s=u(e,o))||s.enumerable});return n};var g=(n,e,i)=\u003e(i=n!=null?h(m(n)):{},r(e||!n||!n.__esModule?a(i,\"default\",{value:n,enumerable:!0}):i,n)),v=n=\u003er(a({},\"__esModule\",{value:!0}),n);var l=w((j,c)=\u003e{c.exports=_jsx_runtime});var D={};y(D,{default:()=\u003ex,frontmatter:()=\u003eb});var t=g(l()),b={title:\"Click, Click\\u2026 Boom! Automating Protections Testing with Detonate\",slug:\"click-click-boom-automating-protections-testing-with-detonate\",date:\"2023-05-04\",description:\"To automate this process and test our protections at scale, we built Detonate, a system that is used by security research engineers to measure the efficacy of our Elastic Security solution in an automated fashion.\",author:[{slug:\"jessica-david\"},{slug:\"hez-carty\"},{slug:\"sergey-polzunov\"}],image:\"blog-thumb-tools-various.jpg\",category:[{slug:\"tools\"},{slug:\"security-research\"},{slug:\"detection-science\"}],tags:[\"detonate\"]};function d(n){let e=Object.assign({h2:\"h2\",p:\"p\",a:\"a\",ul:\"ul\",li:\"li\",h3:\"h3\"},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:\"Imagine you are an Endpoint artifact developer. After you put in the work to ensure protection against conventional shellcode injections or ransomware innovations, how do you know it actually works before you send it out into the world?\"}),`\n`,(0,t.jsx)(e.p,{children:\"First, you set up your end-to-end system, which involves setting up several services, the infrastructure, network configuration, and more. Then, you run some malware; the data you collect answers questions about performance and efficacy, and may be an important research resource in the future. After you spend a day testing and gathering your results, you may want to run several hundred hashes over multiple kinds of operating systems and machine types, a daunting task if done entirely manually.\"}),`\n`,(0,t.jsx)(e.p,{children:\"To automate this process and test our protections at scale, we built Detonate, a system that is used by security research engineers to measure the efficacy of our Elastic Security solution in an automated fashion. Our goal is to have it take security researchers only a couple of clicks to test our protections against malware. (Thus: click, click\\u2026 boom!)\"}),`\n`,(0,t.jsx)(e.p,{children:\"In this series of posts, we\\u2019ll: - Introduce Detonate and why we built it - Explore how Detonate works and the technical implementation details - Describe case studies on how our teams use it at Elastic - Discuss opening our efficacy testing to the community to help the world protect their data from attack\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"Interested in other posts on Detonate? Check out \",(0,t.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/into-the-weeds-how-we-run-detonate\",rel:\"nofollow\",children:\"Part 2 - Into The Weeds: How We Run Detonate\"}),\" where we break down how Detonate works and dive deeper into the technical implementation.\"]}),`\n`,(0,t.jsx)(e.h2,{id:\"what-is-detonate\",children:\"What is Detonate?\"}),`\n`,(0,t.jsx)(e.p,{children:\"At a high level, Detonate runs malware and other potentially malicious software in a controlled (i.e., sandboxed) environment where the full suite of Elastic Security capabilities are enabled. Detonate accepts a file hash (usually a SHA256) and performs the following actions:\"}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:\"Prepares all files needed for detonation, including the malicious file\"}),`\n`,(0,t.jsx)(e.li,{children:\"Provisions a virtual machine (VM) instance in a sandboxed environment, with limited connectivity to the outside world\"}),`\n`,(0,t.jsx)(e.li,{children:\"Waits until file execution completes; this happens when, for example, an execution result file is found or the VM instance is stopped or older than a task timeout\"}),`\n`,(0,t.jsx)(e.li,{children:\"Stops the running VM instance (if necessary) and cleans up the sandboxed environment\"}),`\n`,(0,t.jsx)(e.li,{children:\"Generates an event summary based on telemetry and alerts produced during detonation\"}),`\n`]}),`\n`,(0,t.jsx)(e.p,{children:\"The results of these detonations are made available to the team for research and development purposes. By post-processing the logs, events, and alerts collected during detonation, we can enrich them with third-party intelligence and other sources to evaluate the efficacy of new and existing Elastic Security protection features.\"}),`\n`,(0,t.jsx)(e.h2,{id:\"what-does-it-help-us-with\",children:\"What does it help us with?\"}),`\n`,(0,t.jsx)(e.h3,{id:\"measuring-efficacy\",children:\"Measuring Efficacy\"}),`\n`,(0,t.jsx)(e.p,{children:\"To build the best EPP on the market, we have to continuously measure the effectiveness of our product against the latest threats. Detonate is used to execute many tens of thousands of samples every month from our data feeds. Gaps in coverage are automatically identified and used to prioritize improvements to our protections.\"}),`\n`,(0,t.jsx)(e.h3,{id:\"supporting-existing-protections\",children:\"Supporting existing protections\"}),`\n`,(0,t.jsx)(e.p,{children:\"Many of our protections have associated artifacts (such as machine learning models and rule definitions) which receive regular updates. These updates need testing to ensure we identify and remediate regressions before they end up in a user\\u2019s environment.\"}),`\n`,(0,t.jsx)(e.p,{children:\"Detonate provides a framework and suite of tools to automate the analysis involved in this testing process. By leveraging a corpus of hashes with known good and bad software, we can validate our protections before they are deployed to users.\"}),`\n`,(0,t.jsx)(e.h3,{id:\"threat-research\",children:\"Threat research\"}),`\n`,(0,t.jsx)(e.p,{children:\"Some of our security researchers scour the internet daily for new and emerging threats. By giving them an easy-to-use platform to test malicious software they find in the wild, we better understand how Elastic Security defends against those threats or if we need to update our protections.\"}),`\n`,(0,t.jsx)(e.h3,{id:\"evaluating-new-protections\",children:\"Evaluating new protections\"}),`\n`,(0,t.jsx)(e.p,{children:\"In addition to testing existing protections, new protections run the risk of adverse interactions with our existing suite of layered capabilities. A new protection may be easily tested on its own, but tests may hide unintended interactions or conflicts with existing protections. Detonate provides a way for us to customize the configuration of the Elastic Stack and individual protections to more easily find and identify such conflicts earlier in development.\"}),`\n`,(0,t.jsx)(e.h2,{id:\"whats-next\",children:\"What\\u2019s next?\"}),`\n`,(0,t.jsx)(e.p,{children:\"In this publication, we introduced Detonate \u0026 what we use it for at Elastic. We discussed the benefits it provides our team when assessing the performance of our security artifacts.\"}),`\n`,(0,t.jsx)(e.p,{children:\"Now that you know what it is, we will break down how Detonate works. In our next post, we\\u2019ll dive deeper into the technical implementation of Detonate and how we\\u2019re able to create this sandboxed environment in practice.\"})]})}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 x=k;return v(D);})();\n;return Component;"},"_id":"articles/click-click-boom-automating-protections-testing-with-detonate.mdx","_raw":{"sourceFilePath":"articles/click-click-boom-automating-protections-testing-with-detonate.mdx","sourceFileName":"click-click-boom-automating-protections-testing-with-detonate.mdx","sourceFileDir":"articles","contentType":"mdx","flattenedPath":"articles/click-click-boom-automating-protections-testing-with-detonate"},"type":"Article","imageUrl":"/assets/images/click-click-boom-automating-protections-testing-with-detonate/blog-thumb-tools-various.jpg","readingTime":"5 min read","series":"","url":"/click-click-boom-automating-protections-testing-with-detonate","headings":[{"level":2,"title":"Preamble","href":"#preamble"},{"level":2,"title":"What is Detonate?","href":"#what-is-detonate"},{"level":2,"title":"What does it help us with?","href":"#what-does-it-help-us-with"},{"level":3,"title":"Measuring Efficacy","href":"#measuring-efficacy"},{"level":3,"title":"Supporting existing protections","href":"#supporting-existing-protections"},{"level":3,"title":"Threat research","href":"#threat-research"},{"level":3,"title":"Evaluating new protections","href":"#evaluating-new-protections"},{"level":2,"title":"What’s next?","href":"#whats-next"}],"author":[{"title":"Jessica David","slug":"jessica-david","description":"Principal Data Engineer, Elastic","image":"jessica-david.jpg","body":{"raw":"","code":"var Component=(()=\u003e{var u=Object.create;var r=Object.defineProperty;var g=Object.getOwnPropertyDescriptor;var j=Object.getOwnPropertyNames;var x=Object.getPrototypeOf,l=Object.prototype.hasOwnProperty;var p=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),f=(t,e)=\u003e{for(var n in e)r(t,n,{get:e[n],enumerable:!0})},c=(t,e,n,s)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let i of j(e))!l.call(t,i)\u0026\u0026i!==n\u0026\u0026r(t,i,{get:()=\u003ee[i],enumerable:!(s=g(e,i))||s.enumerable});return t};var _=(t,e,n)=\u003e(n=t!=null?u(x(t)):{},c(e||!t||!t.__esModule?r(n,\"default\",{value:t,enumerable:!0}):n,t)),D=t=\u003ec(r({},\"__esModule\",{value:!0}),t);var d=p((X,o)=\u003e{o.exports=_jsx_runtime});var E={};f(E,{default:()=\u003eC,frontmatter:()=\u003ev});var a=_(d()),v={title:\"Jessica David\",description:\"Principal Data Engineer, Elastic\",slug:\"jessica-david\",image:\"jessica-david.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(E);})();\n;return Component;"},"_id":"authors/jessica-david.mdx","_raw":{"sourceFilePath":"authors/jessica-david.mdx","sourceFileName":"jessica-david.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/jessica-david"},"type":"Author","imageUrl":"/assets/images/authors/jessica-david.jpg","url":"/authors/jessica-david"},{"title":"Hez Carty","slug":"hez-carty","description":"Senior Manager, Threat Intelligence Services, Elastic","body":{"raw":"","code":"var Component=(()=\u003e{var m=Object.create;var o=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var g=Object.getOwnPropertyNames;var f=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)o(t,n,{get:e[n],enumerable:!0})},i=(t,e,n,c)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of g(e))!_.call(t,a)\u0026\u0026a!==n\u0026\u0026o(t,a,{get:()=\u003ee[a],enumerable:!(c=x(e,a))||c.enumerable});return t};var p=(t,e,n)=\u003e(n=t!=null?m(f(t)):{},i(e||!t||!t.__esModule?o(n,\"default\",{value:t,enumerable:!0}):n,t)),M=t=\u003ei(o({},\"__esModule\",{value:!0}),t);var u=d((F,s)=\u003e{s.exports=_jsx_runtime});var z={};j(z,{default:()=\u003eC,frontmatter:()=\u003eh});var r=p(u()),h={title:\"Hez Carty\",description:\"Senior Manager, Threat Intelligence Services, Elastic\",slug:\"hez-carty\"};function l(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)(l,t)})):l(t)}var C=y;return M(z);})();\n;return Component;"},"_id":"authors/hez-carty.mdx","_raw":{"sourceFilePath":"authors/hez-carty.mdx","sourceFileName":"hez-carty.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/hez-carty"},"type":"Author","imageUrl":"","url":"/authors/hez-carty"},{"title":"Sergey Polzunov","slug":"sergey-polzunov","description":"Senior Data Security Data Engineer, Elastic","body":{"raw":"","code":"var Component=(()=\u003e{var l=Object.create;var a=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var f=Object.getPrototypeOf,p=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)a(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 x(e))!p.call(t,o)\u0026\u0026o!==n\u0026\u0026a(t,o,{get:()=\u003ee[o],enumerable:!(i=m(e,o))||i.enumerable});return t};var j=(t,e,n)=\u003e(n=t!=null?l(f(t)):{},s(e||!t||!t.__esModule?a(n,\"default\",{value:t,enumerable:!0}):n,t)),y=t=\u003es(a({},\"__esModule\",{value:!0}),t);var u=_((C,c)=\u003e{c.exports=_jsx_runtime});var v={};d(v,{default:()=\u003eS,frontmatter:()=\u003eD});var r=j(u()),D={title:\"Sergey Polzunov\",description:\"Senior Data Security Data Engineer, Elastic\",slug:\"sergey-polzunov\"};function g(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)(g,t)})):g(t)}var S=M;return y(v);})();\n;return Component;"},"_id":"authors/sergey-polzunov.mdx","_raw":{"sourceFilePath":"authors/sergey-polzunov.mdx","sourceFileName":"sergey-polzunov.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/sergey-polzunov"},"type":"Author","imageUrl":"","url":"/authors/sergey-polzunov"}],"category":[{"title":"Tools","slug":"tools","body":{"raw":"","code":"var Component=(()=\u003e{var x=Object.create;var s=Object.defineProperty;var l=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),d=(t,n)=\u003e{for(var e in n)s(t,e,{get:n[e],enumerable:!0})},c=(t,n,e,a)=\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:!(a=l(n,r))||a.enumerable});return t};var p=(t,n,e)=\u003e(e=t!=null?x(_(t)):{},c(n||!t||!t.__esModule?s(e,\"default\",{value:t,enumerable:!0}):e,t)),M=t=\u003ec(s({},\"__esModule\",{value:!0}),t);var i=j((h,u)=\u003e{u.exports=_jsx_runtime});var X={};d(X,{default:()=\u003eF,frontmatter:()=\u003eC});var o=p(i()),C={title:\"Tools\",slug:\"tools\"};function m(t){return(0,o.jsx)(o.Fragment,{})}function D(t={}){let{wrapper:n}=t.components||{};return n?(0,o.jsx)(n,Object.assign({},t,{children:(0,o.jsx)(m,t)})):m(t)}var F=D;return M(X);})();\n;return Component;"},"_id":"categories/tools.mdx","_raw":{"sourceFilePath":"categories/tools.mdx","sourceFileName":"tools.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/tools"},"type":"Category","url":"/categories/tools"},{"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":"Detection science","slug":"detection-science","body":{"raw":"","code":"var Component=(()=\u003e{var x=Object.create;var c=Object.defineProperty;var f=Object.getOwnPropertyDescriptor;var _=Object.getOwnPropertyNames;var d=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)c(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 _(e))!g.call(t,o)\u0026\u0026o!==n\u0026\u0026c(t,o,{get:()=\u003ee[o],enumerable:!(s=f(e,o))||s.enumerable});return t};var p=(t,e,n)=\u003e(n=t!=null?x(d(t)):{},i(e||!t||!t.__esModule?c(n,\"default\",{value:t,enumerable:!0}):n,t)),D=t=\u003ei(c({},\"__esModule\",{value:!0}),t);var u=j((h,a)=\u003e{a.exports=_jsx_runtime});var X={};l(X,{default:()=\u003eF,frontmatter:()=\u003eM});var r=p(u()),M={title:\"Detection science\",slug:\"detection-science\"};function m(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)(m,t)})):m(t)}var F=C;return D(X);})();\n;return Component;"},"_id":"categories/detection-science.mdx","_raw":{"sourceFilePath":"categories/detection-science.mdx","sourceFileName":"detection-science.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/detection-science"},"type":"Category","url":"/categories/detection-science"}]},{"title":"Unpacking ICEDID","slug":"unpacking-icedid","date":"2023-05-04","description":"ICEDID is known to pack its payloads using custom file formats and a custom encryption scheme. We are releasing a set of tools to automate the unpacking process and help analysts and the community respond to ICEDID.","image":"photo-edited-07@2x.jpg","subtitle":"A comprehensive tutorial with Elastic Security Labs open source tools","tags":["icedid"],"body":{"raw":"\n## Preamble\n\nICEDID is a malware family [discovered](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 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 several 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\nICEDID is known to pack its payloads using custom file formats and a custom encryption scheme. Following our latest [ICEDID research](https://www.elastic.co/security-labs/thawing-the-permafrost-of-icedid-summary) that covers the GZip variant execution chain.\n\nIn this tutorial, we will introduce these tools by unpacking a recent ICEDID sample starting with downloading a copy of the fake GZip binary:\n\n**Analyzing malware can be dangerous to systems and should only be attempted by experienced professionals in a controlled environment, like an isolated virtual machine or analysis sandbox. Malware can be designed to evade detection and infect other systems, so it's important to take all necessary precautions and use specialized tools to protect yourself and your systems.**\n\n[**54d064799115f302a66220b3d0920c1158608a5ba76277666c4ac532b53e855f**](https://bazaar.abuse.ch/sample/54d064799115f302a66220b3d0920c1158608a5ba76277666c4ac532b53e855f/)\n\n## Environment setup\n\nFor this tutorial, we’re using Windows 10 and Python 3.10.\n\nElastic Security Labs is releasing a set of tools to automate the unpacking process and help analysts and the community respond to ICEDID.\n\n| Script | Description | Compatibility |\n| ----------------------------------------- | ---------------------------------------------------------------- | ------------------------------- |\n| decrypt_file.py | Decrypt ICEDID encrypted file | Windows and others (not tested) |\n| gzip_variant/extract_gzip.py | Extract payloads from ICEDID fake GZip file | Windows and others (not tested) |\n| gzip_variant/extract_payload_from_core.py | Extract and decrypt payloads from the rebuilt ICEDID core binary | Windows and others (not tested) |\n| gzip_variant/load_core.py | Load and execute core custom PE binary | Windows only |\n| gzip_variant/read_configuration.py | Read ICEDID configuration file contained in the fake GZip | Windows and others (not tested) |\n| rebuild_pe.py | Rebuild a PE from ICEDID custom PE file | Windows and others (not tested) |\n\nIn order to use the tools, clone the [Elastic Security Lab release repository](https://github.com/elastic/labs-releases) and install the nightMARE module.\n\n```\ngit clone https://github.com/elastic/labs-releases\ncd labs-release\npip install .\\nightMARE\\\n```\n\n\u003e All tools in this tutorial use the **nightMARE** module, this library implements different algorithms we need for unpacking the various payloads embedded within ICEDID. We’re releasing nightMARE because it is required for this ICEDID analysis, but stay tuned - more to come as we continue to develop and mature this framework.\n\n## Unpacking the fake GZip\n\nThe ICEDID fake GZip is a file that [masquerades](https://attack.mitre.org/techniques/T1036/008/) as a valid GZip file formatted by encapsulating the real data with a [GZip header and footer](https://docs.fileformat.com/compression/gz/).\n\n![GZip header and footer](/assets/images/unpacking-icedid/image20.jpg)\n\nGZip magic bytes appear in red. \nThe GZip header is rendered in green. \nThe dummy filename value is blue.\n\nAfter the GZip header is the true data structure, which we describe below.\n\n![FakeGzip data structure](/assets/images/unpacking-icedid/image19.jpg)\n\nWe will use the **labs-releases\\tools\\icedid\\gzip-variant\\extract_gzip.py** script to unpack this fraudulent GZip.\n\n```\nusage: extract_gzip.py [--help] input output\n\npositional arguments:\n input Input file\n output Output directory\n\noptions:\n -h, --help show this help message and exit\n```\n\nWe'll use extract_gzip.py on the ICEDID sample linked above and store the contents into a folder we created called “ **extract** ” (you can use any existing output folder).\n\n```\npython extract_gzip.py 54d064799115f302a66220b3d0920c1158608a5ba76277666c4ac532b53e855f extract\n\n============================================================\nFake Gzip\n============================================================\nis_dll: True\ncore: UponBetter/license.dat (354282 bytes)\nstage_2: lake_x32.tmp (292352 bytes)\n\nextract\\configuration.bin\nextract\\license.dat\nextract\\lake_x32.tmp\n```\n\nThis script returns three individual files consisting of:\n\n- The encrypted configuration file: **configuration.bin**\n- The encrypted core binary: **license.dat**\n- The persistence loader: **lake_x32.tmp**\n\n![Files extracted from the fake GZip](/assets/images/unpacking-icedid/image11.jpg)\n\n## Decrypting the core binary and configuration files\n\nThe configuration and the core binary we extracted are encrypted using ICEDID’s custom encryption scheme. We can decrypt them with the **labs-releases\\tools\\icedid\\decrypt_file.py** script.\n\n```\nusage: decompress_file.py [--help] input output\n\npositional arguments:\n input Input file\n output Output file\n\noptions:\n -h, --help show this help message and exit\n```\n\nAs depicted here (note that decrypted files can be written to any valid destination):\n\n```\npython .\\decrypt_file.py .\\extract\\license.dat .\\extract\\license.dat.decrypted\n\npython .\\decrypt_file.py .\\extract\\configuration.bin .\\extract\\configuration.bin.decrypted\n```\n\nThe core binary and the configuration are now ready to be processed by additional tools. See the data from the decrypted configuration presented in the following screenshot:\n\n![Hex view of the decrypted configuration file](/assets/images/unpacking-icedid/image17.jpg)\n\n## Reading the configuration\n\nThe configuration file format is presented below.\n\n![Configuration file](/assets/images/unpacking-icedid/image4.png)\n\nThe configuration can be read using the **labs-releases\\tools\\icedid\\gzip-variant\\read_configuration.py** script.\n\n```\nusage: read_configuration.py [--help] input\n\npositional arguments:\n input Input file\n\noptions:\n -h, --help show this help message and exit\n```\n\nWe’ll use the **read_configuration.py** script to read the **configuration.bin.decrypted** file we collected in the previous step.\n\n```\npython .\\gzip-variant\\read_configuration.py .\\extract\\configuration.bin.decrypted\n\n============================================================\nConfiguration\n============================================================\nbotnet_id: 0x3B7D6BA4\nauth_var: 0x00000038\nuri: /news/\ndomains:\n alishaskainz.com\n villageskaier.com\n```\n\nThis configuration contains two C2 domains:\n\n- alishaskainz[.]com\n- villageskaier[.]com\n\nFor this sample, the beaconing URI that ICEDID uses is “ **/news/** ”.\n\n## Rebuilding the core binary for static analysis\n\nICEDID uses a custom PE format to obfuscate its payloads thus defeating static or dynamic analysis tools that expect to deal with a normal Windows executable. The custom PE file format is described below.\n\n![Custom PE file format](/assets/images/unpacking-icedid/image8.jpg)\n\nIf we want to analyze the core binary, for example with [IDA Pro](https://hex-rays.com/IDA-pro/), we need to rebuild it into a valid PE. We use the **labs-releases\\tools\\icedid\\rebuild_pe.py** script.\n\n```\nusage: rebuild_pe.py [--help] [-o OFFSET] input output\n\npositional arguments:\n input Input file\n output Output reconstructed PE\n\noptions:\n -h, --help show this help message and exit\n -o OFFSET, --offset OFFSET\n Offset to real data, skip possible garbage\n```\n\nHowever, when attempting to use **rebuild_pe.py** on the decrypted core binary, **license.dat.decrypted** , we receive the following error message:\n\n```\npython .\\rebuild_pe.py .\\extract\\license.dat.decrypted .\\extract\\core.bin\nTraceback (most recent call last):\n File \"rebuild_pe.py\", line 32, in \u003cmodule\u003e\n main()\n File \"rebuild_pe.py\", line 28, in main\n custom_pe.CustomPE(data).to_pe().write(args.output)\n File \"nightmare\\malware\\icedid\\custom_pe.py\", line 86, in __init__\n raise RuntimeError(\"Failed to parse custom pe\")\nRuntimeError: Failed to parse custom pe\n```\n\nThe subtlety here is that the custom PE data doesn’t always start at the beginning of the file. In this case, for example, if we open the file in a hexadecimal editor like [HxD](https://mh-nexus.de/en/hxd/) we can observe a certain amount of garbage bytes before the actual data.\n\n![Prepended garbage bytes](/assets/images/unpacking-icedid/image14.jpg)\n\nWe know from our research that the size of the garbage is **129** bytes.\n\n![Identifying garbage size](/assets/images/unpacking-icedid/image1.jpg)\n\nWith that in mind, we can skip over the garbage bytes and rebuild the core binary using the **rebuild_pe.py** script using the **“-o 129”** parameter. This time we, fortunately, receive no error message. **core.bin** will be saved to the output directory, **extract** in our example.\n\n```\npython .\\rebuild_pe.py .\\extract\\license.dat.decrypted .\\extract\\core.bin -o 129\n```\n\nThe rebuilt PE object is **not** directly executable but you can statically analyze it using your disassembler of choice.\n\n![IDA view of core.bin](/assets/images/unpacking-icedid/image5.jpg)\n\nWe assigned custom names to the rebuilt binary sections ( **.mare\\{0,1,2,...\\}** ).\n\n![Rebuilt binary section names](/assets/images/unpacking-icedid/image7.jpg)\n\nWe want to credit and thank [Hasherezade’s work](https://github.com/hasherezade/funky_malware_formats/blob/f1cacba4ee347601dceacda04e4de8c699971d29/iced_id_parser/iceid_to_pe.cpp#L10) from which we took inspiration to build this tool.\n\n## Executing the core binary (Windows only)\n\nThe core binary can’t be executed without a custom loader that understands ICEDID’s custom PE format as well as the entry point function prototype.\n\nFrom our research, we know that the entry point expects a structure we refer to as the context structure, which contains ICEDID core and persistence loader paths with its encrypted configuration. The context structure is described below.\n\n![Context structure](/assets/images/unpacking-icedid/image2.jpg)\n\nTo natively execute the core binary we use the **labs-releases\\tools\\icedid\\gzip-variant\\load_core.py** script, but before using it we need to create the **context.json** file that’ll contain all the information needed by this script to build this structure.\n\nFor this sample, we copy the information contained in the fake gzip and we use the path to the encrypted configuration file. We’ve included an example at **gzip_variant/context.json.example**.\n\n![Example configuration file](/assets/images/unpacking-icedid/image3.jpg)\n\nPlease note that **“field_0”** and **“stage_2_export”** values have to be found while reversing the sample.\n\n![Populating values from previous research](/assets/images/unpacking-icedid/image16.jpg)\n\nHere we use values from our previous research as placeholders but we have no guarantee that the sample will work 100%. For example, in this sample, we don’t know if the **#1** ordinal export is the actual entry point of the persistence loader.\n\nWe also reproduce the first stage behavior by creating the **UponBetter** directory and moving the **license.dat** file into it.\n\n![license.dat in the UponBetter directory](/assets/images/unpacking-icedid/image18.jpg)\n\nWe execute the **labs-releases\\tools\\icedid\\gzip_variant\\load_core.py** script using the **decrypted core** binary: **license.dat.decrypted** , the **context.json** file.\n\n**WARNING: The binary is going to be loaded/executed natively by this script, Elastic Security Labs does not take responsibility for any damage to your system. Please execute only within a safe environment.**\n\n```\nusage: load_core.py [--help] [-o OFFSET] core_path ctx_path\n\npositional arguments:\n core_path Core custom PE\n ctx_path Path to json file defining core's context\n\noptions:\n -h, --help show this help message and exit\n -o OFFSET, --offset OFFSET\n Offset to real data, skip possible garbage\n```\n\nBecause we have the same garbage bytes problem as stated in the previous section, we use the **“-o 129”** parameter to skip over the garbage bytes.\n\n```\npython .\\gzip-variant\\load_core.py .\\extract\\license.dat.decrypted .\\gzip-variant\\context.example.json -o 129\n\n============================================================\nCore Loader\n============================================================\nBase address: 0x180000000\nEntrypoint: 0x180001390\n\nPress a key to call entrypoint...\n```\n\nWhen launched, the script will wait for user input before calling the entry point. We can easily attach a debugger to the Python process and set a breakpoint on the ICEDID core entry point (in this example **0x180001390** ).\n\n![Breakpoint set on the ICEDID core entry point](/assets/images/unpacking-icedid/image13.jpg)\n\nOnce the key is pressed, we reach the entry point.\n\n![ICEDID entry point](/assets/images/unpacking-icedid/image15.jpg)\n\nIf we let the binary execute, we see ICEDID threads being created (indicated in the following screenshot).\n\n![ICEDID threads being created](/assets/images/unpacking-icedid/image6.jpg)\n\n## Unpacking and rebuilding payloads from the rebuilt core binary\n\nFor extracting any of the payloads that are embedded inside the core binary, we will use the **labs-releases\\tools\\icedid\\gzip-variant\\extract_payloads_from_core.py** script\n\n```\nusage: extract_payloads_from_core.py [--help] input output\n\npositional arguments:\n input Input file\n output Output directory\n\noptions:\n -h, --help show this help message and exit\n```\n\nWe’ll use this script on the rebuilt core binary.\n\n```\npython .\\gzip-variant\\extract_payloads_from_core.py .\\extract\\core.bin core_extract\n\ncore_extract\\browser_hook_payload_0.cpe\ncore_extract\\browser_hook_payload_1.cpe\n```\n\nFrom here, we output two binaries corresponding to ICEDID’s payloads for web browser hooking capabilities, however, they are still in their custom PE format.\n\n![ICEDID payloads](/assets/images/unpacking-icedid/image10.jpg)\n\nBased on our research, we know that **browser_hook_payload_0.cpe** is the x64 version of the browser hook payload and **browser_hook_payload_1.cpe** is the x86 version.\n\n![Browser hook payload architectures](/assets/images/unpacking-icedid/image12.jpg)\n\nIn order to rebuild them, we use the **rebuild_pe.py** script again, this time there are no garbage bytes to skip over.\n\n```\npython .\\rebuild_pe.py .\\core_extract\\browser_hook_payload_0.cpe .\\core_extract\\browser_hook_payload_0.bin\n\npython .\\rebuild_pe.py .\\core_extract\\browser_hook_payload_1.cpe .\\core_extract\\browser_hook_payload_1.bin\n```\n\nNow we have two PE binaries ( **browser_hook_payload_0.bin** and **browser_hook_payload_1.bin** ) we can further analyze.\n\n![Payloads for further analysis](/assets/images/unpacking-icedid/image9.jpg)\n\nAttentive readers may observe that we have skipped the **VNC server** unpacking from the core binary, a decision we made intentionally. We will release it along with other tools in upcoming research, so stay tuned!\n\n## Conclusion\n\nIn this tutorial we covered ICEDID GZip variant unpacking, starting with the extraction of the fake GZip binary, followed by the reconstruction of the core binary and unpacking its payloads.\n\nICEDID is constantly evolving, and we are going to continue to monitor major changes and update our tooling along with our research. Feel free to [open an issue](https://github.com/elastic/labs-releases/issues) or [send us a message](mailto:threat-notification@elastic.co) if something is broken or doesn’t work as expected.\n\nElastic Security Labs is a team of dedicated researchers and security engineers focused on disrupting adversaries through the publication of detailed detection logic, protections, and applied threat research.\n\nFollow us on [@elasticseclabs](https://twitter.com/elasticseclabs)and visit our research portal for more resources and research.\n\n## References\n\nThe following were referenced throughout the above research:\n\n- [https://www.elastic.co/pdf/elastic-security-labs-thawing-the-permafrost-of-icedid.pdf](https://www.elastic.co/pdf/elastic-security-labs-thawing-the-permafrost-of-icedid.pdf)\n- [https://securityintelligence.com/new-banking-trojan-icedid-discovered-by-ibm-x-force-research/](https://securityintelligence.com/new-banking-trojan-icedid-discovered-by-ibm-x-force-research/)\n- [https://www.justice.gov/opa/pr/emotet-botnet-disrupted-international-cyber-operation](https://www.justice.gov/opa/pr/emotet-botnet-disrupted-international-cyber-operation)\n- [https://malpedia.caad.fkie.fraunhofer.de/details/win.darkvnc](https://malpedia.caad.fkie.fraunhofer.de/details/win.darkvnc)\n- [https://www.cybereason.com/blog/threat-analysis-report-all-paths-lead-to-cobalt-strike-icedid-emotet-and-qbot](https://www.cybereason.com/blog/threat-analysis-report-all-paths-lead-to-cobalt-strike-icedid-emotet-and-qbot)\n- [https://github.com/elastic/labs-releases](https://github.com/elastic/labs-releases)\n- [https://github.com/hasherezade/funky_malware_formats/blob/f1cacba4ee347601dceacda04e4de8c699971d29/iced_id_parser/iceid_to_pe.cpp](https://github.com/hasherezade/funky_malware_formats/blob/f1cacba4ee347601dceacda04e4de8c699971d29/iced_id_parser/iceid_to_pe.cpp)\n- [https://mh-nexus.de/en/hxd/](https://mh-nexus.de/en/hxd/)\n- [https://hex-rays.com/IDA-pro/](https://hex-rays.com/IDA-pro/)\n","code":"var Component=(()=\u003e{var h=Object.create;var a=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var g=Object.getOwnPropertyNames;var u=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)a(n,i,{get:e[i],enumerable:!0})},s=(n,e,i,o)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let r of g(e))!m.call(n,r)\u0026\u0026r!==i\u0026\u0026a(n,r,{get:()=\u003ee[r],enumerable:!(o=p(e,r))||o.enumerable});return n};var y=(n,e,i)=\u003e(i=n!=null?h(u(n)):{},s(e||!n||!n.__esModule?a(i,\"default\",{value:n,enumerable:!0}):i,n)),w=n=\u003es(a({},\"__esModule\",{value:!0}),n);var l=f((D,c)=\u003e{c.exports=_jsx_runtime});var v={};b(v,{default:()=\u003ex,frontmatter:()=\u003e_});var t=y(l()),_={title:\"Unpacking ICEDID\",slug:\"unpacking-icedid\",date:\"2023-05-04\",subtitle:\"A comprehensive tutorial with Elastic Security Labs open source tools\",description:\"ICEDID is known to pack its payloads using custom file formats and a custom encryption scheme. We are releasing a set of tools to automate the unpacking process and help analysts and the community respond to ICEDID.\",author:[{slug:\"cyril-francois\"}],image:\"photo-edited-07@2x.jpg\",category:[{slug:\"tools\"}],tags:[\"icedid\"]};function d(n){let e=Object.assign({h2:\"h2\",p:\"p\",a:\"a\",strong:\"strong\",div:\"div\",table:\"table\",thead:\"thead\",tr:\"tr\",th:\"th\",tbody:\"tbody\",td:\"td\",pre:\"pre\",code:\"code\",blockquote:\"blockquote\",img:\"img\",br:\"br\",ul:\"ul\",li:\"li\"},n.components);return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(e.h2,{id:\"preamble\",children:\"Preamble\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"ICEDID is a malware family \",(0,t.jsx)(e.a,{href:\"https://securityintelligence.com/new-banking-trojan-icedid-discovered-by-ibm-x-force-research/\",rel:\"nofollow\",children:\"discovered\"}),\"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 achieved even more growth since EMOTET\\u2019s temporary \",(0,t.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 several distinct malware families including \",(0,t.jsx)(e.a,{href:\"https://malpedia.caad.fkie.fraunhofer.de/details/win.darkvnc\",rel:\"nofollow\",children:\"DarkVNC\"}),\" and \",(0,t.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,t.jsxs)(e.p,{children:[\"ICEDID is known to pack its payloads using custom file formats and a custom encryption scheme. Following our latest \",(0,t.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/thawing-the-permafrost-of-icedid-summary\",rel:\"nofollow\",children:\"ICEDID research\"}),\" that covers the GZip variant execution chain.\"]}),`\n`,(0,t.jsx)(e.p,{children:\"In this tutorial, we will introduce these tools by unpacking a recent ICEDID sample starting with downloading a copy of the fake GZip binary:\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.strong,{children:\"Analyzing malware can be dangerous to systems and should only be attempted by experienced professionals in a controlled environment, like an isolated virtual machine or analysis sandbox. Malware can be designed to evade detection and infect other systems, so it's important to take all necessary precautions and use specialized tools to protect yourself and your systems.\"})}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.a,{href:\"https://bazaar.abuse.ch/sample/54d064799115f302a66220b3d0920c1158608a5ba76277666c4ac532b53e855f/\",rel:\"nofollow\",children:(0,t.jsx)(e.strong,{children:\"54d064799115f302a66220b3d0920c1158608a5ba76277666c4ac532b53e855f\"})})}),`\n`,(0,t.jsx)(e.h2,{id:\"environment-setup\",children:\"Environment setup\"}),`\n`,(0,t.jsx)(e.p,{children:\"For this tutorial, we\\u2019re using Windows 10 and Python 3.10.\"}),`\n`,(0,t.jsx)(e.p,{children:\"Elastic Security Labs is releasing a set of tools to automate the unpacking process and help analysts and the community respond to ICEDID.\"}),`\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:\"Script\"}),(0,t.jsx)(e.th,{children:\"Description\"}),(0,t.jsx)(e.th,{children:\"Compatibility\"})]})}),(0,t.jsxs)(e.tbody,{children:[(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"decrypt_file.py\"}),(0,t.jsx)(e.td,{children:\"Decrypt ICEDID encrypted file\"}),(0,t.jsx)(e.td,{children:\"Windows and others (not tested)\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"gzip_variant/extract_gzip.py\"}),(0,t.jsx)(e.td,{children:\"Extract payloads from ICEDID fake GZip file\"}),(0,t.jsx)(e.td,{children:\"Windows and others (not tested)\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"gzip_variant/extract_payload_from_core.py\"}),(0,t.jsx)(e.td,{children:\"Extract and decrypt payloads from the rebuilt ICEDID core binary\"}),(0,t.jsx)(e.td,{children:\"Windows and others (not tested)\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"gzip_variant/load_core.py\"}),(0,t.jsx)(e.td,{children:\"Load and execute core custom PE binary\"}),(0,t.jsx)(e.td,{children:\"Windows only\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"gzip_variant/read_configuration.py\"}),(0,t.jsx)(e.td,{children:\"Read ICEDID configuration file contained in the fake GZip\"}),(0,t.jsx)(e.td,{children:\"Windows and others (not tested)\"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:\"rebuild_pe.py\"}),(0,t.jsx)(e.td,{children:\"Rebuild a PE from ICEDID custom PE file\"}),(0,t.jsx)(e.td,{children:\"Windows and others (not tested)\"})]})]})]})}),`\n`,(0,t.jsxs)(e.p,{children:[\"In order to use the tools, clone the \",(0,t.jsx)(e.a,{href:\"https://github.com/elastic/labs-releases\",rel:\"nofollow\",children:\"Elastic Security Lab release repository\"}),\" and install the nightMARE module.\"]}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`git clone https://github.com/elastic/labs-releases\ncd labs-release\npip install .\\\\nightMARE\\\\\n`})}),`\n`,(0,t.jsxs)(e.blockquote,{children:[`\n`,(0,t.jsxs)(e.p,{children:[\"All tools in this tutorial use the \",(0,t.jsx)(e.strong,{children:\"nightMARE\"}),\" module, this library implements different algorithms we need for unpacking the various payloads embedded within ICEDID. We\\u2019re releasing nightMARE because it is required for this ICEDID analysis, but stay tuned - more to come as we continue to develop and mature this framework.\"]}),`\n`]}),`\n`,(0,t.jsx)(e.h2,{id:\"unpacking-the-fake-gzip\",children:\"Unpacking the fake GZip\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"The ICEDID fake GZip is a file that \",(0,t.jsx)(e.a,{href:\"https://attack.mitre.org/techniques/T1036/008/\",rel:\"nofollow\",children:\"masquerades\"}),\" as a valid GZip file formatted by encapsulating the real data with a \",(0,t.jsx)(e.a,{href:\"https://docs.fileformat.com/compression/gz/\",rel:\"nofollow\",children:\"GZip header and footer\"}),\".\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/unpacking-icedid/image20.jpg\",alt:\"GZip header and footer\",width:\"609\",height:\"56\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"GZip magic bytes appear in red.\",(0,t.jsx)(e.br,{}),`\n`,\"The GZip header is rendered in green.\",(0,t.jsx)(e.br,{}),`\n`,\"The dummy filename value is blue.\"]}),`\n`,(0,t.jsx)(e.p,{children:\"After the GZip header is the true data structure, which we describe below.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/unpacking-icedid/image19.jpg\",alt:\"FakeGzip data structure\",width:\"344\",height:\"227\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"We will use the \",(0,t.jsx)(e.strong,{children:\"labs-releases\\\\tools\\\\icedid\\\\gzip-variant\\\\extract_gzip.py\"}),\" script to unpack this fraudulent GZip.\"]}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`usage: extract_gzip.py [--help] input output\n\npositional arguments:\n input Input file\n output Output directory\n\noptions:\n -h, --help show this help message and exit\n`})}),`\n`,(0,t.jsxs)(e.p,{children:[\"We'll use extract_gzip.py on the ICEDID sample linked above and store the contents into a folder we created called \\u201C \",(0,t.jsx)(e.strong,{children:\"extract\"}),\" \\u201D (you can use any existing output folder).\"]}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`python extract_gzip.py 54d064799115f302a66220b3d0920c1158608a5ba76277666c4ac532b53e855f extract\n\n============================================================\nFake Gzip\n============================================================\nis_dll: True\ncore: UponBetter/license.dat (354282 bytes)\nstage_2: lake_x32.tmp (292352 bytes)\n\nextract\\\\configuration.bin\nextract\\\\license.dat\nextract\\\\lake_x32.tmp\n`})}),`\n`,(0,t.jsx)(e.p,{children:\"This script returns three individual files consisting of:\"}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsxs)(e.li,{children:[\"The encrypted configuration file: \",(0,t.jsx)(e.strong,{children:\"configuration.bin\"})]}),`\n`,(0,t.jsxs)(e.li,{children:[\"The encrypted core binary: \",(0,t.jsx)(e.strong,{children:\"license.dat\"})]}),`\n`,(0,t.jsxs)(e.li,{children:[\"The persistence loader: \",(0,t.jsx)(e.strong,{children:\"lake_x32.tmp\"})]}),`\n`]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/unpacking-icedid/image11.jpg\",alt:\"Files extracted from the fake GZip\",width:\"696\",height:\"146\"})}),`\n`,(0,t.jsx)(e.h2,{id:\"decrypting-the-core-binary-and-configuration-files\",children:\"Decrypting the core binary and configuration files\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"The configuration and the core binary we extracted are encrypted using ICEDID\\u2019s custom encryption scheme. We can decrypt them with the \",(0,t.jsx)(e.strong,{children:\"labs-releases\\\\tools\\\\icedid\\\\decrypt_file.py\"}),\" script.\"]}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`usage: decompress_file.py [--help] input output\n\npositional arguments:\n input Input file\n output Output file\n\noptions:\n -h, --help show this help message and exit\n`})}),`\n`,(0,t.jsx)(e.p,{children:\"As depicted here (note that decrypted files can be written to any valid destination):\"}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`python .\\\\decrypt_file.py .\\\\extract\\\\license.dat .\\\\extract\\\\license.dat.decrypted\n\npython .\\\\decrypt_file.py .\\\\extract\\\\configuration.bin .\\\\extract\\\\configuration.bin.decrypted\n`})}),`\n`,(0,t.jsx)(e.p,{children:\"The core binary and the configuration are now ready to be processed by additional tools. See the data from the decrypted configuration presented in the following screenshot:\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/unpacking-icedid/image17.jpg\",alt:\"Hex view of the decrypted configuration file\",width:\"598\",height:\"244\"})}),`\n`,(0,t.jsx)(e.h2,{id:\"reading-the-configuration\",children:\"Reading the configuration\"}),`\n`,(0,t.jsx)(e.p,{children:\"The configuration file format is presented below.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/unpacking-icedid/image4.png\",alt:\"Configuration file\",width:\"210\",height:\"211\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"The configuration can be read using the \",(0,t.jsx)(e.strong,{children:\"labs-releases\\\\tools\\\\icedid\\\\gzip-variant\\\\read_configuration.py\"}),\" script.\"]}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`usage: read_configuration.py [--help] input\n\npositional arguments:\n input Input file\n\noptions:\n -h, --help show this help message and exit\n`})}),`\n`,(0,t.jsxs)(e.p,{children:[\"We\\u2019ll use the \",(0,t.jsx)(e.strong,{children:\"read_configuration.py\"}),\" script to read the \",(0,t.jsx)(e.strong,{children:\"configuration.bin.decrypted\"}),\" file we collected in the previous step.\"]}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`python .\\\\gzip-variant\\\\read_configuration.py .\\\\extract\\\\configuration.bin.decrypted\n\n============================================================\nConfiguration\n============================================================\nbotnet_id: 0x3B7D6BA4\nauth_var: 0x00000038\nuri: /news/\ndomains:\n alishaskainz.com\n villageskaier.com\n`})}),`\n`,(0,t.jsx)(e.p,{children:\"This configuration contains two C2 domains:\"}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsx)(e.li,{children:\"alishaskainz[.]com\"}),`\n`,(0,t.jsx)(e.li,{children:\"villageskaier[.]com\"}),`\n`]}),`\n`,(0,t.jsxs)(e.p,{children:[\"For this sample, the beaconing URI that ICEDID uses is \\u201C \",(0,t.jsx)(e.strong,{children:\"/news/\"}),\" \\u201D.\"]}),`\n`,(0,t.jsx)(e.h2,{id:\"rebuilding-the-core-binary-for-static-analysis\",children:\"Rebuilding the core binary for static analysis\"}),`\n`,(0,t.jsx)(e.p,{children:\"ICEDID uses a custom PE format to obfuscate its payloads thus defeating static or dynamic analysis tools that expect to deal with a normal Windows executable. The custom PE file format is described below.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/unpacking-icedid/image8.jpg\",alt:\"Custom PE file format\",width:\"277\",height:\"343\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"If we want to analyze the core binary, for example with \",(0,t.jsx)(e.a,{href:\"https://hex-rays.com/IDA-pro/\",rel:\"nofollow\",children:\"IDA Pro\"}),\", we need to rebuild it into a valid PE. We use the \",(0,t.jsx)(e.strong,{children:\"labs-releases\\\\tools\\\\icedid\\\\rebuild_pe.py\"}),\" script.\"]}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`usage: rebuild_pe.py [--help] [-o OFFSET] input output\n\npositional arguments:\n input Input file\n output Output reconstructed PE\n\noptions:\n -h, --help show this help message and exit\n -o OFFSET, --offset OFFSET\n Offset to real data, skip possible garbage\n`})}),`\n`,(0,t.jsxs)(e.p,{children:[\"However, when attempting to use \",(0,t.jsx)(e.strong,{children:\"rebuild_pe.py\"}),\" on the decrypted core binary, \",(0,t.jsx)(e.strong,{children:\"license.dat.decrypted\"}),\" , we receive the following error message:\"]}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`python .\\\\rebuild_pe.py .\\\\extract\\\\license.dat.decrypted .\\\\extract\\\\core.bin\nTraceback (most recent call last):\n File \"rebuild_pe.py\", line 32, in \u003cmodule\u003e\n main()\n File \"rebuild_pe.py\", line 28, in main\n custom_pe.CustomPE(data).to_pe().write(args.output)\n File \"nightmare\\\\malware\\\\icedid\\\\custom_pe.py\", line 86, in __init__\n raise RuntimeError(\"Failed to parse custom pe\")\nRuntimeError: Failed to parse custom pe\n`})}),`\n`,(0,t.jsxs)(e.p,{children:[\"The subtlety here is that the custom PE data doesn\\u2019t always start at the beginning of the file. In this case, for example, if we open the file in a hexadecimal editor like \",(0,t.jsx)(e.a,{href:\"https://mh-nexus.de/en/hxd/\",rel:\"nofollow\",children:\"HxD\"}),\" we can observe a certain amount of garbage bytes before the actual data.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/unpacking-icedid/image14.jpg\",alt:\"Prepended garbage bytes\",width:\"632\",height:\"168\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"We know from our research that the size of the garbage is \",(0,t.jsx)(e.strong,{children:\"129\"}),\" bytes.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/unpacking-icedid/image1.jpg\",alt:\"Identifying garbage size\",width:\"282\",height:\"62\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"With that in mind, we can skip over the garbage bytes and rebuild the core binary using the \",(0,t.jsx)(e.strong,{children:\"rebuild_pe.py\"}),\" script using the \",(0,t.jsx)(e.strong,{children:\"\\u201C-o 129\\u201D\"}),\" parameter. This time we, fortunately, receive no error message. \",(0,t.jsx)(e.strong,{children:\"core.bin\"}),\" will be saved to the output directory, \",(0,t.jsx)(e.strong,{children:\"extract\"}),\" in our example.\"]}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`python .\\\\rebuild_pe.py .\\\\extract\\\\license.dat.decrypted .\\\\extract\\\\core.bin -o 129\n`})}),`\n`,(0,t.jsxs)(e.p,{children:[\"The rebuilt PE object is \",(0,t.jsx)(e.strong,{children:\"not\"}),\" directly executable but you can statically analyze it using your disassembler of choice.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/unpacking-icedid/image5.jpg\",alt:\"IDA view of core.bin\",width:\"1227\",height:\"505\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"We assigned custom names to the rebuilt binary sections ( \",(0,t.jsx)(e.strong,{children:\".mare{0,1,2,...}\"}),\" ).\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/unpacking-icedid/image7.jpg\",alt:\"Rebuilt binary section names\",width:\"506\",height:\"143\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"We want to credit and thank \",(0,t.jsx)(e.a,{href:\"https://github.com/hasherezade/funky_malware_formats/blob/f1cacba4ee347601dceacda04e4de8c699971d29/iced_id_parser/iceid_to_pe.cpp#L10\",rel:\"nofollow\",children:\"Hasherezade\\u2019s work\"}),\" from which we took inspiration to build this tool.\"]}),`\n`,(0,t.jsx)(e.h2,{id:\"executing-the-core-binary-windows-only\",children:\"Executing the core binary (Windows only)\"}),`\n`,(0,t.jsx)(e.p,{children:\"The core binary can\\u2019t be executed without a custom loader that understands ICEDID\\u2019s custom PE format as well as the entry point function prototype.\"}),`\n`,(0,t.jsx)(e.p,{children:\"From our research, we know that the entry point expects a structure we refer to as the context structure, which contains ICEDID core and persistence loader paths with its encrypted configuration. The context structure is described below.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/unpacking-icedid/image2.jpg\",alt:\"Context structure\",width:\"286\",height:\"246\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"To natively execute the core binary we use the \",(0,t.jsx)(e.strong,{children:\"labs-releases\\\\tools\\\\icedid\\\\gzip-variant\\\\load_core.py\"}),\" script, but before using it we need to create the \",(0,t.jsx)(e.strong,{children:\"context.json\"}),\" file that\\u2019ll contain all the information needed by this script to build this structure.\"]}),`\n`,(0,t.jsxs)(e.p,{children:[\"For this sample, we copy the information contained in the fake gzip and we use the path to the encrypted configuration file. We\\u2019ve included an example at \",(0,t.jsx)(e.strong,{children:\"gzip_variant/context.json.example\"}),\".\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/unpacking-icedid/image3.jpg\",alt:\"Example configuration file\",width:\"691\",height:\"173\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"Please note that \",(0,t.jsx)(e.strong,{children:\"\\u201Cfield_0\\u201D\"}),\" and \",(0,t.jsx)(e.strong,{children:\"\\u201Cstage_2_export\\u201D\"}),\" values have to be found while reversing the sample.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/unpacking-icedid/image16.jpg\",alt:\"Populating values from previous research\",width:\"465\",height:\"107\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"Here we use values from our previous research as placeholders but we have no guarantee that the sample will work 100%. For example, in this sample, we don\\u2019t know if the \",(0,t.jsx)(e.strong,{children:\"#1\"}),\" ordinal export is the actual entry point of the persistence loader.\"]}),`\n`,(0,t.jsxs)(e.p,{children:[\"We also reproduce the first stage behavior by creating the \",(0,t.jsx)(e.strong,{children:\"UponBetter\"}),\" directory and moving the \",(0,t.jsx)(e.strong,{children:\"license.dat\"}),\" file into it.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/unpacking-icedid/image18.jpg\",alt:\"license.dat in the UponBetter directory\",width:\"251\",height:\"104\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"We execute the \",(0,t.jsx)(e.strong,{children:\"labs-releases\\\\tools\\\\icedid\\\\gzip_variant\\\\load_core.py\"}),\" script using the \",(0,t.jsx)(e.strong,{children:\"decrypted core\"}),\" binary: \",(0,t.jsx)(e.strong,{children:\"license.dat.decrypted\"}),\" , the \",(0,t.jsx)(e.strong,{children:\"context.json\"}),\" file.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.strong,{children:\"WARNING: The binary is going to be loaded/executed natively by this script, Elastic Security Labs does not take responsibility for any damage to your system. Please execute only within a safe environment.\"})}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`usage: load_core.py [--help] [-o OFFSET] core_path ctx_path\n\npositional arguments:\n core_path Core custom PE\n ctx_path Path to json file defining core's context\n\noptions:\n -h, --help show this help message and exit\n -o OFFSET, --offset OFFSET\n Offset to real data, skip possible garbage\n`})}),`\n`,(0,t.jsxs)(e.p,{children:[\"Because we have the same garbage bytes problem as stated in the previous section, we use the \",(0,t.jsx)(e.strong,{children:\"\\u201C-o 129\\u201D\"}),\" parameter to skip over the garbage bytes.\"]}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`python .\\\\gzip-variant\\\\load_core.py .\\\\extract\\\\license.dat.decrypted .\\\\gzip-variant\\\\context.example.json -o 129\n\n============================================================\nCore Loader\n============================================================\nBase address: 0x180000000\nEntrypoint: 0x180001390\n\nPress a key to call entrypoint...\n`})}),`\n`,(0,t.jsxs)(e.p,{children:[\"When launched, the script will wait for user input before calling the entry point. We can easily attach a debugger to the Python process and set a breakpoint on the ICEDID core entry point (in this example \",(0,t.jsx)(e.strong,{children:\"0x180001390\"}),\" ).\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/unpacking-icedid/image13.jpg\",alt:\"Breakpoint set on the ICEDID core entry point\",width:\"692\",height:\"192\"})}),`\n`,(0,t.jsx)(e.p,{children:\"Once the key is pressed, we reach the entry point.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/unpacking-icedid/image15.jpg\",alt:\"ICEDID entry point\",width:\"589\",height:\"84\"})}),`\n`,(0,t.jsx)(e.p,{children:\"If we let the binary execute, we see ICEDID threads being created (indicated in the following screenshot).\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/unpacking-icedid/image6.jpg\",alt:\"ICEDID threads being created\",width:\"436\",height:\"95\"})}),`\n`,(0,t.jsx)(e.h2,{id:\"unpacking-and-rebuilding-payloads-from-the-rebuilt-core-binary\",children:\"Unpacking and rebuilding payloads from the rebuilt core binary\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"For extracting any of the payloads that are embedded inside the core binary, we will use the \",(0,t.jsx)(e.strong,{children:\"labs-releases\\\\tools\\\\icedid\\\\gzip-variant\\\\extract_payloads_from_core.py\"}),\" script\"]}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`usage: extract_payloads_from_core.py [--help] input output\n\npositional arguments:\n input Input file\n output Output directory\n\noptions:\n -h, --help show this help message and exit\n`})}),`\n`,(0,t.jsx)(e.p,{children:\"We\\u2019ll use this script on the rebuilt core binary.\"}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`python .\\\\gzip-variant\\\\extract_payloads_from_core.py .\\\\extract\\\\core.bin core_extract\n\ncore_extract\\\\browser_hook_payload_0.cpe\ncore_extract\\\\browser_hook_payload_1.cpe\n`})}),`\n`,(0,t.jsx)(e.p,{children:\"From here, we output two binaries corresponding to ICEDID\\u2019s payloads for web browser hooking capabilities, however, they are still in their custom PE format.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/unpacking-icedid/image10.jpg\",alt:\"ICEDID payloads\",width:\"679\",height:\"125\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"Based on our research, we know that \",(0,t.jsx)(e.strong,{children:\"browser_hook_payload_0.cpe\"}),\" is the x64 version of the browser hook payload and \",(0,t.jsx)(e.strong,{children:\"browser_hook_payload_1.cpe\"}),\" is the x86 version.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/unpacking-icedid/image12.jpg\",alt:\"Browser hook payload architectures\",width:\"500\",height:\"153\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"In order to rebuild them, we use the \",(0,t.jsx)(e.strong,{children:\"rebuild_pe.py\"}),\" script again, this time there are no garbage bytes to skip over.\"]}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`python .\\\\rebuild_pe.py .\\\\core_extract\\\\browser_hook_payload_0.cpe .\\\\core_extract\\\\browser_hook_payload_0.bin\n\npython .\\\\rebuild_pe.py .\\\\core_extract\\\\browser_hook_payload_1.cpe .\\\\core_extract\\\\browser_hook_payload_1.bin\n`})}),`\n`,(0,t.jsxs)(e.p,{children:[\"Now we have two PE binaries ( \",(0,t.jsx)(e.strong,{children:\"browser_hook_payload_0.bin\"}),\" and \",(0,t.jsx)(e.strong,{children:\"browser_hook_payload_1.bin\"}),\" ) we can further analyze.\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/unpacking-icedid/image9.jpg\",alt:\"Payloads for further analysis\",width:\"614\",height:\"176\"})}),`\n`,(0,t.jsxs)(e.p,{children:[\"Attentive readers may observe that we have skipped the \",(0,t.jsx)(e.strong,{children:\"VNC server\"}),\" unpacking from the core binary, a decision we made intentionally. We will release it along with other tools in upcoming research, so stay tuned!\"]}),`\n`,(0,t.jsx)(e.h2,{id:\"conclusion\",children:\"Conclusion\"}),`\n`,(0,t.jsx)(e.p,{children:\"In this tutorial we covered ICEDID GZip variant unpacking, starting with the extraction of the fake GZip binary, followed by the reconstruction of the core binary and unpacking its payloads.\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"ICEDID is constantly evolving, and we are going to continue to monitor major changes and update our tooling along with our research. Feel free to \",(0,t.jsx)(e.a,{href:\"https://github.com/elastic/labs-releases/issues\",rel:\"nofollow\",children:\"open an issue\"}),\" or \",(0,t.jsx)(e.a,{href:\"mailto:threat-notification@elastic.co\",children:\"send us a message\"}),\" if something is broken or doesn\\u2019t work as expected.\"]}),`\n`,(0,t.jsx)(e.p,{children:\"Elastic Security Labs is a team of dedicated researchers and security engineers focused on disrupting adversaries through the publication of detailed detection logic, protections, and applied threat research.\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"Follow us on \",(0,t.jsx)(e.a,{href:\"https://twitter.com/elasticseclabs\",rel:\"nofollow\",children:\"@elasticseclabs\"}),\"and visit our research portal for more resources and research.\"]}),`\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://www.elastic.co/pdf/elastic-security-labs-thawing-the-permafrost-of-icedid.pdf\",rel:\"nofollow\",children:\"https://www.elastic.co/pdf/elastic-security-labs-thawing-the-permafrost-of-icedid.pdf\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://securityintelligence.com/new-banking-trojan-icedid-discovered-by-ibm-x-force-research/\",rel:\"nofollow\",children:\"https://securityintelligence.com/new-banking-trojan-icedid-discovered-by-ibm-x-force-research/\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://www.justice.gov/opa/pr/emotet-botnet-disrupted-international-cyber-operation\",rel:\"nofollow\",children:\"https://www.justice.gov/opa/pr/emotet-botnet-disrupted-international-cyber-operation\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://malpedia.caad.fkie.fraunhofer.de/details/win.darkvnc\",rel:\"nofollow\",children:\"https://malpedia.caad.fkie.fraunhofer.de/details/win.darkvnc\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.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:\"https://www.cybereason.com/blog/threat-analysis-report-all-paths-lead-to-cobalt-strike-icedid-emotet-and-qbot\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://github.com/elastic/labs-releases\",rel:\"nofollow\",children:\"https://github.com/elastic/labs-releases\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://github.com/hasherezade/funky_malware_formats/blob/f1cacba4ee347601dceacda04e4de8c699971d29/iced_id_parser/iceid_to_pe.cpp\",rel:\"nofollow\",children:\"https://github.com/hasherezade/funky_malware_formats/blob/f1cacba4ee347601dceacda04e4de8c699971d29/iced_id_parser/iceid_to_pe.cpp\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://mh-nexus.de/en/hxd/\",rel:\"nofollow\",children:\"https://mh-nexus.de/en/hxd/\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://hex-rays.com/IDA-pro/\",rel:\"nofollow\",children:\"https://hex-rays.com/IDA-pro/\"})}),`\n`]})]})}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 x=k;return w(v);})();\n;return Component;"},"_id":"articles/unpacking-icedid.mdx","_raw":{"sourceFilePath":"articles/unpacking-icedid.mdx","sourceFileName":"unpacking-icedid.mdx","sourceFileDir":"articles","contentType":"mdx","flattenedPath":"articles/unpacking-icedid"},"type":"Article","imageUrl":"/assets/images/unpacking-icedid/photo-edited-07@2x.jpg","readingTime":"14 min read","series":"","url":"/unpacking-icedid","headings":[{"level":2,"title":"Preamble","href":"#preamble"},{"level":2,"title":"Environment setup","href":"#environment-setup"},{"level":2,"title":"Unpacking the fake GZip","href":"#unpacking-the-fake-gzip"},{"level":2,"title":"Decrypting the core binary and configuration files","href":"#decrypting-the-core-binary-and-configuration-files"},{"level":2,"title":"Reading the configuration","href":"#reading-the-configuration"},{"level":2,"title":"Rebuilding the core binary for static analysis","href":"#rebuilding-the-core-binary-for-static-analysis"},{"level":2,"title":"Executing the core binary (Windows only)","href":"#executing-the-core-binary-windows-only"},{"level":2,"title":"Unpacking and rebuilding payloads from the rebuilt core binary","href":"#unpacking-and-rebuilding-payloads-from-the-rebuilt-core-binary"},{"level":2,"title":"Conclusion","href":"#conclusion"},{"level":2,"title":"References","href":"#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"}],"category":[{"title":"Tools","slug":"tools","body":{"raw":"","code":"var Component=(()=\u003e{var x=Object.create;var s=Object.defineProperty;var l=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),d=(t,n)=\u003e{for(var e in n)s(t,e,{get:n[e],enumerable:!0})},c=(t,n,e,a)=\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:!(a=l(n,r))||a.enumerable});return t};var p=(t,n,e)=\u003e(e=t!=null?x(_(t)):{},c(n||!t||!t.__esModule?s(e,\"default\",{value:t,enumerable:!0}):e,t)),M=t=\u003ec(s({},\"__esModule\",{value:!0}),t);var i=j((h,u)=\u003e{u.exports=_jsx_runtime});var X={};d(X,{default:()=\u003eF,frontmatter:()=\u003eC});var o=p(i()),C={title:\"Tools\",slug:\"tools\"};function m(t){return(0,o.jsx)(o.Fragment,{})}function D(t={}){let{wrapper:n}=t.components||{};return n?(0,o.jsx)(n,Object.assign({},t,{children:(0,o.jsx)(m,t)})):m(t)}var F=D;return M(X);})();\n;return Component;"},"_id":"categories/tools.mdx","_raw":{"sourceFilePath":"categories/tools.mdx","sourceFileName":"tools.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/tools"},"type":"Category","url":"/categories/tools"}]},{"title":"NETWIRE Configuration Extractor","slug":"netwire-configuration-extractor","date":"2023-01-27","description":"Python script to extract the configuration from NETWIRE samples.","image":"tools-image.jpg","subtitle":"Configuration extraction tool for the NETWIRE malware.","tags":["netwire","ref9965"],"body":{"raw":"\nPython script to extract the payload from NETWIRE samples.\n\n[Download netwire-configuration-extractor.tar.gz](https://assets.contentstack.io/v3/assets/bltefdd0b53724fa2ce/bltdcef1d05d2077d05/63d43627c31a7126813ff8b6/netwire-configuration-extractor.tar.gz)\n\n\u003e For information on the NETWIRE malware check out the following resources:\n\u003e\n\u003e - [NETWIRE Dynamic Configuration Extraction](https://www.elastic.co/security-labs/netwire-dynamic-configuration-extraction)\n\n## Getting started\n\n### Docker\n\nThe recommended and easiest way to get going is to use Docker. From the directory this README is in, you can build a local container.\n\n```\ndocker build . -t netwire_loader_config_extractor\n```\n\nThen we run the container with the **-v** flag to map a host directory to the docker container directory.\n\n```\ndocker run -ti --rm -v $(pwd)/data:/data netwire_loader_config_extractor:latest --help\n```\n\n### Running it locally\n\nAs mentioned above, Docker is the recommended approach to running this project, however you can also run this locally. This project uses [Poetry](https://python-poetry.org/) to manage dependencies, testing, and metadata. If you have Poetry installed already, from this directory, you can simply run the following commands to run the tool. This will setup a virtual environment, install the dependencies, activate the virtual environment, and run the console script.\n\n```\npoetry lock\npoetry install\npoetry shell\nnetwire-config-extractor --help\n```\n\n## Usage\n\nAll samples need to be unpacked prior to execution extraction attempts.\n\nOur extractor takes either a directory of samples with **-d** option or **-f** for a single sample and then can output parts of the configuration of note, specifically:\n\n- **-k** : extract the encryption keys\n- **-c** : extract the C2 information\n- **-s** : extract the wide-character strings\n- **-a** : extract the ASCII character strings\n\n```\ndocker run -ti --rm -v $(pwd)/data:/data netwire_loader_config_extractor:latest -d \"C:\\tmp\\samples\"\n```\n\n![NETWIRE configuration extractor](/assets/images/netwire-configuration-extractor/image6.jpg)\n\nYou can collect the extracted configurations from the directory you set when running the extractor.\n","code":"var Component=(()=\u003e{var h=Object.create;var i=Object.defineProperty;var g=Object.getOwnPropertyDescriptor;var u=Object.getOwnPropertyNames;var p=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var m=(n,e)=\u003e()=\u003e(e||n((e={exports:{}}).exports,e),e.exports),y=(n,e)=\u003e{for(var r in e)i(n,r,{get:e[r],enumerable:!0})},a=(n,e,r,c)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let o of u(e))!f.call(n,o)\u0026\u0026o!==r\u0026\u0026i(n,o,{get:()=\u003ee[o],enumerable:!(c=g(e,o))||c.enumerable});return n};var w=(n,e,r)=\u003e(r=n!=null?h(p(n)):{},a(e||!n||!n.__esModule?i(r,\"default\",{value:n,enumerable:!0}):r,n)),x=n=\u003ea(i({},\"__esModule\",{value:!0}),n);var s=m((j,l)=\u003e{l.exports=_jsx_runtime});var _={};y(_,{default:()=\u003eb,frontmatter:()=\u003ek});var t=w(s()),k={title:\"NETWIRE Configuration Extractor\",slug:\"netwire-configuration-extractor\",date:\"2023-01-27\",subtitle:\"Configuration extraction tool for the NETWIRE malware.\",description:\"Python script to extract the configuration from NETWIRE samples.\",author:[{slug:\"elastic-security-labs\"}],image:\"tools-image.jpg\",category:[{slug:\"tools\"}],tags:[\"netwire\",\"ref9965\"]};function d(n){let e=Object.assign({p:\"p\",a:\"a\",blockquote:\"blockquote\",ul:\"ul\",li:\"li\",h2:\"h2\",h3:\"h3\",pre:\"pre\",code:\"code\",strong:\"strong\",img:\"img\"},n.components);return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(e.p,{children:\"Python script to extract the payload from NETWIRE samples.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.a,{href:\"https://assets.contentstack.io/v3/assets/bltefdd0b53724fa2ce/bltdcef1d05d2077d05/63d43627c31a7126813ff8b6/netwire-configuration-extractor.tar.gz\",rel:\"nofollow\",children:\"Download netwire-configuration-extractor.tar.gz\"})}),`\n`,(0,t.jsxs)(e.blockquote,{children:[`\n`,(0,t.jsx)(e.p,{children:\"For information on the NETWIRE malware check out the following resources:\"}),`\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/netwire-dynamic-configuration-extraction\",rel:\"nofollow\",children:\"NETWIRE Dynamic Configuration Extraction\"})}),`\n`]}),`\n`]}),`\n`,(0,t.jsx)(e.h2,{id:\"getting-started\",children:\"Getting started\"}),`\n`,(0,t.jsx)(e.h3,{id:\"docker\",children:\"Docker\"}),`\n`,(0,t.jsx)(e.p,{children:\"The recommended and easiest way to get going is to use Docker. From the directory this README is in, you can build a local container.\"}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`docker build . -t netwire_loader_config_extractor\n`})}),`\n`,(0,t.jsxs)(e.p,{children:[\"Then we run the container with the \",(0,t.jsx)(e.strong,{children:\"-v\"}),\" flag to map a host directory to the docker container directory.\"]}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`docker run -ti --rm -v $(pwd)/data:/data netwire_loader_config_extractor:latest --help\n`})}),`\n`,(0,t.jsx)(e.h3,{id:\"running-it-locally\",children:\"Running it locally\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"As mentioned above, Docker is the recommended approach to running this project, however you can also run this locally. This project uses \",(0,t.jsx)(e.a,{href:\"https://python-poetry.org/\",rel:\"nofollow\",children:\"Poetry\"}),\" to manage dependencies, testing, and metadata. If you have Poetry installed already, from this directory, you can simply run the following commands to run the tool. This will setup a virtual environment, install the dependencies, activate the virtual environment, and run the console script.\"]}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`poetry lock\npoetry install\npoetry shell\nnetwire-config-extractor --help\n`})}),`\n`,(0,t.jsx)(e.h2,{id:\"usage\",children:\"Usage\"}),`\n`,(0,t.jsx)(e.p,{children:\"All samples need to be unpacked prior to execution extraction attempts.\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"Our extractor takes either a directory of samples with \",(0,t.jsx)(e.strong,{children:\"-d\"}),\" option or \",(0,t.jsx)(e.strong,{children:\"-f\"}),\" for a single sample and then can output parts of the configuration of note, specifically:\"]}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.strong,{children:\"-k\"}),\" : extract the encryption keys\"]}),`\n`,(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.strong,{children:\"-c\"}),\" : extract the C2 information\"]}),`\n`,(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.strong,{children:\"-s\"}),\" : extract the wide-character strings\"]}),`\n`,(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.strong,{children:\"-a\"}),\" : extract the ASCII character strings\"]}),`\n`]}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`docker run -ti --rm -v $(pwd)/data:/data netwire_loader_config_extractor:latest -d \"C:\\\\tmp\\\\samples\"\n`})}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/netwire-configuration-extractor/image6.jpg\",alt:\"NETWIRE configuration extractor\",width:\"1440\",height:\"598\"})}),`\n`,(0,t.jsx)(e.p,{children:\"You can collect the extracted configurations from the directory you set when running the extractor.\"})]})}function E(n={}){let{wrapper:e}=n.components||{};return e?(0,t.jsx)(e,Object.assign({},n,{children:(0,t.jsx)(d,n)})):d(n)}var b=E;return x(_);})();\n;return Component;"},"_id":"articles/netwire-configuration-extractor.mdx","_raw":{"sourceFilePath":"articles/netwire-configuration-extractor.mdx","sourceFileName":"netwire-configuration-extractor.mdx","sourceFileDir":"articles","contentType":"mdx","flattenedPath":"articles/netwire-configuration-extractor"},"type":"Article","imageUrl":"/assets/images/netwire-configuration-extractor/tools-image.jpg","readingTime":"2 min read","series":"","url":"/netwire-configuration-extractor","headings":[{"level":2,"title":"Getting started","href":"#getting-started"},{"level":3,"title":"Docker","href":"#docker"},{"level":3,"title":"Running it locally","href":"#running-it-locally"},{"level":2,"title":"Usage","href":"#usage"}],"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":"Tools","slug":"tools","body":{"raw":"","code":"var Component=(()=\u003e{var x=Object.create;var s=Object.defineProperty;var l=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),d=(t,n)=\u003e{for(var e in n)s(t,e,{get:n[e],enumerable:!0})},c=(t,n,e,a)=\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:!(a=l(n,r))||a.enumerable});return t};var p=(t,n,e)=\u003e(e=t!=null?x(_(t)):{},c(n||!t||!t.__esModule?s(e,\"default\",{value:t,enumerable:!0}):e,t)),M=t=\u003ec(s({},\"__esModule\",{value:!0}),t);var i=j((h,u)=\u003e{u.exports=_jsx_runtime});var X={};d(X,{default:()=\u003eF,frontmatter:()=\u003eC});var o=p(i()),C={title:\"Tools\",slug:\"tools\"};function m(t){return(0,o.jsx)(o.Fragment,{})}function D(t={}){let{wrapper:n}=t.components||{};return n?(0,o.jsx)(n,Object.assign({},t,{children:(0,o.jsx)(m,t)})):m(t)}var F=D;return M(X);})();\n;return Component;"},"_id":"categories/tools.mdx","_raw":{"sourceFilePath":"categories/tools.mdx","sourceFileName":"tools.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/tools"},"type":"Category","url":"/categories/tools"}]},{"title":"BLISTER Configuration Extractor","slug":"blister-configuration-extractor","date":"2022-12-06","description":"Python script to extract the configuration and payload from BLISTER samples.","image":"tools-image.jpg","tags":["blister","ref7890"],"body":{"raw":"\nPython script to extract the configuration and payload from BLISTER samples.\n\n[Download blister-config-extractor.tar.gz](https://assets.contentstack.io/v3/assets/bltefdd0b53724fa2ce/blt9bce8a0e1a513bd5/62882db13b9b8554904a4baa/blister-config-extractor.tar.gz)\n\n## Getting Started\n\nThis tool provides a Python module and command line tool that will extract configurations from the BLISTER malware loader and dump the results to screen.\n\n\u003e For information on the BLISTER malware loader and campaign observations, check out our blog posts detailing this:\n\u003e\n\u003e - [BLISTER Campaign Analysis](https://www.elastic.co/security-labs/elastic-security-uncovers-blister-malware-campaign)\n\u003e - [BLISTER Malware Analysis](https://www.elastic.co/security-labs/blister-loader)\n\n### Docker\n\nWe can easily run the extractor with Docker, first we need to build the image:\n\n```\ndocker build . -t blister-config-extractor\n```\n\nThen we run the container with the **-v** flag to map a host directory to the docker container directory:\n\n```\ndocker run -ti --rm -v \\\n\"$(pwd)/binaries\":/binaries blister-config-extractor:latest -d /binaries/\n\n```\n\nWe can either specify a single sample with **-f** option or a directory of samples with **-d**.\n\n![BLISTER configuration extrator output](/assets/images/blister-configuration-extractor/blister-configuration-extractor-image41.jpg)\n\n### Running it Locally\n\nAs mentioned above, Docker is the recommended approach to running this project, however you can also run this locally. This project uses [Poetry](https://python-poetry.org/) to manage dependencies, testing, and metadata. If you have Poetry installed already, from this directory, you can simply run the following commands to run the tool. This will setup a virtual environment, install the dependencies, activate the virtual environment, and run the console script.\n\n```\npoetry lock\npoetry install\npoetry shell\nblister-config-extractor -h\n\n```\n\nOnce that works, you can do the same sort of things as mentioned in the Docker instructions above.\n\n## References\n\n- Customised Rabbit cipher implementation based on [Rabbit-Cipher](https://github.com/Robin-Pwner/Rabbit-Cipher/)\n","code":"var Component=(()=\u003e{var d=Object.create;var i=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var u=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,m=Object.prototype.hasOwnProperty;var b=(n,e)=\u003e()=\u003e(e||n((e={exports:{}}).exports,e),e.exports),f=(n,e)=\u003e{for(var r in e)i(n,r,{get:e[r],enumerable:!0})},l=(n,e,r,a)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let o of u(e))!m.call(n,o)\u0026\u0026o!==r\u0026\u0026i(n,o,{get:()=\u003ee[o],enumerable:!(a=p(e,o))||a.enumerable});return n};var y=(n,e,r)=\u003e(r=n!=null?d(g(n)):{},l(e||!n||!n.__esModule?i(r,\"default\",{value:n,enumerable:!0}):r,n)),w=n=\u003el(i({},\"__esModule\",{value:!0}),n);var s=b((j,c)=\u003e{c.exports=_jsx_runtime});var R={};f(R,{default:()=\u003ev,frontmatter:()=\u003ex});var t=y(s()),x={title:\"BLISTER Configuration Extractor\",slug:\"blister-configuration-extractor\",date:\"2022-12-06\",description:\"Python script to extract the configuration and payload from BLISTER samples.\",author:[{slug:\"elastic-security-labs\"}],image:\"tools-image.jpg\",category:[{slug:\"tools\"}],tags:[\"blister\",\"ref7890\"]};function h(n){let e=Object.assign({p:\"p\",a:\"a\",h2:\"h2\",blockquote:\"blockquote\",ul:\"ul\",li:\"li\",h3:\"h3\",pre:\"pre\",code:\"code\",strong:\"strong\",img:\"img\"},n.components);return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(e.p,{children:\"Python script to extract the configuration and payload from BLISTER samples.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.a,{href:\"https://assets.contentstack.io/v3/assets/bltefdd0b53724fa2ce/blt9bce8a0e1a513bd5/62882db13b9b8554904a4baa/blister-config-extractor.tar.gz\",rel:\"nofollow\",children:\"Download blister-config-extractor.tar.gz\"})}),`\n`,(0,t.jsx)(e.h2,{id:\"getting-started\",children:\"Getting Started\"}),`\n`,(0,t.jsx)(e.p,{children:\"This tool provides a Python module and command line tool that will extract configurations from the BLISTER malware loader and dump the results to screen.\"}),`\n`,(0,t.jsxs)(e.blockquote,{children:[`\n`,(0,t.jsx)(e.p,{children:\"For information on the BLISTER malware loader and campaign observations, 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/elastic-security-uncovers-blister-malware-campaign\",rel:\"nofollow\",children:\"BLISTER Campaign Analysis\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/blister-loader\",rel:\"nofollow\",children:\"BLISTER Malware Analysis\"})}),`\n`]}),`\n`]}),`\n`,(0,t.jsx)(e.h3,{id:\"docker\",children:\"Docker\"}),`\n`,(0,t.jsx)(e.p,{children:\"We can easily run the extractor with Docker, first we need to build the image:\"}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`docker build . -t blister-config-extractor\n`})}),`\n`,(0,t.jsxs)(e.p,{children:[\"Then we run the container with the \",(0,t.jsx)(e.strong,{children:\"-v\"}),\" flag to map a host directory to the docker container directory:\"]}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`docker run -ti --rm -v \\\\\n\"$(pwd)/binaries\":/binaries blister-config-extractor:latest -d /binaries/\n\n`})}),`\n`,(0,t.jsxs)(e.p,{children:[\"We can either specify a single sample with \",(0,t.jsx)(e.strong,{children:\"-f\"}),\" option or a directory of samples with \",(0,t.jsx)(e.strong,{children:\"-d\"}),\".\"]}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/blister-configuration-extractor/blister-configuration-extractor-image41.jpg\",alt:\"BLISTER configuration extrator output\",width:\"1046\",height:\"512\"})}),`\n`,(0,t.jsx)(e.h3,{id:\"running-it-locally\",children:\"Running it Locally\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"As mentioned above, Docker is the recommended approach to running this project, however you can also run this locally. This project uses \",(0,t.jsx)(e.a,{href:\"https://python-poetry.org/\",rel:\"nofollow\",children:\"Poetry\"}),\" to manage dependencies, testing, and metadata. If you have Poetry installed already, from this directory, you can simply run the following commands to run the tool. This will setup a virtual environment, install the dependencies, activate the virtual environment, and run the console script.\"]}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`poetry lock\npoetry install\npoetry shell\nblister-config-extractor -h\n\n`})}),`\n`,(0,t.jsx)(e.p,{children:\"Once that works, you can do the same sort of things as mentioned in the Docker instructions above.\"}),`\n`,(0,t.jsx)(e.h2,{id:\"references\",children:\"References\"}),`\n`,(0,t.jsxs)(e.ul,{children:[`\n`,(0,t.jsxs)(e.li,{children:[\"Customised Rabbit cipher implementation based on \",(0,t.jsx)(e.a,{href:\"https://github.com/Robin-Pwner/Rabbit-Cipher/\",rel:\"nofollow\",children:\"Rabbit-Cipher\"})]}),`\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 v=k;return w(R);})();\n;return Component;"},"_id":"articles/blister-configuration-extractor.mdx","_raw":{"sourceFilePath":"articles/blister-configuration-extractor.mdx","sourceFileName":"blister-configuration-extractor.mdx","sourceFileDir":"articles","contentType":"mdx","flattenedPath":"articles/blister-configuration-extractor"},"type":"Article","imageUrl":"/assets/images/blister-configuration-extractor/tools-image.jpg","readingTime":"2 min read","series":"","url":"/blister-configuration-extractor","headings":[{"level":2,"title":"Getting Started","href":"#getting-started"},{"level":3,"title":"Docker","href":"#docker"},{"level":3,"title":"Running it Locally","href":"#running-it-locally"},{"level":2,"title":"References","href":"#references"}],"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":"Tools","slug":"tools","body":{"raw":"","code":"var Component=(()=\u003e{var x=Object.create;var s=Object.defineProperty;var l=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),d=(t,n)=\u003e{for(var e in n)s(t,e,{get:n[e],enumerable:!0})},c=(t,n,e,a)=\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:!(a=l(n,r))||a.enumerable});return t};var p=(t,n,e)=\u003e(e=t!=null?x(_(t)):{},c(n||!t||!t.__esModule?s(e,\"default\",{value:t,enumerable:!0}):e,t)),M=t=\u003ec(s({},\"__esModule\",{value:!0}),t);var i=j((h,u)=\u003e{u.exports=_jsx_runtime});var X={};d(X,{default:()=\u003eF,frontmatter:()=\u003eC});var o=p(i()),C={title:\"Tools\",slug:\"tools\"};function m(t){return(0,o.jsx)(o.Fragment,{})}function D(t={}){let{wrapper:n}=t.components||{};return n?(0,o.jsx)(n,Object.assign({},t,{children:(0,o.jsx)(m,t)})):m(t)}var F=D;return M(X);})();\n;return Component;"},"_id":"categories/tools.mdx","_raw":{"sourceFilePath":"categories/tools.mdx","sourceFileName":"tools.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/tools"},"type":"Category","url":"/categories/tools"}]},{"title":"BPFDoor Configuration Extractor","slug":"bpfdoor-configuration-extractor","date":"2022-12-06","description":"Configuration extractor to dump out hardcoded passwords with BPFDoor.","image":"tools-image.jpg","tags":["bpfdoor"],"body":{"raw":"\nConfiguration extractor to dump out hardcoded passwords with BPFDoor.\n\n[Download bpfdoor-config-extractor.tar.gz](https://assets.contentstack.io/v3/assets/bltefdd0b53724fa2ce/blt3f57100ade3473c5/62882ccdb4fa6b61ed70ba87/bpfdoor-config-extractor.tar.gz)\n\n## Overview\n\nThis tool provides a Python module and command line tool that will extract passwords from BPFDoor samples.\n\n\u003e The Elastic Security Team has released an indepth analysis of the BPFDoor malware and created an additional tool that will scan for BPFDoor infected hosts.\n\u003e\n\u003e - [BPFDoor analysis](https://bookish-bassoon-c37be003.pages.github.io/intelligence/2022/05/04.bpfdoor/article/)\n\u003e - [BPFDoor scanner](https://www.elastic.co/security-labs/bpfdoor-scanner)\n\n## Getting Started\n\n### Docker\n\nWe can easily run the extractor with Docker, first we need to build the image.\n\n```\nBuilding the BPFDoor Docker image\n\ndocker build . -t bpfdoor-extractor\n```\n\nThen we run the container with the **-v** flag to map a host directory to the Docker container directory that contains the BPFDoor samples.\n\n```\nRunning the BPFDoor Docker container\n\ndocker run -ti --rm -v $(pwd)/binaries:/binaries \\\n bpfdoor-extractor:latest -d /binaries/\n```\n\nWe can either specify a single sample with **-f** option or a directory of samples with **-d**\n\n```\nBPFDoor Configuration Extractor help output\n\ndocker run -ti --rm bpfdoor-extractor:latest -h\n\nAuthor: Elastic Security (MARE)\n\n______ ______ ______ ______\n| ___ \\| ___ \\| ___|| _ \\\n| |_/ /| |_/ /| |_ | | | | ___ ___ _ __\n| ___ \\| __/ | _| | | | |/ _ \\ / _ \\ | '__|\n| |_/ /| | | | | |/ /| (_) || (_) || |\n\\____/ \\_| \\_| |___/ \\___/ \\___/ |_|\n _____ __ _ _____ _ _\n/ __ \\ / _|(_) | ___| | | | |\n| / \\/ ___ _ __ | |_ _ __ _ | |__ __ __| |_ _ __ __ _ ___ | |_ ___ _ __\n| | / _ \\ | '_ \\ | _|| | / _` | | __|\\ \\/ /| __|| '__|/ _` | / __|| __|/ _ \\ | '__|\n| \\__/\\| (_) || | | || | | || (_| | | |___ \u003e \u003c | |_ | | | (_| || (__ | |_| (_) || |\n \\____/ \\___/ |_| |_||_| |_| \\__, | \\____//_/\\_\\ \\__||_| \\__,_| \\___| \\__|\\___/ |_|\n __/ |\n |___/\n\n\nusage: bpfdoor-extractor [-h] (-f FILENAME | -d DIRNAME)\n\noptions:\n -h, --help show this help message and exit\n -f FILENAME, --file FILENAME\n File\n -d DIRNAME, --dir DIRNAME\n Directory\n\n```\n\n### Running it Locally\n\nAs mentioned above, Docker is the recommended approach to running this project, however you can also run this locally. This project uses [Poetry](https://python-poetry.org/) to manage dependencies, testing, and metadata. If you have Poetry installed already, from this directory, you can simply run the following commands to run the tool. This will setup a virtual environment, install the dependencies, activate the virtual environment, and run the console script.\n\n```\npoetry lock\npoetry install\npoetry shell\nbpfdoor-extractor --help\n```\n\nOnce that works, you can do the same sort of things as mentioned in the Docker instructions above.\n","code":"var Component=(()=\u003e{var d=Object.create;var _=Object.defineProperty;var h=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var u=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var g=(o,e)=\u003e()=\u003e(e||o((e={exports:{}}).exports,e),e.exports),m=(o,e)=\u003e{for(var t in e)_(o,t,{get:e[t],enumerable:!0})},a=(o,e,t,i)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let r of p(e))!f.call(o,r)\u0026\u0026r!==t\u0026\u0026_(o,r,{get:()=\u003ee[r],enumerable:!(i=h(e,r))||i.enumerable});return o};var b=(o,e,t)=\u003e(t=o!=null?d(u(o)):{},a(e||!o||!o.__esModule?_(t,\"default\",{value:o,enumerable:!0}):t,o)),y=o=\u003ea(_({},\"__esModule\",{value:!0}),o);var l=g((v,c)=\u003e{c.exports=_jsx_runtime});var k={};m(k,{default:()=\u003ex,frontmatter:()=\u003ew});var n=b(l()),w={title:\"BPFDoor Configuration Extractor\",slug:\"bpfdoor-configuration-extractor\",date:\"2022-12-06\",description:\"Configuration extractor to dump out hardcoded passwords with BPFDoor.\",author:[{slug:\"elastic-security-labs\"}],image:\"tools-image.jpg\",category:[{slug:\"tools\"}],tags:[\"bpfdoor\"]};function s(o){let e=Object.assign({p:\"p\",a:\"a\",h2:\"h2\",blockquote:\"blockquote\",ul:\"ul\",li:\"li\",h3:\"h3\",pre:\"pre\",code:\"code\",strong:\"strong\"},o.components);return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(e.p,{children:\"Configuration extractor to dump out hardcoded passwords with BPFDoor.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.a,{href:\"https://assets.contentstack.io/v3/assets/bltefdd0b53724fa2ce/blt3f57100ade3473c5/62882ccdb4fa6b61ed70ba87/bpfdoor-config-extractor.tar.gz\",rel:\"nofollow\",children:\"Download bpfdoor-config-extractor.tar.gz\"})}),`\n`,(0,n.jsx)(e.h2,{id:\"overview\",children:\"Overview\"}),`\n`,(0,n.jsx)(e.p,{children:\"This tool provides a Python module and command line tool that will extract passwords from BPFDoor samples.\"}),`\n`,(0,n.jsxs)(e.blockquote,{children:[`\n`,(0,n.jsx)(e.p,{children:\"The Elastic Security Team has released an indepth analysis of the BPFDoor malware and created an additional tool that will scan for BPFDoor infected hosts.\"}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://bookish-bassoon-c37be003.pages.github.io/intelligence/2022/05/04.bpfdoor/article/\",rel:\"nofollow\",children:\"BPFDoor analysis\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/bpfdoor-scanner\",rel:\"nofollow\",children:\"BPFDoor scanner\"})}),`\n`]}),`\n`]}),`\n`,(0,n.jsx)(e.h2,{id:\"getting-started\",children:\"Getting Started\"}),`\n`,(0,n.jsx)(e.h3,{id:\"docker\",children:\"Docker\"}),`\n`,(0,n.jsx)(e.p,{children:\"We can easily run the extractor with Docker, first we need to build the image.\"}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`Building the BPFDoor Docker image\n\ndocker build . -t bpfdoor-extractor\n`})}),`\n`,(0,n.jsxs)(e.p,{children:[\"Then we run the container with the \",(0,n.jsx)(e.strong,{children:\"-v\"}),\" flag to map a host directory to the Docker container directory that contains the BPFDoor samples.\"]}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`Running the BPFDoor Docker container\n\ndocker run -ti --rm -v $(pwd)/binaries:/binaries \\\\\n bpfdoor-extractor:latest -d /binaries/\n`})}),`\n`,(0,n.jsxs)(e.p,{children:[\"We can either specify a single sample with \",(0,n.jsx)(e.strong,{children:\"-f\"}),\" option or a directory of samples with \",(0,n.jsx)(e.strong,{children:\"-d\"})]}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`BPFDoor Configuration Extractor help output\n\ndocker run -ti --rm bpfdoor-extractor:latest -h\n\nAuthor: Elastic Security (MARE)\n\n______ ______ ______ ______\n| ___ \\\\| ___ \\\\| ___|| _ \\\\\n| |_/ /| |_/ /| |_ | | | | ___ ___ _ __\n| ___ \\\\| __/ | _| | | | |/ _ \\\\ / _ \\\\ | '__|\n| |_/ /| | | | | |/ /| (_) || (_) || |\n\\\\____/ \\\\_| \\\\_| |___/ \\\\___/ \\\\___/ |_|\n _____ __ _ _____ _ _\n/ __ \\\\ / _|(_) | ___| | | | |\n| / \\\\/ ___ _ __ | |_ _ __ _ | |__ __ __| |_ _ __ __ _ ___ | |_ ___ _ __\n| | / _ \\\\ | '_ \\\\ | _|| | / _\\` | | __|\\\\ \\\\/ /| __|| '__|/ _\\` | / __|| __|/ _ \\\\ | '__|\n| \\\\__/\\\\| (_) || | | || | | || (_| | | |___ \u003e \u003c | |_ | | | (_| || (__ | |_| (_) || |\n \\\\____/ \\\\___/ |_| |_||_| |_| \\\\__, | \\\\____//_/\\\\_\\\\ \\\\__||_| \\\\__,_| \\\\___| \\\\__|\\\\___/ |_|\n __/ |\n |___/\n\n\nusage: bpfdoor-extractor [-h] (-f FILENAME | -d DIRNAME)\n\noptions:\n -h, --help show this help message and exit\n -f FILENAME, --file FILENAME\n File\n -d DIRNAME, --dir DIRNAME\n Directory\n\n`})}),`\n`,(0,n.jsx)(e.h3,{id:\"running-it-locally\",children:\"Running it Locally\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"As mentioned above, Docker is the recommended approach to running this project, however you can also run this locally. This project uses \",(0,n.jsx)(e.a,{href:\"https://python-poetry.org/\",rel:\"nofollow\",children:\"Poetry\"}),\" to manage dependencies, testing, and metadata. If you have Poetry installed already, from this directory, you can simply run the following commands to run the tool. This will setup a virtual environment, install the dependencies, activate the virtual environment, and run the console script.\"]}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`poetry lock\npoetry install\npoetry shell\nbpfdoor-extractor --help\n`})}),`\n`,(0,n.jsx)(e.p,{children:\"Once that works, you can do the same sort of things as mentioned in the Docker instructions above.\"})]})}function D(o={}){let{wrapper:e}=o.components||{};return e?(0,n.jsx)(e,Object.assign({},o,{children:(0,n.jsx)(s,o)})):s(o)}var x=D;return y(k);})();\n;return Component;"},"_id":"articles/bpfdoor-configuration-extractor.mdx","_raw":{"sourceFilePath":"articles/bpfdoor-configuration-extractor.mdx","sourceFileName":"bpfdoor-configuration-extractor.mdx","sourceFileDir":"articles","contentType":"mdx","flattenedPath":"articles/bpfdoor-configuration-extractor"},"type":"Article","imageUrl":"/assets/images/bpfdoor-configuration-extractor/tools-image.jpg","readingTime":"4 min read","series":"","url":"/bpfdoor-configuration-extractor","headings":[{"level":2,"title":"Overview","href":"#overview"},{"level":2,"title":"Getting Started","href":"#getting-started"},{"level":3,"title":"Docker","href":"#docker"},{"level":3,"title":"Running it Locally","href":"#running-it-locally"}],"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":"Tools","slug":"tools","body":{"raw":"","code":"var Component=(()=\u003e{var x=Object.create;var s=Object.defineProperty;var l=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),d=(t,n)=\u003e{for(var e in n)s(t,e,{get:n[e],enumerable:!0})},c=(t,n,e,a)=\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:!(a=l(n,r))||a.enumerable});return t};var p=(t,n,e)=\u003e(e=t!=null?x(_(t)):{},c(n||!t||!t.__esModule?s(e,\"default\",{value:t,enumerable:!0}):e,t)),M=t=\u003ec(s({},\"__esModule\",{value:!0}),t);var i=j((h,u)=\u003e{u.exports=_jsx_runtime});var X={};d(X,{default:()=\u003eF,frontmatter:()=\u003eC});var o=p(i()),C={title:\"Tools\",slug:\"tools\"};function m(t){return(0,o.jsx)(o.Fragment,{})}function D(t={}){let{wrapper:n}=t.components||{};return n?(0,o.jsx)(n,Object.assign({},t,{children:(0,o.jsx)(m,t)})):m(t)}var F=D;return M(X);})();\n;return Component;"},"_id":"categories/tools.mdx","_raw":{"sourceFilePath":"categories/tools.mdx","sourceFileName":"tools.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/tools"},"type":"Category","url":"/categories/tools"}]},{"title":"BPFDoor Scanner","slug":"bpfdoor-scanner","date":"2022-12-06","description":"Python script to identify hosts infected with the BPFDoor malware.","image":"tools-image.jpg","tags":["bpfdoor"],"body":{"raw":"\nPython script to identify hosts infected with the BPFDoor malware.\n\n[Download bpfdoor-scanner.tar.gz](https://assets.contentstack.io/v3/assets/bltefdd0b53724fa2ce/bltae9bafece9048014/62882b50dcc93261eccb04e2/bpfdoor-scanner.tar.gz)\n\n## Getting Started\n\nThis tool provides a Python script to identify hosts that are infected with the BPFDoor malware.\n\n\u003e The Elastic Security Team has released an indepth analysis of the BPFDoor malware and created an additional tool that will extract configurations from BPFDoor malware samples.\n\u003e\n\u003e - [BPFDoor analysis](https://bookish-bassoon-c37be003.pages.github.io/intelligence/2022/05/04.bpfdoor/article/)\n\u003e - [BPFDoor configuration extractor](https://www.elastic.co/security-labs/bpfdoor-configuration-extractor)\n\n### Permissions\n\nOn Linux (and thus in a container), the tool requires the following permissions:\n\n- CAP_NET_BIND_SERVICE\n- CAP_NET_RAW\n\nOn any \\*NIX host, running the script with sudo will get you what you need. As long as you don’t strip the privileges listed for your container and you publish the UDP port you intend to receive on, you should be set.\n\n### Docker\n\nWe can easily run the scanner with Docker, first we need to build the image:\n\n```\nBuilding the BPFDoor scanner Docker image\n\ndocker build . -t bpfdoor-scanner\n```\n\n## Usage\n\nOnce you’be built the Docker iamge, we can run the container to get a list of the options.\n\n```\nRuning the BPFDoor container\n\ndocker run -ti --rm bpfdoor-scanner:latest --help\n\nUsage: bpfdoor-scanner [OPTIONS]\n\n Sends a discovery packet to suspected BPFDoor endpoints.\n\n Example usage:\n\n sudo ./bpfdoor-scanner --target-ip 1.2.3.4\n\n Sends a packet to IP 1.2.3.4 using the default target port 68/UDP (tool\n listens on all ports) using the default interface on this host and listens\n on port 53/UDP to masquerade as traffic.\n\n NOTE: Elevated privileges are required for source ports \u003c 1024.\n\nOptions:\n --target-ip TEXT [required]\n --target-port INTEGER [default: 68]\n --source-ip TEXT IP for target to respond to and attempt to bind\n locally [default: 172.17.0.3]\n --source-port INTEGER Local port to listen on for response [default: 53]\n --timeout INTEGER Number of seconds to wait for response [default: 5]\n -v, --verbose Show verbose output\n -d, --debug Show debug output\n --version\n --help Show this message and exit.\n```\n\nThe minimum required option is just --target-ip. The rest have defaults. For running in a container, you’ll want to publish the return port (defaults to 53) and specify --source-ip of the host interface you wish to use. In the following example, the IP 192.168.100.10 is the interface on my host that will receive the packet.\n\n```\nExample running the BPFDoor scanner\n\ndocker run -ti --publish 53:53/udp --rm bpfdoor-scanner:latest \\\n --target-ip 192.168.32.18 --source-ip 192.168.100.10\n```\n\n## Running Locally\n\nAs mentioned above, Docker is the recommended approach to running this project, however you can also run this locally. This project uses [Poetry](https://python-poetry.org/) to manage dependencies, testing, and metadata. If you have Poetry installed already, from this directory, you can simply run the following commands to run the tool. This will setup a virtual environment, install the dependencies, activate the virtual environment, and run the console script.\n\n```\nRunning BPFDoor scanner locally\n\npoetry lock\npoetry install\npoetry shell\nsudo bpfdoor-scanner --help\n```\n\nOnce that works, you can do the same sort of things as mentioned in the Docker instructions above.\n","code":"var Component=(()=\u003e{var h=Object.create;var i=Object.defineProperty;var u=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var f=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var m=(t,e)=\u003e()=\u003e(e||t((e={exports:{}}).exports,e),e.exports),y=(t,e)=\u003e{for(var o in e)i(t,o,{get:e[o],enumerable:!0})},a=(t,e,o,s)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let r of p(e))!g.call(t,r)\u0026\u0026r!==o\u0026\u0026i(t,r,{get:()=\u003ee[r],enumerable:!(s=u(e,r))||s.enumerable});return t};var b=(t,e,o)=\u003e(o=t!=null?h(f(t)):{},a(e||!t||!t.__esModule?i(o,\"default\",{value:t,enumerable:!0}):o,t)),w=t=\u003ea(i({},\"__esModule\",{value:!0}),t);var c=m((x,l)=\u003e{l.exports=_jsx_runtime});var k={};y(k,{default:()=\u003ev,frontmatter:()=\u003eP});var n=b(c()),P={title:\"BPFDoor Scanner\",slug:\"bpfdoor-scanner\",date:\"2022-12-06\",description:\"Python script to identify hosts infected with the BPFDoor malware.\",author:[{slug:\"elastic-security-labs\"}],image:\"tools-image.jpg\",category:[{slug:\"tools\"}],tags:[\"bpfdoor\"]};function d(t){let e=Object.assign({p:\"p\",a:\"a\",h2:\"h2\",blockquote:\"blockquote\",ul:\"ul\",li:\"li\",h3:\"h3\",pre:\"pre\",code:\"code\"},t.components);return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(e.p,{children:\"Python script to identify hosts infected with the BPFDoor malware.\"}),`\n`,(0,n.jsx)(e.p,{children:(0,n.jsx)(e.a,{href:\"https://assets.contentstack.io/v3/assets/bltefdd0b53724fa2ce/bltae9bafece9048014/62882b50dcc93261eccb04e2/bpfdoor-scanner.tar.gz\",rel:\"nofollow\",children:\"Download bpfdoor-scanner.tar.gz\"})}),`\n`,(0,n.jsx)(e.h2,{id:\"getting-started\",children:\"Getting Started\"}),`\n`,(0,n.jsx)(e.p,{children:\"This tool provides a Python script to identify hosts that are infected with the BPFDoor malware.\"}),`\n`,(0,n.jsxs)(e.blockquote,{children:[`\n`,(0,n.jsx)(e.p,{children:\"The Elastic Security Team has released an indepth analysis of the BPFDoor malware and created an additional tool that will extract configurations from BPFDoor malware samples.\"}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://bookish-bassoon-c37be003.pages.github.io/intelligence/2022/05/04.bpfdoor/article/\",rel:\"nofollow\",children:\"BPFDoor analysis\"})}),`\n`,(0,n.jsx)(e.li,{children:(0,n.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/bpfdoor-configuration-extractor\",rel:\"nofollow\",children:\"BPFDoor configuration extractor\"})}),`\n`]}),`\n`]}),`\n`,(0,n.jsx)(e.h3,{id:\"permissions\",children:\"Permissions\"}),`\n`,(0,n.jsx)(e.p,{children:\"On Linux (and thus in a container), the tool requires the following permissions:\"}),`\n`,(0,n.jsxs)(e.ul,{children:[`\n`,(0,n.jsx)(e.li,{children:\"CAP_NET_BIND_SERVICE\"}),`\n`,(0,n.jsx)(e.li,{children:\"CAP_NET_RAW\"}),`\n`]}),`\n`,(0,n.jsx)(e.p,{children:\"On any *NIX host, running the script with sudo will get you what you need. As long as you don\\u2019t strip the privileges listed for your container and you publish the UDP port you intend to receive on, you should be set.\"}),`\n`,(0,n.jsx)(e.h3,{id:\"docker\",children:\"Docker\"}),`\n`,(0,n.jsx)(e.p,{children:\"We can easily run the scanner with Docker, first we need to build the image:\"}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`Building the BPFDoor scanner Docker image\n\ndocker build . -t bpfdoor-scanner\n`})}),`\n`,(0,n.jsx)(e.h2,{id:\"usage\",children:\"Usage\"}),`\n`,(0,n.jsx)(e.p,{children:\"Once you\\u2019be built the Docker iamge, we can run the container to get a list of the options.\"}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`Runing the BPFDoor container\n\ndocker run -ti --rm bpfdoor-scanner:latest --help\n\nUsage: bpfdoor-scanner [OPTIONS]\n\n Sends a discovery packet to suspected BPFDoor endpoints.\n\n Example usage:\n\n sudo ./bpfdoor-scanner --target-ip 1.2.3.4\n\n Sends a packet to IP 1.2.3.4 using the default target port 68/UDP (tool\n listens on all ports) using the default interface on this host and listens\n on port 53/UDP to masquerade as traffic.\n\n NOTE: Elevated privileges are required for source ports \u003c 1024.\n\nOptions:\n --target-ip TEXT [required]\n --target-port INTEGER [default: 68]\n --source-ip TEXT IP for target to respond to and attempt to bind\n locally [default: 172.17.0.3]\n --source-port INTEGER Local port to listen on for response [default: 53]\n --timeout INTEGER Number of seconds to wait for response [default: 5]\n -v, --verbose Show verbose output\n -d, --debug Show debug output\n --version\n --help Show this message and exit.\n`})}),`\n`,(0,n.jsx)(e.p,{children:\"The minimum required option is just --target-ip. The rest have defaults. For running in a container, you\\u2019ll want to publish the return port (defaults to 53) and specify --source-ip of the host interface you wish to use. In the following example, the IP 192.168.100.10 is the interface on my host that will receive the packet.\"}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`Example running the BPFDoor scanner\n\ndocker run -ti --publish 53:53/udp --rm bpfdoor-scanner:latest \\\\\n --target-ip 192.168.32.18 --source-ip 192.168.100.10\n`})}),`\n`,(0,n.jsx)(e.h2,{id:\"running-locally\",children:\"Running Locally\"}),`\n`,(0,n.jsxs)(e.p,{children:[\"As mentioned above, Docker is the recommended approach to running this project, however you can also run this locally. This project uses \",(0,n.jsx)(e.a,{href:\"https://python-poetry.org/\",rel:\"nofollow\",children:\"Poetry\"}),\" to manage dependencies, testing, and metadata. If you have Poetry installed already, from this directory, you can simply run the following commands to run the tool. This will setup a virtual environment, install the dependencies, activate the virtual environment, and run the console script.\"]}),`\n`,(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{children:`Running BPFDoor scanner locally\n\npoetry lock\npoetry install\npoetry shell\nsudo bpfdoor-scanner --help\n`})}),`\n`,(0,n.jsx)(e.p,{children:\"Once that works, you can do the same sort of things as mentioned in the Docker instructions above.\"})]})}function D(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=D;return w(k);})();\n;return Component;"},"_id":"articles/bpfdoor-scanner.mdx","_raw":{"sourceFilePath":"articles/bpfdoor-scanner.mdx","sourceFileName":"bpfdoor-scanner.mdx","sourceFileDir":"articles","contentType":"mdx","flattenedPath":"articles/bpfdoor-scanner"},"type":"Article","imageUrl":"/assets/images/bpfdoor-scanner/tools-image.jpg","readingTime":"4 min read","series":"","url":"/bpfdoor-scanner","headings":[{"level":2,"title":"Getting Started","href":"#getting-started"},{"level":3,"title":"Permissions","href":"#permissions"},{"level":3,"title":"Docker","href":"#docker"},{"level":2,"title":"Usage","href":"#usage"},{"level":2,"title":"Running Locally","href":"#running-locally"}],"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":"Tools","slug":"tools","body":{"raw":"","code":"var Component=(()=\u003e{var x=Object.create;var s=Object.defineProperty;var l=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),d=(t,n)=\u003e{for(var e in n)s(t,e,{get:n[e],enumerable:!0})},c=(t,n,e,a)=\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:!(a=l(n,r))||a.enumerable});return t};var p=(t,n,e)=\u003e(e=t!=null?x(_(t)):{},c(n||!t||!t.__esModule?s(e,\"default\",{value:t,enumerable:!0}):e,t)),M=t=\u003ec(s({},\"__esModule\",{value:!0}),t);var i=j((h,u)=\u003e{u.exports=_jsx_runtime});var X={};d(X,{default:()=\u003eF,frontmatter:()=\u003eC});var o=p(i()),C={title:\"Tools\",slug:\"tools\"};function m(t){return(0,o.jsx)(o.Fragment,{})}function D(t={}){let{wrapper:n}=t.components||{};return n?(0,o.jsx)(n,Object.assign({},t,{children:(0,o.jsx)(m,t)})):m(t)}var F=D;return M(X);})();\n;return Component;"},"_id":"categories/tools.mdx","_raw":{"sourceFilePath":"categories/tools.mdx","sourceFileName":"tools.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/tools"},"type":"Category","url":"/categories/tools"}]},{"title":"Cobalt Strike Beacon Extractor","slug":"cobalt-strike-beacon-extractor","date":"2022-12-06","description":"Python script that collects Cobalt Strike memory data generated by security events from an Elasticsearch cluster, extracts the configuration from the CS beacon, and writes the data back to Elasticsearch.","image":"tools-image.jpg","tags":["cobaltstrike"],"body":{"raw":"\nPython script that collects Cobalt Strike memory data generated by security events from an Elasticsearch cluster, extracts the configuration from the CS beacon, and writes the data back to Elasticsearch.\n\n[Download cobalt-strike-extractor.tar.gz](https://assets.contentstack.io/v3/assets/bltefdd0b53724fa2ce/bltdbc4f9f2366d2f06/628829603b9b8554904a4ba2/cobalt-strike-extractor.tar.gz)\n\n## Overview\n\nThis tool provides a Python module and command line tool that will search Elastic Endpoint alert data for detections of Cobalt Strike and the extracted memory data. When present, this tool will extract the implant configuration using the [cobaltstrike-config-extractor](https://github.com/strozfriedberg/cobaltstrike-config-extractor). The information is then normalized into an ECS-formatted JSON document and indexed into an Elasticsearch cluster or output to the terminal as JSON.\n\n\u003e For help on creating Fleet policies to collect and analyze Cobalt Strike beacons in the Elastic Stack, check out our blog posts detailing this:\n\u003e\n\u003e - [Collecting Colbalt Strike beacons](https://www.elastic.co/security-labs/collecting-cobalt-strike-beacons-with-the-elastic-stack)\n\u003e - [Extracting Cobalt Strike beacon configurations](https://www.elastic.co/security-labs/extracting-cobalt-strike-beacon-configurations)\n\n## Getting Started\n\n### Docker\n\nThe recommended and easiest way to get going is to use Docker. From the directory this README is in, you can build a local container.\n\n```\ndocker build . -t cobalt-strike-extractor\n```\n\nNext, make a copy of config.reference.yml and name it config.local.yml and edit for your environment. A minimal config looks like the example below. The input and output could use the same values, but you can optionally push it to a different cluster for analysis.\n\n```\n## Using an Elastic Cloud instance (this is a randomly generated example)\ninput.elasticsearch:\n enabled: True\n cloud.id: security-cluster:dXMtd2VzdDEuZ2NwLmNsb3VkLmVzLmlvJGU0MWU1YTc3YmRjNzY2OTY0MDg2NjIzNDA5NzFjNjFkJDdlYjRlYTJkMzJkMTgzYTRiMmJkMjlkNTNjODhjMjQ4\n cloud.auth: elastic:\u003cPASSWORD\u003e\n\n## Default output will use localhost:9092, see reference config\noutput.elasticsearch:\n enabled: True\n username: elastic\n password: \u003cPASSWORD\u003e\n\n```\n\nNow, run the container, passing in our local configuration. The -v flag here will add informational messages to the log output. Here, it tells us how many documents were successfully parsed and written.\n\n```\ndocker run -ti --rm -v \"$(pwd)/config.local.yml:/config.yml\" \\\n cobalt-strike-extractor:latest -c /config.yml -v\n\n```\n\n_Output_:\n\n```\n[2022-01-10T21:33:31.493][INFO] Setting up input/output\n[2022-01-10T21:33:31.493][INFO] Connecting to Elasticsearch for input\n[2022-01-10T21:33:31.493][INFO] Successfully connected to Elasticsearch for input\n[2022-01-10T21:33:31.834][INFO] Connecting to Elasticsearch for output\n[2022-01-10T21:33:31.835][INFO] Successfully connected to Elasticsearch for output\n[2022-01-10T21:33:33.030][WARNING] Could not parse source as PE file (DOS Header magic not found.)\n[2022-01-10T21:33:33.078][WARNING] CobaltStrike Beacon config not found:\n[2022-01-10T21:33:33.093][WARNING] Could not parse source as PE file (DOS Header magic not found.)\n[2022-01-10T21:33:33.096][WARNING] CobaltStrike Beacon config not found:\n[2022-01-10T21:33:33.097][WARNING] Could not parse source as PE file (DOS Header magic not found.)\n[2022-01-10T21:33:33.097][WARNING] CobaltStrike Beacon config not found:\n[2022-01-10T21:33:33.097][WARNING] Could not parse source as PE file (DOS Header magic not found.)\n[2022-01-10T21:33:33.098][WARNING] CobaltStrike Beacon config not found:\n[2022-01-10T21:33:33.186][WARNING] Could not parse source as PE file (DOS Header magic not found.)\n[2022-01-10T21:33:33.191][WARNING] CobaltStrike Beacon config not found:\n[2022-01-10T21:33:33.461][WARNING] Could not parse source as PE file (DOS Header magic not found.)\n[2022-01-10T21:33:33.516][WARNING] CobaltStrike Beacon config not found:\n[2022-01-10T21:33:33.927][INFO] Wrote 2 docs to Elasticsearch\n\n```\n\nThe [WARNING] messages here are to be expected. These are simply source documents that didn’t contain the configuration information.\n\n#### Filter by time\n\nTo limit the search by time frame, you can add the --since argument, which takes either an ISO-formatted date time string or you can use [Elastic date math](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-range-query.html#ranges-on-dates). For example, to limit search to the last 30 days, you can do the following.\n\n```\ndocker run -ti --rm -v \"$(pwd)/config.local.yml:/config.yml\" \\\n cobalt-strike-extractor:latest --since \"now-30d/d\" -c config.local.yml\n\n```\n\n#### Pipe output to other tools\n\nLastly, you can pipe the output to other commands, such as jq to do local analysis. You can also override the configuration file values using environment variables.\n\n```\ndocker run -i --rm -a stdin -a stdout -a stderr \\\n -v \"$(pwd)/config.local.yml:/config.yml\" \\\n -e \"OUTPUT_ELASTICSEARCH_ENABLED=False\" \\\n -e \"OUTPUT_CONSOLE_ENABLED=True\" cobalt-strike-extractor:latest -c /config.yml -q | jq '.cobaltstrike.server.hostname'\n\n```\n\nIn the example above, we disabled the Elasticsearch output and enabled the Console output using environment variables. We made the output more quiet using the -q flag (hiding the warnings). Then, we used jq to just pull out the “hostname” value of the configuration.\n\n### Running it Locally\n\nAs mentioned above, Docker is the recommended approach to running this project, however you can also run this locally. This project uses [Poetry](https://python-poetry.org/) to manage dependencies, testing, and metadata. If you have Poetry installed already, from this directory, you can simply run the following commands to run the tool. This will setup a virtual environment, install the dependencies, activate the virtual environment, and run the console script.\n\n```\npoetry lock\npoetry install\npoetry shell\ncobalt-strike-extractor --help\n\n```\n\nOnce that works, you can do the same sort of things as mentioned in the Docker instructions above.\n","code":"var Component=(()=\u003e{var h=Object.create;var r=Object.defineProperty;var u=Object.getOwnPropertyDescriptor;var m=Object.getOwnPropertyNames;var f=Object.getPrototypeOf,p=Object.prototype.hasOwnProperty;var g=(n,e)=\u003e()=\u003e(e||n((e={exports:{}}).exports,e),e.exports),b=(n,e)=\u003e{for(var o in e)r(n,o,{get:e[o],enumerable:!0})},c=(n,e,o,i)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let a of m(e))!p.call(n,a)\u0026\u0026a!==o\u0026\u0026r(n,a,{get:()=\u003ee[a],enumerable:!(i=u(e,a))||i.enumerable});return n};var y=(n,e,o)=\u003e(o=n!=null?h(f(n)):{},c(e||!n||!n.__esModule?r(o,\"default\",{value:n,enumerable:!0}):o,n)),k=n=\u003ec(r({},\"__esModule\",{value:!0}),n);var s=g((v,l)=\u003e{l.exports=_jsx_runtime});var S={};b(S,{default:()=\u003eT,frontmatter:()=\u003eN});var t=y(s()),N={title:\"Cobalt Strike Beacon Extractor\",slug:\"cobalt-strike-beacon-extractor\",date:\"2022-12-06\",description:\"Python script that collects Cobalt Strike memory data generated by security events from an Elasticsearch cluster, extracts the configuration from the CS beacon, and writes the data back to Elasticsearch.\",author:[{slug:\"elastic-security-labs\"}],image:\"tools-image.jpg\",category:[{slug:\"tools\"}],tags:[\"cobaltstrike\"]};function d(n){let e=Object.assign({p:\"p\",a:\"a\",h2:\"h2\",blockquote:\"blockquote\",ul:\"ul\",li:\"li\",h3:\"h3\",pre:\"pre\",code:\"code\",em:\"em\",h4:\"h4\"},n.components);return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(e.p,{children:\"Python script that collects Cobalt Strike memory data generated by security events from an Elasticsearch cluster, extracts the configuration from the CS beacon, and writes the data back to Elasticsearch.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.a,{href:\"https://assets.contentstack.io/v3/assets/bltefdd0b53724fa2ce/bltdbc4f9f2366d2f06/628829603b9b8554904a4ba2/cobalt-strike-extractor.tar.gz\",rel:\"nofollow\",children:\"Download cobalt-strike-extractor.tar.gz\"})}),`\n`,(0,t.jsx)(e.h2,{id:\"overview\",children:\"Overview\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"This tool provides a Python module and command line tool that will search Elastic Endpoint alert data for detections of Cobalt Strike and the extracted memory data. When present, this tool will extract the implant configuration using the \",(0,t.jsx)(e.a,{href:\"https://github.com/strozfriedberg/cobaltstrike-config-extractor\",rel:\"nofollow\",children:\"cobaltstrike-config-extractor\"}),\". The information is then normalized into an ECS-formatted JSON document and indexed into an Elasticsearch cluster or output to the terminal as JSON.\"]}),`\n`,(0,t.jsxs)(e.blockquote,{children:[`\n`,(0,t.jsx)(e.p,{children:\"For help on creating Fleet policies to collect and analyze Cobalt Strike beacons in the Elastic Stack, 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/collecting-cobalt-strike-beacons-with-the-elastic-stack\",rel:\"nofollow\",children:\"Collecting Colbalt Strike beacons\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://www.elastic.co/security-labs/extracting-cobalt-strike-beacon-configurations\",rel:\"nofollow\",children:\"Extracting Cobalt Strike beacon configurations\"})}),`\n`]}),`\n`]}),`\n`,(0,t.jsx)(e.h2,{id:\"getting-started\",children:\"Getting Started\"}),`\n`,(0,t.jsx)(e.h3,{id:\"docker\",children:\"Docker\"}),`\n`,(0,t.jsx)(e.p,{children:\"The recommended and easiest way to get going is to use Docker. From the directory this README is in, you can build a local container.\"}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`docker build . -t cobalt-strike-extractor\n`})}),`\n`,(0,t.jsx)(e.p,{children:\"Next, make a copy of config.reference.yml and name it config.local.yml and edit for your environment. A minimal config looks like the example below. The input and output could use the same values, but you can optionally push it to a different cluster for analysis.\"}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`## Using an Elastic Cloud instance (this is a randomly generated example)\ninput.elasticsearch:\n enabled: True\n cloud.id: security-cluster:dXMtd2VzdDEuZ2NwLmNsb3VkLmVzLmlvJGU0MWU1YTc3YmRjNzY2OTY0MDg2NjIzNDA5NzFjNjFkJDdlYjRlYTJkMzJkMTgzYTRiMmJkMjlkNTNjODhjMjQ4\n cloud.auth: elastic:\u003cPASSWORD\u003e\n\n## Default output will use localhost:9092, see reference config\noutput.elasticsearch:\n enabled: True\n username: elastic\n password: \u003cPASSWORD\u003e\n\n`})}),`\n`,(0,t.jsx)(e.p,{children:\"Now, run the container, passing in our local configuration. The -v flag here will add informational messages to the log output. Here, it tells us how many documents were successfully parsed and written.\"}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`docker run -ti --rm -v \"$(pwd)/config.local.yml:/config.yml\" \\\\\n cobalt-strike-extractor:latest -c /config.yml -v\n\n`})}),`\n`,(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.em,{children:\"Output\"}),\":\"]}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`[2022-01-10T21:33:31.493][INFO] Setting up input/output\n[2022-01-10T21:33:31.493][INFO] Connecting to Elasticsearch for input\n[2022-01-10T21:33:31.493][INFO] Successfully connected to Elasticsearch for input\n[2022-01-10T21:33:31.834][INFO] Connecting to Elasticsearch for output\n[2022-01-10T21:33:31.835][INFO] Successfully connected to Elasticsearch for output\n[2022-01-10T21:33:33.030][WARNING] Could not parse source as PE file (DOS Header magic not found.)\n[2022-01-10T21:33:33.078][WARNING] CobaltStrike Beacon config not found:\n[2022-01-10T21:33:33.093][WARNING] Could not parse source as PE file (DOS Header magic not found.)\n[2022-01-10T21:33:33.096][WARNING] CobaltStrike Beacon config not found:\n[2022-01-10T21:33:33.097][WARNING] Could not parse source as PE file (DOS Header magic not found.)\n[2022-01-10T21:33:33.097][WARNING] CobaltStrike Beacon config not found:\n[2022-01-10T21:33:33.097][WARNING] Could not parse source as PE file (DOS Header magic not found.)\n[2022-01-10T21:33:33.098][WARNING] CobaltStrike Beacon config not found:\n[2022-01-10T21:33:33.186][WARNING] Could not parse source as PE file (DOS Header magic not found.)\n[2022-01-10T21:33:33.191][WARNING] CobaltStrike Beacon config not found:\n[2022-01-10T21:33:33.461][WARNING] Could not parse source as PE file (DOS Header magic not found.)\n[2022-01-10T21:33:33.516][WARNING] CobaltStrike Beacon config not found:\n[2022-01-10T21:33:33.927][INFO] Wrote 2 docs to Elasticsearch\n\n`})}),`\n`,(0,t.jsx)(e.p,{children:\"The [WARNING] messages here are to be expected. These are simply source documents that didn\\u2019t contain the configuration information.\"}),`\n`,(0,t.jsx)(e.h4,{id:\"filter-by-time\",children:\"Filter by time\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"To limit the search by time frame, you can add the --since argument, which takes either an ISO-formatted date time string or you can use \",(0,t.jsx)(e.a,{href:\"https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-range-query.html#ranges-on-dates\",rel:\"nofollow\",children:\"Elastic date math\"}),\". For example, to limit search to the last 30 days, you can do the following.\"]}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`docker run -ti --rm -v \"$(pwd)/config.local.yml:/config.yml\" \\\\\n cobalt-strike-extractor:latest --since \"now-30d/d\" -c config.local.yml\n\n`})}),`\n`,(0,t.jsx)(e.h4,{id:\"pipe-output-to-other-tools\",children:\"Pipe output to other tools\"}),`\n`,(0,t.jsx)(e.p,{children:\"Lastly, you can pipe the output to other commands, such as jq to do local analysis. You can also override the configuration file values using environment variables.\"}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`docker run -i --rm -a stdin -a stdout -a stderr \\\\\n -v \"$(pwd)/config.local.yml:/config.yml\" \\\\\n -e \"OUTPUT_ELASTICSEARCH_ENABLED=False\" \\\\\n -e \"OUTPUT_CONSOLE_ENABLED=True\" cobalt-strike-extractor:latest -c /config.yml -q | jq '.cobaltstrike.server.hostname'\n\n`})}),`\n`,(0,t.jsx)(e.p,{children:\"In the example above, we disabled the Elasticsearch output and enabled the Console output using environment variables. We made the output more quiet using the -q flag (hiding the warnings). Then, we used jq to just pull out the \\u201Chostname\\u201D value of the configuration.\"}),`\n`,(0,t.jsx)(e.h3,{id:\"running-it-locally\",children:\"Running it Locally\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"As mentioned above, Docker is the recommended approach to running this project, however you can also run this locally. This project uses \",(0,t.jsx)(e.a,{href:\"https://python-poetry.org/\",rel:\"nofollow\",children:\"Poetry\"}),\" to manage dependencies, testing, and metadata. If you have Poetry installed already, from this directory, you can simply run the following commands to run the tool. This will setup a virtual environment, install the dependencies, activate the virtual environment, and run the console script.\"]}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`poetry lock\npoetry install\npoetry shell\ncobalt-strike-extractor --help\n\n`})}),`\n`,(0,t.jsx)(e.p,{children:\"Once that works, you can do the same sort of things as mentioned in the Docker instructions above.\"})]})}function w(n={}){let{wrapper:e}=n.components||{};return e?(0,t.jsx)(e,Object.assign({},n,{children:(0,t.jsx)(d,n)})):d(n)}var T=w;return k(S);})();\n;return Component;"},"_id":"articles/cobalt-strike-beacon-extractor.mdx","_raw":{"sourceFilePath":"articles/cobalt-strike-beacon-extractor.mdx","sourceFileName":"cobalt-strike-beacon-extractor.mdx","sourceFileDir":"articles","contentType":"mdx","flattenedPath":"articles/cobalt-strike-beacon-extractor"},"type":"Article","imageUrl":"/assets/images/cobalt-strike-beacon-extractor/tools-image.jpg","readingTime":"5 min read","series":"","url":"/cobalt-strike-beacon-extractor","headings":[{"level":2,"title":"Overview","href":"#overview"},{"level":2,"title":"Getting Started","href":"#getting-started"},{"level":3,"title":"Docker","href":"#docker"},{"level":2,"title":"Using an Elastic Cloud instance (this is a randomly generated example)","href":"#using-an-elastic-cloud-instance-this-is-a-randomly-generated-example"},{"level":2,"title":"Default output will use localhost:9092, see reference config","href":"#default-output-will-use-localhost9092-see-reference-config"},{"level":4,"title":"Filter by time","href":"#filter-by-time"},{"level":4,"title":"Pipe output to other tools","href":"#pipe-output-to-other-tools"},{"level":3,"title":"Running it Locally","href":"#running-it-locally"}],"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":"Tools","slug":"tools","body":{"raw":"","code":"var Component=(()=\u003e{var x=Object.create;var s=Object.defineProperty;var l=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),d=(t,n)=\u003e{for(var e in n)s(t,e,{get:n[e],enumerable:!0})},c=(t,n,e,a)=\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:!(a=l(n,r))||a.enumerable});return t};var p=(t,n,e)=\u003e(e=t!=null?x(_(t)):{},c(n||!t||!t.__esModule?s(e,\"default\",{value:t,enumerable:!0}):e,t)),M=t=\u003ec(s({},\"__esModule\",{value:!0}),t);var i=j((h,u)=\u003e{u.exports=_jsx_runtime});var X={};d(X,{default:()=\u003eF,frontmatter:()=\u003eC});var o=p(i()),C={title:\"Tools\",slug:\"tools\"};function m(t){return(0,o.jsx)(o.Fragment,{})}function D(t={}){let{wrapper:n}=t.components||{};return n?(0,o.jsx)(n,Object.assign({},t,{children:(0,o.jsx)(m,t)})):m(t)}var F=D;return M(X);})();\n;return Component;"},"_id":"categories/tools.mdx","_raw":{"sourceFilePath":"categories/tools.mdx","sourceFileName":"tools.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/tools"},"type":"Category","url":"/categories/tools"}]},{"title":"EMOTET Configuration Extractor","slug":"emotet-configuration-extractor","date":"2022-12-06","description":"Python script to extract the configuration from EMOTET samples.","image":"tools-image.jpg","subtitle":"Configuration extraction tool for the EMOTET malware.","tags":["emotet"],"body":{"raw":"\nPython script to extract the payload from EMOTET samples.\n\n[Download emotet-configuration-extractor.tar.gz](https://assets.contentstack.io/v3/assets/bltefdd0b53724fa2ce/blte2addf7080c31792/635ad4a5a739cc5f6cbd595e/emotet-configuration-extractor.tar.gz)\n\n\u003e For information on the EMOTET malware check out the following resources:\n\u003e\n\u003e - [EMOTET Dynamic Configuration Extraction](https://www.elastic.co/security-labs/emotet-dynamic-configuration-extraction)\n\n## Getting started\n\n### Docker\n\nThe recommended and easiest way to get going is to use Docker. From the directory this README is in, you can build a local container.\n\n```\ndocker build . -t emotet-config-extractor\n```\n\nThen we run the container with the **-v** flag to map a host directory to the docker container directory.\n\n```\ndocker run -ti --rm -v $(pwd)/data:/data emotet-config-extractor:latest --help\n```\n\n### Running it locally\n\nAs mentioned above, Docker is the recommended approach to running this project, however you can also run this locally. This project uses [Poetry](https://python-poetry.org/) to manage dependencies, testing, and metadata. If you have Poetry installed already, from this directory, you can simply run the following commands to run the tool. This will setup a virtual environment, install the dependencies, activate the virtual environment, and run the console script.\n\n```\npoetry lock\npoetry install\npoetry shell\nemotet-config-extractor --help\n```\n\n## Usage\n\nAll samples need to be unpacked prior to execution extraction attempts.\n\nOur extractor takes either a directory of samples with **-d** option or **-f** for a single sample and then can output parts of the configuration of note, specifically:\n\n- **-k** : extract the encryption keys\n- **-c** : extract the C2 information\n- **-s** : extract the wide-character strings\n- **-a** : extract the ASCII character strings\n\n```\ndocker run -ti --rm -v $(pwd)/data:/data emotet-config-extractor:latest -d \"C:\\tmp\\samples\"\n```\n\n![EMOTET configuration extractor](/assets/images/emotet-configuration-extractor/image.jpg)\n\nYou can collect the extracted configurations from the directory you set when running the extractor.\n","code":"var Component=(()=\u003e{var h=Object.create;var i=Object.defineProperty;var g=Object.getOwnPropertyDescriptor;var u=Object.getOwnPropertyNames;var p=Object.getPrototypeOf,m=Object.prototype.hasOwnProperty;var f=(n,t)=\u003e()=\u003e(t||n((t={exports:{}}).exports,t),t.exports),y=(n,t)=\u003e{for(var r in t)i(n,r,{get:t[r],enumerable:!0})},a=(n,t,r,c)=\u003e{if(t\u0026\u0026typeof t==\"object\"||typeof t==\"function\")for(let o of u(t))!m.call(n,o)\u0026\u0026o!==r\u0026\u0026i(n,o,{get:()=\u003et[o],enumerable:!(c=g(t,o))||c.enumerable});return n};var x=(n,t,r)=\u003e(r=n!=null?h(p(n)):{},a(t||!n||!n.__esModule?i(r,\"default\",{value:n,enumerable:!0}):r,n)),w=n=\u003ea(i({},\"__esModule\",{value:!0}),n);var s=f((j,l)=\u003e{l.exports=_jsx_runtime});var b={};y(b,{default:()=\u003eT,frontmatter:()=\u003ek});var e=x(s()),k={title:\"EMOTET Configuration Extractor\",slug:\"emotet-configuration-extractor\",date:\"2022-12-06\",subtitle:\"Configuration extraction tool for the EMOTET malware.\",description:\"Python script to extract the configuration from EMOTET samples.\",author:[{slug:\"elastic-security-labs\"}],image:\"tools-image.jpg\",category:[{slug:\"tools\"}],tags:[\"emotet\"]};function d(n){let t=Object.assign({p:\"p\",a:\"a\",blockquote:\"blockquote\",ul:\"ul\",li:\"li\",h2:\"h2\",h3:\"h3\",pre:\"pre\",code:\"code\",strong:\"strong\",img:\"img\"},n.components);return(0,e.jsxs)(e.Fragment,{children:[(0,e.jsx)(t.p,{children:\"Python script to extract the payload from EMOTET samples.\"}),`\n`,(0,e.jsx)(t.p,{children:(0,e.jsx)(t.a,{href:\"https://assets.contentstack.io/v3/assets/bltefdd0b53724fa2ce/blte2addf7080c31792/635ad4a5a739cc5f6cbd595e/emotet-configuration-extractor.tar.gz\",rel:\"nofollow\",children:\"Download emotet-configuration-extractor.tar.gz\"})}),`\n`,(0,e.jsxs)(t.blockquote,{children:[`\n`,(0,e.jsx)(t.p,{children:\"For information on the EMOTET malware check out the following resources:\"}),`\n`,(0,e.jsxs)(t.ul,{children:[`\n`,(0,e.jsx)(t.li,{children:(0,e.jsx)(t.a,{href:\"https://www.elastic.co/security-labs/emotet-dynamic-configuration-extraction\",rel:\"nofollow\",children:\"EMOTET Dynamic Configuration Extraction\"})}),`\n`]}),`\n`]}),`\n`,(0,e.jsx)(t.h2,{id:\"getting-started\",children:\"Getting started\"}),`\n`,(0,e.jsx)(t.h3,{id:\"docker\",children:\"Docker\"}),`\n`,(0,e.jsx)(t.p,{children:\"The recommended and easiest way to get going is to use Docker. From the directory this README is in, you can build a local container.\"}),`\n`,(0,e.jsx)(t.pre,{children:(0,e.jsx)(t.code,{children:`docker build . -t emotet-config-extractor\n`})}),`\n`,(0,e.jsxs)(t.p,{children:[\"Then we run the container with the \",(0,e.jsx)(t.strong,{children:\"-v\"}),\" flag to map a host directory to the docker container directory.\"]}),`\n`,(0,e.jsx)(t.pre,{children:(0,e.jsx)(t.code,{children:`docker run -ti --rm -v $(pwd)/data:/data emotet-config-extractor:latest --help\n`})}),`\n`,(0,e.jsx)(t.h3,{id:\"running-it-locally\",children:\"Running it locally\"}),`\n`,(0,e.jsxs)(t.p,{children:[\"As mentioned above, Docker is the recommended approach to running this project, however you can also run this locally. This project uses \",(0,e.jsx)(t.a,{href:\"https://python-poetry.org/\",rel:\"nofollow\",children:\"Poetry\"}),\" to manage dependencies, testing, and metadata. If you have Poetry installed already, from this directory, you can simply run the following commands to run the tool. This will setup a virtual environment, install the dependencies, activate the virtual environment, and run the console script.\"]}),`\n`,(0,e.jsx)(t.pre,{children:(0,e.jsx)(t.code,{children:`poetry lock\npoetry install\npoetry shell\nemotet-config-extractor --help\n`})}),`\n`,(0,e.jsx)(t.h2,{id:\"usage\",children:\"Usage\"}),`\n`,(0,e.jsx)(t.p,{children:\"All samples need to be unpacked prior to execution extraction attempts.\"}),`\n`,(0,e.jsxs)(t.p,{children:[\"Our extractor takes either a directory of samples with \",(0,e.jsx)(t.strong,{children:\"-d\"}),\" option or \",(0,e.jsx)(t.strong,{children:\"-f\"}),\" for a single sample and then can output parts of the configuration of note, specifically:\"]}),`\n`,(0,e.jsxs)(t.ul,{children:[`\n`,(0,e.jsxs)(t.li,{children:[(0,e.jsx)(t.strong,{children:\"-k\"}),\" : extract the encryption keys\"]}),`\n`,(0,e.jsxs)(t.li,{children:[(0,e.jsx)(t.strong,{children:\"-c\"}),\" : extract the C2 information\"]}),`\n`,(0,e.jsxs)(t.li,{children:[(0,e.jsx)(t.strong,{children:\"-s\"}),\" : extract the wide-character strings\"]}),`\n`,(0,e.jsxs)(t.li,{children:[(0,e.jsx)(t.strong,{children:\"-a\"}),\" : extract the ASCII character strings\"]}),`\n`]}),`\n`,(0,e.jsx)(t.pre,{children:(0,e.jsx)(t.code,{children:`docker run -ti --rm -v $(pwd)/data:/data emotet-config-extractor:latest -d \"C:\\\\tmp\\\\samples\"\n`})}),`\n`,(0,e.jsx)(t.p,{children:(0,e.jsx)(t.img,{src:\"/assets/images/emotet-configuration-extractor/image.jpg\",alt:\"EMOTET configuration extractor\",width:\"1440\",height:\"1013\"})}),`\n`,(0,e.jsx)(t.p,{children:\"You can collect the extracted configurations from the directory you set when running the extractor.\"})]})}function E(n={}){let{wrapper:t}=n.components||{};return t?(0,e.jsx)(t,Object.assign({},n,{children:(0,e.jsx)(d,n)})):d(n)}var T=E;return w(b);})();\n;return Component;"},"_id":"articles/emotet-configuration-extractor.mdx","_raw":{"sourceFilePath":"articles/emotet-configuration-extractor.mdx","sourceFileName":"emotet-configuration-extractor.mdx","sourceFileDir":"articles","contentType":"mdx","flattenedPath":"articles/emotet-configuration-extractor"},"type":"Article","imageUrl":"/assets/images/emotet-configuration-extractor/tools-image.jpg","readingTime":"2 min read","series":"","url":"/emotet-configuration-extractor","headings":[{"level":2,"title":"Getting started","href":"#getting-started"},{"level":3,"title":"Docker","href":"#docker"},{"level":3,"title":"Running it locally","href":"#running-it-locally"},{"level":2,"title":"Usage","href":"#usage"}],"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":"Tools","slug":"tools","body":{"raw":"","code":"var Component=(()=\u003e{var x=Object.create;var s=Object.defineProperty;var l=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),d=(t,n)=\u003e{for(var e in n)s(t,e,{get:n[e],enumerable:!0})},c=(t,n,e,a)=\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:!(a=l(n,r))||a.enumerable});return t};var p=(t,n,e)=\u003e(e=t!=null?x(_(t)):{},c(n||!t||!t.__esModule?s(e,\"default\",{value:t,enumerable:!0}):e,t)),M=t=\u003ec(s({},\"__esModule\",{value:!0}),t);var i=j((h,u)=\u003e{u.exports=_jsx_runtime});var X={};d(X,{default:()=\u003eF,frontmatter:()=\u003eC});var o=p(i()),C={title:\"Tools\",slug:\"tools\"};function m(t){return(0,o.jsx)(o.Fragment,{})}function D(t={}){let{wrapper:n}=t.components||{};return n?(0,o.jsx)(n,Object.assign({},t,{children:(0,o.jsx)(m,t)})):m(t)}var F=D;return M(X);})();\n;return Component;"},"_id":"categories/tools.mdx","_raw":{"sourceFilePath":"categories/tools.mdx","sourceFileName":"tools.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/tools"},"type":"Category","url":"/categories/tools"}]},{"title":"ICEDID Configuration Extractor","slug":"icedid-configuration-extractor","date":"2022-12-06","description":"Python script to extract the configuration from ICEDID samples.","image":"tools-image.jpg","subtitle":"Configuration extraction tool for ICEDID malware.","tags":["icedid","ref1021"],"body":{"raw":"\nPython script to extract the payload from ICEDID samples.\n\n[Download icedid-configuration-extractor.tar.gz](https://assets.contentstack.io/v3/assets/bltefdd0b53724fa2ce/blt95ce19ae8cffda29/6351abcf20f42038fb989fae/icedid-config-extractor.tar.gz)\n\n\u003e For information on the ICEDID malware and network infrastructure, check out the following resources:\n\u003e\n\u003e - [ICEDIDs network infrastructure is alive and well](https://www.elastic.co/security-labs/icedids-network-infrastructure-is-alive-and-well)\n\u003e - [ICEDID network infrastructure checking utility](https://assets.contentstack.io/v3/assets/bltefdd0b53724fa2ce/bltb86bffd1aef20c5b/6351aba34e565f1cdce29da5/icedid-checker.tar.gz)\n\n## Getting started\n\n### Docker\n\nThe recommended and easiest way to get going is to use Docker. From the directory this README is in, you can build a local container.\n\n```\ndocker build . -t icedid_loader_config_extractor\n```\n\nThen we run the container with the -v flag to map a host directory to the docker container directory.\n\n```\ndocker run -ti --rm -v $(pwd)/data:/data icedid_loader_config_extractor:latest --help\n```\n\n### Running it locally\n\nAs mentioned above, Docker is the recommended approach to running this project, however you can also run this locally. This project uses [Poetry](https://python-poetry.org/) to manage dependencies, testing, and metadata. If you have Poetry installed already, from this directory, you can simply run the following commands to run the tool. This will setup a virtual environment, install the dependencies, activate the virtual environment, and run the console script.\n\n```\npoetry lock\npoetry install\npoetry shell\npoetry lock\npoetry install\npoetry shell\nicedid_loader_config_extractor --help\n```\n\n## Usage\n\nAll samples need to be unpacked prior to execution extraction attempts.\n\nWe can either specify a single sample with **-f** option or a directory of samples with **-d**.\n\n```\ndocker run -ti --rm -v $(pwd)/data:/data icedid_loader_config_extractor:latest -d \"C:\\tmp\\samples\"\n```\n\n![ICEDID configuration extractor](/assets/images/icedid-configuration-extractor/196841115-5a3a0d95-8df4-45c2-9baa-264cfa9530e9.jpg)\n\nYou can collect the extracted configurations from the directory you set when running the extractor.\n","code":"var Component=(()=\u003e{var h=Object.create;var i=Object.defineProperty;var u=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var f=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var m=(n,e)=\u003e()=\u003e(e||n((e={exports:{}}).exports,e),e.exports),y=(n,e)=\u003e{for(var r in e)i(n,r,{get:e[r],enumerable:!0})},a=(n,e,r,c)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let o of p(e))!g.call(n,o)\u0026\u0026o!==r\u0026\u0026i(n,o,{get:()=\u003ee[o],enumerable:!(c=u(e,o))||c.enumerable});return n};var w=(n,e,r)=\u003e(r=n!=null?h(f(n)):{},a(e||!n||!n.__esModule?i(r,\"default\",{value:n,enumerable:!0}):r,n)),x=n=\u003ea(i({},\"__esModule\",{value:!0}),n);var d=m((v,l)=\u003e{l.exports=_jsx_runtime});var _={};y(_,{default:()=\u003eD,frontmatter:()=\u003eb});var t=w(d()),b={title:\"ICEDID Configuration Extractor\",slug:\"icedid-configuration-extractor\",date:\"2022-12-06\",subtitle:\"Configuration extraction tool for ICEDID malware.\",description:\"Python script to extract the configuration from ICEDID samples.\",author:[{slug:\"elastic-security-labs\"}],image:\"tools-image.jpg\",category:[{slug:\"tools\"}],tags:[\"icedid\",\"ref1021\"]};function s(n){let e=Object.assign({p:\"p\",a:\"a\",blockquote:\"blockquote\",ul:\"ul\",li:\"li\",h2:\"h2\",h3:\"h3\",pre:\"pre\",code:\"code\",strong:\"strong\",img:\"img\"},n.components);return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(e.p,{children:\"Python script to extract the payload from ICEDID samples.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.a,{href:\"https://assets.contentstack.io/v3/assets/bltefdd0b53724fa2ce/blt95ce19ae8cffda29/6351abcf20f42038fb989fae/icedid-config-extractor.tar.gz\",rel:\"nofollow\",children:\"Download icedid-configuration-extractor.tar.gz\"})}),`\n`,(0,t.jsxs)(e.blockquote,{children:[`\n`,(0,t.jsx)(e.p,{children:\"For information on the ICEDID malware and network infrastructure, check out the following resources:\"}),`\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/icedids-network-infrastructure-is-alive-and-well\",rel:\"nofollow\",children:\"ICEDIDs network infrastructure is alive and well\"})}),`\n`,(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:\"https://assets.contentstack.io/v3/assets/bltefdd0b53724fa2ce/bltb86bffd1aef20c5b/6351aba34e565f1cdce29da5/icedid-checker.tar.gz\",rel:\"nofollow\",children:\"ICEDID network infrastructure checking utility\"})}),`\n`]}),`\n`]}),`\n`,(0,t.jsx)(e.h2,{id:\"getting-started\",children:\"Getting started\"}),`\n`,(0,t.jsx)(e.h3,{id:\"docker\",children:\"Docker\"}),`\n`,(0,t.jsx)(e.p,{children:\"The recommended and easiest way to get going is to use Docker. From the directory this README is in, you can build a local container.\"}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`docker build . -t icedid_loader_config_extractor\n`})}),`\n`,(0,t.jsx)(e.p,{children:\"Then we run the container with the -v flag to map a host directory to the docker container directory.\"}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`docker run -ti --rm -v $(pwd)/data:/data icedid_loader_config_extractor:latest --help\n`})}),`\n`,(0,t.jsx)(e.h3,{id:\"running-it-locally\",children:\"Running it locally\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"As mentioned above, Docker is the recommended approach to running this project, however you can also run this locally. This project uses \",(0,t.jsx)(e.a,{href:\"https://python-poetry.org/\",rel:\"nofollow\",children:\"Poetry\"}),\" to manage dependencies, testing, and metadata. If you have Poetry installed already, from this directory, you can simply run the following commands to run the tool. This will setup a virtual environment, install the dependencies, activate the virtual environment, and run the console script.\"]}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`poetry lock\npoetry install\npoetry shell\npoetry lock\npoetry install\npoetry shell\nicedid_loader_config_extractor --help\n`})}),`\n`,(0,t.jsx)(e.h2,{id:\"usage\",children:\"Usage\"}),`\n`,(0,t.jsx)(e.p,{children:\"All samples need to be unpacked prior to execution extraction attempts.\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"We can either specify a single sample with \",(0,t.jsx)(e.strong,{children:\"-f\"}),\" option or a directory of samples with \",(0,t.jsx)(e.strong,{children:\"-d\"}),\".\"]}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`docker run -ti --rm -v $(pwd)/data:/data icedid_loader_config_extractor:latest -d \"C:\\\\tmp\\\\samples\"\n`})}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/icedid-configuration-extractor/196841115-5a3a0d95-8df4-45c2-9baa-264cfa9530e9.jpg\",alt:\"ICEDID configuration extractor\",width:\"861\",height:\"313\"})}),`\n`,(0,t.jsx)(e.p,{children:\"You can collect the extracted configurations from the directory you set when running the extractor.\"})]})}function k(n={}){let{wrapper:e}=n.components||{};return e?(0,t.jsx)(e,Object.assign({},n,{children:(0,t.jsx)(s,n)})):s(n)}var D=k;return x(_);})();\n;return Component;"},"_id":"articles/icedid-configuration-extractor.mdx","_raw":{"sourceFilePath":"articles/icedid-configuration-extractor.mdx","sourceFileName":"icedid-configuration-extractor.mdx","sourceFileDir":"articles","contentType":"mdx","flattenedPath":"articles/icedid-configuration-extractor"},"type":"Article","imageUrl":"/assets/images/icedid-configuration-extractor/tools-image.jpg","readingTime":"2 min read","series":"","url":"/icedid-configuration-extractor","headings":[{"level":2,"title":"Getting started","href":"#getting-started"},{"level":3,"title":"Docker","href":"#docker"},{"level":3,"title":"Running it locally","href":"#running-it-locally"},{"level":2,"title":"Usage","href":"#usage"}],"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":"Tools","slug":"tools","body":{"raw":"","code":"var Component=(()=\u003e{var x=Object.create;var s=Object.defineProperty;var l=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),d=(t,n)=\u003e{for(var e in n)s(t,e,{get:n[e],enumerable:!0})},c=(t,n,e,a)=\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:!(a=l(n,r))||a.enumerable});return t};var p=(t,n,e)=\u003e(e=t!=null?x(_(t)):{},c(n||!t||!t.__esModule?s(e,\"default\",{value:t,enumerable:!0}):e,t)),M=t=\u003ec(s({},\"__esModule\",{value:!0}),t);var i=j((h,u)=\u003e{u.exports=_jsx_runtime});var X={};d(X,{default:()=\u003eF,frontmatter:()=\u003eC});var o=p(i()),C={title:\"Tools\",slug:\"tools\"};function m(t){return(0,o.jsx)(o.Fragment,{})}function D(t={}){let{wrapper:n}=t.components||{};return n?(0,o.jsx)(n,Object.assign({},t,{children:(0,o.jsx)(m,t)})):m(t)}var F=D;return M(X);})();\n;return Component;"},"_id":"categories/tools.mdx","_raw":{"sourceFilePath":"categories/tools.mdx","sourceFileName":"tools.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/tools"},"type":"Category","url":"/categories/tools"}]},{"title":"PARALLAX Payload Extractor","slug":"parallax-payload-extractor","date":"2022-12-06","description":"Python script to extract the payload from PARALLAX samples.","image":"tools-image.jpg","tags":["parallax","ref2731"],"body":{"raw":"\nPython script to extract the payload from PARALLAX samples.\n\n[Download parallax-payload-extractor.tar.gz](https://assets.contentstack.io/v3/assets/bltefdd0b53724fa2ce/bltdcec03c5c91923f5/633613d524bebb2394c2773d/parallax-payload-extractor.tar.gz)\n\n\u003e For information on the PARALLAX malware loader and campaign observations, check out our [blog posts](https://elastic.co/security-labs/exploring-the-ref2731-intrusion-set) detailing this intrusion set.\n\n## Getting started\n\n### Docker\n\nThe recommended and easiest way to get going is to use Docker. From the directory this README is in, you can build a local container.\n\n```\ndocker build . -t parallax_loader_payload_extractor\n```\n\nThen we run the container with the -v flag to map a host directory to the docker container directory.\n\n```\ndocker run -ti --rm -v $(pwd)/data:/data parallax_loader_payload_extractor:latest --help\n```\n\n### Running it locally\n\nAs mentioned above, Docker is the recommended approach to running this project, however you can also run this locally. This project uses [Poetry](https://python-poetry.org/) to manage dependencies, testing, and metadata. If you have Poetry installed already, from this directory, you can simply run the following commands to run the tool. This will setup a virtual environment, install the dependencies, activate the virtual environment, and run the console script.\n\n```\npoetry lock\npoetry install\npoetry shell\nparallax_loader_payload_extractor --help\n```\n\n## Usage\n\nWe can either specify a single sample with **-f** option or a directory of samples with **-d**. You can use the -o switch to set the output directory of the payloads.\n\n```\ndocker run -ti --rm -v $(pwd)/data:/data parallax_loader_payload_extractor:latest -d /data -o /data\n```\n\n![PARALLAX payload extractor](/assets/images/parallax-payload-extractor/image41.jpg)\n\nYou can collect the extracted payloads from the directory you set when running the extractor, the data directory in the root of the extractor in the above example.\n","code":"var Component=(()=\u003e{var h=Object.create;var n=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var u=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,y=Object.prototype.hasOwnProperty;var m=(a,e)=\u003e()=\u003e(e||a((e={exports:{}}).exports,e),e.exports),x=(a,e)=\u003e{for(var r in e)n(a,r,{get:e[r],enumerable:!0})},i=(a,e,r,l)=\u003e{if(e\u0026\u0026typeof e==\"object\"||typeof e==\"function\")for(let o of u(e))!y.call(a,o)\u0026\u0026o!==r\u0026\u0026n(a,o,{get:()=\u003ee[o],enumerable:!(l=p(e,o))||l.enumerable});return a};var f=(a,e,r)=\u003e(r=a!=null?h(g(a)):{},i(e||!a||!a.__esModule?n(r,\"default\",{value:a,enumerable:!0}):r,a)),b=a=\u003ei(n({},\"__esModule\",{value:!0}),a);var d=m((j,c)=\u003e{c.exports=_jsx_runtime});var k={};x(k,{default:()=\u003eA,frontmatter:()=\u003ew});var t=f(d()),w={title:\"PARALLAX Payload Extractor\",slug:\"parallax-payload-extractor\",date:\"2022-12-06\",description:\"Python script to extract the payload from PARALLAX samples.\",author:[{slug:\"elastic-security-labs\"}],image:\"tools-image.jpg\",category:[{slug:\"tools\"}],tags:[\"parallax\",\"ref2731\"]};function s(a){let e=Object.assign({p:\"p\",a:\"a\",blockquote:\"blockquote\",h2:\"h2\",h3:\"h3\",pre:\"pre\",code:\"code\",strong:\"strong\",img:\"img\"},a.components);return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(e.p,{children:\"Python script to extract the payload from PARALLAX samples.\"}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.a,{href:\"https://assets.contentstack.io/v3/assets/bltefdd0b53724fa2ce/bltdcec03c5c91923f5/633613d524bebb2394c2773d/parallax-payload-extractor.tar.gz\",rel:\"nofollow\",children:\"Download parallax-payload-extractor.tar.gz\"})}),`\n`,(0,t.jsxs)(e.blockquote,{children:[`\n`,(0,t.jsxs)(e.p,{children:[\"For information on the PARALLAX malware loader and campaign observations, check out our \",(0,t.jsx)(e.a,{href:\"https://elastic.co/security-labs/exploring-the-ref2731-intrusion-set\",rel:\"nofollow\",children:\"blog posts\"}),\" detailing this intrusion set.\"]}),`\n`]}),`\n`,(0,t.jsx)(e.h2,{id:\"getting-started\",children:\"Getting started\"}),`\n`,(0,t.jsx)(e.h3,{id:\"docker\",children:\"Docker\"}),`\n`,(0,t.jsx)(e.p,{children:\"The recommended and easiest way to get going is to use Docker. From the directory this README is in, you can build a local container.\"}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`docker build . -t parallax_loader_payload_extractor\n`})}),`\n`,(0,t.jsx)(e.p,{children:\"Then we run the container with the -v flag to map a host directory to the docker container directory.\"}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`docker run -ti --rm -v $(pwd)/data:/data parallax_loader_payload_extractor:latest --help\n`})}),`\n`,(0,t.jsx)(e.h3,{id:\"running-it-locally\",children:\"Running it locally\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"As mentioned above, Docker is the recommended approach to running this project, however you can also run this locally. This project uses \",(0,t.jsx)(e.a,{href:\"https://python-poetry.org/\",rel:\"nofollow\",children:\"Poetry\"}),\" to manage dependencies, testing, and metadata. If you have Poetry installed already, from this directory, you can simply run the following commands to run the tool. This will setup a virtual environment, install the dependencies, activate the virtual environment, and run the console script.\"]}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`poetry lock\npoetry install\npoetry shell\nparallax_loader_payload_extractor --help\n`})}),`\n`,(0,t.jsx)(e.h2,{id:\"usage\",children:\"Usage\"}),`\n`,(0,t.jsxs)(e.p,{children:[\"We can either specify a single sample with \",(0,t.jsx)(e.strong,{children:\"-f\"}),\" option or a directory of samples with \",(0,t.jsx)(e.strong,{children:\"-d\"}),\". You can use the -o switch to set the output directory of the payloads.\"]}),`\n`,(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{children:`docker run -ti --rm -v $(pwd)/data:/data parallax_loader_payload_extractor:latest -d /data -o /data\n`})}),`\n`,(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:\"/assets/images/parallax-payload-extractor/image41.jpg\",alt:\"PARALLAX payload extractor\",width:\"1440\",height:\"389\"})}),`\n`,(0,t.jsx)(e.p,{children:\"You can collect the extracted payloads from the directory you set when running the extractor, the data directory in the root of the extractor in the above example.\"})]})}function _(a={}){let{wrapper:e}=a.components||{};return e?(0,t.jsx)(e,Object.assign({},a,{children:(0,t.jsx)(s,a)})):s(a)}var A=_;return b(k);})();\n;return Component;"},"_id":"articles/parallax-payload-extractor.mdx","_raw":{"sourceFilePath":"articles/parallax-payload-extractor.mdx","sourceFileName":"parallax-payload-extractor.mdx","sourceFileDir":"articles","contentType":"mdx","flattenedPath":"articles/parallax-payload-extractor"},"type":"Article","imageUrl":"/assets/images/parallax-payload-extractor/tools-image.jpg","readingTime":"2 min read","series":"","url":"/parallax-payload-extractor","headings":[{"level":2,"title":"Getting started","href":"#getting-started"},{"level":3,"title":"Docker","href":"#docker"},{"level":3,"title":"Running it locally","href":"#running-it-locally"},{"level":2,"title":"Usage","href":"#usage"}],"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":"Tools","slug":"tools","body":{"raw":"","code":"var Component=(()=\u003e{var x=Object.create;var s=Object.defineProperty;var l=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),d=(t,n)=\u003e{for(var e in n)s(t,e,{get:n[e],enumerable:!0})},c=(t,n,e,a)=\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:!(a=l(n,r))||a.enumerable});return t};var p=(t,n,e)=\u003e(e=t!=null?x(_(t)):{},c(n||!t||!t.__esModule?s(e,\"default\",{value:t,enumerable:!0}):e,t)),M=t=\u003ec(s({},\"__esModule\",{value:!0}),t);var i=j((h,u)=\u003e{u.exports=_jsx_runtime});var X={};d(X,{default:()=\u003eF,frontmatter:()=\u003eC});var o=p(i()),C={title:\"Tools\",slug:\"tools\"};function m(t){return(0,o.jsx)(o.Fragment,{})}function D(t={}){let{wrapper:n}=t.components||{};return n?(0,o.jsx)(n,Object.assign({},t,{children:(0,o.jsx)(m,t)})):m(t)}var F=D;return M(X);})();\n;return Component;"},"_id":"categories/tools.mdx","_raw":{"sourceFilePath":"categories/tools.mdx","sourceFileName":"tools.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/tools"},"type":"Category","url":"/categories/tools"}]},{"title":"QBOT Configuration Extractor","slug":"qbot-configuration-extractor","date":"2022-12-06","description":"Python script to extract the configuration from QBOT samples.","image":"tools-image.jpg","subtitle":"Configuration extraction tool for QBOT malware","tags":["qbot","ref3726","qakbot"],"body":{"raw":"\nPython script to extract the configuration from QBOT samples.\n\n[Download qbot-config-extractor.tar.gz](https://assets.contentstack.io/v3/assets/bltefdd0b53724fa2ce/blta4523f3b586ba6ac/62e16e26d2f5267009ac073a/qbot-config-extractor.tar.gz)\n\n## Getting Started\n\nThis tool provides a Python module and command line tool that will extract configurations from the QBOT malware samples and dump the results to screen.\n\n\u003e For information on the QBOT attack pattern and malware analysis, check out our blog posts detailing this:\n\u003e\n\u003e - [Exploring the QBOT Attack Pattern](https://www.elastic.co/security-labs/exploring-the-qbot-attack-pattern)\n\u003e - [QBOT Malware Analysis](https://www.elastic.co/security-labs/qbot-malware-analysis)\n\n### Docker\n\nWe can easily run the extractor with Docker, first we need to build the image:\n\n```\ndocker build . -t qbot-config-extractor\n```\n\nThen we run the container with the **-v** flag to map a host directory to the docker container directory:\n\n```\ndocker run -ti --rm -v \\\n\"$(pwd)/data\":/data qbot-config-extractor:latest -d /data/\n```\n\nWe can either specify a single sample with **-f** option or a directory of samples with **-d**.\n\n```\n$ docker run -ti --rm -v $(pwd)/data:/data qbot-config-extractor:latest -f data/c2ba065654f13612ae63bca7f972ea91c6fe97291caeaaa3a28a180fb1912b3a\n\n=== Strings ===\n# Blob address: 0x100840a0\n# Key address: 0x10084040\n[0x0]: ProgramData\n[0xc]: /t4\n[0x10]: EBBA\n[0x15]: netstat -nao\n[0x22]: jHxastDcds)oMc=jvh7wdUhxcsdt2\n[0x40]: schtasks.exe /Create /RU \"NT AUTHORITY\\SYSTEM\" /SC ONSTART /TN %u /TR \"%s\" /NP /F\n\n...truncated...\n\n=== RESOURCE 1 ===\nKey: b'\\\\System32\\\\WindowsPowerShel1\\\\v1.0\\\\powershel1.exe'\nType: DataType.DOMAINS\n41.228.22.180:443\n47.23.89.62:995\n176.67.56.94:443\n103.107.113.120:443\n148.64.96.100:443\n47.180.172.159:443\n181.118.183.98:443\n\n...truncated...\n```\n\n### Running it Locally\n\nAs mentioned above, Docker is the recommended approach to running this project, however you can also run this locally. This project uses [Poetry](https://python-poetry.org/) to manage dependencies, testing, and metadata. If you have Poetry installed already, from this directory, you can simply run the following commands to run the tool. This will setup a virtual environment, install the dependencies, activate the virtual environment, and run the console script.\n\n```\npoetry lock\npoetry install\npoetry shell\nqbot-config-extractor -h\n```\n\nOnce that works, you can do the same sort of things as mentioned in the Docker instructions above.\n","code":"var Component=(()=\u003e{var h=Object.create;var a=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var u=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var m=(n,t)=\u003e()=\u003e(t||n((t={exports:{}}).exports,t),t.exports),y=(n,t)=\u003e{for(var o in t)a(n,o,{get:t[o],enumerable:!0})},c=(n,t,o,i)=\u003e{if(t\u0026\u0026typeof t==\"object\"||typeof t==\"function\")for(let r of u(t))!f.call(n,r)\u0026\u0026r!==o\u0026\u0026a(n,r,{get:()=\u003et[r],enumerable:!(i=p(t,r))||i.enumerable});return n};var b=(n,t,o)=\u003e(o=n!=null?h(g(n)):{},c(t||!n||!n.__esModule?a(o,\"default\",{value:n,enumerable:!0}):o,n)),x=n=\u003ec(a({},\"__esModule\",{value:!0}),n);var s=m((q,l)=\u003e{l.exports=_jsx_runtime});var v={};y(v,{default:()=\u003ek,frontmatter:()=\u003ew});var e=b(s()),w={title:\"QBOT Configuration Extractor\",slug:\"qbot-configuration-extractor\",date:\"2022-12-06\",subtitle:\"Configuration extraction tool for QBOT malware\",description:\"Python script to extract the configuration from QBOT samples.\",author:[{slug:\"elastic-security-labs\"}],image:\"tools-image.jpg\",category:[{slug:\"tools\"}],tags:[\"qbot\",\"ref3726\",\"qakbot\"]};function d(n){let t=Object.assign({p:\"p\",a:\"a\",h2:\"h2\",blockquote:\"blockquote\",ul:\"ul\",li:\"li\",h3:\"h3\",pre:\"pre\",code:\"code\",strong:\"strong\"},n.components);return(0,e.jsxs)(e.Fragment,{children:[(0,e.jsx)(t.p,{children:\"Python script to extract the configuration from QBOT samples.\"}),`\n`,(0,e.jsx)(t.p,{children:(0,e.jsx)(t.a,{href:\"https://assets.contentstack.io/v3/assets/bltefdd0b53724fa2ce/blta4523f3b586ba6ac/62e16e26d2f5267009ac073a/qbot-config-extractor.tar.gz\",rel:\"nofollow\",children:\"Download qbot-config-extractor.tar.gz\"})}),`\n`,(0,e.jsx)(t.h2,{id:\"getting-started\",children:\"Getting Started\"}),`\n`,(0,e.jsx)(t.p,{children:\"This tool provides a Python module and command line tool that will extract configurations from the QBOT malware samples and dump the results to screen.\"}),`\n`,(0,e.jsxs)(t.blockquote,{children:[`\n`,(0,e.jsx)(t.p,{children:\"For information on the QBOT attack pattern and malware analysis, check out our blog posts detailing this:\"}),`\n`,(0,e.jsxs)(t.ul,{children:[`\n`,(0,e.jsx)(t.li,{children:(0,e.jsx)(t.a,{href:\"https://www.elastic.co/security-labs/exploring-the-qbot-attack-pattern\",rel:\"nofollow\",children:\"Exploring the QBOT Attack Pattern\"})}),`\n`,(0,e.jsx)(t.li,{children:(0,e.jsx)(t.a,{href:\"https://www.elastic.co/security-labs/qbot-malware-analysis\",rel:\"nofollow\",children:\"QBOT Malware Analysis\"})}),`\n`]}),`\n`]}),`\n`,(0,e.jsx)(t.h3,{id:\"docker\",children:\"Docker\"}),`\n`,(0,e.jsx)(t.p,{children:\"We can easily run the extractor with Docker, first we need to build the image:\"}),`\n`,(0,e.jsx)(t.pre,{children:(0,e.jsx)(t.code,{children:`docker build . -t qbot-config-extractor\n`})}),`\n`,(0,e.jsxs)(t.p,{children:[\"Then we run the container with the \",(0,e.jsx)(t.strong,{children:\"-v\"}),\" flag to map a host directory to the docker container directory:\"]}),`\n`,(0,e.jsx)(t.pre,{children:(0,e.jsx)(t.code,{children:`docker run -ti --rm -v \\\\\n\"$(pwd)/data\":/data qbot-config-extractor:latest -d /data/\n`})}),`\n`,(0,e.jsxs)(t.p,{children:[\"We can either specify a single sample with \",(0,e.jsx)(t.strong,{children:\"-f\"}),\" option or a directory of samples with \",(0,e.jsx)(t.strong,{children:\"-d\"}),\".\"]}),`\n`,(0,e.jsx)(t.pre,{children:(0,e.jsx)(t.code,{children:`$ docker run -ti --rm -v $(pwd)/data:/data qbot-config-extractor:latest -f data/c2ba065654f13612ae63bca7f972ea91c6fe97291caeaaa3a28a180fb1912b3a\n\n=== Strings ===\n# Blob address: 0x100840a0\n# Key address: 0x10084040\n[0x0]: ProgramData\n[0xc]: /t4\n[0x10]: EBBA\n[0x15]: netstat -nao\n[0x22]: jHxastDcds)oMc=jvh7wdUhxcsdt2\n[0x40]: schtasks.exe /Create /RU \"NT AUTHORITY\\\\SYSTEM\" /SC ONSTART /TN %u /TR \"%s\" /NP /F\n\n...truncated...\n\n=== RESOURCE 1 ===\nKey: b'\\\\\\\\System32\\\\\\\\WindowsPowerShel1\\\\\\\\v1.0\\\\\\\\powershel1.exe'\nType: DataType.DOMAINS\n41.228.22.180:443\n47.23.89.62:995\n176.67.56.94:443\n103.107.113.120:443\n148.64.96.100:443\n47.180.172.159:443\n181.118.183.98:443\n\n...truncated...\n`})}),`\n`,(0,e.jsx)(t.h3,{id:\"running-it-locally\",children:\"Running it Locally\"}),`\n`,(0,e.jsxs)(t.p,{children:[\"As mentioned above, Docker is the recommended approach to running this project, however you can also run this locally. This project uses \",(0,e.jsx)(t.a,{href:\"https://python-poetry.org/\",rel:\"nofollow\",children:\"Poetry\"}),\" to manage dependencies, testing, and metadata. If you have Poetry installed already, from this directory, you can simply run the following commands to run the tool. This will setup a virtual environment, install the dependencies, activate the virtual environment, and run the console script.\"]}),`\n`,(0,e.jsx)(t.pre,{children:(0,e.jsx)(t.code,{children:`poetry lock\npoetry install\npoetry shell\nqbot-config-extractor -h\n`})}),`\n`,(0,e.jsx)(t.p,{children:\"Once that works, you can do the same sort of things as mentioned in the Docker instructions above.\"})]})}function T(n={}){let{wrapper:t}=n.components||{};return t?(0,e.jsx)(t,Object.assign({},n,{children:(0,e.jsx)(d,n)})):d(n)}var k=T;return x(v);})();\n;return Component;"},"_id":"articles/qbot-configuration-extractor.mdx","_raw":{"sourceFilePath":"articles/qbot-configuration-extractor.mdx","sourceFileName":"qbot-configuration-extractor.mdx","sourceFileDir":"articles","contentType":"mdx","flattenedPath":"articles/qbot-configuration-extractor"},"type":"Article","imageUrl":"/assets/images/qbot-configuration-extractor/tools-image.jpg","readingTime":"2 min read","series":"","url":"/qbot-configuration-extractor","headings":[{"level":2,"title":"Getting Started","href":"#getting-started"},{"level":3,"title":"Docker","href":"#docker"},{"level":3,"title":"Running it Locally","href":"#running-it-locally"}],"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":"Tools","slug":"tools","body":{"raw":"","code":"var Component=(()=\u003e{var x=Object.create;var s=Object.defineProperty;var l=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),d=(t,n)=\u003e{for(var e in n)s(t,e,{get:n[e],enumerable:!0})},c=(t,n,e,a)=\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:!(a=l(n,r))||a.enumerable});return t};var p=(t,n,e)=\u003e(e=t!=null?x(_(t)):{},c(n||!t||!t.__esModule?s(e,\"default\",{value:t,enumerable:!0}):e,t)),M=t=\u003ec(s({},\"__esModule\",{value:!0}),t);var i=j((h,u)=\u003e{u.exports=_jsx_runtime});var X={};d(X,{default:()=\u003eF,frontmatter:()=\u003eC});var o=p(i()),C={title:\"Tools\",slug:\"tools\"};function m(t){return(0,o.jsx)(o.Fragment,{})}function D(t={}){let{wrapper:n}=t.components||{};return n?(0,o.jsx)(n,Object.assign({},t,{children:(0,o.jsx)(m,t)})):m(t)}var F=D;return M(X);})();\n;return Component;"},"_id":"categories/tools.mdx","_raw":{"sourceFilePath":"categories/tools.mdx","sourceFileName":"tools.mdx","sourceFileDir":"categories","contentType":"mdx","flattenedPath":"categories/tools"},"type":"Category","url":"/categories/tools"}]}]},"__N_SSG":true},"page":"/category/[slug]","query":{"slug":"tools"},"buildId":"wTIynxBm98ujmQxLsgK6X","assetPrefix":"/security-labs","isFallback":false,"gsp":true,"scriptLoader":[]}</script></body></html>

Pages: 1 2 3 4 5 6 7 8 9 10