reverse-skills-max: initial public release (restored, redacted, hardened)
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
Apache License 2.0 — see the repository root LICENSE file for the full text.
|
||||
|
||||
Copyright the AnalystAIPack contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
@@ -0,0 +1,89 @@
|
||||
---
|
||||
name: analyzing-malicious-iso-and-container-files
|
||||
description: 'Analyzes malicious ISO, IMG, VHD, and similar container files used to smuggle payloads
|
||||
past email and mark-of-the-web defenses by enumerating contents and flagging hidden executables,
|
||||
LNKs, and scripts. Activates for requests to analyze a malicious ISO/IMG, inspect a container
|
||||
delivery file, or find payloads hidden inside a disk image attachment.'
|
||||
domain: cybersecurity
|
||||
subdomain: malware-analysis
|
||||
tags:
|
||||
- malware-analysis
|
||||
- iso
|
||||
- container
|
||||
- delivery
|
||||
- mark-of-the-web
|
||||
version: 1.0.0
|
||||
author: analyst-ai-pack
|
||||
license: Apache-2.0
|
||||
mitre_attack:
|
||||
- T1553.005
|
||||
- T1204.002
|
||||
- T1027
|
||||
d3fend:
|
||||
- D3-FCR
|
||||
- D3-FA
|
||||
references:
|
||||
- 'MITRE ATT&CK T1553.005 Mark-of-the-Web Bypass — https://attack.mitre.org/techniques/T1553/005/'
|
||||
- 'ISO 9660 file system — https://wiki.osdev.org/ISO_9660'
|
||||
---
|
||||
|
||||
# Analyzing Malicious ISO and Container Files
|
||||
|
||||
## When to Use
|
||||
|
||||
- You have an ISO/IMG/VHD attachment suspected of smuggling a payload (LNK + hidden DLL/EXE/script)
|
||||
past MOTW and scanners.
|
||||
- You need to enumerate contents and flag hidden/executable entries without mounting the image.
|
||||
|
||||
**Do not use** mounting/auto-run to inspect — that can trigger the lure. Parse the container's
|
||||
directory records statically.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- The container file (read inertly). Optional: `pycdlib` for full ISO parsing (the script falls
|
||||
back to signature/string carving if absent).
|
||||
|
||||
## Safety & Handling
|
||||
|
||||
- Never mount or open the container interactively; carve statically. Defang any URLs found.
|
||||
|
||||
## Workflow
|
||||
|
||||
### Step 1: Identify the container type
|
||||
|
||||
```bash
|
||||
python scripts/analyst.py inspect sample.iso
|
||||
```
|
||||
|
||||
Detects ISO 9660 (`CD001`), UDF, FAT/VHD signatures and reports the format.
|
||||
|
||||
### Step 2: Enumerate entries and flag payloads
|
||||
|
||||
Lists embedded file signatures (`MZ`, `PK`, LNK `\x4C\x00\x00\x00`, script headers) and flags
|
||||
hidden/executable/decoy entries.
|
||||
|
||||
### Step 3: Assess the lure chain
|
||||
|
||||
A typical chain is a visible LNK pointing at a hidden DLL/EXE/script in the same image — document
|
||||
the relationship.
|
||||
|
||||
### Step 4: Extract and route
|
||||
|
||||
Carve the hidden payload and route it to the appropriate analysis workflow; defang URLs.
|
||||
|
||||
## Validation
|
||||
|
||||
- The container format is identified by signature.
|
||||
- Hidden executables/LNKs/scripts are enumerated with offsets.
|
||||
- The lure→payload relationship is documented.
|
||||
|
||||
## Pitfalls
|
||||
|
||||
- Mounting the image and triggering the lure.
|
||||
- Missing payloads in less-common container formats (VHDX, UDF) without the right parser.
|
||||
- Overlooking hidden-attribute files that the file manager would not show.
|
||||
|
||||
## References
|
||||
|
||||
- See [`references/api-reference.md`](references/api-reference.md) for the inspector.
|
||||
- ATT&CK T1553.005 and ISO 9660 references (linked in frontmatter).
|
||||
@@ -0,0 +1,38 @@
|
||||
# API Reference: Analyzing Malicious ISO and Container Files
|
||||
|
||||
## Overview
|
||||
|
||||
`scripts/analyst.py` identifies a container's format (ISO 9660, VHD/VHDX, FAT/IMG) by signature and
|
||||
carves embedded file signatures (PE, ZIP/Office, LNK, scripts) with offsets. With pycdlib it adds a
|
||||
root directory listing. It reads bytes statically and never mounts the image.
|
||||
|
||||
## Dependencies
|
||||
|
||||
| Package | Version | Purpose |
|
||||
|---------|---------|---------|
|
||||
| pycdlib | latest | full ISO directory listing (optional) |
|
||||
| (stdlib) | — | JSON, file IO |
|
||||
|
||||
## Core functions
|
||||
|
||||
### `inspect(path)`
|
||||
Returns format, ISO directory (if pycdlib), embedded signatures, and a hidden-payload flag.
|
||||
|
||||
### `_format(data)`
|
||||
Signature-based container format detection (`CD001`, `conectix`, `vhdxfile`, FAT markers).
|
||||
|
||||
## Carved signatures
|
||||
|
||||
PE (`MZ`), ZIP/Office (`PK`), LNK header, shebang/WSF/batch scripts.
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
python scripts/analyst.py inspect sample.iso
|
||||
```
|
||||
|
||||
## Sources
|
||||
|
||||
- MITRE ATT&CK T1553.005 Mark-of-the-Web Bypass — https://attack.mitre.org/techniques/T1553/005/
|
||||
- ISO 9660 (`CD001` at sector 16) — https://wiki.osdev.org/ISO_9660
|
||||
- VHD `conectix` / VHDX `vhdxfile` signatures from Microsoft VHD/VHDX specifications
|
||||
@@ -0,0 +1,97 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Inspect ISO/IMG/VHD container files for hidden/smuggled payloads.
|
||||
|
||||
Identifies the container format by signature and carves embedded file signatures (PE, archives,
|
||||
LNK, scripts) with offsets. Uses pycdlib for full ISO directory listing when available; otherwise
|
||||
falls back to signature carving. Reads bytes statically; never mounts the image.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
try:
|
||||
import pycdlib # type: ignore
|
||||
HAVE_PYCDLIB = True
|
||||
except ImportError:
|
||||
HAVE_PYCDLIB = False
|
||||
|
||||
EMBED_SIGS = [
|
||||
(b"MZ", "PE executable"),
|
||||
(b"PK\x03\x04", "ZIP/Office"),
|
||||
(b"\x4c\x00\x00\x00\x01\x14\x02\x00", "LNK shortcut"),
|
||||
(b"#!", "script (shebang)"),
|
||||
(b"<job", "WSF job"),
|
||||
(b"@echo", "batch script"),
|
||||
]
|
||||
|
||||
|
||||
def _format(data: bytes) -> str:
|
||||
if data[0x8001:0x8006] == b"CD001" or b"CD001" in data[:0x10000]:
|
||||
return "ISO 9660"
|
||||
if data[:8] == b"conectix":
|
||||
return "VHD"
|
||||
if data[:8] == b"vhdxfile":
|
||||
return "VHDX"
|
||||
if data[0x36:0x3b] == b"FAT16" or data[0x52:0x57] == b"FAT32":
|
||||
return "FAT (IMG)"
|
||||
return "unknown"
|
||||
|
||||
|
||||
def _carve(data: bytes) -> list[dict]:
|
||||
found = []
|
||||
for sig, label in EMBED_SIGS:
|
||||
start = 0
|
||||
while len(found) < 100:
|
||||
idx = data.find(sig, start)
|
||||
if idx == -1:
|
||||
break
|
||||
found.append({"offset": idx, "type": label})
|
||||
start = idx + 1
|
||||
return found
|
||||
|
||||
|
||||
def _iso_listing(path: str) -> list[str]:
|
||||
if not HAVE_PYCDLIB:
|
||||
return []
|
||||
names = []
|
||||
try:
|
||||
iso = pycdlib.PyCdlib()
|
||||
iso.open(path)
|
||||
for child in iso.list_children(iso_path="/"):
|
||||
ident = getattr(child.file_identifier(), "decode", lambda *_: "")("utf-8", "ignore")
|
||||
if ident and ident not in (".", ".."):
|
||||
names.append(ident)
|
||||
iso.close()
|
||||
except Exception:
|
||||
return []
|
||||
return names
|
||||
|
||||
|
||||
def inspect(path: str) -> dict:
|
||||
data = Path(path).read_bytes()
|
||||
carved = _carve(data)
|
||||
return {
|
||||
"format": _format(data),
|
||||
"pycdlib_available": HAVE_PYCDLIB,
|
||||
"iso_directory": _iso_listing(path),
|
||||
"embedded_signatures": carved,
|
||||
"hidden_payload_suspected": any(c["type"].startswith(("PE", "LNK", "script"))
|
||||
for c in carved),
|
||||
}
|
||||
|
||||
|
||||
def main(argv: list[str] | None = None) -> int:
|
||||
parser = argparse.ArgumentParser(description="Inspect ISO/container files")
|
||||
sub = parser.add_subparsers(dest="cmd", required=True)
|
||||
p = sub.add_parser("inspect")
|
||||
p.add_argument("file")
|
||||
args = parser.parse_args(argv)
|
||||
print(json.dumps(inspect(args.file), indent=2))
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user