Skip to content

feat: add lightweight WAF mitigation check mode - #2

Open
msuiche wants to merge 2 commits into
assetnote:masterfrom
msuiche:feat/lightweight-waf-check
Open

msuiche wants to merge 2 commits into
assetnote:masterfrom
msuiche:feat/lightweight-waf-check

Conversation

@msuiche

@msuiche msuiche commented Oct 22, 2026

Copy link
Copy Markdown

The existing scanner treats rejected probes as inconclusive and uses large multipart bodies to look for PHP failure signals. This adds an opt-in --waf-check mode for checking edge mitigation with a benign control and a small exploit-shaped multipart request.

The shaped request contains PHP_SESSION_UPLOAD_PROGRESS, three t[] fields, and two 4 KB file parts. Both requests use the same cookie context. This mode never builds or sends the existing memory-pressure probes.

A passing control followed by HTTP 403 with a Cloudflare block-page marker reports BLOCKED. Accepted shaped requests report NOT BLOCKED; rejected controls, non-Cloudflare rejections, redirects, and request errors remain distinct. Results describe only the tested shape and do not identify the rule that fired or establish PHP patch status. vulnerable stays null in WAF mode.

Existing URL/path, custom-header, TLS, timeout, and threading options apply. JSON includes all WAF results; quiet mode prints checks that are not confirmed blocked. Exit status is 0 only when every tested target/path is blocked, 1 otherwise, or 2 on output-write failure. The default vulnerability scan retains its existing behavior.

Attribution

The WAF-check technique and multipart layout are adapted from my earlier php2shell_waf_check, credited to Matt Suiche, Tolmo in the README and implementation.

Validation

21 tests pass on Python 3.9.25 and Python 3.14.7:

python3 -m unittest discover -s tests -v

Tests cover payload structure and size, verdicts, control rejection, redirects, network errors, custom-cookie handling and credential redaction, multi-path aggregation, threaded and quiet output, JSON, exit statuses, and the existing scanner mode. Integration tests use a local HTTP server; no external targets are probed. Changed executable lines have 100% line coverage. Basic lint and git diff --check also pass.

Add small control and exploit-shaped multipart requests to assess selective Cloudflare blocking without running memory-pressure probes. Keep WAF results separate from vulnerability status and support existing CLI, path, threading, and JSON options.

Adapt the WAF-check technique and multipart layout from Matt Suiche's php2shell_waf_check. Add local HTTP integration tests, verdict tests, and usage documentation.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant