reconflow 0.2.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- reconflow-0.2.2/LICENSE +21 -0
- reconflow-0.2.2/PKG-INFO +184 -0
- reconflow-0.2.2/README.md +160 -0
- reconflow-0.2.2/pyproject.toml +48 -0
- reconflow-0.2.2/reconflow/__init__.py +3 -0
- reconflow-0.2.2/reconflow/__main__.py +6 -0
- reconflow-0.2.2/reconflow/cli.py +118 -0
- reconflow-0.2.2/reconflow/diff.py +206 -0
- reconflow-0.2.2/reconflow/history.py +46 -0
- reconflow-0.2.2/reconflow/scan.py +448 -0
- reconflow-0.2.2/reconflow.egg-info/PKG-INFO +184 -0
- reconflow-0.2.2/reconflow.egg-info/SOURCES.txt +18 -0
- reconflow-0.2.2/reconflow.egg-info/dependency_links.txt +1 -0
- reconflow-0.2.2/reconflow.egg-info/entry_points.txt +2 -0
- reconflow-0.2.2/reconflow.egg-info/top_level.txt +1 -0
- reconflow-0.2.2/setup.cfg +4 -0
- reconflow-0.2.2/tests/test_cli.py +214 -0
- reconflow-0.2.2/tests/test_diff.py +288 -0
- reconflow-0.2.2/tests/test_diff_noise.py +40 -0
- reconflow-0.2.2/tests/test_scan.py +39 -0
reconflow-0.2.2/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Nithishvelan M
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
reconflow-0.2.2/PKG-INFO
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: reconflow
|
|
3
|
+
Version: 0.2.2
|
|
4
|
+
Summary: Recon pipeline for bug bounty hunters with differential change tracking
|
|
5
|
+
Author: Nithishvelan M
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/ErenYeager1836/reconflow
|
|
8
|
+
Project-URL: Repository, https://github.com/ErenYeager1836/reconflow
|
|
9
|
+
Project-URL: Issues, https://github.com/ErenYeager1836/reconflow/issues
|
|
10
|
+
Keywords: bugbounty,recon,reconnaissance,subdomain,subfinder,httpx,differential,security,infosec
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Operating System :: OS Independent
|
|
18
|
+
Classifier: Topic :: Security
|
|
19
|
+
Classifier: Intended Audience :: Information Technology
|
|
20
|
+
Requires-Python: >=3.8
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
License-File: LICENSE
|
|
23
|
+
Dynamic: license-file
|
|
24
|
+
|
|
25
|
+
# reconflow
|
|
26
|
+
|
|
27
|
+
Recon for bug bounty hunters that tells you **what changed** since your last scan.
|
|
28
|
+
|
|
29
|
+
`reconflow` chains [subfinder](https://github.com/projectdiscovery/subfinder) and [httpx](https://github.com/projectdiscovery/httpx) into one command, filters out wildcard DNS noise, saves a snapshot of every run, and lets you `diff` any two runs to see new subdomains, newly live hosts, and changed responses.
|
|
30
|
+
|
|
31
|
+
> **Use responsibly.** Only scan domains you own or that are explicitly in scope for a bug bounty / pentest program you are authorized to test.
|
|
32
|
+
|
|
33
|
+
## Features
|
|
34
|
+
|
|
35
|
+
- **`scan`**: finds subdomains, drops wildcard DNS false positives (including rotating IP pools), probes live hosts for status code, title and technologies, and writes a Markdown report
|
|
36
|
+
- **`diff`**: compares your two most recent scans of a domain and highlights what's new
|
|
37
|
+
- **Scan history**: every scan saves a structured snapshot, so nothing is overwritten
|
|
38
|
+
- **Cron-friendly**: `diff` exits `1` when something changed and `0` when nothing did
|
|
39
|
+
- No Python dependencies beyond the standard library
|
|
40
|
+
|
|
41
|
+
## Requirements
|
|
42
|
+
|
|
43
|
+
- Python 3.8+
|
|
44
|
+
- [`subfinder`](https://github.com/projectdiscovery/subfinder/releases) and [`httpx`](https://github.com/projectdiscovery/httpx/releases) (ProjectDiscovery's Go versions) on your `PATH`
|
|
45
|
+
- [`gowitness`](https://github.com/sensepost/gowitness/releases) (optional, only for `--screenshots`)
|
|
46
|
+
|
|
47
|
+
> **Note:** `httpx` must be ProjectDiscovery's tool, not the Python `httpx` library. On Kali/Debian/Ubuntu it is often packaged as `httpx-toolkit`. reconflow checks for both names and verifies the binary.
|
|
48
|
+
|
|
49
|
+
Check your tools:
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
subfinder -version
|
|
53
|
+
httpx -version
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Install
|
|
57
|
+
|
|
58
|
+
From PyPI:
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
pip install reconflow
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
From source:
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
git clone https://github.com/ErenYeager1836/reconflow.git
|
|
68
|
+
cd reconflow
|
|
69
|
+
pip install -e .
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Usage
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
reconflow scan example.com
|
|
76
|
+
reconflow diff example.com
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
You can also run it as a module: `python -m reconflow scan example.com`
|
|
80
|
+
|
|
81
|
+
### `scan`
|
|
82
|
+
|
|
83
|
+
| Option | Description |
|
|
84
|
+
| --- | --- |
|
|
85
|
+
| `domain` | Target domain (required, must be in scope) |
|
|
86
|
+
| `-o`, `--output` | Output folder (default: `output`) |
|
|
87
|
+
| `--threads` | Number of threads for probing (default: 10) |
|
|
88
|
+
| `--timeout` | Timeout in seconds for probing (default: 5) |
|
|
89
|
+
| `--keep-wildcard` | Warn about wildcard DNS but don't filter wildcard results |
|
|
90
|
+
| `--json` | Also write structured results to `report.json` |
|
|
91
|
+
| `--screenshots` | Capture screenshots of live hosts (requires gowitness) |
|
|
92
|
+
|
|
93
|
+
### `diff`
|
|
94
|
+
|
|
95
|
+
| Option | Description |
|
|
96
|
+
| --- | --- |
|
|
97
|
+
| `domain` | Target domain to compare runs for (required) |
|
|
98
|
+
| `-o`, `--output` | Output folder (default: `output`) |
|
|
99
|
+
| `--json` | Print the comparison as JSON |
|
|
100
|
+
|
|
101
|
+
`diff` needs at least two saved scans of the same domain. Run `scan` twice first.
|
|
102
|
+
|
|
103
|
+
## Track changes with `diff`
|
|
104
|
+
|
|
105
|
+
Most recon tools tell you what exists. reconflow also tells you what changed. New subdomains and newly live hosts are often the least-tested parts of a target.
|
|
106
|
+
|
|
107
|
+
Example output (illustrative):
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
[*] Recon diff: 2026-10-18_185218 -> 2026-10-18_190412
|
|
111
|
+
============================================================
|
|
112
|
+
[+] NEW SUBDOMAINS (2):
|
|
113
|
+
+ beta.example.com
|
|
114
|
+
+ staging-api.example.com
|
|
115
|
+
[+] NEWLY LIVE HOSTS (1):
|
|
116
|
+
+ https://beta.example.com [200] [Beta Portal] [Nginx, React]
|
|
117
|
+
[*] CHANGED HOSTS (1):
|
|
118
|
+
~ https://admin.example.com
|
|
119
|
+
status: 403 -> 200
|
|
120
|
+
title: 'Forbidden' -> 'Admin Login'
|
|
121
|
+
tech: ['Apache'] -> ['Apache', 'PHP']
|
|
122
|
+
[-] Removed subdomains (1) [informational]:
|
|
123
|
+
- old.example.com
|
|
124
|
+
============================================================
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Removed subdomains are informational only, because subfinder's sources can return slightly different results between runs.
|
|
128
|
+
|
|
129
|
+
### Exit codes
|
|
130
|
+
|
|
131
|
+
| Code | Meaning |
|
|
132
|
+
| --- | --- |
|
|
133
|
+
| `0` | No changes found (or not enough history to compare) |
|
|
134
|
+
| `1` | Changes were detected |
|
|
135
|
+
|
|
136
|
+
### Run it on a schedule
|
|
137
|
+
|
|
138
|
+
```
|
|
139
|
+
# Every 6 hours: rescan and log changes
|
|
140
|
+
0 */6 * * * reconflow scan example.com && reconflow diff example.com >> ~/recon-changes.log
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Output
|
|
144
|
+
|
|
145
|
+
Files are saved under `output/<domain>/`:
|
|
146
|
+
|
|
147
|
+
```
|
|
148
|
+
subdomains.txt all discovered subdomains
|
|
149
|
+
live.txt live hosts with status code, title, tech
|
|
150
|
+
report.md summary report
|
|
151
|
+
report.json structured report (with --json)
|
|
152
|
+
screenshots/ screenshots of live hosts (with --screenshots)
|
|
153
|
+
runs/<run_id>/ snapshot of each scan, used by diff
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## Known limitations
|
|
157
|
+
|
|
158
|
+
- **Wildcard DNS domains** return many fake "live" hosts that all point to the same server. reconflow detects them and filters those hosts (use `--keep-wildcard` to disable).
|
|
159
|
+
- Discovery depends on subfinder's sources, so results can vary between runs.
|
|
160
|
+
|
|
161
|
+
## Roadmap
|
|
162
|
+
|
|
163
|
+
- [x] Subdomain discovery and live host probing
|
|
164
|
+
- [x] Wildcard DNS detection (including rotating IP pools)
|
|
165
|
+
- [x] `--threads` and `--timeout` options
|
|
166
|
+
- [x] JSON report output
|
|
167
|
+
- [x] Screenshots of live hosts
|
|
168
|
+
- [x] Scan history and `reconflow diff`
|
|
169
|
+
- [ ] `reconflow scope`: check targets against program scope
|
|
170
|
+
- [ ] `reconflow report`: regenerate reports from saved scans
|
|
171
|
+
- [ ] `--notify`: Discord/Slack webhook alerts for diff results
|
|
172
|
+
- [ ] Save results as they come in
|
|
173
|
+
|
|
174
|
+
## Contributing
|
|
175
|
+
|
|
176
|
+
Contributions are welcome. Look for issues labelled `good first issue`. Run the tests with:
|
|
177
|
+
|
|
178
|
+
```
|
|
179
|
+
python -m unittest discover tests -v
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## License
|
|
183
|
+
|
|
184
|
+
MIT
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# reconflow
|
|
2
|
+
|
|
3
|
+
Recon for bug bounty hunters that tells you **what changed** since your last scan.
|
|
4
|
+
|
|
5
|
+
`reconflow` chains [subfinder](https://github.com/projectdiscovery/subfinder) and [httpx](https://github.com/projectdiscovery/httpx) into one command, filters out wildcard DNS noise, saves a snapshot of every run, and lets you `diff` any two runs to see new subdomains, newly live hosts, and changed responses.
|
|
6
|
+
|
|
7
|
+
> **Use responsibly.** Only scan domains you own or that are explicitly in scope for a bug bounty / pentest program you are authorized to test.
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- **`scan`**: finds subdomains, drops wildcard DNS false positives (including rotating IP pools), probes live hosts for status code, title and technologies, and writes a Markdown report
|
|
12
|
+
- **`diff`**: compares your two most recent scans of a domain and highlights what's new
|
|
13
|
+
- **Scan history**: every scan saves a structured snapshot, so nothing is overwritten
|
|
14
|
+
- **Cron-friendly**: `diff` exits `1` when something changed and `0` when nothing did
|
|
15
|
+
- No Python dependencies beyond the standard library
|
|
16
|
+
|
|
17
|
+
## Requirements
|
|
18
|
+
|
|
19
|
+
- Python 3.8+
|
|
20
|
+
- [`subfinder`](https://github.com/projectdiscovery/subfinder/releases) and [`httpx`](https://github.com/projectdiscovery/httpx/releases) (ProjectDiscovery's Go versions) on your `PATH`
|
|
21
|
+
- [`gowitness`](https://github.com/sensepost/gowitness/releases) (optional, only for `--screenshots`)
|
|
22
|
+
|
|
23
|
+
> **Note:** `httpx` must be ProjectDiscovery's tool, not the Python `httpx` library. On Kali/Debian/Ubuntu it is often packaged as `httpx-toolkit`. reconflow checks for both names and verifies the binary.
|
|
24
|
+
|
|
25
|
+
Check your tools:
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
subfinder -version
|
|
29
|
+
httpx -version
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Install
|
|
33
|
+
|
|
34
|
+
From PyPI:
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
pip install reconflow
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
From source:
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
git clone https://github.com/ErenYeager1836/reconflow.git
|
|
44
|
+
cd reconflow
|
|
45
|
+
pip install -e .
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Usage
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
reconflow scan example.com
|
|
52
|
+
reconflow diff example.com
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
You can also run it as a module: `python -m reconflow scan example.com`
|
|
56
|
+
|
|
57
|
+
### `scan`
|
|
58
|
+
|
|
59
|
+
| Option | Description |
|
|
60
|
+
| --- | --- |
|
|
61
|
+
| `domain` | Target domain (required, must be in scope) |
|
|
62
|
+
| `-o`, `--output` | Output folder (default: `output`) |
|
|
63
|
+
| `--threads` | Number of threads for probing (default: 10) |
|
|
64
|
+
| `--timeout` | Timeout in seconds for probing (default: 5) |
|
|
65
|
+
| `--keep-wildcard` | Warn about wildcard DNS but don't filter wildcard results |
|
|
66
|
+
| `--json` | Also write structured results to `report.json` |
|
|
67
|
+
| `--screenshots` | Capture screenshots of live hosts (requires gowitness) |
|
|
68
|
+
|
|
69
|
+
### `diff`
|
|
70
|
+
|
|
71
|
+
| Option | Description |
|
|
72
|
+
| --- | --- |
|
|
73
|
+
| `domain` | Target domain to compare runs for (required) |
|
|
74
|
+
| `-o`, `--output` | Output folder (default: `output`) |
|
|
75
|
+
| `--json` | Print the comparison as JSON |
|
|
76
|
+
|
|
77
|
+
`diff` needs at least two saved scans of the same domain. Run `scan` twice first.
|
|
78
|
+
|
|
79
|
+
## Track changes with `diff`
|
|
80
|
+
|
|
81
|
+
Most recon tools tell you what exists. reconflow also tells you what changed. New subdomains and newly live hosts are often the least-tested parts of a target.
|
|
82
|
+
|
|
83
|
+
Example output (illustrative):
|
|
84
|
+
|
|
85
|
+
```
|
|
86
|
+
[*] Recon diff: 2026-10-18_185218 -> 2026-10-18_190412
|
|
87
|
+
============================================================
|
|
88
|
+
[+] NEW SUBDOMAINS (2):
|
|
89
|
+
+ beta.example.com
|
|
90
|
+
+ staging-api.example.com
|
|
91
|
+
[+] NEWLY LIVE HOSTS (1):
|
|
92
|
+
+ https://beta.example.com [200] [Beta Portal] [Nginx, React]
|
|
93
|
+
[*] CHANGED HOSTS (1):
|
|
94
|
+
~ https://admin.example.com
|
|
95
|
+
status: 403 -> 200
|
|
96
|
+
title: 'Forbidden' -> 'Admin Login'
|
|
97
|
+
tech: ['Apache'] -> ['Apache', 'PHP']
|
|
98
|
+
[-] Removed subdomains (1) [informational]:
|
|
99
|
+
- old.example.com
|
|
100
|
+
============================================================
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Removed subdomains are informational only, because subfinder's sources can return slightly different results between runs.
|
|
104
|
+
|
|
105
|
+
### Exit codes
|
|
106
|
+
|
|
107
|
+
| Code | Meaning |
|
|
108
|
+
| --- | --- |
|
|
109
|
+
| `0` | No changes found (or not enough history to compare) |
|
|
110
|
+
| `1` | Changes were detected |
|
|
111
|
+
|
|
112
|
+
### Run it on a schedule
|
|
113
|
+
|
|
114
|
+
```
|
|
115
|
+
# Every 6 hours: rescan and log changes
|
|
116
|
+
0 */6 * * * reconflow scan example.com && reconflow diff example.com >> ~/recon-changes.log
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Output
|
|
120
|
+
|
|
121
|
+
Files are saved under `output/<domain>/`:
|
|
122
|
+
|
|
123
|
+
```
|
|
124
|
+
subdomains.txt all discovered subdomains
|
|
125
|
+
live.txt live hosts with status code, title, tech
|
|
126
|
+
report.md summary report
|
|
127
|
+
report.json structured report (with --json)
|
|
128
|
+
screenshots/ screenshots of live hosts (with --screenshots)
|
|
129
|
+
runs/<run_id>/ snapshot of each scan, used by diff
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## Known limitations
|
|
133
|
+
|
|
134
|
+
- **Wildcard DNS domains** return many fake "live" hosts that all point to the same server. reconflow detects them and filters those hosts (use `--keep-wildcard` to disable).
|
|
135
|
+
- Discovery depends on subfinder's sources, so results can vary between runs.
|
|
136
|
+
|
|
137
|
+
## Roadmap
|
|
138
|
+
|
|
139
|
+
- [x] Subdomain discovery and live host probing
|
|
140
|
+
- [x] Wildcard DNS detection (including rotating IP pools)
|
|
141
|
+
- [x] `--threads` and `--timeout` options
|
|
142
|
+
- [x] JSON report output
|
|
143
|
+
- [x] Screenshots of live hosts
|
|
144
|
+
- [x] Scan history and `reconflow diff`
|
|
145
|
+
- [ ] `reconflow scope`: check targets against program scope
|
|
146
|
+
- [ ] `reconflow report`: regenerate reports from saved scans
|
|
147
|
+
- [ ] `--notify`: Discord/Slack webhook alerts for diff results
|
|
148
|
+
- [ ] Save results as they come in
|
|
149
|
+
|
|
150
|
+
## Contributing
|
|
151
|
+
|
|
152
|
+
Contributions are welcome. Look for issues labelled `good first issue`. Run the tests with:
|
|
153
|
+
|
|
154
|
+
```
|
|
155
|
+
python -m unittest discover tests -v
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## License
|
|
159
|
+
|
|
160
|
+
MIT
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "reconflow"
|
|
3
|
+
version = "0.2.2"
|
|
4
|
+
description = "Recon pipeline for bug bounty hunters with differential change tracking"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.8"
|
|
7
|
+
license = "MIT"
|
|
8
|
+
license-files= ["LICENSE"]
|
|
9
|
+
authors = [
|
|
10
|
+
{ name = "Nithishvelan M" }
|
|
11
|
+
]
|
|
12
|
+
keywords = [
|
|
13
|
+
"bugbounty",
|
|
14
|
+
"recon",
|
|
15
|
+
"reconnaissance",
|
|
16
|
+
"subdomain",
|
|
17
|
+
"subfinder",
|
|
18
|
+
"httpx",
|
|
19
|
+
"differential",
|
|
20
|
+
"security",
|
|
21
|
+
"infosec",
|
|
22
|
+
]
|
|
23
|
+
classifiers = [
|
|
24
|
+
"Programming Language :: Python :: 3",
|
|
25
|
+
"Programming Language :: Python :: 3.8",
|
|
26
|
+
"Programming Language :: Python :: 3.9",
|
|
27
|
+
"Programming Language :: Python :: 3.10",
|
|
28
|
+
"Programming Language :: Python :: 3.11",
|
|
29
|
+
"Programming Language :: Python :: 3.12",
|
|
30
|
+
"Operating System :: OS Independent",
|
|
31
|
+
"Topic :: Security",
|
|
32
|
+
"Intended Audience :: Information Technology",
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
[project.urls]
|
|
36
|
+
Homepage = "https://github.com/ErenYeager1836/reconflow"
|
|
37
|
+
Repository = "https://github.com/ErenYeager1836/reconflow"
|
|
38
|
+
Issues = "https://github.com/ErenYeager1836/reconflow/issues"
|
|
39
|
+
|
|
40
|
+
[project.scripts]
|
|
41
|
+
reconflow = "reconflow.cli:main"
|
|
42
|
+
|
|
43
|
+
[build-system]
|
|
44
|
+
requires = ["setuptools>=77"]
|
|
45
|
+
build-backend = "setuptools.build_meta"
|
|
46
|
+
|
|
47
|
+
[tool.setuptools]
|
|
48
|
+
packages = ["reconflow"]
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"""reconflow.cli - Command-line interface and subcommand routing."""
|
|
2
|
+
|
|
3
|
+
import argparse
|
|
4
|
+
import sys
|
|
5
|
+
from . import __version__, scan
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def build_parser():
|
|
9
|
+
"""Construct the main argument parser with subcommands."""
|
|
10
|
+
parser = argparse.ArgumentParser(
|
|
11
|
+
prog="reconflow",
|
|
12
|
+
description="Recon pipeline for bug bounty hunters",
|
|
13
|
+
)
|
|
14
|
+
parser.add_argument(
|
|
15
|
+
"-v",
|
|
16
|
+
"--version",
|
|
17
|
+
action="version",
|
|
18
|
+
version=f"%(prog)s {__version__}",
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
subparsers = parser.add_subparsers(
|
|
22
|
+
dest="command",
|
|
23
|
+
title="subcommands",
|
|
24
|
+
description="available operations",
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
# scan subcommand
|
|
28
|
+
p_scan = subparsers.add_parser(
|
|
29
|
+
"scan",
|
|
30
|
+
help="Run recon on a domain",
|
|
31
|
+
description="Discover subdomains, filter wildcard DNS, and probe live web services.",
|
|
32
|
+
)
|
|
33
|
+
p_scan.add_argument(
|
|
34
|
+
"domain",
|
|
35
|
+
help="Target domain (must be in scope!)",
|
|
36
|
+
)
|
|
37
|
+
p_scan.add_argument(
|
|
38
|
+
"-o",
|
|
39
|
+
"--output",
|
|
40
|
+
default="output",
|
|
41
|
+
help="Output folder (default: output)",
|
|
42
|
+
)
|
|
43
|
+
p_scan.add_argument(
|
|
44
|
+
"--threads",
|
|
45
|
+
type=int,
|
|
46
|
+
default=10,
|
|
47
|
+
help="Number of threads for probing (default: 10)",
|
|
48
|
+
)
|
|
49
|
+
p_scan.add_argument(
|
|
50
|
+
"--timeout",
|
|
51
|
+
type=int,
|
|
52
|
+
default=5,
|
|
53
|
+
help="Timeout in seconds for probing (default: 5)",
|
|
54
|
+
)
|
|
55
|
+
p_scan.add_argument(
|
|
56
|
+
"--keep-wildcard",
|
|
57
|
+
action="store_true",
|
|
58
|
+
help="Warn about wildcard DNS but don't filter wildcard results",
|
|
59
|
+
)
|
|
60
|
+
p_scan.add_argument(
|
|
61
|
+
"--json",
|
|
62
|
+
action="store_true",
|
|
63
|
+
dest="json_report",
|
|
64
|
+
help="Also write structured results to report.json",
|
|
65
|
+
)
|
|
66
|
+
p_scan.add_argument(
|
|
67
|
+
"--screenshots",
|
|
68
|
+
action="store_true",
|
|
69
|
+
help="Capture screenshots of live hosts using gowitness",
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
# diff subcommand
|
|
73
|
+
p_diff = subparsers.add_parser(
|
|
74
|
+
"diff",
|
|
75
|
+
help="Compare the latest two scans for a domain",
|
|
76
|
+
description=(
|
|
77
|
+
"Compare the latest two scan snapshots to detect "
|
|
78
|
+
"newly discovered subdomains and host changes."
|
|
79
|
+
),
|
|
80
|
+
)
|
|
81
|
+
p_diff.add_argument(
|
|
82
|
+
"domain",
|
|
83
|
+
help="Target domain to compare runs for",
|
|
84
|
+
)
|
|
85
|
+
p_diff.add_argument(
|
|
86
|
+
"-o",
|
|
87
|
+
"--output",
|
|
88
|
+
default="output",
|
|
89
|
+
help="Output folder (default: output)",
|
|
90
|
+
)
|
|
91
|
+
p_diff.add_argument(
|
|
92
|
+
"--json",
|
|
93
|
+
action="store_true",
|
|
94
|
+
dest="json_report",
|
|
95
|
+
help="Output diff comparison as JSON",
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
return parser
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def main(args=None):
|
|
102
|
+
"""Main entrypoint for CLI command dispatch."""
|
|
103
|
+
parser = build_parser()
|
|
104
|
+
parsed_args = parser.parse_args(args)
|
|
105
|
+
|
|
106
|
+
if parsed_args.command == "scan":
|
|
107
|
+
scan.run(parsed_args)
|
|
108
|
+
elif parsed_args.command == "diff":
|
|
109
|
+
from . import diff
|
|
110
|
+
|
|
111
|
+
diff.run(parsed_args)
|
|
112
|
+
else:
|
|
113
|
+
parser.print_help()
|
|
114
|
+
sys.exit(0)
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
if __name__ == "__main__":
|
|
118
|
+
main()
|