Metadata-Version: 2.4
Name: exploitsynth
Version: 0.3.0
Summary: ExploitSynth scanner CLI — AI port-identification from your terminal
Project-URL: Homepage, https://scan.exploitsynth.com
Project-URL: Documentation, https://scan.exploitsynth.com/docs
Project-URL: Issues, https://github.com/exploitsynth/cli/issues
Author: ExploitSynth
License: MIT
Requires-Python: >=3.9
Requires-Dist: defusedxml>=0.7
Requires-Dist: httpx>=0.27
Requires-Dist: rich>=13.7
Requires-Dist: typer>=0.12
Description-Content-Type: text/markdown

# ExploitSynth CLI

AI port identification from your terminal — for the open ports your scanner
(nmap, Nessus) couldn't fingerprint. The CLI talks to the same engine as
[scan.exploitsynth.com](https://scan.exploitsynth.com); your scans, projects,
and credits are shared.

## Install

```bash
pipx install exploitsynth        # recommended — isolated, on your PATH
# or
pip install exploitsynth
```

Optional tab-completion for your shell:

```bash
exploitsynth --install-completion        # bash | zsh | fish | powershell
```

## Authenticate

Grab an API key from **Settings → API keys** in the web app, then:

```bash
exploitsynth login               # prompts for the key, verifies, stores it
```

The key lives in `~/.config/exploitsynth/config.json` (chmod 600). You can also
skip the file and export it per-shell:

```bash
export EXPLOITSYNTH_API_KEY=sk_...
```

## Scan

```bash
# Known-open ports — identify them directly
exploitsynth scan 45.33.32.156 --ports 22,80,9929

# Discovery — find open ports first, then identify
exploitsynth scan 10.0.0.0/28 --scope top1000

# Import — feed the ports your scanner left unidentified
exploitsynth scan --nessus engagement.nessus --project acme
exploitsynth scan --nmap recon.xml --project acme
```

### Chain it after your scanner

`exploitsynth` reads targets from **stdin** (`-`) or a file (`-iL`), so it drops
straight into a recon pipeline — point a fast scanner at the network, then let
ExploitSynth identify what it couldn't:

```bash
# pipe targets in
rustscan -a 10.0.0.5 --ports-only | exploitsynth scan - --ports 22,80,9929

# or a host list
exploitsynth scan -iL hosts.txt --scope top100
```

Live per-port progress streams into your terminal, with the same per-port
timeout countdown you see in the web app. Each scan costs **1 credit per port**;
the cost is previewed (and confirmed in an interactive shell) before it runs.

### Scan a private network (`--via local`)

Targets on an internal network (`10.x`, `192.168.x`) or behind a firewall that
only allows *your* source IP aren't reachable from the cloud. `--via local` solves
this: discovery runs on **your** machine, and a reverse tunnel routes the engine's
probes back out through **your** machine — so the scan reaches anything *you* can
reach. Typical HTB / internal-pentest flow:

```bash
# 1. get on the network (client VPN, on-site LAN, HTB, …)
sudo openvpn engagement.ovpn        # you can now reach 10.129.45.12

# 2. one command
exploitsynth scan 10.129.45.12 --via local --scope top1000
```

What happens: local `nmap` finds the open ports, the CLI opens an outbound tunnel
(no inbound ports needed), and the cloud identifies each service *through* that
tunnel. The agent, prompts, and LLM stay in the cloud — only network egress is
borrowed from your box.

Requirements & notes:

- You must be on a network that can reach the target (the CLI says so if you're not).
- `nmap` must be installed; `chisel` is fetched automatically if it isn't on PATH.
- The tunnel only lives while the command runs, so `--via local` streams live and
  can't be combined with `--no-follow`. Ctrl-C tears the tunnel down.
- Cost is the number of open ports found (discovery is free — it's your nmap).

### Options

| Flag | Meaning |
|------|---------|
| `--ports 22,80,9929` | Known-open ports to identify directly (skips discovery) |
| `--scope top100\|top1000\|all` | Discovery scope (or a range like `1-1000`) |
| `--via local` | Scan a private/firewalled target through a tunnel out of this machine |
| `-iL FILE` | Read newline/comma-separated targets from a file |
| `-` (as TARGET) | Read targets from stdin |
| `--nessus FILE` / `--nmap FILE` | Import unidentified ports from a scan export |
| `--project NAME` | Engagement to file the scan under (created if missing) |
| `--label TEXT` | Optional scan label |
| `--timeout 300` | Per-port agent budget in seconds (30–600) |
| `--slow` | Run one agent at a time instead of three |
| `--no-follow` | Fire-and-forget; don't stream progress |
| `--yes` | Skip the credit-cost confirmation |
| `--json` | Emit machine-readable JSON on stdout |

## Inspect

```bash
exploitsynth scans                       # recent scans
exploitsynth scans --project acme
exploitsynth show <scan_id>              # full result table
exploitsynth show <scan_id> --reasoning  # include the agent's reasoning
exploitsynth credits                     # your credit balance
exploitsynth cancel <scan_id>            # cancel a queued/running scan
```

### Scripting

Every read command supports `--json` (printed to stdout; progress and notes go to
stderr, so pipes stay clean):

```bash
exploitsynth scans --json | jq '.[] | {id, status}'
exploitsynth show <scan_id> --json | jq '.results[] | {port, service, version}'
```

Exit codes: `0` success, `1` error, `3` insufficient credits.

## Self-hosting

Point the CLI at your own deployment:

```bash
exploitsynth login --url https://scan.example.com
# or
export EXPLOITSYNTH_API_URL=https://scan.example.com
```
