Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
2465b72
draft
May 12, 2026
f3cee69
Update
ZhidongPeng May 13, 2026
d99f7db
Set Linux file‑mode for more restrictive permissions
May 13, 2026
0e37096
GPA proxy_server to have an explicit http-method allow-list
ZhidongPeng May 14, 2026
fa3a916
update test
ZhidongPeng May 14, 2026
4e9419e
Merge branch 'file' of github.com:ZhidongPeng/GuestProxyAgent into pen
ZhidongPeng May 14, 2026
091eda5
Merge branch 'connect' of github.com:ZhidongPeng/GuestProxyAgent into…
ZhidongPeng May 14, 2026
b33d5e0
Update reports
ZhidongPeng May 14, 2026
42988c1
Updated the design md file
ZhidongPeng May 14, 2026
f7671cf
add windows pentests
ZhidongPeng May 14, 2026
3266a47
re-struct
ZhidongPeng May 14, 2026
373e19f
re-saved every .ps1 and .psm1 under windows with a UTF-8 BOM so Windo…
ZhidongPeng May 14, 2026
a2ad88a
Fix: renamed the local variable to $findingRows so the imported $Find…
ZhidongPeng May 14, 2026
580f379
Replaced the unreliable runas /trustlevel:0x20000 path with Invoke-As…
ZhidongPeng May 14, 2026
64f4818
Shortened the -Description for New-LocalUser
ZhidongPeng May 14, 2026
39cce9f
rendered HTML — including the failures/info/per-phase tables and the …
ZhidongPeng May 14, 2026
21394a6
Fixed. The credential, username, and "created" flag now live in $glob…
ZhidongPeng May 14, 2026
89b71ad
fix
ZhidongPeng May 14, 2026
89ffddf
fix pass standand-user info
ZhidongPeng May 14, 2026
c8abadc
update cleanup logic
ZhidongPeng May 14, 2026
dfb3d69
fix
ZhidongPeng May 14, 2026
cc4454f
run 4b tests
ZhidongPeng May 14, 2026
b527ab0
json_read_from_file to skip the BOM bytes before deserialize the cont…
May 19, 2026
b503afc
Merge branch 'bom' of https://github.com/ZhidongPeng/GuestProxyAgent …
ZhidongPeng May 19, 2026
baedf10
update audit mode test
ZhidongPeng May 19, 2026
4b58830
fix formatting
May 19, 2026
fe2f3ea
add more pen tests
ZhidongPeng May 19, 2026
57dd6ed
Merge branch 'bom' of github.com:ZhidongPeng/GuestProxyAgent into pen
ZhidongPeng May 19, 2026
d7432ee
update rull_all.sh
ZhidongPeng May 19, 2026
7ee8f89
Update the docs
ZhidongPeng May 19, 2026
ce28133
Merge branch 'dev' of https://github.com/ZhidongPeng/GuestProxyAgent …
ZhidongPeng May 21, 2026
c0a62fb
Fix windows automation scripts
ZhidongPeng May 28, 2026
198b2d0
fix
ZhidongPeng May 28, 2026
6775969
fix
ZhidongPeng May 28, 2026
c01da34
update linux scripts
ZhidongPeng Jun 2, 2026
84ce67f
Merge branch 'dev' into pen
ZhidongPeng Jun 2, 2026
b2aee16
update the fix
ZhidongPeng Jun 2, 2026
58451b2
fix spelling.
ZhidongPeng Jun 2, 2026
3bf0cd0
fix
ZhidongPeng Jun 2, 2026
f9a4418
Fix spell check: add hmacs and nics to expect.txt
ZhidongPeng Jun 2, 2026
b9c05f3
Fix spell check: un-shadow hmacs/nics by removing redundant singular …
ZhidongPeng Jun 2, 2026
301c077
Fix spell check: use only mixed-case HMACs and NICs entries
ZhidongPeng Jun 2, 2026
ac2529b
Merge branch 'dev' of https://github.com/ZhidongPeng/GuestProxyAgent …
ZhidongPeng Jun 5, 2026
4ce0b8d
resolve comments
Jun 5, 2026
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
133 changes: 131 additions & 2 deletions .github/actions/spelling/expect.txt

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,7 @@

# Visual Studio cache/options directory
.vs/

