Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ dist/
.env.*
__pycache__/

# Internal working docs — never published
# Internal working docs, never published
docs/
/.atl

# RFSAM Skill — audit artifacts and secrets, never committed
# RFSAM Skill, audit artifacts and secrets, never committed
Skill/loot/
22 changes: 11 additions & 11 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
# Contributing to RFSAM

RFSAM grows by pull request. A good contribution is a control that is **accurate, cited, and reproducible** — wrong depth is worse than missing depth, so every nontrivial claim must carry a source you can check.
RFSAM grows by pull request. A good contribution is a control that is **accurate, cited, and reproducible**: wrong depth is worse than missing depth, so every nontrivial claim must carry a source you can check.

## Add a control

1. Copy `src/content/controls/_template.md` to `src/content/controls/<id>.md`, where `<id>` is the lower-cased control ID (e.g. `rfsam-zigbee-cr-01.md`).
2. Fill the frontmatter and the body sections.
3. Run `npm run validate` and `npm run build` — both must pass.
3. Run `npm run validate` and `npm run build`: both must pass.
4. Open a pull request.

## The control ID

`RFSAM-<PROTOCOL>-<LAYER>-<NN>` — e.g. `RFSAM-BLE-AT-01`.
`RFSAM-<PROTOCOL>-<LAYER>-<NN>`, e.g. `RFSAM-BLE-AT-01`.

- `<PROTOCOL>` is one of the protocol ids (`BLE`, `WIFI`, `LORA`, `LTE`, `RFID`, `SUBG`, `ZIGBEE`, `ZWAVE`, `THREAD`, `GNSS`, `ADSB`, `NR5G`, `GSM`, `UWB`).
- `<LAYER>` is one of `IG SP PHY LL CR AT AP`.
Expand All @@ -31,32 +31,32 @@ Frontmatter (validated by `src/content.config.ts` and `scripts/validate.mjs`):
| `objective` | one testable statement of what the control verifies (required once `draft`/`verified`) |
| `intro` | short callout shown above the body |
| `prerequisites` | `hardware[]`, `software[]`, `signal{freq,bandwidth,modulation}`, `skill` |
| `attacks[]` | `{name, cve?, refs[], impact, preconditions, summary}` — each `refs` key MUST exist in `references` |
| `attacks[]` | `{name, cve?, refs[], impact, preconditions, summary}`; each `refs` key MUST exist in `references` |
| `references[]` | `{key, title, authors?, venue?, year?, url, type}`; `type ∈ paper cve talk spec standard tool blog` |
| `tools[]` | slugs that exist in `src/content/tools/` |
| `bsam[]` | ids that exist in the BSAM registry (`src/data/bsam.js`) |
| `resources[]` | `RFSAM-RES-NN` ids that exist in `src/content/resources/` |
| `reviewStatus` | `stub` → `draft` → `verified` |
| `confidence` | `low medium high` — honest self-assessment of the draft |
| `confidence` | `low medium high`: honest self-assessment of the draft |
| `lastResearched` | date the sources were pulled |

Body sections, in order: `## Mechanism`, `## Procedure`, `## Field case`, `## Remediation`. Put real commands in fenced code blocks with the expected output. Preserve command strings verbatim.

## Criticality rubric

- **info** — observational; no direct security impact (e.g. capture feasibility).
- **low** — minor exposure or hardening gap.
- **medium** — meaningful weakness requiring specific conditions to exploit.
- **high** — readily exploitable weakness with significant impact.
- **critical** — full compromise (takeover, key recovery, impersonation) with practical preconditions.
- **info**: observational; no direct security impact (e.g. capture feasibility).
- **low**: minor exposure or hardening gap.
- **medium**: meaningful weakness requiring specific conditions to exploit.
- **high**: readily exploitable weakness with significant impact.
- **critical**: full compromise (takeover, key recovery, impersonation) with practical preconditions.

## Research → verify workflow

1. **Research** the sources (papers, CVE databases, specs, tool docs, talks). Record each as a `references[]` entry with a resolvable URL.
2. **Draft** to the schema. Every nontrivial claim in `## Mechanism` and every attack maps to a reference. Set `reviewStatus: draft`.
3. **Be honest about uncertainty.** Set `confidence` accordingly, and mark any claim you could not fully verify:
```
> [!FLAG] the claim — what still needs to be checked
> [!FLAG] the claim: what still needs to be checked
```
4. **Verify.** A reviewer resolves the flags and confirms the citations, then sets `reviewStatus: verified`. A `verified` control must carry at least one reference and contain no unresolved `[!FLAG]`.

Expand Down
38 changes: 19 additions & 19 deletions CONTROLS-AUTHORING.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
# Controls authoring rules

How to research and write an RFSAM **control** — one numbered, cited, reproducible
How to research and write an RFSAM **control**: one numbered, cited, reproducible
verification procedure for a single *protocol × layer*. This is the brief a
contributor or a sub-agent follows.

The machine-checkable schema lives in `src/content.config.ts`; the human PR flow,
the field-by-field table and the criticality rubric live in **`CONTRIBUTING.md`**;
copy **`src/content/controls/_template.md`** to start; **`rfsam-ble-at-01.md`** is
the reference depth. This file is the *operational* guide — what makes a control
the reference depth. This file is the *operational* guide: what makes a control
accurate, reproducible, and consistent with the rest of RFSAM.

---
Expand All @@ -21,8 +21,8 @@ procedure with real commands) and **cited** (every nontrivial claim carries a
resolvable source). Wrong depth is worse than missing depth.

A control is **not** the Wayfinder. The Wayfinder (`src/data/toolchains/<proto>.js`)
is the *kit map* — what hardware + software to use at each step. A control is the
*method and the finding* — how to run the check, a real worked example, the known
is the *kit map*: what hardware + software to use at each step. A control is the
*method and the finding*: how to run the check, a real worked example, the known
attacks with references, and the remediation. They are **paired**: a control's
`layer`, `tools[]` and `attacks[]` must be consistent with that protocol's Wayfinder
toolchain at the same layer (read it first; the bands, tools and attack framing are
Expand All @@ -32,55 +32,55 @@ already researched there).

## File & ID

- One control per file: `src/content/controls/<id-lowercased>.md` — e.g. `rfsam-zwave-cr-01.md`.
- One control per file: `src/content/controls/<id-lowercased>.md`, e.g. `rfsam-zwave-cr-01.md`.
- `id` = `RFSAM-<PROTOCOL>-<LAYER>-<NN>`. **Invariant: the PROTOCOL and LAYER segments MUST equal the `protocol` and `layer` frontmatter fields.** The validator fails otherwise.
- Protocols: `BLE WIFI LORA LTE RFID SUBG ZIGBEE ZWAVE THREAD GNSS ADSB NR5G GSM UWB`. Layers: `IG SP PHY LL CR AT AP`.

## Frontmatter

