尚未收集儲存庫資訊。
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
製作者的介紹僅有上面的一句話。 更多詳情請閱讀儲存庫 README。 儲存庫 README ↗
正在載入完整 README。
檢視完整 README ↗Cosentinel runs on your laptop, connects to the machines you own over SSH, and orchestrates established security scanners in one place — then normalizes, correlates and keeps a history of everything they find.
It is deliberately not two things:
Cosentinel's value is orchestration, normalization, correlation and history across tools that otherwise live in separate silos.
It wraps each scanner in a small adapter and gives you one consistent workflow across all of them:
| Scanner | What it checks | Runs from | Tier |
|---|---|---|---|
| Lynis | Host hardening audit | inside the machine (SSH) | safe |
| Nmap | Network surface / open ports | outside | safe |
| Nuclei | Known-vulnerability detection | outside | safe |
| testssl.sh | TLS / certificate posture | outside | safe |
| Nikto | Web-server misconfigurations & dangerous files | outside | safe |
| OpenVAS / Greenbone | Deep vulnerability scan via a running GVM | outside | safe |
| ffuf | Content & endpoint discovery (hidden paths, backups, .git/.env) | outside | active |
| sqlmap | SQL-injection detection, lab-only proof of impact | outside | active |
| OWASP ZAP | Full active web-application scan (SQLi, XSS, traversal, …) | outside | active |
Everything becomes a single normalized finding, stored in a local SQLite file so you can diff "today vs last week" and render a static, read-only HTML report.
cosentinel risks groups findings by asset (mostly the port) and scores them, so a weak
SSH config (Lynis) on a port that is also open (Nmap) and carries a CVE (Nuclei)
surfaces as one high-priority risk — reachable and weak and corroborated — instead
of three unrelated lines in three different tools.
cosentinel scan <target> --profile full
│
▼
config.load() ──► Scope (your allowlist)
│
▼
Engine.run():
scope.authorize(target, intensity, confirmed) # gate + audit
│
├─ adapter runs "inside" ──► SSHRunner / LocalRunner (on the target)
└─ adapter runs "outside" ──► LocalRunner, pointed at target.host
│
▼
adapter.plan() → runner.run() → adapter.parse() → [Finding, …]
│
▼
Store (SQLite): scans + findings + history
│
▼
cosentinel risks / report / diff / history
diff between two scans is meaningful.transport/ssh.py ever touches a machine; it shells out to the
system ssh binary with BatchMode=yes — Cosentinel never handles your private keys.See ARCHITECTURE.md for the full design.
Three ideas are built into the core, not bolted on:
passive → safe → aggressive → exploit. The default profiles are
detection only (safe). Active profiles (pentest, exploit) send real payloads
the way a human tester does, and are gated: aggressive needs an explicit --confirm;
exploit additionally requires the target to be marked lab: true. A profile's intensity
is a ceiling — each tool runs only as hard as it is allowed, and the heavy tools
(sqlmap / ZAP / ffuf) never fire in a safe scan at all..cosentinel/audit.jsonl, and --dry-run prints the exact commands before anything runs.Use it only on systems you own or are explicitly authorized to test. The allowlist is the control, and every action is written to the audit log.
python3 -m venv .venv && . .venv/bin/activate
pip install -e .
Then install the scanners you want. Adapters skip gracefully when a tool is missing —
cosentinel adapters shows what's available on this host.
brew install nmap nuclei # macOS (plus testssl, nikto, ffuf, sqlmap as needed)
# Lynis runs on the *target*; install it there (e.g. apt install lynis).
cosentinel init # create cosentinel.yaml (your allowlist) + .cosentinel/
cosentinel targets # show the allowlist
cosentinel adapters # which scanners are available on this host
cosentinel scan localhost --dry-run # see the EXACT commands, run nothing
cosentinel scan localhost # run the 'full' profile (SAFE, detection only)
cosentinel risks localhost # correlated, prioritized risks (not raw findings)
cosentinel report localhost -o report.html # static HTML report
cosentinel diff localhost # what changed since the previous scan
cosentinel history # past scans
Your cosentinel.yaml is the allowlist. A target can be the local box, a remote host
over SSH, or a website — each reached differently:
settings:
db: .cosentinel/cosentinel.db
audit_log: .cosentinel/audit.jsonl
targets:
# The machine you're on (no SSH). Good for a first run.
- id: localhost
host: 127.0.0.1
ssh: false
sudo: true # Lynis wants root to read system config
lab: true # a box you own outright
# A remote host over SSH. `host` matches ~/.ssh/config, or is an IP/hostname;
# your keys and agent are reused automatically.
- id: homeserver
host: homeserver
ssh: true # enables Lynis from inside
sudo: true
url: http://homeserver # optional, for web/vuln scanners
tags: [prod]
# A website / web address you own. ssh:false + a non-local host => "web-only":
# only the outside-in scanners run (nmap, nuclei, testssl, nikto); Lynis is skipped.
- id: mysite
host: example.com
ssh: false
url: https://example.com
tags: [web]
| Profile | Intensity | Scanners | What it does |
|---|---|---|---|
audit | safe | lynis | Hardening audit from inside |
network | safe | nmap | Network surface from outside |
vuln | safe | nuclei | Known-vulnerability detection |
tls | safe | testssl | TLS / certificate posture |
web | safe | nikto | Web-server misconfigurations |
full | safe | lynis + nmap + nuclei + testssl + nikto | Everything available (default) |
openvas | safe | openvas | Deep GVM scan (needs a running Greenbone) |
pentest | aggressive | full + ffuf + sqlmap + zap | Active testing like a human attacker. Needs --confirm. |
exploit | exploit | nmap + nuclei + testssl + nikto + sqlmap + zap | Prove impact, not just presence. Needs --confirm + lab: true. |
cosentinel scan e0 -p pentest --confirm # active test of a host you own
cosentinel scan e0 -p pentest --confirm --dry-run # see exactly what WOULD run, first
| Command | Purpose |
|---|---|
cosentinel init [--dir DIR] | Create a starter cosentinel.yaml + .cosentinel/ |
cosentinel targets | List the allowlist (id, host, access, sudo, lab, tags) |
cosentinel adapters | List scanners and whether each tool is present on this host |
cosentinel profiles | List the scan profiles |
cosentinel scan <target…> [--all] [-p PROFILE] [--confirm] [--dry-run] | Run a scan |
cosentinel risks <target> | Correlated, prioritized, scored risks |
cosentinel report <target> [-o FILE] | Write a static HTML report |
cosentinel diff <target> | What changed since the previous scan |
cosentinel history [target] | Past scans |
Global: -c/--config PATH to point at a specific config, --version.
ffuf wordlist. Point COSENTINEL_WORDLIST at a wordlist, or install one (SecLists /
dirb); a small starter list ships in wordlists/common-web.txt.
sqlmap against anti-CSRF login forms (Laravel, Rails, …). Forms with a per-request
hidden token reject any POST without a fresh one, so by default sqlmap re-reads the token
before each request. The token field name defaults to Laravel's _token; override it (or
set it empty to disable) and, if the token lives on a different page, point sqlmap at it:
export COSENTINEL_SQLMAP_CSRF_TOKEN=authenticity_token # e.g. Rails; "" disables
export COSENTINEL_SQLMAP_CSRF_URL=http://host/login # optional: where to fetch it
For a form app, point the target's url: at the form page (e.g. …/login) so the fields
actually get tested.
Time-based false positives under rate-limiting. A time-based injection is inferred
from response delay, so a target that rate-limits (HTTP 429 / WAF throttling) makes sqlmap
see phantom SLEEP hits. Cosentinel detects the throttling and treats a parameter that is
injectable only via time-based payloads as a MEDIUM "suspected" finding (never a
confirmed HIGH), then automatically re-tests just that parameter with a delay to confirm or
clear it. Tune it: COSENTINEL_SQLMAP_DELAY=N (seconds between requests, applied from the
first pass too) and COSENTINEL_SQLMAP_AUTOVERIFY=0 (skip the confirming re-run).
Running ZAP natively (for Tailscale / host-only targets). ZAP's packaged
zap-full-scan.py ships only in its Docker image, and a container can't reach a Tailscale
IP. To scan such a target, install ZAP natively and point the adapter at the bundled shim,
which drives zap.sh in quick-scan mode:
# one-time: install a JDK 17+ and ZAP (fetch ZAP's Cross-Platform package from the
# official release, since the Homebrew cask is currently disabled), then:
export COSENTINEL_ZAP="$PWD/scripts/zap-native.sh" # or symlink it onto your PATH
cosentinel scan e0 -p pentest --confirm
The shim finds openjdk and zap.sh automatically (override with JAVA_HOME / ZAP_SH).
COSENTINEL_ZAP also accepts a full command (e.g. a docker … zap-full-scan.py
invocation), exactly like GVM_CLI does for OpenVAS.
cosentinel report <target> writes a single self-contained HTML file: severity counts,
the prioritized risks, and every finding with its remediation. It executes nothing and
talks to nothing — it's just a read-only view of a scan you can open in a browser or hand
to someone else.
Detection (Lynis, Nmap, Nuclei, testssl.sh, Nikto, OpenVAS) plus gated active
testing (nuclei DAST, ffuf, sqlmap, OWASP ZAP) behind the pentest / exploit tiers.
Exploitation is limited to proving impact (e.g. sqlmap reaching the DBMS) and only on
lab targets; it never dumps table data. Roadmap and internals are in
ARCHITECTURE.md.
pip install -e ".[dev]" && pytest -q
MIT.