dsh-fuzz: Differential fuzzing and logic testing on top of diffprobe

Introduction

When performing interface security testing on a DSH Agent, the two most expensive steps in manually verifying privilege escalation or logic flaws are not “sending one packet,” but constructing comparative requests and then determining response differences. rannyrjjy/dsh-fuzz automates these two steps: it performs differential fuzzing and logic testing on top of the diffprobe package engine. The process is fixed as sampling values → planning → executing → judging, and is read-only by default. Below is an introduction to its capabilities, installation method, and usage.

What is this

The plugin maintainer is rannyrjjy, with 1 star on GitHub, and classified as a workflow in the community directory. The plugin registers only one DSH Host tool, fuzz, responsible for parameter mapping and subprocess orchestration; all requests are always executed by engine/diffprobe, with no second request engine. Plans, seeds, original requests, and responses are all persisted to disk and do not enter the chat history.

It adheres to three verdict disciplines:

  1. Baseline comparability: Every payload carries a baseline and a same-type comparison to avoid treating “different lengths” as a vulnerability.
  2. Difference != Vulnerability: Distinguishing transport layer differences, error branches (errorCode/errorMsg) from truly worth-reading state or data changes (ownerId/role/status/amount, etc.).
  3. Verifiable: run produces diffs.csv, verify produces state.csv, and verdict only performs classification; evidence is left in the workspace.

Note: This plugin is intended for authorized penetration testing, CTF/target ranges, and evaluation of own systems only.

Environment Requirements

- Node.js 22.19+ (or 24+)
- Python 3.9+, python / python3 in PATH
- DeepSeek Harness (Supports bundle plugins / Host tools)

The plugin is pure JS + Python with no build steps.

Installation and Enabling

# --profile is required: replace <profile> with your profile name (desktop usually)
# 1) Install from GitHub (public repository)
dsh plugin --profile <profile> add github:rannyrjjy/dsh-fuzz

# 2) Local install (after git clone / unzip, replace <plugin-dir> with absolute path)
dsh plugin --profile <profile> add file:<plugin-dir>

Local path syntax varies by platform: Windows uses file:D:\tools\dsh-fuzz, macOS/Linux uses file:/opt/dsh-fuzz. After installation, restart DeepSeek Harness (or let the plugin manager reload the profile), and the fuzz tool will appear in the tool list.

Update:

dsh plugin --profile <profile> update dsh-fuzz
# or remove then re-add
dsh plugin --profile <profile> remove dsh-fuzz
dsh plugin --profile <profile> add github:rannyrjjy/dsh-fuzz

Configuration

Default values are parsed in index.js and work without configuration. If you need to override, add a dsh-fuzz segment to the DSH patch layer:

- insert:
    - id: dsh-fuzz
      name: dsh-fuzz
      config:
        workspaceDir: /path/to/workspace   # Recommended to configure explicitly: root for evidence, @file, diffprobe cwd
        pythonPath: python3                # Default python on Windows
        evidenceRoot: evidence             # Name of evidence directory, default "漏洞记录"
        timeoutMs: 300000

Windows paths can use C:/work/pentest or C:\\work\\pentest.

Key Default Description
workspaceDir DSH Host current directory (or DSH_FUZZ_WORKSPACE) Root of workspace; @file relative paths, diffprobe cwd, and evidence directory are all based on this
pythonPath python (Windows) / python3 Python interpreter
enginePath <plugin-dir>/engine/fuzz/fuzz_ops.py Engine entry point, can point to another engine
evidenceRoot 漏洞记录 Name of evidence directory, located under workspaceDir, can be renamed to anything
timeoutMs 300000 Single subprocess timeout (milliseconds)

The engine also accepts environment variables (the plugin automatically injects the first three):

Variable Purpose
DSH_FUZZ_WORKSPACE Same as workspaceDir
DSH_FUZZ_EVIDENCE_DIR Same as evidenceRoot
DSH_FUZZ_STATE Persistence location for plans/seeds/runs, default <workspace>/.dsh-fuzz
DSH_FUZZ_ENGINE Engine root containing diffprobe/ and payloadsets/

fuzz Tool

The plugin exposes only one tool with six actions:

