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.
@@ -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.
@@ -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,3 @@
1
+ """reconflow package."""
2
+
3
+ __version__ = "0.2.2"
@@ -0,0 +1,6 @@
1
+ """reconflow - Command line execution module."""
2
+
3
+ from .cli import main
4
+
5
+ if __name__ == "__main__":
6
+ main()
@@ -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()