ci: add strict case-contract test for examples/ctf-demo (P1-3)
- Refactor examples/ctf-demo to satisfy the review_case.py contract: split evidence/E-001-E-003.md into per-record E-001/E-002/E-003.md with ### E-xxx headings and severity/status/repro_command fields - Add evidence/checksec-output.txt artifact with matching content_hash so --verify-hashes has a real object to verify - Convert report.md finding/path sections to structured F-01/P-01 blocks - New case-contract CI job runs review_case.py --verify-hashes --strict on examples/ctf-demo; local result: PASS (0 errors, 0 warnings)
This commit is contained in:
@@ -158,6 +158,15 @@ jobs:
|
||||
shell: pwsh
|
||||
run: ./skills/scripts/scan-leaks.ps1 -Path skills/field-journal
|
||||
|
||||
case-contract:
|
||||
name: case contract test (ctf-demo)
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
- name: Review examples/ctf-demo under strict contract
|
||||
shell: bash
|
||||
run: python3 skills/case-review/scripts/review_case.py examples/ctf-demo --verify-hashes --strict
|
||||
|
||||
version-check:
|
||||
name: version consistency
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
# Evidence E-001 — Binary triage
|
||||
|
||||
- **id**: E-001
|
||||
- **date**: 2026-08-02T00:15:00
|
||||
- **title**: pwn1 ELF triage (checksec)
|
||||
- **finding**: ELF 64-bit x86-64, no PIE, NX enabled, partial RELRO, no canary on main
|
||||
- **repro_command**: `file ./pwn1 && checksec --file=./pwn1`
|
||||
- **output**:
|
||||
```text
|
||||
./pwn1: ELF 64-bit LSB executable, x86-64, dynamically linked
|
||||
RELRO: Partial RELRO
|
||||
Stack: No canary found
|
||||
NX: NX enabled
|
||||
PIE: PIE disabled
|
||||
```
|
||||
- **path**: Evidence → Finding → Path (skills/ops/evidence-finding-path.md)
|
||||
|
||||
---
|
||||
|
||||
# Evidence E-002 — Overflow confirmation
|
||||
|
||||
- **id**: E-002
|
||||
- **date**: 2026-08-02T00:40:00
|
||||
- **title**: gets() stack overflow in main
|
||||
- **finding**: main reads into buf[0x40] via gets(); return offset 0x48; no canary
|
||||
- **repro_command**: `python3 -c "print('A'*0x48 + 'B'*8)" | ./pwn1` (segfault at 0x4242424242424242)
|
||||
- **output**:
|
||||
```text
|
||||
Program received signal SIGSEGV, Segmentation fault.
|
||||
RIP=0x4242424242424242
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Evidence E-003 — Flag captured
|
||||
|
||||
- **id**: E-003
|
||||
- **date**: 2026-08-02T01:10:00
|
||||
- **title**: remote exploit success
|
||||
- **finding**: ret2win payload works remotely, flag captured
|
||||
- **repro_command**: `python3 exploit.py REMOTE`
|
||||
- **output**: `ctf{example_flag_do_not_use}`
|
||||
@@ -0,0 +1,19 @@
|
||||
### E-001
|
||||
|
||||
- title: pwn1 ELF triage (checksec)
|
||||
- severity: info
|
||||
- status: observed
|
||||
- observed_at: 2026-08-02T00:15:00
|
||||
- source_type: command
|
||||
- source_ref: recon phase
|
||||
- repro_command: |
|
||||
file ./pwn1 && checksec --file=./pwn1
|
||||
- raw_excerpt: |
|
||||
./pwn1: ELF 64-bit LSB executable, x86-64, dynamically linked
|
||||
RELRO: Partial RELRO
|
||||
Stack: No canary found
|
||||
NX: NX enabled
|
||||
PIE: PIE disabled
|
||||
- artifact_path: evidence/checksec-output.txt
|
||||
- content_hash: 395aa1546e0e22873e10334c4225097e9111f1b8fb5dcd1a2a3b7640d6fcc6ed
|
||||
- linked_workitem: WI-002
|
||||
@@ -0,0 +1,15 @@
|
||||
### E-002
|
||||
|
||||
- title: gets() stack overflow in main
|
||||
- severity: info
|
||||
- status: observed
|
||||
- observed_at: 2026-08-02T00:40:00
|
||||
- source_type: command
|
||||
- source_ref: static analysis
|
||||
- repro_command: |
|
||||
python3 -c "print('A'*0x48 + 'B'*8)" | ./pwn1
|
||||
- raw_excerpt: |
|
||||
Program received signal SIGSEGV, Segmentation fault.
|
||||
RIP=0x4242424242424242
|
||||
- content_hash: n/a
|
||||
- linked_workitem: WI-003
|
||||
@@ -0,0 +1,14 @@
|
||||
### E-003
|
||||
|
||||
- title: remote exploit success
|
||||
- severity: high
|
||||
- status: validated
|
||||
- observed_at: 2026-08-02T01:10:00
|
||||
- source_type: command
|
||||
- source_ref: exploit phase
|
||||
- repro_command: |
|
||||
python3 exploit.py REMOTE
|
||||
- raw_excerpt: |
|
||||
ctf{{example_flag_do_not_use}}
|
||||
- content_hash: n/a
|
||||
- linked_workitem: WI-004
|
||||
@@ -0,0 +1,5 @@
|
||||
./pwn1: ELF 64-bit LSB executable, x86-64, dynamically linked
|
||||
RELRO: Partial RELRO
|
||||
Stack: No canary found
|
||||
NX: NX enabled
|
||||
PIE: PIE disabled
|
||||
@@ -22,12 +22,35 @@ pwn1 为无 PIE/无 canary 的 64 位 ELF,main 使用 `gets()` 读取 0x40 缓
|
||||
|
||||
## 4. 发现
|
||||
|
||||
| # | 严重度 | 描述 | 证据 |
|
||||
|---|--------|------|------|
|
||||
| F-01 | High (CTF) | gets() 栈溢出,ret 偏移 0x48,可 ROP/ret2win | E-001, E-002, E-003 |
|
||||
### F-01
|
||||
|
||||
- title: gets() stack overflow in main (ret2win)
|
||||
- severity: high
|
||||
- status: validated
|
||||
- confidence: high
|
||||
- evidence_ids: [E-001, E-002, E-003]
|
||||
- location: pwn1:main — gets() into buf[0x40], return offset 0x48, no canary
|
||||
- impact: Remote code execution as the pwn1 process user; flag disclosure in CTF context.
|
||||
- repro_steps:
|
||||
1. Triage the binary (E-001)
|
||||
2. Confirm the overflow offset with a cyclic/crash test (E-002)
|
||||
3. Send the ret2win payload against the remote service (E-003)
|
||||
- remediation: Replace gets() with fgets/read; enable canary, PIE and full RELRO; rely on ASLR.
|
||||
|
||||
## 5. 攻击路径(Evidence → Finding → Path)
|
||||
|
||||
### P-01
|
||||
|
||||
- title: pwn1 ret2win solve path
|
||||
- path_type: solve
|
||||
- start: challenge binary download
|
||||
- goal: flag capture
|
||||
- steps:
|
||||
1. action: download and triage pwn1 — evidence: E-001 — finding: F-01 | none
|
||||
2. action: decompile main and confirm gets() overflow — evidence: E-002 — finding: F-01
|
||||
3. action: craft ret2win payload and verify remotely — evidence: E-003 — finding: F-01
|
||||
- residual_risks: none (isolated CTF lab)
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
A[下载 pwn1] --> B[checksec 侦察]
|
||||
|
||||
Reference in New Issue
Block a user