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,93 @@
|
||||
---
|
||||
name: analyzing-malicious-onenote-and-html-smuggling
|
||||
description: 'Analyzes two modern delivery techniques: malicious OneNote (.one) attachments with
|
||||
embedded payloads behind fake buttons, and HTML smuggling pages that reconstruct payloads in the
|
||||
browser from embedded blobs. Activates for requests to analyze a malicious OneNote file, detect
|
||||
HTML smuggling, or extract a smuggled/embedded payload.'
|
||||
domain: cybersecurity
|
||||
subdomain: malware-analysis
|
||||
tags:
|
||||
- malware-analysis
|
||||
- onenote
|
||||
- html-smuggling
|
||||
- document-malware
|
||||
- delivery
|
||||
version: 1.0.0
|
||||
author: analyst-ai-pack
|
||||
license: Apache-2.0
|
||||
mitre_attack:
|
||||
- T1027.006
|
||||
- T1204.002
|
||||
- T1566.001
|
||||
d3fend:
|
||||
- D3-FCR
|
||||
- D3-DA
|
||||
references:
|
||||
- 'MITRE ATT&CK T1027.006 HTML Smuggling — https://attack.mitre.org/techniques/T1027/006/'
|
||||
- 'OneNote file format (MS-ONESTORE) — https://learn.microsoft.com/openspecs/office_file_formats/ms-onestore/'
|
||||
---
|
||||
|
||||
# Analyzing Malicious OneNote and HTML Smuggling
|
||||
|
||||
## When to Use
|
||||
|
||||
- You have a OneNote (`.one`) attachment suspected of hiding an embedded executable/script behind a
|
||||
"click to view" lure.
|
||||
- You have an HTML/SVG page that reconstructs and auto-downloads a payload from an embedded blob
|
||||
(HTML smuggling).
|
||||
- You need to extract the hidden payload without triggering the lure.
|
||||
|
||||
**Do not use** OneNote or a browser to open these files for analysis — that is exactly the
|
||||
delivery mechanism. Carve the embedded data statically.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- A static carver (Python) for embedded file signatures; the sample handled inertly.
|
||||
|
||||
## Safety & Handling
|
||||
|
||||
- Never open the `.one` in OneNote or the HTML in a browser.
|
||||
- Defang URLs and store carved payloads password-protected.
|
||||
|
||||
## Workflow
|
||||
|
||||
### Step 1: For OneNote — carve embedded files
|
||||
|
||||
OneNote stores attached files in the document. Scan for embedded file signatures (`MZ`, script
|
||||
headers, archives) and the `FileDataStoreObject` GUIDs, and carve them out.
|
||||
|
||||
```bash
|
||||
python scripts/analyst.py carve sample.one
|
||||
```
|
||||
|
||||
### Step 2: For HTML smuggling — find the embedded blob
|
||||
|
||||
Look for large base64/`Blob`/`Uint8Array` constructions, `data:` URIs, and a JS routine that
|
||||
builds a Blob and triggers a download (`msSaveOrOpenBlob`, anchor `download`, `createObjectURL`).
|
||||
|
||||
### Step 3: Reconstruct the payload statically
|
||||
|
||||
Decode the embedded base64/byte array (and any XOR/char-code layer) to recover the payload as
|
||||
data — without executing the page.
|
||||
|
||||
### Step 4: Analyze and extract IOCs
|
||||
|
||||
Hash carved payloads, identify their type, defang any URLs, and route executables/scripts to the
|
||||
appropriate analysis workflow.
|
||||
|
||||
## Validation
|
||||
|
||||
- Embedded payloads are carved/reconstructed from the inert file, not by opening it.
|
||||
- The recovered payload's type is identified and hashed.
|
||||
- The lure/trigger mechanism (fake button, Blob download) is documented.
|
||||
|
||||
## Pitfalls
|
||||
|
||||
- Opening the OneNote/HTML to "see" the lure and executing the payload.
|
||||
- Decoding only the first layer when the blob is additionally XOR/char-code encoded.
|
||||
- Missing multiple embedded objects in a single OneNote page.
|
||||
|
||||
## References
|
||||
|
||||
- See [`references/api-reference.md`](references/api-reference.md) for the carver/decoder.
|
||||
- ATT&CK T1027.006 and MS-ONESTORE (linked in frontmatter).
|
||||
@@ -0,0 +1,34 @@
|
||||
# API Reference: Analyzing Malicious OneNote and HTML Smuggling
|
||||
|
||||
## Overview
|
||||
|
||||
`scripts/analyst.py` carves embedded file signatures (PE, archives, scripts) from OneNote/binary
|
||||
files by offset, and detects HTML smuggling by locating large base64 blobs that decode to
|
||||
executables/archives alongside Blob-download hints. It reads statically and executes nothing.
|
||||
|
||||
## Dependencies
|
||||
|
||||
| Package | Version | Purpose |
|
||||
|---------|---------|---------|
|
||||
| (stdlib) | — | base64, regex, JSON, file IO |
|
||||
|
||||
## Core functions
|
||||
|
||||
### `carve(data)`
|
||||
Returns offsets and types of embedded file signatures.
|
||||
|
||||
### `html_smuggle(data)`
|
||||
Returns smuggling hints (Blob/Uint8Array/download) and any base64 blobs that decode to payloads.
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
python scripts/analyst.py carve sample.one
|
||||
```
|
||||
|
||||
## Sources
|
||||
|
||||
- MITRE ATT&CK T1027.006 HTML Smuggling — https://attack.mitre.org/techniques/T1027/006/
|
||||
- OneNote file format (MS-ONESTORE, embedded FileDataStoreObject) —
|
||||
https://learn.microsoft.com/openspecs/office_file_formats/ms-onestore/
|
||||
- Blob/createObjectURL/msSaveOrOpenBlob smuggling pattern, established delivery-analysis practice
|
||||
@@ -0,0 +1,81 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Carve embedded payloads from OneNote files and reconstruct HTML-smuggling blobs.
|
||||
|
||||
For OneNote (and any binary), it scans for embedded file signatures (PE, archives, scripts) and
|
||||
reports their offsets. For HTML, it locates large base64/byte-array blobs and decodes them to
|
||||
recover a smuggled payload. It reads bytes/text statically and executes nothing.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import base64
|
||||
import binascii
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
EMBED_SIGS = [
|
||||
(b"MZ", "PE executable"),
|
||||
(b"PK\x03\x04", "ZIP/Office/JAR"),
|
||||
(b"\x1f\x8b", "GZIP"),
|
||||
(b"Rar!\x1a\x07", "RAR"),
|
||||
(b"%PDF", "PDF"),
|
||||
(b"#!", "script (shebang)"),
|
||||
(b"<job", "WSF job"),
|
||||
]
|
||||
|
||||
RE_B64_BLOB = re.compile(rb"[A-Za-z0-9+/]{200,}={0,2}")
|
||||
SMUGGLE_HINTS = [b"msSaveOrOpenBlob", b"createObjectURL", b"Uint8Array", b"new Blob",
|
||||
b"download=", b"base64"]
|
||||
|
||||
|
||||
def carve(data: bytes) -> list[dict]:
|
||||
found = []
|
||||
for sig, label in EMBED_SIGS:
|
||||
start = 0
|
||||
while True:
|
||||
idx = data.find(sig, start)
|
||||
if idx == -1:
|
||||
break
|
||||
found.append({"offset": idx, "type": label})
|
||||
start = idx + 1
|
||||
if len(found) > 50:
|
||||
return found
|
||||
return found
|
||||
|
||||
|
||||
def html_smuggle(data: bytes) -> dict:
|
||||
hints = sorted({h.decode() for h in SMUGGLE_HINTS if h in data})
|
||||
decoded = []
|
||||
for m in RE_B64_BLOB.findall(data):
|
||||
try:
|
||||
raw = base64.b64decode(m)
|
||||
except (binascii.Error, ValueError):
|
||||
continue
|
||||
if raw[:2] == b"MZ" or raw[:4] == b"PK\x03\x04" or raw[:4] == b"%PDF":
|
||||
decoded.append({"size": len(raw), "carved_type": carve(raw)[:1]})
|
||||
return {"smuggling_hints": hints, "decoded_blobs": decoded,
|
||||
"likely_smuggling": bool(hints and decoded)}
|
||||
|
||||
|
||||
def analyze(path: str) -> dict:
|
||||
data = Path(path).read_bytes()
|
||||
return {
|
||||
"embedded_signatures": carve(data),
|
||||
"html_smuggling": html_smuggle(data),
|
||||
}
|
||||
|
||||
|
||||
def main(argv: list[str] | None = None) -> int:
|
||||
parser = argparse.ArgumentParser(description="Carve OneNote / HTML-smuggling payloads")
|
||||
sub = parser.add_subparsers(dest="cmd", required=True)
|
||||
p = sub.add_parser("carve")
|
||||
p.add_argument("file")
|
||||
args = parser.parse_args(argv)
|
||||
print(json.dumps(analyze(args.file), indent=2))
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user