Metadata-Version: 2.4
Name: pentest-framework
Version: 1.0.0
Summary: Low-noise pentest orchestration: recon + scanning + passive checks normalized into one schema, deduplicated, and rendered to a professional PDF.
Author: Matteo Perino
License: MIT
Project-URL: Homepage, https://github.com/matte97p/pentest-framework
Project-URL: Issues, https://github.com/matte97p/pentest-framework/issues
Keywords: security,pentest,recon,nuclei,owasp,report,scanner
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Information Technology
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Topic :: Security
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests>=2.31
Requires-Dist: reportlab>=4.0
Provides-Extra: ai
Requires-Dist: anthropic>=0.49; extra == "ai"
Provides-Extra: dev
Requires-Dist: pytest>=7; extra == "dev"
Dynamic: license-file

# Pentest Framework

A modular, automated penetration-testing pipeline that orchestrates open-source
tooling, normalizes results into a single schema, deduplicates, optionally
enriches findings with an LLM, and produces a professional PDF report.

> **FOR AUTHORIZED SECURITY TESTING ONLY.** Only run this against assets you own
> or have explicit written permission to test. The pipeline asks for an
> authorization confirmation before active testing (skippable with `--no-confirm`
> for automation).

## Pipeline

```
target ─▶ recon ─▶ scanners ─▶ api_checks ─▶ aggregate ─▶ [enrich] ─▶ PDF report
         (subfinder/    (nuclei/    (headers/CORS/   (dedup +        (Claude,
          amass/httpx)   nikto)      exposed paths)   group)          optional)
```

## Low-noise by design

Most header/recon scanners drown you in false positives. This one suppresses the
common ones at the source:

- **Content-type-aware headers** — CSP, X-Frame-Options, Referrer-Policy and
  Permissions-Policy are flagged only on rendered HTML documents, not on JSON
  APIs where they have no effect.
- **HSTS only over HTTPS** — never reported on plaintext `http://` targets, where
  the header is ignored by browsers.
- **SPA-fallback fingerprinting** — a single-page-app catch-all that returns the
  index shell for every path is not reported as an "exposed endpoint".
- **CORS** — flags the precise dangerous combination (reflected / `null` origin
  *with credentials*), not a correctly-configured allowlist.
- **One schema** — every tool's output is normalized, deduplicated, and severity-
  escalated into a single finding shape.

## Architecture

```
pentest-framework/            # repo root
├── pentest_framework/        # the package
│   ├── main.py               # full pipeline (CLI: pentest-framework)
│   ├── scan_local.py         # scan a locally-running app by URL
│   ├── recon/ scanner/ api_checks/ parser/ enrichment/ report/
│   ├── models/               # the single Finding schema + Severity
│   └── utils/                # logging, subprocess runner, scope handling
├── examples/                 # standalone usage examples
├── tests/                    # pytest unit tests
└── pyproject.toml  LICENSE  README.md
```

## Install

```bash
pip install -e ".[ai]"        # editable install; '[ai]' adds optional Claude enrichment
# or runtime deps only:
pip install -r requirements.txt
```

Installs a `pentest-framework` console command (equivalent to
`python -m pentest_framework.main`).

External CLI tools are **not** Python packages — install them separately and put
them on `$PATH`:

| Tool | Role | Link |
|------|------|------|
| `subfinder` | subdomain enumeration (primary) | https://github.com/projectdiscovery/subfinder |
| `httpx` | liveness + tech fingerprinting | https://github.com/projectdiscovery/httpx |
| `nuclei` | vulnerability scanning (primary) | https://github.com/projectdiscovery/nuclei |
| `amass` | subdomain enumeration (fallback) | https://github.com/owasp-amass/amass |
| `nikto` | web-server scan (fallback) | https://github.com/sullo/nikto |

The pipeline **degrades gracefully**: missing tools are logged and skipped rather
than crashing the run.

## Usage

```bash
# Full run
python -m pentest_framework.main example.com

# With a scope file and AI enrichment
python -m pentest_framework.main example.com --scope scope.txt --enrich

# Scan a single IP, custom output dir, no interactive prompt
python -m pentest_framework.main 203.0.113.10 -o /output --no-confirm
```

Output (under `--output`, default `output/`):

- `pentest_report.pdf` — the report
- `findings.json` — normalized, deduplicated findings
- `recon.json` — recon results
- `pentest.log` — full run log

On success it prints:

```
Pentest completed. Report saved at output/pentest_report.pdf
```

### Scope file format

```
# one entry per line; '#' comments allowed
example.com
api.example.com
*.staging.example.com
203.0.113.10
```

Any discovered host not matching an in-scope entry is dropped before probing.

## Run modules independently

Each module is runnable on its own:

```bash
python -m pentest_framework.recon.recon example.com
python -m pentest_framework.scanner.scanner --url https://example.com
python -m pentest_framework.api_checks.api_checks https://example.com
python -m pentest_framework.parser.aggregator findings.json
python -m pentest_framework.enrichment.enrich findings.json
python -m pentest_framework.report.report findings.json --target example.com
```

## AI-assisted enrichment

`enhance_finding(finding)` clarifies the description, adds realistic impact, and
suggests remediation. It is **strictly editorial** — it never invents
vulnerabilities and never changes severity/title/target/evidence.

- With `anthropic` installed and `ANTHROPIC_API_KEY` set, it uses Claude
  (`claude-opus-4-8` by default; override with `ANTHROPIC_MODEL`).
- Otherwise it falls back to a safe offline heuristic that only fills obviously
  missing fields.

## Scan a local app

`recon` resolves hostnames, so for an app on a non-standard port, target the URLs
directly instead:

```bash
python -m pentest_framework.scan_local            # defaults: localhost:8080 + :8000
python -m pentest_framework.scan_local --targets http://localhost:3000/
```

## Finding schema

```json
{
  "title": "",
  "severity": "Critical | High | Medium | Low | Info",
  "description": "",
  "target": "",
  "evidence": "",
  "remediation": ""
}
```

## Tests

```bash
pip install -e ".[dev]" && pytest
```

## License

MIT — see [LICENSE](LICENSE). For authorized security testing only; please read
[CONTRIBUTING.md](CONTRIBUTING.md) before contributing.