action What it does Sends packet
harvest Samples values with types (id/uuid/phone/token/email/amount, etc.) and field names from responses to generate seeds.json No
plan Generates diffprobe plans (see kind table below), with baseline + same-type comparison, optional verify No (dryRun only validates)
run Invokes diffprobe to execute plans, rate limiting, stopping on 403/429/503 hits; requires allowWrite for write methods Yes
verdict Reads diffs.csv/state.csv for classification No
doctor Checks if Python, engine, and payloadsets are ready No
bizmap Reads/writes target business map <workspace>/<evidenceRoot>/<target>/fuzz-bizmap.json No

plan kind

kind Purpose
chain Moves returned values from other interfaces to target parameter positions (BOLA/Reference chain)
idor Neighbor/Comparison/Other user IDs, paired with verify to read owner fields back
massassign Appends role/isAdmin/tenantId etc. to JSON body, checking if persisted
role / tenant / amount Candidate fields for role, tenant, and amount
param Appends hidden parameter names
bypass Path segment normalization bypasses (%61dmin, admin/, admin/..;/, ..%2f, etc.)
sqli xss ssrf lfi ssti cmdi xxe Reusing classic payload sets from engine/payloadsets/

Verdict criteria

Category Meaning
DIFFERENTIAL Engine determines differential, or semantic layer judges DIFF
INVALID Baseline itself unreachable—conclusion is invalid, not “no difference”
BLOCKED Hit protection (403/429/503, etc.)
STATE_CHANGED JSON path read back by verify actually changed
NO_SIGNAL Others

Differentials are further graded by “what changed”: state-or-data (changes in ownerId/userId/role/status/amount etc.) are worth expanding the sample; error-channel (only changing errorCode/errorMsg) is just an error branch or protection layer, do not treat as a vulnerability.

Typical Usage

Use python on Windows, python3 on macOS/Linux. Execute three offline self-check steps from the repository root (example spec does not contain real targets, offline, no network, no packets sent):

# 1) Environment self-check
python engine/fuzz/fuzz_ops.py --spec examples/doctor.json

# 2) Sample values from example responses (offline)
python engine/fuzz/fuzz_ops.py --spec examples/harvest.json

# 3) Generate idor plan and dry-run (offline, no network, no packets)
python engine/fuzz/fuzz_ops.py --spec examples/plan-idor.json

The engine also has an offline self-test server, listening only on 127.0.0.1, used to verify the differential judgment logic itself without producing external network requests:

python engine/diffprobe/selftest_server.py

Directory Structure

dsh-fuzz/
├─ index.js                  # DSH plugin: registers fuzz tool, forwards to engine
├─ cordis.patch.yml          # bundle patch (single line insert)
├─ engine/
│  ├─ fuzz/                  # fuzz_ops.py (plan/execute/judge), fuzz_verify.py (state read back), bench_verdict.py (judgment regression)
│  ├─ diffprobe/             # Request execution engine: rate limiting, destructive payload gates, differential and semantic comparison
│  └─ payloadsets/           # Shared payload sets (sqli/xss/idor/logic_*/fuzz_params, etc.)
├─ examples/                 # Example specs without real targets
└─ locale/                   # Plugin title and description

Applicable Scenarios and Notes

Suitable for DSH developers and security testing workflows that need to perform differential verification of privilege escalation and logic flaws on APIs within an authorized environment. Three points to note:

  1. Read-only by default: POST/PUT/PATCH/DELETE must explicitly have allowWrite: true. Destructive payload rejection, rate limiting, and stopping on protection hits are all performed by diffprobe; plans cannot bypass this.
  2. Evidence is persisted to <workspace>/<evidenceRoot>/<target>/evidence/fuzz/ or <workspace>/.dsh-fuzz/runs/; target authentication materials (Cookie/Token) only appear in the original requests you provide, the plugin does not persist them.
  3. Known limitations: race concurrency and state state machine generation are not yet implemented (schema reserved), current run will skip plans with kind=race; verify is “read back after a batch finishes”, which works for single-value plans, but continuous write payloads accumulate state; if you need isolation per payload, please split the plan.

The plugin runs with the current dsh process permissions. You should check the plugin source code and license (MIT) before installing. Current version is 0.1.2, requires DSH >=0.2.0-rc.2 || >=0.2.1-rc.2 || >=0.2.2-rc.1.

Directory page and source code:

  • Community directory: https://www.skillhub.cn/plugins/rannyrjjy/dsh-fuzz
  • GitHub: https://github.com/rannyrjjy/dsh-fuzz
羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

Xiaoye