# pentest run & results
/pentest/*/results/
__pycache__/
33 changes: 33 additions & 0 deletions pentest/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# GPA Pen-Test Harness

Two parallel harnesses — one per OS — exercising the same scenario set
(`A1` / `B1b` / `C7` / `IMDS-S6` / …) against the Guest Proxy Agent. Each
folder is self-contained: its own scripts, its own design doc, its own
report generator, its own `results/` directory.

| Folder | Language | Report generator | Run from |
|---|---|---|---|
| [linux/](linux/) | Bash + Python | `linux/generate_report.py` | Bash on the GPA Linux VM (`bash linux/run_all.sh`) |
| [windows/](windows/) | PowerShell | `windows/Generate-Report.ps1` | Elevated PowerShell on the GPA Windows VM (`.\windows\Run-AllPenTests.ps1`) |

Findings on either platform are written as TSV rows with the same schema:

```
<iso-utc>\t<test-id>\t<PASS|FAIL|INFO>\t<short-message>
```

so a Linux `findings.tsv` and a Windows `findings.tsv` can be diffed
test-by-test.

## Pick a side

- **Linux harness** — see [linux/README.md](linux/README.md) and
[linux/DESIGN.md](linux/DESIGN.md).
- **Windows harness** — see [windows/README.md](windows/README.md) and
[windows/DESIGN.md](windows/DESIGN.md).

The Windows DESIGN doc has a cross-platform mapping table at the bottom
([windows/DESIGN.md §5](windows/DESIGN.md)) that lists each Linux concept
(eBPF redirect, `bpftool`, `tcpdump`, POSIX modes, `unshare -Cr`, …) next
to its Windows equivalent (WFP, `netsh wfp show filters`, `pktmon`, ACLs,
Containers feature, …).
247 changes: 247 additions & 0 deletions pentest/linux/DESIGN.md

Large diffs are not rendered by default.

87 changes: 87 additions & 0 deletions pentest/linux/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# GPA Pen-Test Harness

Local pen-test scaffolding for the Guest Proxy Agent running on this VM.

Mirror of the Windows harness under [../windows/](../windows/), with the
same scenario IDs and the same `findings.tsv` schema; design rationale
lives in [DESIGN.md](DESIGN.md).

## Layout

| File | Purpose |
|------|---------|
| [lib/common.sh](lib/common.sh) | Shared helpers: endpoints, paths, `record` (TSV writer), HTTP helpers, root check. |
| [test_catalog.py](test_catalog.py) | Per-test metadata (title / design / automation / repro / fix) consumed by the report. |
| [phase2_listener/run.sh](phase2_listener/run.sh) | A1, A1b, A2, A3, A4 (CONNECT → 405), A5 (open-proxy), G1 (burst). |
| [phase3_authn_authz/run.sh](phase3_authn_authz/run.sh) | P3-cap (tcpdump), B1a, B1b (kernel-side `ss -tnp` proof), B3, B4, C1 (low-IL probe via `nobody`), C5 (`unshare -Cr`), C7 (alt-IP-form parity). |
| [phase4_rules_fuzz/url_diff.py](phase4_rules_fuzz/url_diff.py) | URL / encoding differential (11 variants of the IMDS token URL). |
| [phase4b_local_rules/run.py](phase4b_local_rules/run.py) | Local-file authorization-rules matrix: IMDS S1–S10 + S11/S12/S17/S18/S19 and WS S1–S10 + S11/S12/S17/S18/S19 (30 scenarios). Mutates `/var/lib/azure-proxy-agent/rules/`. |
| [phase5_state_fs/audit.sh](phase5_state_fs/audit.sh) | E1 (keys/log/binary/unit mode+owner), F1 (no secrets in observable JSON), F4 (Rules dir mode+owner — admin-only WRITE), bpftool snapshots. |
| [generate_report.py](generate_report.py) | Renders `results/report.html` from `results/findings.tsv` (+ latest `url_diff.tsv`). |
| [run_all.sh](run_all.sh) | Driver. Runs phases 2 / 3 / 4 / 4b / 5 + report by default. Flags: `--no-truncate`, `--skip-phase{2,3,4,4b,5}`, `--phase4b-target {both,imds,wireserver}`, `--no-report`. |
| `results/` | Populated at runtime: `findings.tsv`, `url_diff.tsv`, `report.html`, per-phase pcaps / bpftool snapshots, `phase4b_local_rules.log`. |

## Prereqs

```bash
sudo apt install -y nmap tcpdump bpftool radamsa python3-scapy wrk jq strace curl
```

Python ≥ 3.8 (stdlib only — no `pip install` required for the harness or
the report generator).

The harness assumes:
- `azure-proxy-agent.service` is active.
- Listener is at `127.0.0.1:3080`.
- Fabric endpoints `169.254.169.254:80`, `168.63.129.16:{80,32526}` are reachable.
- For **Phase 4b**: the fabric has delivered an `AuthorizationRules_*.json`
whose decoded JSON contains `useLocalFileRules:true` AND its effective
`mode` is `Enforce` for the chosen target(s). Phase 4b's `PRE` row will
fast-fail if either pre-condition is missing.
- For **Phase 5 F4**: the Rules dir (`/var/lib/azure-proxy-agent/rules`)
exists on disk so its mode/owner can be audited.

## Run

```bash
# Default — phases 2, 3, 4, 4b, 5 + HTML report (truncates findings.tsv first):
sudo ./pentest/linux/run_all.sh

# Append instead of truncating:
sudo ./pentest/linux/run_all.sh --no-truncate

# Skip the mutating Phase 4b on a production VM:
sudo ./pentest/linux/run_all.sh --skip-phase4b

# Phase 4b alone, IMDS only:
sudo python3 pentest/linux/phase4b_local_rules/run.py --target imds

# Re-render the report from the existing findings.tsv:
python3 pentest/linux/generate_report.py
```

## Safety

- Phase 2 sends only loopback traffic.
- Phase 3 sends real requests to the Azure fabric — keep volumes low.
- Phase 4b *writes* to `/var/lib/azure-proxy-agent/rules/` and bounces the
agent's view of the local rule file. Backups of any pre-existing rules
files are restored on exit (including `Ctrl+C` / crash); skip with
`--skip-phase4b` if running on a fabric that doesn't allow local rules.
- Snapshot the VM (or back up `/var/lib/azure-proxy-agent` and
`/var/log/azure-proxy-agent`) before Phase 5.
- Do **not** run Phase 5 fault-injection tests (E2 symlink, E3 disk-full,
E4 kill, E5 key downgrade) on a production VM; `audit.sh` itself is
read-only and safe.

## Result format

Each test appends one TSV row to `results/findings.tsv`:

```
<iso-timestamp>\t<test-id>\t<PASS|FAIL|INFO>\t<short-message>
```

A `FAIL` means the GPA invariant was violated (potential finding) and
warrants triage. Designs, repro steps, and suggested fixes are inlined
per row in the HTML report.
Loading
Loading