@intentsolutionsio/penetration-tester 2.0.0 → 3.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +8 -3
- package/README.md +8 -0
- package/commands/pentest.md +5 -0
- package/package.json +8 -3
- package/skills/analyzing-tls-config/SKILL.md +221 -0
- package/skills/analyzing-tls-config/references/AUTHORIZATION.md +133 -0
- package/skills/analyzing-tls-config/references/PLAYBOOK.md +267 -0
- package/skills/analyzing-tls-config/references/THEORY.md +128 -0
- package/skills/analyzing-tls-config/scripts/analyze_tls.py +415 -0
- package/skills/auditing-cors-policy/SKILL.md +186 -0
- package/skills/auditing-cors-policy/references/PLAYBOOK.md +220 -0
- package/skills/auditing-cors-policy/references/THEORY.md +142 -0
- package/skills/auditing-cors-policy/scripts/audit_cors.py +350 -0
- package/skills/auditing-npm-dependencies/SKILL.md +254 -0
- package/skills/auditing-npm-dependencies/references/PLAYBOOK.md +175 -0
- package/skills/auditing-npm-dependencies/references/THEORY.md +122 -0
- package/skills/auditing-npm-dependencies/scripts/audit_npm.py +408 -0
- package/skills/auditing-python-dependencies/SKILL.md +251 -0
- package/skills/auditing-python-dependencies/references/PLAYBOOK.md +193 -0
- package/skills/auditing-python-dependencies/references/THEORY.md +122 -0
- package/skills/auditing-python-dependencies/scripts/audit_python.py +459 -0
- package/skills/checking-http-security-headers/SKILL.md +176 -0
- package/skills/checking-http-security-headers/references/PLAYBOOK.md +212 -0
- package/skills/checking-http-security-headers/references/THEORY.md +137 -0
- package/skills/checking-http-security-headers/scripts/check_headers.py +362 -0
- package/skills/checking-license-compliance/SKILL.md +225 -0
- package/skills/checking-license-compliance/references/PLAYBOOK.md +161 -0
- package/skills/checking-license-compliance/references/THEORY.md +152 -0
- package/skills/checking-license-compliance/scripts/check_licenses.py +461 -0
- package/skills/composing-vulnerability-report/SKILL.md +212 -0
- package/skills/composing-vulnerability-report/references/PLAYBOOK.md +180 -0
- package/skills/composing-vulnerability-report/references/THEORY.md +178 -0
- package/skills/composing-vulnerability-report/scripts/compose_report.py +396 -0
- package/skills/confirming-pentest-authorization/SKILL.md +247 -0
- package/skills/confirming-pentest-authorization/references/PLAYBOOK.md +189 -0
- package/skills/confirming-pentest-authorization/references/THEORY.md +167 -0
- package/skills/confirming-pentest-authorization/scripts/check_authorization.py +457 -0
- package/skills/defining-pentest-scope/SKILL.md +227 -0
- package/skills/defining-pentest-scope/references/PLAYBOOK.md +238 -0
- package/skills/defining-pentest-scope/references/THEORY.md +170 -0
- package/skills/defining-pentest-scope/scripts/define_scope.py +472 -0
- package/skills/detecting-command-injection-patterns/SKILL.md +144 -0
- package/skills/detecting-command-injection-patterns/references/PLAYBOOK.md +302 -0
- package/skills/detecting-command-injection-patterns/references/THEORY.md +206 -0
- package/skills/detecting-command-injection-patterns/scripts/scan_cmdi.py +290 -0
- package/skills/detecting-debug-endpoints/SKILL.md +207 -0
- package/skills/detecting-debug-endpoints/references/PLAYBOOK.md +402 -0
- package/skills/detecting-debug-endpoints/references/THEORY.md +218 -0
- package/skills/detecting-debug-endpoints/scripts/probe_debug.py +518 -0
- package/skills/detecting-directory-listing/SKILL.md +206 -0
- package/skills/detecting-directory-listing/references/PLAYBOOK.md +277 -0
- package/skills/detecting-directory-listing/references/THEORY.md +203 -0
- package/skills/detecting-directory-listing/scripts/probe_directory_listing.py +180 -0
- package/skills/detecting-eval-exec-usage/SKILL.md +128 -0
- package/skills/detecting-eval-exec-usage/references/PLAYBOOK.md +306 -0
- package/skills/detecting-eval-exec-usage/references/THEORY.md +159 -0
- package/skills/detecting-eval-exec-usage/scripts/scan_eval.py +223 -0
- package/skills/detecting-exposed-secrets-files/SKILL.md +179 -0
- package/skills/detecting-exposed-secrets-files/references/PLAYBOOK.md +274 -0
- package/skills/detecting-exposed-secrets-files/references/THEORY.md +174 -0
- package/skills/detecting-exposed-secrets-files/scripts/probe_secrets.py +207 -0
- package/skills/detecting-insecure-deserialization/SKILL.md +148 -0
- package/skills/detecting-insecure-deserialization/references/PLAYBOOK.md +333 -0
- package/skills/detecting-insecure-deserialization/references/THEORY.md +199 -0
- package/skills/detecting-insecure-deserialization/scripts/scan_deserialization.py +250 -0
- package/skills/detecting-sql-injection-patterns/SKILL.md +161 -0
- package/skills/detecting-sql-injection-patterns/references/PLAYBOOK.md +317 -0
- package/skills/detecting-sql-injection-patterns/references/THEORY.md +261 -0
- package/skills/detecting-sql-injection-patterns/scripts/scan_sqli.py +354 -0
- package/skills/detecting-ssl-cert-issues/SKILL.md +182 -0
- package/skills/detecting-ssl-cert-issues/references/PLAYBOOK.md +203 -0
- package/skills/detecting-ssl-cert-issues/references/THEORY.md +133 -0
- package/skills/detecting-ssl-cert-issues/scripts/check_cert_chain.py +481 -0
- package/skills/detecting-weak-cryptography/SKILL.md +147 -0
- package/skills/detecting-weak-cryptography/references/PLAYBOOK.md +466 -0
- package/skills/detecting-weak-cryptography/references/THEORY.md +194 -0
- package/skills/detecting-weak-cryptography/scripts/scan_weak_crypto.py +417 -0
- package/skills/fingerprinting-server-software/SKILL.md +191 -0
- package/skills/fingerprinting-server-software/references/PLAYBOOK.md +337 -0
- package/skills/fingerprinting-server-software/references/THEORY.md +183 -0
- package/skills/fingerprinting-server-software/scripts/fingerprint_server.py +347 -0
- package/skills/generating-executive-summary/SKILL.md +261 -0
- package/skills/generating-executive-summary/references/PLAYBOOK.md +201 -0
- package/skills/generating-executive-summary/references/THEORY.md +195 -0
- package/skills/generating-executive-summary/scripts/exec_summary.py +538 -0
- package/skills/mapping-findings-to-owasp-top10/SKILL.md +235 -0
- package/skills/mapping-findings-to-owasp-top10/references/PLAYBOOK.md +193 -0
- package/skills/mapping-findings-to-owasp-top10/references/THEORY.md +160 -0
- package/skills/mapping-findings-to-owasp-top10/scripts/map_owasp.py +540 -0
- package/skills/performing-penetration-testing/SKILL.md +282 -190
- package/skills/performing-penetration-testing/references/OWASP_TOP_10.md +22 -0
- package/skills/performing-penetration-testing/references/REMEDIATION_PLAYBOOK.md +46 -0
- package/skills/performing-penetration-testing/references/SECURITY_HEADERS.md +41 -0
- package/skills/performing-penetration-testing/scripts/code_security_scanner.py +144 -79
- package/skills/performing-penetration-testing/scripts/dependency_auditor.py +116 -93
- package/skills/performing-penetration-testing/scripts/security_scanner.py +574 -446
- package/skills/probing-dangerous-http-methods/SKILL.md +182 -0
- package/skills/probing-dangerous-http-methods/references/PLAYBOOK.md +234 -0
- package/skills/probing-dangerous-http-methods/references/THEORY.md +145 -0
- package/skills/probing-dangerous-http-methods/scripts/probe_methods.py +263 -0
- package/skills/recording-pentest-engagement/SKILL.md +253 -0
- package/skills/recording-pentest-engagement/references/PLAYBOOK.md +203 -0
- package/skills/recording-pentest-engagement/references/THEORY.md +195 -0
- package/skills/recording-pentest-engagement/scripts/record_engagement.py +461 -0
- package/skills/scanning-for-hardcoded-secrets/SKILL.md +215 -0
- package/skills/scanning-for-hardcoded-secrets/references/PLAYBOOK.md +325 -0
- package/skills/scanning-for-hardcoded-secrets/references/THEORY.md +175 -0
- package/skills/scanning-for-hardcoded-secrets/scripts/scan_secrets.py +395 -0
- package/skills/tracing-transitive-vulnerabilities/SKILL.md +235 -0
- package/skills/tracing-transitive-vulnerabilities/references/PLAYBOOK.md +233 -0
- package/skills/tracing-transitive-vulnerabilities/references/THEORY.md +138 -0
- package/skills/tracing-transitive-vulnerabilities/scripts/trace_vulns.py +484 -0
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
# PLAYBOOK — Recording, Closeout, and Long-Term Storage
|
|
2
|
+
|
|
3
|
+
## Recommended engagement directory layout
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
engagements/<client>-<year>-<quarter>/
|
|
7
|
+
├── roe.yaml # signed ROE
|
|
8
|
+
├── allowed-authorizers # signer allowlist
|
|
9
|
+
├── roe.amendments/
|
|
10
|
+
│ └── amendment-NNN-<date>.yaml
|
|
11
|
+
├── scope/
|
|
12
|
+
│ ├── allowed-ips.txt # produced by defining-pentest-scope
|
|
13
|
+
│ ├── normalized-targets.json
|
|
14
|
+
│ └── scope-report.md
|
|
15
|
+
├── findings/
|
|
16
|
+
│ ├── 2026-06-05-cluster1-tls.json # one file per scan session
|
|
17
|
+
│ ├── 2026-06-05-cluster1-cors.json
|
|
18
|
+
│ ├── 2026-06-07-cluster3-secrets.json
|
|
19
|
+
│ └── ...
|
|
20
|
+
├── evidence/
|
|
21
|
+
│ ├── screenshots/ # PNG / JPG of vulnerable pages
|
|
22
|
+
│ ├── tool-logs/ # raw nmap, Burp, custom tool logs
|
|
23
|
+
│ └── raw-scan-output/ # other raw artifacts
|
|
24
|
+
├── reports/
|
|
25
|
+
│ ├── vulnerability-report.md # produced by composing-vulnerability-report
|
|
26
|
+
│ ├── owasp-mapping.json # produced by mapping-findings-to-owasp-top10
|
|
27
|
+
│ └── executive-summary.md # produced by generating-executive-summary
|
|
28
|
+
├── manifest.sha256 # produced by THIS skill
|
|
29
|
+
├── manifest.sha256.asc # optional GPG signature
|
|
30
|
+
└── chain-of-custody.md # this skill's output report
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Daily-snapshot cron pattern
|
|
34
|
+
|
|
35
|
+
For long engagements (red-team, multi-month), build a daily
|
|
36
|
+
snapshot trail:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
#!/usr/bin/env bash
|
|
40
|
+
# cron: 0 23 * * * /opt/pentest/daily-snapshot.sh acme-2026-q2
|
|
41
|
+
ENGAGEMENT="$1"
|
|
42
|
+
ROOT="engagements/${ENGAGEMENT}"
|
|
43
|
+
DATE=$(date +%Y%m%d)
|
|
44
|
+
python3 plugins/security/penetration-tester/skills/recording-pentest-engagement/scripts/record_engagement.py \
|
|
45
|
+
"$ROOT" \
|
|
46
|
+
--manifest "$ROOT/snapshots/manifest-$DATE.sha256" \
|
|
47
|
+
--sign \
|
|
48
|
+
--output "$ROOT/snapshots/snapshot-$DATE.md"
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Daily snapshots give you a time-series of the engagement's
|
|
52
|
+
state. If a dispute arises about what was found on a specific
|
|
53
|
+
date, the daily snapshot from that date is the authoritative
|
|
54
|
+
answer.
|
|
55
|
+
|
|
56
|
+
## Customer-handoff protocol
|
|
57
|
+
|
|
58
|
+
End of engagement:
|
|
59
|
+
|
|
60
|
+
1. Run the final manifest + signing + archive:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
python3 ./scripts/record_engagement.py engagements/acme-2026-q2/ \
|
|
64
|
+
--sign --signer your-key-id \
|
|
65
|
+
--tar engagements/archives/acme-2026-q2.tar.gz \
|
|
66
|
+
--output engagements/acme-2026-q2/chain-of-custody.md
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
2. Verify the archive end-to-end:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
cd /tmp/verify
|
|
73
|
+
tar xzf .../acme-2026-q2.tar.gz
|
|
74
|
+
cd acme-2026-q2
|
|
75
|
+
sha256sum -c manifest.sha256 # should print "OK" for every file
|
|
76
|
+
gpg --verify manifest.sha256.asc manifest.sha256
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
3. Hand to the customer's documented evidence-receipt contact.
|
|
80
|
+
Get a written acknowledgment of receipt.
|
|
81
|
+
|
|
82
|
+
4. Archive your own copy in long-term storage (see below).
|
|
83
|
+
|
|
84
|
+
## Dispute-resolution playbook
|
|
85
|
+
|
|
86
|
+
### "The customer says the archive is missing files"
|
|
87
|
+
|
|
88
|
+
1. Run the skill against the archive (current state).
|
|
89
|
+
2. Run the skill against your tester working copy (current
|
|
90
|
+
state).
|
|
91
|
+
3. Diff the two file lists. Anything in the tester copy but not
|
|
92
|
+
in the archive is a candidate addition.
|
|
93
|
+
4. Decide: was the file in scope? In-scope evidence: re-archive
|
|
94
|
+
with addition. Out-of-scope: explain why it wasn't included.
|
|
95
|
+
|
|
96
|
+
### "The customer says the evidence was modified"
|
|
97
|
+
|
|
98
|
+
1. Verify the existing manifest: `sha256sum -c manifest.sha256`.
|
|
99
|
+
If OK, archive is internally consistent.
|
|
100
|
+
2. Verify the GPG signature: `gpg --verify manifest.sha256.asc
|
|
101
|
+
manifest.sha256`. If OK, the manifest is attestably the one
|
|
102
|
+
you produced.
|
|
103
|
+
3. If both checks pass, the evidence in the archive matches what
|
|
104
|
+
you produced at engagement close. The dispute is about the
|
|
105
|
+
evidence itself, not the archive integrity.
|
|
106
|
+
|
|
107
|
+
### "The customer says the tester accessed an unauthorized system"
|
|
108
|
+
|
|
109
|
+
1. Locate the relevant finding(s) referencing the system in the
|
|
110
|
+
archive.
|
|
111
|
+
2. Cross-reference against `scope/normalized-targets.json` and
|
|
112
|
+
`roe.yaml`.
|
|
113
|
+
3. If the system was in scope at the engagement time, present
|
|
114
|
+
the cross-reference.
|
|
115
|
+
4. If the system was NOT in scope, the dispute is about whether
|
|
116
|
+
the access was unauthorized. The tester's own working logs
|
|
117
|
+
(often raw tool output in `evidence/tool-logs/`) may contain
|
|
118
|
+
forensic details about how the access happened.
|
|
119
|
+
|
|
120
|
+
## Long-term storage patterns
|
|
121
|
+
|
|
122
|
+
| Storage | Pros | Cons |
|
|
123
|
+
|---|---|---|
|
|
124
|
+
| Encrypted S3 bucket with object-lock | Cheap, retention-policy enforceable | Vendor lock-in; cost over decades |
|
|
125
|
+
| Encrypted USB drive in fireproof safe | Air-gapped, simple | Physical loss / damage risk |
|
|
126
|
+
| On-prem NAS with versioned snapshots | Self-controlled | Operational burden, hardware refresh |
|
|
127
|
+
| Cloud + on-prem (both) | Best of both | 2x cost |
|
|
128
|
+
|
|
129
|
+
For pentest evidence with potential litigation exposure, the
|
|
130
|
+
S3-with-object-lock pattern is popular: tier 1 is S3 Glacier with
|
|
131
|
+
6-year retention lock, tier 2 is local encrypted backup.
|
|
132
|
+
|
|
133
|
+
## Access control over retained archives
|
|
134
|
+
|
|
135
|
+
Define who can read the archive at retrieval time:
|
|
136
|
+
|
|
137
|
+
- Engagement lead (the tester)
|
|
138
|
+
- Customer authorization recipient (original ROE signer)
|
|
139
|
+
- Legal counsel for either party
|
|
140
|
+
- External auditors (with separate written authorization)
|
|
141
|
+
|
|
142
|
+
Access logs themselves are evidence — log every retrieval of an
|
|
143
|
+
archived engagement with timestamp + retrieving party. Some
|
|
144
|
+
storage systems do this automatically; others require explicit
|
|
145
|
+
audit configuration.
|
|
146
|
+
|
|
147
|
+
## Encryption of the archive
|
|
148
|
+
|
|
149
|
+
For sensitive engagements (financial services, healthcare,
|
|
150
|
+
defense), encrypt the archive at rest:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
# After archive creation
|
|
154
|
+
gpg --encrypt --recipient archive-encryption-key \
|
|
155
|
+
--output acme-2026-q2.tar.gz.gpg acme-2026-q2.tar.gz
|
|
156
|
+
# Securely wipe the unencrypted copy
|
|
157
|
+
shred -u acme-2026-q2.tar.gz
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
The encryption recipient should be a key managed by your firm's
|
|
161
|
+
key-custody process, NOT the tester's individual GPG identity.
|
|
162
|
+
The tester may not be reachable in 7 years; the firm's key
|
|
163
|
+
custody process should be.
|
|
164
|
+
|
|
165
|
+
## Common closeout mistakes
|
|
166
|
+
|
|
167
|
+
| Mistake | Consequence | Fix |
|
|
168
|
+
|---|---|---|
|
|
169
|
+
| Forgot to manifest screenshots | Customer can't verify screenshot integrity | Re-run skill, re-sign manifest |
|
|
170
|
+
| Manifest signed by tester's personal key | Key unavailable years later | Sign with firm-managed identity |
|
|
171
|
+
| Findings reference paths in tester's home dir | Customer can't open the linked file | Copy files into engagement tree before archiving |
|
|
172
|
+
| Archive on tester's laptop only | Single point of failure | Replicate to long-term storage immediately |
|
|
173
|
+
| No daily snapshots during long engagement | Disputes about specific-date state are uncheckable | Daily snapshot cron |
|
|
174
|
+
| Manifest emitted but never signed | Integrity provable; provenance not | Add `--sign` to closeout command |
|
|
175
|
+
|
|
176
|
+
## Sample closeout script
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
#!/usr/bin/env bash
|
|
180
|
+
# closeout.sh — run at end of engagement
|
|
181
|
+
set -euo pipefail
|
|
182
|
+
ENGAGEMENT="${1:?engagement name required}"
|
|
183
|
+
ROOT="engagements/${ENGAGEMENT}"
|
|
184
|
+
ARCHIVE_DIR="engagements/archives"
|
|
185
|
+
|
|
186
|
+
mkdir -p "$ARCHIVE_DIR"
|
|
187
|
+
|
|
188
|
+
python3 plugins/security/penetration-tester/skills/recording-pentest-engagement/scripts/record_engagement.py \
|
|
189
|
+
"$ROOT" \
|
|
190
|
+
--sign --signer "firm-pentest-2026" \
|
|
191
|
+
--tar "$ARCHIVE_DIR/${ENGAGEMENT}.tar.gz" \
|
|
192
|
+
--output "$ROOT/chain-of-custody.md" \
|
|
193
|
+
--format markdown
|
|
194
|
+
|
|
195
|
+
# Verify the archive end-to-end
|
|
196
|
+
tmpdir=$(mktemp -d)
|
|
197
|
+
tar xzf "$ARCHIVE_DIR/${ENGAGEMENT}.tar.gz" -C "$tmpdir"
|
|
198
|
+
cd "$tmpdir/${ENGAGEMENT}"
|
|
199
|
+
sha256sum -c manifest.sha256 || { echo "MANIFEST CHECK FAILED"; exit 1; }
|
|
200
|
+
gpg --verify manifest.sha256.asc manifest.sha256 || { echo "SIGNATURE CHECK FAILED"; exit 1; }
|
|
201
|
+
|
|
202
|
+
echo "Closeout complete: $ARCHIVE_DIR/${ENGAGEMENT}.tar.gz"
|
|
203
|
+
```
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
# THEORY — Chain of Custody for Pentest Evidence
|
|
2
|
+
|
|
3
|
+
## Why chain of custody matters
|
|
4
|
+
|
|
5
|
+
A pentest produces evidence. Evidence has two properties that
|
|
6
|
+
matter legally:
|
|
7
|
+
|
|
8
|
+
1. **Integrity** — the evidence has not been modified since it was
|
|
9
|
+
collected.
|
|
10
|
+
2. **Provenance** — the evidence's path from creation to current
|
|
11
|
+
custodian is documented.
|
|
12
|
+
|
|
13
|
+
Together they answer: "is this report telling me what was actually
|
|
14
|
+
found, or has someone edited it after the fact?"
|
|
15
|
+
|
|
16
|
+
The downstream consumers of pentest evidence vary by engagement:
|
|
17
|
+
|
|
18
|
+
- **Customer's internal audit team** — needs to file the report
|
|
19
|
+
for compliance evidence (SOC2, ISO 27001, PCI DSS audit).
|
|
20
|
+
- **Legal counsel** — needs the evidence for breach
|
|
21
|
+
notification, insurance claim, or litigation contexts.
|
|
22
|
+
- **Outside SOC reviewing the activity** — needs to confirm that
|
|
23
|
+
alerts they raised during the engagement match authorized
|
|
24
|
+
testing.
|
|
25
|
+
- **Future readers of the same customer's engagement history** —
|
|
26
|
+
need to know what was tested when, to make scope decisions for
|
|
27
|
+
the next engagement.
|
|
28
|
+
|
|
29
|
+
Each consumer asks variations of "show me the proof." The
|
|
30
|
+
chain-of-custody artifact this skill produces is that proof.
|
|
31
|
+
|
|
32
|
+
## NIST SP 800-86 evidence-handling principles
|
|
33
|
+
|
|
34
|
+
NIST Special Publication 800-86 (Guide to Integrating Forensic
|
|
35
|
+
Techniques into Incident Response) establishes the principles
|
|
36
|
+
this skill follows:
|
|
37
|
+
|
|
38
|
+
- Acquire evidence using techniques that preserve the original
|
|
39
|
+
state.
|
|
40
|
+
- Document everything — who, what, when, where, how.
|
|
41
|
+
- Use cryptographic hashing to detect any modification after
|
|
42
|
+
acquisition.
|
|
43
|
+
- Limit access to evidence to a documented chain of custody.
|
|
44
|
+
|
|
45
|
+
The pentest case isn't a forensic incident, but the same
|
|
46
|
+
principles apply: the evidence we produce will be examined by
|
|
47
|
+
parties we don't fully control, and they need objective grounds
|
|
48
|
+
to trust it.
|
|
49
|
+
|
|
50
|
+
## SHA-256 vs SHA-3 vs SHA-512
|
|
51
|
+
|
|
52
|
+
The skill uses SHA-256. Reasons:
|
|
53
|
+
|
|
54
|
+
- **Universally available.** Python's `hashlib`, Linux's
|
|
55
|
+
`sha256sum`, macOS's `shasum`, Windows's `Get-FileHash`. No
|
|
56
|
+
party verifying the manifest needs to install anything special.
|
|
57
|
+
- **No known practical preimage attacks** as of 2026. Collision
|
|
58
|
+
attacks on SHA-256 have been theorized but not demonstrated.
|
|
59
|
+
- **Output size (64 hex chars) is human-tractable** for spot
|
|
60
|
+
checks.
|
|
61
|
+
|
|
62
|
+
SHA-3 is fine — academically preferred for new designs — but
|
|
63
|
+
tooling is less universal. SHA-512 is fine too — slightly slower,
|
|
64
|
+
larger output. For evidence-integrity purposes, SHA-256 is
|
|
65
|
+
sufficient and the most portable choice. If your customer's policy
|
|
66
|
+
requires SHA-512, the skill could be extended to emit both.
|
|
67
|
+
|
|
68
|
+
MD5 and SHA-1 are NOT acceptable. Both have practical collision
|
|
69
|
+
attacks. Don't use them for evidence integrity even if old tooling
|
|
70
|
+
defaults to them.
|
|
71
|
+
|
|
72
|
+
## GPG detached signatures
|
|
73
|
+
|
|
74
|
+
A GPG detached signature is a separate file (typically `.asc` or
|
|
75
|
+
`.sig`) that contains a cryptographic signature over the contents
|
|
76
|
+
of the original file, made with the signer's private key. Anyone
|
|
77
|
+
with the signer's public key can verify:
|
|
78
|
+
|
|
79
|
+
- The signature was made by the holder of the private key.
|
|
80
|
+
- The signed content hasn't been modified since signing.
|
|
81
|
+
|
|
82
|
+
Detached signatures are preferred over inline signatures because
|
|
83
|
+
the original file remains unchanged — easier to feed to tools that
|
|
84
|
+
expect the original format.
|
|
85
|
+
|
|
86
|
+
The skill produces `manifest.sha256.asc` alongside the
|
|
87
|
+
`manifest.sha256`. Verification flow:
|
|
88
|
+
|
|
89
|
+
1. `gpg --verify manifest.sha256.asc manifest.sha256` — confirms
|
|
90
|
+
the manifest is signed by the claimed signer.
|
|
91
|
+
2. `sha256sum -c manifest.sha256` — confirms the manifest's
|
|
92
|
+
contents match the on-disk files.
|
|
93
|
+
|
|
94
|
+
Both checks together: the signer attests that the manifest is
|
|
95
|
+
correct, AND the manifest is currently correct against the
|
|
96
|
+
archive.
|
|
97
|
+
|
|
98
|
+
## Archive format choices
|
|
99
|
+
|
|
100
|
+
The skill uses gzip-compressed tar (`.tar.gz`) for the optional
|
|
101
|
+
portable archive. Comparison:
|
|
102
|
+
|
|
103
|
+
| Format | Tooling | Compression | Notes |
|
|
104
|
+
|---|---|---|---|
|
|
105
|
+
| `.tar.gz` | universal (Linux/macOS/Windows-WSL) | Good | Preserves Unix permissions, mtimes |
|
|
106
|
+
| `.zip` | universal (incl. Windows native) | Good | Loses some Unix metadata; password-protect is weak |
|
|
107
|
+
| WORM (Write-Once Read-Many) media | requires WORM library | n/a | Strongest integrity claim; expensive |
|
|
108
|
+
|
|
109
|
+
Tar.gz is the practical choice. WORM is the strongest claim but
|
|
110
|
+
operationally rare outside specialized forensic shops. The
|
|
111
|
+
manifest provides equivalent integrity guarantees without the
|
|
112
|
+
operational burden.
|
|
113
|
+
|
|
114
|
+
## Retention horizons per jurisdiction
|
|
115
|
+
|
|
116
|
+
How long to keep pentest evidence depends on the jurisdiction and
|
|
117
|
+
the customer's regulatory posture. Common defaults:
|
|
118
|
+
|
|
119
|
+
| Driver | Typical retention |
|
|
120
|
+
|---|---|
|
|
121
|
+
| Statute of limitations on unauthorized-access offences (US) | 5 years |
|
|
122
|
+
| Statute of limitations (UK, CMA offences) | 6 years |
|
|
123
|
+
| SOC2 audit evidence | 7 years |
|
|
124
|
+
| ISO 27001 audit evidence | 5 years |
|
|
125
|
+
| PCI DSS evidence | 1-3 years (varies by control) |
|
|
126
|
+
| HIPAA breach evidence | 6 years from creation or last effective date |
|
|
127
|
+
| Customer-contractual retention | varies — read the engagement contract |
|
|
128
|
+
|
|
129
|
+
The skill doesn't enforce retention — that's a storage-policy
|
|
130
|
+
concern. The skill ensures the evidence is portable and verifiable
|
|
131
|
+
for whatever retention period applies.
|
|
132
|
+
|
|
133
|
+
## Out-of-tree path detection
|
|
134
|
+
|
|
135
|
+
A finding that references a file at `/home/tester/notes.md` is a
|
|
136
|
+
chain-of-custody problem: when the engagement archive is moved to
|
|
137
|
+
the customer's storage, that file won't come along. The finding
|
|
138
|
+
becomes uncheckable.
|
|
139
|
+
|
|
140
|
+
The skill scans `findings/*.json` for path-shaped string values in
|
|
141
|
+
the `evidence` dicts and flags any absolute path that isn't within
|
|
142
|
+
the engagement directory tree. The remediation is to copy the
|
|
143
|
+
referenced file INTO the engagement tree, OR change the finding to
|
|
144
|
+
not reference the out-of-tree path.
|
|
145
|
+
|
|
146
|
+
## When the customer disputes the archive
|
|
147
|
+
|
|
148
|
+
Two failure modes:
|
|
149
|
+
|
|
150
|
+
### "The archive is incomplete"
|
|
151
|
+
|
|
152
|
+
Customer claims they didn't get all the evidence. Resolution:
|
|
153
|
+
|
|
154
|
+
1. Run this skill against the archive directory; the report lists
|
|
155
|
+
every file with its hash.
|
|
156
|
+
2. Compare the list against the customer's expected file list.
|
|
157
|
+
3. If files are missing from the archive, restore from the
|
|
158
|
+
tester's working copy and re-archive.
|
|
159
|
+
4. If the customer's expected list includes files that were never
|
|
160
|
+
in scope, document that in the resolution communication.
|
|
161
|
+
|
|
162
|
+
### "The archive has been modified"
|
|
163
|
+
|
|
164
|
+
Customer claims the evidence doesn't match what they saw during
|
|
165
|
+
the engagement. Resolution:
|
|
166
|
+
|
|
167
|
+
1. Run `sha256sum -c manifest.sha256` against the archive
|
|
168
|
+
directory. If output is "OK," the archive is internally
|
|
169
|
+
consistent.
|
|
170
|
+
2. If the customer's claim is that the EVIDENCE itself was
|
|
171
|
+
manipulated (not the archive), compare against the daily
|
|
172
|
+
snapshots taken during the engagement (if available).
|
|
173
|
+
3. If no daily snapshots were taken, the integrity claim depends
|
|
174
|
+
on the original manifest signature and any external retention
|
|
175
|
+
timestamps (e.g. WORM storage, email of the manifest at
|
|
176
|
+
engagement close).
|
|
177
|
+
|
|
178
|
+
The skill's daily-snapshot pattern (see PLAYBOOK.md) is the cheap
|
|
179
|
+
preventive measure for this dispute class.
|
|
180
|
+
|
|
181
|
+
## Why the manifest is in standard sha256sum format
|
|
182
|
+
|
|
183
|
+
The skill could emit a custom JSON manifest. The sha256sum format
|
|
184
|
+
is preferred because:
|
|
185
|
+
|
|
186
|
+
- Standard Unix tooling (`sha256sum -c`) verifies it without any
|
|
187
|
+
custom code.
|
|
188
|
+
- A customer or legal counsel can verify the manifest 10 years
|
|
189
|
+
from now even if this skill no longer exists.
|
|
190
|
+
- The format is line-oriented; diffs are readable.
|
|
191
|
+
|
|
192
|
+
The standard format is one line per file: 64-hex-char digest,
|
|
193
|
+
exactly two spaces, then the file's relative path. Both Linux's
|
|
194
|
+
`sha256sum` and macOS's `shasum -a 256` produce and verify this
|
|
195
|
+
form.
|