Full schema + table: `CONTRIBUTING.md` / `src/content.config.ts`. The must-gets:
- `title` short + imperative; `criticality` per the rubric; `objective` = the one testable thing it verifies (required once `draft`).
- `prerequisites { hardware[], software[], signal{freq,bandwidth,modulation}, skill }` — pull the signal facts from the protocol's Wayfinder `facts`.
- `prerequisites { hardware[], software[], signal{freq,bandwidth,modulation}, skill }`; pull the signal facts from the protocol's Wayfinder `facts`.
- `attacks[]` = named real attacks `{name, cve?, refs[], impact, preconditions, summary}`. **Every `refs` key MUST exist in `references[]`.**
- `references[]` = `{key, title, authors?, venue?, year?, url, type}`. **Every `url` must resolve and actually be the cited work.**
- `tools[]` = slugs that exist in `src/content/tools/` (reuse the protocol's Wayfinder tools).
- `bsam[]` = ids that exist in the BSAM registry (`src/data/bsam.js`); set when deferring.
- `resources[]` = `RFSAM-RES-NN` ids that exist in `src/content/resources/`.
- `reviewStatus` + `confidence` (lifecycle below); `lastResearched` = the date you pulled the sources.

## Body — four sections, in order
## Body: four sections, in order

`## Mechanism` → `## Procedure` → `## Field case` → `## Remediation`.
- **Mechanism** — how the RF/protocol works and why the control matters. Every nontrivial claim cites a `references[]` key. Name the real attack families.
- **Procedure** — a NUMBERED, reproducible method, with real commands in fenced code blocks and the expected output / how to read it. Preserve command strings verbatim.
- **Field case** — a concrete worked example with real data (the war story). Keep author field data and any intentional `[FILL: …]` placeholder verbatim — do NOT fabricate a finding.
- **Remediation** — specific, layered guidance (developer / integrator / operator).
- **Mechanism**: how the RF/protocol works and why the control matters. Every nontrivial claim cites a `references[]` key. Name the real attack families.
- **Procedure**: a NUMBERED, reproducible method, with real commands in fenced code blocks and the expected output / how to read it. Preserve command strings verbatim.
- **Field case**: a concrete worked example with real data (the war story). Keep author field data and any intentional `[FILL: …]` placeholder verbatim; do NOT fabricate a finding.
- **Remediation**: specific, layered guidance (developer / integrator / operator).

---

## The ten rules (accuracy first)

1. **Cite or flag everything.** Every nontrivial claim, attack and number maps to a resolvable `references[]` entry. Verify each source actually exists and says what you claim — `gh api repos/<o>/<n>` for a tool, the NVD page for a CVE, the real paper/talk URL. Never assert what you can't cite. (`[[no-unverified-claims]]`)
2. **Flag uncertainty inline:** `> [!FLAG] the claim — what still needs checking`. A `draft` may carry flags; a `verified` control must have none.
1. **Cite or flag everything.** Every nontrivial claim, attack and number maps to a resolvable `references[]` entry. Verify each source actually exists and says what you claim: `gh api repos/<o>/<n>` for a tool, the NVD page for a CVE, the real paper/talk URL. Never assert what you can't cite. (`[[no-unverified-claims]]`)
2. **Flag uncertainty inline:** `> [!FLAG] the claim: what still needs checking`. A `draft` may carry flags; a `verified` control must have none.
3. **A sub-agent produces `draft`, never `verified`.** Verification is a separate review pass that resolves the flags and confirms the citations. Set `confidence` honestly (`low`/`medium`/`high`).
4. **Align with the Wayfinder.** Read `src/data/toolchains/<proto>.js` for this layer first: reuse its `facts` (bands/modulation), its tools (as `tools[]`), and its attack framing. A control *deepens* what the Wayfinder summarises — they must not contradict.
5. **BSAM deference.** Where BSAM owns the layer (BLE link-and-above; the deferred IG controls), set `deferred: true`, cite the specific `bsam[]` ids, and describe ONLY the RF-capture prerequisite that reaches the point where the BSAM control applies — do not re-derive BSAM's content. (`src/data/bsamRelation.js`)
4. **Align with the Wayfinder.** Read `src/data/toolchains/<proto>.js` for this layer first: reuse its `facts` (bands/modulation), its tools (as `tools[]`), and its attack framing. A control *deepens* what the Wayfinder summarises; they must not contradict.
5. **BSAM deference.** Where BSAM owns the layer (BLE link-and-above; the deferred IG controls), set `deferred: true`, cite the specific `bsam[]` ids, and describe ONLY the RF-capture prerequisite that reaches the point where the BSAM control applies; do not re-derive BSAM's content. (`src/data/bsamRelation.js`)
6. **Tone: a north, not novelty.** RFSAM orients and organises; it builds on OSSTMM / BSAM / the SDR-pentest lineage. Never "first / nobody does this / invented". Frame tool & CVE corpora as "representative, check current advisories".
7. **Authorised-testing framing** on every active / transmit / decrypt step (rogue cells, replay, key recovery): your own equipment, test SIMs/devices, RF shielding, explicit permission.
8. **Verbatim load-bearing content.** Monospace command strings, war-story values (`cur_aa`, `w 0x000e 7e 07 05 03 ff 00 00 10 ef`) and `[FILL: …]` notes are kept exactly — never paraphrase, "complete", or invent them.
8. **Verbatim load-bearing content.** Monospace command strings, war-story values (`cur_aa`, `w 0x000e 7e 07 05 03 ff 00 00 10 ef`) and `[FILL: …]` notes are kept exactly; never paraphrase, "complete", or invent them.
9. **Criticality honestly** per the CONTRIBUTING rubric (info → critical). Observational capture-feasibility is `info`/`low`; full takeover / key recovery / impersonation is `high`/`critical`.
10. **It must validate and build.** Controls don't need `seed-tools`, but `npm run validate` (cross-refs) and `npm run build` (zod schema) MUST pass. The validator checks: id ↔ protocol ↔ layer; every `tools` / `bsam` / `resources` / attack-`refs` reference resolves; enums valid; no empty required fields.

---

## reviewStatus / confidence lifecycle

`stub` (placeholder, little real content) → `draft` (researched, cited, may carry `[!FLAG]`s — what a sub-agent produces) → `verified` (a reviewer resolved every flag and confirmed every citation; ≥ 1 reference, zero unresolved flags). Sub-agents stop at `draft`.
`stub` (placeholder, little real content) → `draft` (researched, cited, may carry `[!FLAG]`s, what a sub-agent produces) → `verified` (a reviewer resolved every flag and confirmed every citation; ≥ 1 reference, zero unresolved flags). Sub-agents stop at `draft`.

## What to write (coverage)

`src/data/coverage-map.js` and the `/roadmap` page list every control: `existing`
(a file exists — but most are `stub`s needing depth) and `planned` (proposed scope,
(a file exists, but most are `stub`s needing depth) and `planned` (proposed scope,
unwritten). A sub-agent task is usually **either** deepen one existing stub to
`draft`, **or** write one planned control to `draft`. **One control per sub-agent.**

Expand All @@ -89,7 +89,7 @@ unwritten). A sub-agent task is usually **either** deepen one existing stub to
Give each sub-agent ONE control id. Tell it to:
1. Read this file, `_template.md`, `CONTRIBUTING.md`, the protocol's Wayfinder
(`src/data/toolchains/<proto>.js`), and the existing stub if any.
2. Research and **verify every source** (gh/web) — papers, CVEs (NVD), specs, tool repos, talks.
2. Research and **verify every source** (gh/web): papers, CVEs (NVD), specs, tool repos, talks.
3. Write `src/content/controls/<id>.md` as `reviewStatus: draft` with an honest
`confidence`, citing every claim and `[!FLAG]`-ing anything it could not fully verify.
4. NOT run the shared `seed-tools` (controls don't need it); just self-check the
Expand Down
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# RFSAM — Radio Frequency Security Assessment Methodology
# RFSAM: Radio Frequency Security Assessment Methodology

An open, structured methodology for RF research and auditing, by [Electronic Cats](https://electroniccats.com) and [PWNLabs](https://pwnlab.mx).

RFSAM is meant to be **a north** for RF work: faced with an unknown signal or device, where do you start — and how do you know what you've missed? It walks you from the spectrum up through the signal, link, crypto, attack and application layers, per protocol, with a verification procedure and a real worked example at each step.
RFSAM is meant to be **a north** for RF work: faced with an unknown signal or device, where do you start, and how do you know what you've missed? It walks you from the spectrum up through the signal, link, crypto, attack and application layers, per protocol, with a verification procedure and a real worked example at each step.

It does **not** claim to invent RF security. OSSTMM, BSAM, the SDR‑pentest lineage and a deep body of research came first; RFSAM organises that landscape into something you can navigate by. For Bluetooth at the link layer and above it defers to [Tarlogic's BSAM](https://www.tarlogic.com/bsam/) rather than duplicating it.

## The model

Controls are indexed on two axes — **protocol** and **layer**. The layer axis is a descent from spectrum down to application:
Controls are indexed on two axes: **protocol** and **layer**. The layer axis is a descent from spectrum down to application:

| | layer | what it asks |
|---|---|---|
Expand All @@ -20,7 +20,7 @@ Controls are indexed on two axes — **protocol** and **layer**. The layer axis
| `AT` | Attack | injection, replay, hijack, rogue infrastructure |
| `AP` | Application | what the device trusts above the link |

Control IDs follow `RFSAM-<PROTOCOL>-<LAYER>-<NN>` (e.g. `RFSAM-BLE-AT-01`). The protocol and layer segments must match the control's fields — this is enforced in validation.
Control IDs follow `RFSAM-<PROTOCOL>-<LAYER>-<NN>` (e.g. `RFSAM-BLE-AT-01`). The protocol and layer segments must match the control's fields; this is enforced in validation.

Each control carries a `reviewStatus`: **stub** (migrated outline), **draft** (researched and cited, awaiting review), or **verified** (checked). Every nontrivial claim cites a source; uncertain claims are flagged inline for review.

Expand Down Expand Up @@ -56,4 +56,4 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for the control schema, the ID/layer rule

## License

The methodology content is licensed **CC BY‑SA 4.0** — see [LICENSE](LICENSE). Reuse and adapt it with attribution to Electronic Cats, sharing derivatives under the same license.
The methodology content is licensed **CC BY‑SA 4.0**, see [LICENSE](LICENSE). Reuse and adapt it with attribution to Electronic Cats, sharing derivatives under the same license.
Loading
Loading