pentool 1.0.0__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.
Files changed (174) hide show
  1. pentool-1.0.0/LICENSE +34 -0
  2. pentool-1.0.0/PKG-INFO +155 -0
  3. pentool-1.0.0/README.md +111 -0
  4. pentool-1.0.0/pentool/__init__.py +4 -0
  5. pentool-1.0.0/pentool/__main__.py +17 -0
  6. pentool-1.0.0/pentool/api/__init__.py +45 -0
  7. pentool-1.0.0/pentool/api/base_api.py +52 -0
  8. pentool-1.0.0/pentool/api/comparer_api.py +23 -0
  9. pentool-1.0.0/pentool/api/decoder_api.py +28 -0
  10. pentool-1.0.0/pentool/api/intruder_api.py +209 -0
  11. pentool-1.0.0/pentool/api/proxy_api.py +319 -0
  12. pentool-1.0.0/pentool/api/repeater_api.py +118 -0
  13. pentool-1.0.0/pentool/api/scanner_api.py +336 -0
  14. pentool-1.0.0/pentool/api/sequencer_api.py +21 -0
  15. pentool-1.0.0/pentool/api/spider_api.py +126 -0
  16. pentool-1.0.0/pentool/api/target_api.py +121 -0
  17. pentool-1.0.0/pentool/cli/__init__.py +1 -0
  18. pentool-1.0.0/pentool/cli/main.py +100 -0
  19. pentool-1.0.0/pentool/cli/project.py +90 -0
  20. pentool-1.0.0/pentool/cli/proxy.py +185 -0
  21. pentool-1.0.0/pentool/cli/scan.py +118 -0
  22. pentool-1.0.0/pentool/core/__init__.py +1 -0
  23. pentool-1.0.0/pentool/core/config.py +184 -0
  24. pentool-1.0.0/pentool/core/crash_reporter.py +75 -0
  25. pentool-1.0.0/pentool/core/database.py +139 -0
  26. pentool-1.0.0/pentool/core/event_bus.py +232 -0
  27. pentool-1.0.0/pentool/core/events.py +164 -0
  28. pentool-1.0.0/pentool/core/features.py +410 -0
  29. pentool-1.0.0/pentool/core/license.py +294 -0
  30. pentool-1.0.0/pentool/core/logging.py +59 -0
  31. pentool-1.0.0/pentool/core/plugin_manager.py +332 -0
  32. pentool-1.0.0/pentool/core/project.py +37 -0
  33. pentool-1.0.0/pentool/core/storage_interface.py +311 -0
  34. pentool-1.0.0/pentool/core/updater.py +96 -0
  35. pentool-1.0.0/pentool/core/utils.py +61 -0
  36. pentool-1.0.0/pentool/modules/__init__.py +1 -0
  37. pentool-1.0.0/pentool/modules/comparer.py +177 -0
  38. pentool-1.0.0/pentool/modules/decoder.py +281 -0
  39. pentool-1.0.0/pentool/modules/intruder.py +432 -0
  40. pentool-1.0.0/pentool/modules/intruder_turbo.py +190 -0
  41. pentool-1.0.0/pentool/modules/match_replace.py +146 -0
  42. pentool-1.0.0/pentool/modules/proxy.py +803 -0
  43. pentool-1.0.0/pentool/modules/repeater.py +237 -0
  44. pentool-1.0.0/pentool/modules/scanner/__init__.py +7 -0
  45. pentool-1.0.0/pentool/modules/scanner/ai_analyzer.py +230 -0
  46. pentool-1.0.0/pentool/modules/scanner/base.py +173 -0
  47. pentool-1.0.0/pentool/modules/scanner/baseline.py +101 -0
  48. pentool-1.0.0/pentool/modules/scanner/checks/__init__.py +47 -0
  49. pentool-1.0.0/pentool/modules/scanner/checks/broken_auth.py +231 -0
  50. pentool-1.0.0/pentool/modules/scanner/checks/cors.py +209 -0
  51. pentool-1.0.0/pentool/modules/scanner/checks/dom_xss.py +114 -0
  52. pentool-1.0.0/pentool/modules/scanner/checks/graphql.py +110 -0
  53. pentool-1.0.0/pentool/modules/scanner/checks/header_injection.py +262 -0
  54. pentool-1.0.0/pentool/modules/scanner/checks/headers.py +75 -0
  55. pentool-1.0.0/pentool/modules/scanner/checks/helpers.py +358 -0
  56. pentool-1.0.0/pentool/modules/scanner/checks/info_leak.py +68 -0
  57. pentool-1.0.0/pentool/modules/scanner/checks/jwt_none.py +238 -0
  58. pentool-1.0.0/pentool/modules/scanner/checks/lfi.py +186 -0
  59. pentool-1.0.0/pentool/modules/scanner/checks/nosql_injection.py +92 -0
  60. pentool-1.0.0/pentool/modules/scanner/checks/oauth.py +123 -0
  61. pentool-1.0.0/pentool/modules/scanner/checks/open_redirect.py +168 -0
  62. pentool-1.0.0/pentool/modules/scanner/checks/path_traversal.py +229 -0
  63. pentool-1.0.0/pentool/modules/scanner/checks/prototype_pollution.py +88 -0
  64. pentool-1.0.0/pentool/modules/scanner/checks/rce.py +338 -0
  65. pentool-1.0.0/pentool/modules/scanner/checks/sensitive_data.py +74 -0
  66. pentool-1.0.0/pentool/modules/scanner/checks/sqli.py +546 -0
  67. pentool-1.0.0/pentool/modules/scanner/checks/ssrf.py +273 -0
  68. pentool-1.0.0/pentool/modules/scanner/checks/ssti.py +353 -0
  69. pentool-1.0.0/pentool/modules/scanner/checks/xss.py +622 -0
  70. pentool-1.0.0/pentool/modules/scanner/checks/xxe.py +240 -0
  71. pentool-1.0.0/pentool/modules/scanner/engine.py +407 -0
  72. pentool-1.0.0/pentool/modules/scanner/fingerprint.py +169 -0
  73. pentool-1.0.0/pentool/modules/scanner/helpers.py +94 -0
  74. pentool-1.0.0/pentool/modules/scanner/mutator.py +378 -0
  75. pentool-1.0.0/pentool/modules/scanner/oob.py +104 -0
  76. pentool-1.0.0/pentool/modules/scanner/passive.py +114 -0
  77. pentool-1.0.0/pentool/modules/scanner/payloads.py +224 -0
  78. pentool-1.0.0/pentool/modules/scanner/report.py +117 -0
  79. pentool-1.0.0/pentool/modules/sequencer.py +500 -0
  80. pentool-1.0.0/pentool/modules/spider.py +702 -0
  81. pentool-1.0.0/pentool/modules/target.py +190 -0
  82. pentool-1.0.0/pentool/modules/websocket_handler.py +259 -0
  83. pentool-1.0.0/pentool/plugins/__init__.py +7 -0
  84. pentool-1.0.0/pentool/plugins/builtin/__init__.py +1 -0
  85. pentool-1.0.0/pentool/plugins/builtin/payloads_pro.py +404 -0
  86. pentool-1.0.0/pentool/plugins/builtin/reports_pro.py +450 -0
  87. pentool-1.0.0/pentool/plugins/builtin/scanner_pro.py +308 -0
  88. pentool-1.0.0/pentool/plugins/example_plugin.py +75 -0
  89. pentool-1.0.0/pentool/project_to_txt.py +67 -0
  90. pentool-1.0.0/pentool/services/__init__.py +1 -0
  91. pentool-1.0.0/pentool/services/base_service.py +64 -0
  92. pentool-1.0.0/pentool/services/intruder_service.py +108 -0
  93. pentool-1.0.0/pentool/services/proxy_service.py +232 -0
  94. pentool-1.0.0/pentool/services/repeater_service.py +111 -0
  95. pentool-1.0.0/pentool/services/scan_service.py +340 -0
  96. pentool-1.0.0/pentool/storage/__init__.py +0 -0
  97. pentool-1.0.0/pentool/storage/http_storage.py +522 -0
  98. pentool-1.0.0/pentool/storage/large_body_handler.py +54 -0
  99. pentool-1.0.0/pentool/storage/lru_cache.py +49 -0
  100. pentool-1.0.0/pentool/t.py +213 -0
  101. pentool-1.0.0/pentool/tui/__init__.py +1 -0
  102. pentool-1.0.0/pentool/tui/app.py +1438 -0
  103. pentool-1.0.0/pentool/tui/constants.py +79 -0
  104. pentool-1.0.0/pentool/tui/dialogs/__init__.py +0 -0
  105. pentool-1.0.0/pentool/tui/dialogs/cert_dialog.py +81 -0
  106. pentool-1.0.0/pentool/tui/dialogs/file_selector.py +227 -0
  107. pentool-1.0.0/pentool/tui/dialogs/load_from_proxy.py +125 -0
  108. pentool-1.0.0/pentool/tui/dialogs/match_replace_dialog.py +229 -0
  109. pentool-1.0.0/pentool/tui/dialogs/project_dialog.py +82 -0
  110. pentool-1.0.0/pentool/tui/dialogs/scope_dialog.py +225 -0
  111. pentool-1.0.0/pentool/tui/messages.py +121 -0
  112. pentool-1.0.0/pentool/tui/mixins/__init__.py +0 -0
  113. pentool-1.0.0/pentool/tui/mixins/app_mixin.py +61 -0
  114. pentool-1.0.0/pentool/tui/mixins/dialog_cancel.py +25 -0
  115. pentool-1.0.0/pentool/tui/mixins/request_context_menu.py +285 -0
  116. pentool-1.0.0/pentool/tui/mixins/tab_rename.py +101 -0
  117. pentool-1.0.0/pentool/tui/screens/__init__.py +31 -0
  118. pentool-1.0.0/pentool/tui/screens/comparer/__init__.py +3 -0
  119. pentool-1.0.0/pentool/tui/screens/comparer/screen.py +233 -0
  120. pentool-1.0.0/pentool/tui/screens/dashboard/__init__.py +2 -0
  121. pentool-1.0.0/pentool/tui/screens/dashboard/live_dashboard.py +741 -0
  122. pentool-1.0.0/pentool/tui/screens/dashboard/screen.py +820 -0
  123. pentool-1.0.0/pentool/tui/screens/decoder/__init__.py +3 -0
  124. pentool-1.0.0/pentool/tui/screens/decoder/screen.py +311 -0
  125. pentool-1.0.0/pentool/tui/screens/extensions/__init__.py +3 -0
  126. pentool-1.0.0/pentool/tui/screens/extensions/screen.py +24 -0
  127. pentool-1.0.0/pentool/tui/screens/intruder/__init__.py +3 -0
  128. pentool-1.0.0/pentool/tui/screens/intruder/screen.py +1362 -0
  129. pentool-1.0.0/pentool/tui/screens/proxy/__init__.py +3 -0
  130. pentool-1.0.0/pentool/tui/screens/proxy/screen.py +1664 -0
  131. pentool-1.0.0/pentool/tui/screens/repeater/__init__.py +3 -0
  132. pentool-1.0.0/pentool/tui/screens/repeater/screen.py +646 -0
  133. pentool-1.0.0/pentool/tui/screens/scanner/__init__.py +3 -0
  134. pentool-1.0.0/pentool/tui/screens/scanner/screen.py +1984 -0
  135. pentool-1.0.0/pentool/tui/screens/sequencer/__init__.py +3 -0
  136. pentool-1.0.0/pentool/tui/screens/sequencer/screen.py +520 -0
  137. pentool-1.0.0/pentool/tui/screens/settings/__init__.py +5 -0
  138. pentool-1.0.0/pentool/tui/screens/settings/hotkeys.py +134 -0
  139. pentool-1.0.0/pentool/tui/screens/settings/screen.py +543 -0
  140. pentool-1.0.0/pentool/tui/screens/spider/__init__.py +3 -0
  141. pentool-1.0.0/pentool/tui/screens/spider/screen.py +385 -0
  142. pentool-1.0.0/pentool/tui/screens/target/__init__.py +4 -0
  143. pentool-1.0.0/pentool/tui/screens/target/screen.py +361 -0
  144. pentool-1.0.0/pentool/tui/screens/terminal/__init__.py +5 -0
  145. pentool-1.0.0/pentool/tui/screens/terminal/screen.py +181 -0
  146. pentool-1.0.0/pentool/tui/widgets/__init__.py +1 -0
  147. pentool-1.0.0/pentool/tui/widgets/context_menu.py +148 -0
  148. pentool-1.0.0/pentool/tui/widgets/filter_bar.py +206 -0
  149. pentool-1.0.0/pentool/tui/widgets/inspector_panel.py +112 -0
  150. pentool-1.0.0/pentool/tui/widgets/menu.py +86 -0
  151. pentool-1.0.0/pentool/tui/widgets/menu_bar.py +238 -0
  152. pentool-1.0.0/pentool/tui/widgets/module_tabs.py +73 -0
  153. pentool-1.0.0/pentool/tui/widgets/payload_drop_zone.py +66 -0
  154. pentool-1.0.0/pentool/tui/widgets/request_editor.py +504 -0
  155. pentool-1.0.0/pentool/tui/widgets/resize_handle.py +116 -0
  156. pentool-1.0.0/pentool/tui/widgets/search_bar.py +113 -0
  157. pentool-1.0.0/pentool/tui/widgets/statusbar.py +99 -0
  158. pentool-1.0.0/pentool/tui/widgets/toolbar_button.py +76 -0
  159. pentool-1.0.0/pentool/utils/__init__.py +1 -0
  160. pentool-1.0.0/pentool/utils/cert.py +361 -0
  161. pentool-1.0.0/pentool/utils/coder.py +170 -0
  162. pentool-1.0.0/pentool/utils/copy_as.py +251 -0
  163. pentool-1.0.0/pentool/utils/diff.py +91 -0
  164. pentool-1.0.0/pentool/utils/http_client.py +175 -0
  165. pentool-1.0.0/pentool/utils/parser.py +227 -0
  166. pentool-1.0.0/pentool/utils/terminal_check.py +32 -0
  167. pentool-1.0.0/pentool.egg-info/PKG-INFO +155 -0
  168. pentool-1.0.0/pentool.egg-info/SOURCES.txt +172 -0
  169. pentool-1.0.0/pentool.egg-info/dependency_links.txt +1 -0
  170. pentool-1.0.0/pentool.egg-info/entry_points.txt +2 -0
  171. pentool-1.0.0/pentool.egg-info/requires.txt +17 -0
  172. pentool-1.0.0/pentool.egg-info/top_level.txt +1 -0
  173. pentool-1.0.0/pyproject.toml +109 -0
  174. pentool-1.0.0/setup.cfg +4 -0
pentool-1.0.0/LICENSE ADDED
@@ -0,0 +1,34 @@
1
+ GNU AFFERO GENERAL PUBLIC LICENSE
2
+ Version 3, 19 November 2007
3
+
4
+ Copyright (C) 2026 Pentool Project
5
+
6
+ This program is free software: you can redistribute it and/or modify
7
+ it under the terms of the GNU Affero General Public License as published
8
+ by the Free Software Foundation, either version 3 of the License, or
9
+ (at your option) any later version.
10
+
11
+ This program is distributed in the hope that it will be useful,
12
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ GNU Affero General Public License for more details.
15
+
16
+ You should have received a copy of the GNU Affero General Public License
17
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
18
+
19
+ ---
20
+
21
+ Additional Terms:
22
+
23
+ This software is dual-licensed:
24
+
25
+ 1. Community Edition: AGPL-3.0 (this license)
26
+ - Free for personal and open-source use
27
+ - Source code modifications must be shared
28
+
29
+ 2. Commercial/PRO Edition: Commercial License
30
+ - Contact: sales@pentool.dev
31
+ - For proprietary/closed-source use
32
+ - Includes enterprise features and support
33
+
34
+ For commercial licensing inquiries, please contact: sales@pentool.dev
pentool-1.0.0/PKG-INFO ADDED
@@ -0,0 +1,155 @@
1
+ Metadata-Version: 2.4
2
+ Name: pentool
3
+ Version: 1.0.0
4
+ Summary: Modern Web Pentesting TUI - Professional security testing tool
5
+ Author-email: Pentool Team <dev@pentool.pro>
6
+ License: AGPL-3.0
7
+ Project-URL: Homepage, https://github.com/pentool/pentool
8
+ Project-URL: Documentation, https://pentool.dev/docs
9
+ Project-URL: Repository, https://github.com/pentool/pentool
10
+ Project-URL: Issues, https://github.com/pentool/pentool/issues
11
+ Project-URL: Changelog, https://github.com/pentool/pentool/blob/main/CHANGELOG.md
12
+ Keywords: pentesting,security,burp,proxy,scanner,intruder
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Intended Audience :: Information Technology
16
+ Classifier: Topic :: Security
17
+ Classifier: License :: OSI Approved :: GNU Affero General Public License v3
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3.10
20
+ Classifier: Programming Language :: Python :: 3.11
21
+ Classifier: Programming Language :: Python :: 3.12
22
+ Classifier: Operating System :: OS Independent
23
+ Classifier: Environment :: Console
24
+ Requires-Python: >=3.10
25
+ Description-Content-Type: text/markdown
26
+ License-File: LICENSE
27
+ Requires-Dist: textual>=0.40.0
28
+ Requires-Dist: aiohttp>=3.9.0
29
+ Requires-Dist: aiosqlite>=0.19.0
30
+ Requires-Dist: beautifulsoup4>=4.12.0
31
+ Requires-Dist: click>=8.1.0
32
+ Requires-Dist: cryptography>=41.0.0
33
+ Requires-Dist: pyyaml>=6.0
34
+ Requires-Dist: rich>=13.0.0
35
+ Provides-Extra: dev
36
+ Requires-Dist: pytest>=7.4.0; extra == "dev"
37
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
38
+ Requires-Dist: pytest-cov>=4.1.0; extra == "dev"
39
+ Requires-Dist: pytest-timeout>=2.1.0; extra == "dev"
40
+ Requires-Dist: ruff>=0.1.0; extra == "dev"
41
+ Requires-Dist: mypy>=1.5.0; extra == "dev"
42
+ Requires-Dist: pre-commit>=3.4.0; extra == "dev"
43
+ Dynamic: license-file
44
+
45
+ # 🔐 Pentool — Modern Web Pentesting TUI
46
+
47
+ [![PyPI version](https://badge.fury.io/py/pentool.svg)](https://badge.fury.io/py/pentool)
48
+ [![Python](https://img.shields.io/pypi/pyversions/pentool)](https://pypi.org/project/pentool/)
49
+ [![License: AGPL-3.0](https://img.shields.io/badge/License-AGPL--3.0-blue.svg)](LICENSE)
50
+ [![Tests](https://github.com/docx/pentool/actions/workflows/ci.yml/badge.svg)](https://github.com/docx/pentool/actions)
51
+
52
+ **Pentool** is a fast, modular web security testing tool with a terminal UI. Built for pentesters and security researchers who prefer working in the terminal.
53
+
54
+ ```bash
55
+ pip install pentool
56
+ pentool
57
+ ```
58
+
59
+ ---
60
+
61
+ ## ✨ Features
62
+
63
+ - **🌐 Proxy** — Intercept and modify HTTP/HTTPS traffic in real time, manage scope, apply match & replace rules
64
+ - **🔄 Repeater** — Replay requests with any modifications, persist tabs between sessions
65
+ - **💥 Intruder** — Automated attacks with 4 strategies: Sniper, Battering Ram, Pitchfork, Cluster Bomb
66
+ - **🚀 Turbo Intruder** — 10× speed via HTTP Keep-Alive and connection pooling (100–200 req/sec)
67
+ - **🔍 Scanner** — Detect SQLi, XSS, SSTI, LFI, RCE, SSRF, XXE and more (active + passive modes)
68
+ - **🕷 Spider** — Crawl sites automatically, collect pages, forms and JS endpoints
69
+ - **🎯 Target / Site Map** — Build a site map and manage testing scope from the UI
70
+ - **🔐 Decoder + Comparer + Sequencer** — Encode/decode, diff requests, analyze token entropy
71
+ - **🧩 Plugin system** — Extend functionality without recompiling
72
+ - **⚡ Async core** — Fully async, optimized for high load
73
+ - **🆓 Open Source + PRO** — Free base, optional PRO license for advanced features
74
+
75
+ ---
76
+
77
+ ## 📦 Installation
78
+
79
+ **Requirements:** Python 3.10+, Linux / macOS / Windows
80
+
81
+ ```bash
82
+ pip install pentool
83
+ ```
84
+
85
+ From source:
86
+
87
+ ```bash
88
+ git clone https://github.com/docx/pentool.git
89
+ cd pentool
90
+ pip install -e ".[dev]"
91
+ ```
92
+
93
+ ---
94
+
95
+ ## 🚀 Quick Start
96
+
97
+ ```bash
98
+ # Launch the TUI
99
+ pentool
100
+
101
+ # Start proxy on custom port
102
+ pentool proxy start --port 8080
103
+
104
+ # Run active scan
105
+ pentool scan active --url https://example.com
106
+ ```
107
+
108
+ ---
109
+
110
+ ## 💰 Pricing
111
+
112
+ | Plan | Price | Features |
113
+ |------|-------|----------|
114
+ | **Free** | $0 | Proxy, Repeater, Intruder, Decoder |
115
+ | **Lite** | $29/mo | + Scanner, Spider, Match & Replace |
116
+ | **Medium** | $99/mo | + WebSocket, Plugins, Turbo Mode |
117
+ | **Full** | $299/mo | + PRO Reports, API, Unlimited |
118
+
119
+ [Get PRO license →](https://pentool.pro)
120
+
121
+ ---
122
+
123
+ ## 🤝 Support the project
124
+
125
+ Pentool is developed in free time. If it helps your work, consider supporting:
126
+
127
+ - [GitHub Sponsors](https://github.com/sponsors/docx)
128
+ - [Buy PRO license](https://pentool.pro) — also supports development
129
+
130
+ ---
131
+
132
+ ## 📖 Documentation
133
+
134
+ - [Quick Start](docs/QUICKSTART.md)
135
+ - [User Guide](docs/user/)
136
+ - [Architecture](docs/ARCHITECTURE_AUDIT.md)
137
+ - [API Reference](docs/API_CONTRACTS.md)
138
+
139
+ ---
140
+
141
+ ## 🧪 Tests
142
+
143
+ ```bash
144
+ pytest tests/unit/ -q
145
+ ```
146
+
147
+ ---
148
+
149
+ ## 🤝 Contributing
150
+
151
+ See [CONTRIBUTING.md](CONTRIBUTING.md). Report vulnerabilities to security@pentool.pro.
152
+
153
+ ## 📄 License
154
+
155
+ Community Edition: [AGPL-3.0](LICENSE) · PRO Edition: Commercial
@@ -0,0 +1,111 @@
1
+ # 🔐 Pentool — Modern Web Pentesting TUI
2
+
3
+ [![PyPI version](https://badge.fury.io/py/pentool.svg)](https://badge.fury.io/py/pentool)
4
+ [![Python](https://img.shields.io/pypi/pyversions/pentool)](https://pypi.org/project/pentool/)
5
+ [![License: AGPL-3.0](https://img.shields.io/badge/License-AGPL--3.0-blue.svg)](LICENSE)
6
+ [![Tests](https://github.com/docx/pentool/actions/workflows/ci.yml/badge.svg)](https://github.com/docx/pentool/actions)
7
+
8
+ **Pentool** is a fast, modular web security testing tool with a terminal UI. Built for pentesters and security researchers who prefer working in the terminal.
9
+
10
+ ```bash
11
+ pip install pentool
12
+ pentool
13
+ ```
14
+
15
+ ---
16
+
17
+ ## ✨ Features
18
+
19
+ - **🌐 Proxy** — Intercept and modify HTTP/HTTPS traffic in real time, manage scope, apply match & replace rules
20
+ - **🔄 Repeater** — Replay requests with any modifications, persist tabs between sessions
21
+ - **💥 Intruder** — Automated attacks with 4 strategies: Sniper, Battering Ram, Pitchfork, Cluster Bomb
22
+ - **🚀 Turbo Intruder** — 10× speed via HTTP Keep-Alive and connection pooling (100–200 req/sec)
23
+ - **🔍 Scanner** — Detect SQLi, XSS, SSTI, LFI, RCE, SSRF, XXE and more (active + passive modes)
24
+ - **🕷 Spider** — Crawl sites automatically, collect pages, forms and JS endpoints
25
+ - **🎯 Target / Site Map** — Build a site map and manage testing scope from the UI
26
+ - **🔐 Decoder + Comparer + Sequencer** — Encode/decode, diff requests, analyze token entropy
27
+ - **🧩 Plugin system** — Extend functionality without recompiling
28
+ - **⚡ Async core** — Fully async, optimized for high load
29
+ - **🆓 Open Source + PRO** — Free base, optional PRO license for advanced features
30
+
31
+ ---
32
+
33
+ ## 📦 Installation
34
+
35
+ **Requirements:** Python 3.10+, Linux / macOS / Windows
36
+
37
+ ```bash
38
+ pip install pentool
39
+ ```
40
+
41
+ From source:
42
+
43
+ ```bash
44
+ git clone https://github.com/docx/pentool.git
45
+ cd pentool
46
+ pip install -e ".[dev]"
47
+ ```
48
+
49
+ ---
50
+
51
+ ## 🚀 Quick Start
52
+
53
+ ```bash
54
+ # Launch the TUI
55
+ pentool
56
+
57
+ # Start proxy on custom port
58
+ pentool proxy start --port 8080
59
+
60
+ # Run active scan
61
+ pentool scan active --url https://example.com
62
+ ```
63
+
64
+ ---
65
+
66
+ ## 💰 Pricing
67
+
68
+ | Plan | Price | Features |
69
+ |------|-------|----------|
70
+ | **Free** | $0 | Proxy, Repeater, Intruder, Decoder |
71
+ | **Lite** | $29/mo | + Scanner, Spider, Match & Replace |
72
+ | **Medium** | $99/mo | + WebSocket, Plugins, Turbo Mode |
73
+ | **Full** | $299/mo | + PRO Reports, API, Unlimited |
74
+
75
+ [Get PRO license →](https://pentool.pro)
76
+
77
+ ---
78
+
79
+ ## 🤝 Support the project
80
+
81
+ Pentool is developed in free time. If it helps your work, consider supporting:
82
+
83
+ - [GitHub Sponsors](https://github.com/sponsors/docx)
84
+ - [Buy PRO license](https://pentool.pro) — also supports development
85
+
86
+ ---
87
+
88
+ ## 📖 Documentation
89
+
90
+ - [Quick Start](docs/QUICKSTART.md)
91
+ - [User Guide](docs/user/)
92
+ - [Architecture](docs/ARCHITECTURE_AUDIT.md)
93
+ - [API Reference](docs/API_CONTRACTS.md)
94
+
95
+ ---
96
+
97
+ ## 🧪 Tests
98
+
99
+ ```bash
100
+ pytest tests/unit/ -q
101
+ ```
102
+
103
+ ---
104
+
105
+ ## 🤝 Contributing
106
+
107
+ See [CONTRIBUTING.md](CONTRIBUTING.md). Report vulnerabilities to security@pentool.pro.
108
+
109
+ ## 📄 License
110
+
111
+ Community Edition: [AGPL-3.0](LICENSE) · PRO Edition: Commercial
@@ -0,0 +1,4 @@
1
+ """Pentool — консольный аналог Burp Suite с TUI на Textual."""
2
+
3
+ __version__ = "0.1.0"
4
+ __author__ = "pentool"
@@ -0,0 +1,17 @@
1
+ """Точка входа: без аргументов — TUI, с аргументами — CLI."""
2
+
3
+ import sys
4
+
5
+
6
+ def main() -> None:
7
+ """Запустить TUI или CLI в зависимости от аргументов."""
8
+ if len(sys.argv) > 1:
9
+ from pentool.cli.main import cli
10
+ cli()
11
+ else:
12
+ from pentool.tui.app import PentoolApp
13
+ PentoolApp().run()
14
+
15
+
16
+ if __name__ == "__main__":
17
+ main()
@@ -0,0 +1,45 @@
1
+ """API-слой pentool — публичный интерфейс между modules/ и TUI/CLI.
2
+
3
+ TUI и CLI импортируют только из pentool.api, не из pentool.modules напрямую.
4
+ Это позволяет независимо менять логику и отображение.
5
+ """
6
+
7
+ from pentool.api.proxy_api import ProxyAPI, InterceptedRequest, MatchReplaceRule
8
+ from pentool.api.repeater_api import RepeaterAPI
9
+ from pentool.api.scanner_api import ScannerAPI
10
+ from pentool.api.intruder_api import IntruderAPI, IntruderConfig, IntruderAttack
11
+ from pentool.api.spider_api import SpiderAPI
12
+ from pentool.api.target_api import TargetAPI
13
+ # Decoder/Comparer/Sequencer — функциональные API без класса-обёртки
14
+ from pentool.api.decoder_api import ( # noqa: F401
15
+ OPERATIONS, OP_LABELS, DecoderChain,
16
+ decode_op, decode_smart, encode_op, run_chain,
17
+ )
18
+ from pentool.api.comparer_api import ( # noqa: F401
19
+ compare, compare_lines, CompareStats, DiffLine, DiffResult,
20
+ )
21
+ from pentool.api.sequencer_api import ( # noqa: F401
22
+ Sequencer, SequencerReport, token_entropy, charset_size,
23
+ )
24
+
25
+ __all__ = [
26
+ # Proxy
27
+ "ProxyAPI", "InterceptedRequest", "MatchReplaceRule",
28
+ # Repeater
29
+ "RepeaterAPI",
30
+ # Scanner
31
+ "ScannerAPI",
32
+ # Intruder
33
+ "IntruderAPI", "IntruderConfig", "IntruderAttack",
34
+ # Spider
35
+ "SpiderAPI",
36
+ # Target
37
+ "TargetAPI",
38
+ # Decoder
39
+ "OPERATIONS", "OP_LABELS", "DecoderChain",
40
+ "decode_op", "decode_smart", "encode_op", "run_chain",
41
+ # Comparer
42
+ "compare", "compare_lines", "CompareStats", "DiffLine", "DiffResult",
43
+ # Sequencer
44
+ "Sequencer", "SequencerReport", "token_entropy", "charset_size",
45
+ ]
@@ -0,0 +1,52 @@
1
+ """ExportableAPI — base mixin for API classes supporting project persistence.
2
+
3
+ All API classes that implement export_project_data/import_project_data should
4
+ inherit from this mixin for type consistency and documentation.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ from abc import ABC, abstractmethod
10
+
11
+
12
+ class ExportableAPI(ABC):
13
+ """Mixin for API classes that support project data export/import.
14
+
15
+ Subclasses must implement export_project_data and import_project_data.
16
+ These methods are called by core.project.save_project/load_project.
17
+
18
+ Usage::
19
+
20
+ class MyAPI(ExportableAPI):
21
+ def export_project_data(self) -> dict:
22
+ return {"my_data": [...]}
23
+
24
+ def import_project_data(self, data: dict) -> int:
25
+ items = data.get("my_data", [])
26
+ # restore items
27
+ return len(items)
28
+ """
29
+
30
+ @abstractmethod
31
+ def export_project_data(self) -> dict:
32
+ """Export module state to a serializable dict.
33
+
34
+ Returns:
35
+ dict: Module-specific data structure (e.g., {"results": [...]}).
36
+ Must be JSON-serializable (no datetime, use .isoformat()).
37
+ """
38
+ raise NotImplementedError
39
+
40
+ @abstractmethod
41
+ def import_project_data(self, data: dict) -> int | tuple[int, str]:
42
+ """Import module state from a loaded project dict.
43
+
44
+ Args:
45
+ data: The module's block from project.json (e.g., data["intruder"]).
46
+
47
+ Returns:
48
+ int: Number of items loaded successfully.
49
+ OR
50
+ tuple[int, str]: (count, error_message) — empty string if OK.
51
+ """
52
+ raise NotImplementedError
@@ -0,0 +1,23 @@
1
+ """ComparerAPI — публичный интерфейс Comparer для TUI.
2
+
3
+ TUI-экраны импортируют только этот модуль,
4
+ не modules/comparer.py напрямую.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ from pentool.modules.comparer import ( # noqa: F401
10
+ compare,
11
+ compare_lines,
12
+ CompareStats,
13
+ DiffLine,
14
+ DiffResult,
15
+ )
16
+
17
+ __all__ = [
18
+ "compare",
19
+ "compare_lines",
20
+ "CompareStats",
21
+ "DiffLine",
22
+ "DiffResult",
23
+ ]
@@ -0,0 +1,28 @@
1
+ """DecoderAPI — публичный интерфейс Decoder/Encoder для TUI.
2
+
3
+ TUI-экраны импортируют только этот модуль,
4
+ не modules/decoder.py напрямую.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ # Реэкспорт всего публичного из modules/decoder
10
+ from pentool.modules.decoder import ( # noqa: F401
11
+ OPERATIONS,
12
+ OP_LABELS,
13
+ DecoderChain,
14
+ decode_op,
15
+ decode_smart,
16
+ encode_op,
17
+ run_chain,
18
+ )
19
+
20
+ __all__ = [
21
+ "OPERATIONS",
22
+ "OP_LABELS",
23
+ "DecoderChain",
24
+ "decode_op",
25
+ "decode_smart",
26
+ "encode_op",
27
+ "run_chain",
28
+ ]
@@ -0,0 +1,209 @@
1
+ """Публичный API Intruder-модуля для TUI и CLI."""
2
+
3
+ from __future__ import annotations
4
+
5
+
6
+
7
+ from pentool.modules.intruder import (
8
+ AttackType,
9
+ IntruderAttack,
10
+ IntruderConfig,
11
+ IntruderResult,
12
+ count_markers,
13
+ extract_marker_defaults,
14
+ generate_char_payloads,
15
+ generate_numeric_payloads,
16
+ load_payloads_from_file,
17
+ process_payload,
18
+ )
19
+
20
+ __all__ = [
21
+ "IntruderAPI",
22
+ "AttackType",
23
+ "IntruderAttack",
24
+ "IntruderConfig",
25
+ "IntruderResult",
26
+ "count_markers",
27
+ "extract_marker_defaults",
28
+ "generate_char_payloads",
29
+ "generate_numeric_payloads",
30
+ "load_payloads_from_file",
31
+ "process_payload",
32
+ ]
33
+
34
+
35
+ class IntruderAPI:
36
+ """Публичный интерфейс Intruder-модуля.
37
+
38
+ Тонкая обёртка над IntruderAttack.
39
+ Не знает о Textual.
40
+ """
41
+
42
+ def __init__(self, db_path: str | None = None) -> None:
43
+ self._db_path = db_path
44
+ self._attack: IntruderAttack | None = None
45
+
46
+ async def start_attack(
47
+ self,
48
+ config: IntruderConfig,
49
+ on_result=None,
50
+ on_progress=None,
51
+ turbo_mode: bool = False,
52
+ ) -> str:
53
+ """Запустить атаку. Возвращает attack_id.
54
+
55
+ Args:
56
+ config: Конфиг атаки.
57
+ on_result: Callback(IntruderResult) — вызывается на каждый результат.
58
+ on_progress: Callback(done, total) — вызывается при обновлении прогресса.
59
+ turbo_mode: Использовать Turbo Mode (HTTP Keep-Alive, connection pooling).
60
+
61
+ Returns:
62
+ str: attack_id (UUID).
63
+ """
64
+ if turbo_mode:
65
+ # Turbo Mode: connection pooling + Keep-Alive
66
+ from pentool.modules.intruder_turbo import TurboIntruderAttack
67
+ self._attack = TurboIntruderAttack(config)
68
+ else:
69
+ # Обычный режим
70
+ self._attack = IntruderAttack(config, db_path=self._db_path)
71
+
72
+ _on_result = on_result if on_result else lambda r: None
73
+ _on_progress = on_progress if on_progress else lambda d, t: None
74
+
75
+ import asyncio
76
+ asyncio.create_task(self._attack.run(_on_result, _on_progress))
77
+ return self._attack.attack_id if hasattr(self._attack, 'attack_id') else "turbo"
78
+
79
+ async def pause(self) -> None:
80
+ """Поставить атаку на паузу."""
81
+ if self._attack:
82
+ await self._attack.pause()
83
+
84
+ async def resume(self) -> None:
85
+ """Возобновить атаку после паузы."""
86
+ if self._attack:
87
+ await self._attack.resume()
88
+
89
+ async def stop(self) -> None:
90
+ """Остановить атаку."""
91
+ if self._attack:
92
+ await self._attack.stop()
93
+
94
+ def get_results(self) -> list[IntruderResult]:
95
+ """Получить список результатов текущей атаки."""
96
+ if self._attack:
97
+ # Turbo mode использует get_results(), обычный - results property
98
+ if hasattr(self._attack, 'get_results'):
99
+ return self._attack.get_results()
100
+ return self._attack.results
101
+ return []
102
+
103
+ def get_progress(self) -> tuple[int, int]:
104
+ """Вернуть (done, total) текущей атаки."""
105
+ if self._attack:
106
+ return self._attack.progress
107
+ return (0, 0)
108
+
109
+ @property
110
+ def is_running(self) -> bool:
111
+ """Возвращает True если атака сейчас выполняется."""
112
+ return bool(self._attack and self._attack.is_running)
113
+
114
+ async def load_payloads(self, path: str) -> list[str]:
115
+ """Загрузить payload'ы из файла."""
116
+ return load_payloads_from_file(path)
117
+
118
+ async def generate_numeric(self, start: int, end: int, step: int = 1) -> list[str]:
119
+ """Сгенерировать числовые payload'ы."""
120
+ return generate_numeric_payloads(start, end, step)
121
+
122
+ async def generate_chars(
123
+ self, charset: str, min_len: int, max_len: int
124
+ ) -> list[str]:
125
+ """Сгенерировать символьные payload'ы."""
126
+ return generate_char_payloads(charset, min_len, max_len)
127
+
128
+ def export_csv(self, path: str) -> None:
129
+ """Экспортировать результаты в CSV."""
130
+ if self._attack:
131
+ self._attack.export_csv(path)
132
+
133
+ # ── Project persistence ────────────────────────────────────────────────────
134
+
135
+ def export_project_data(self) -> dict:
136
+ """Экспортировать результаты Intruder в сериализуемый dict.
137
+
138
+ Returns:
139
+ dict с ключом "results" — список IntruderResult в виде dict.
140
+ """
141
+ results = self.get_results()
142
+ return {
143
+ "results": [
144
+ {
145
+ "id": r.id,
146
+ "attack_id": r.attack_id,
147
+ "request_number": r.request_number,
148
+ "payload_values": r.payload_values,
149
+ "request_raw": r.request_raw,
150
+ "response_status": r.response_status,
151
+ "response_length": r.response_length,
152
+ "response_time_ms": r.response_time_ms,
153
+ "error": r.error,
154
+ "timestamp": r.timestamp.isoformat(),
155
+ }
156
+ for r in results
157
+ ]
158
+ }
159
+
160
+ def import_project_data(self, data: dict) -> int:
161
+ """Импортировать результаты Intruder из загруженного dict проекта.
162
+
163
+ Args:
164
+ data: Блок "intruder" из project.json ({"results": [...]}).
165
+
166
+ Returns:
167
+ Количество загруженных результатов.
168
+ """
169
+ from datetime import datetime, timezone
170
+ from pentool.modules.intruder import IntruderResult
171
+
172
+ results_data = data.get("results", [])
173
+ # Создаём фиктивный attack для хранения результатов
174
+ # без реального запуска атаки
175
+ if self._attack is None:
176
+ # Ленивая инициализация — просто храним в атрибуте
177
+ self._restored_results: list[IntruderResult] = []
178
+ else:
179
+ self._restored_results = []
180
+
181
+ loaded = 0
182
+ for rd in results_data:
183
+ try:
184
+ ts_raw = rd.get("timestamp", "")
185
+ try:
186
+ ts = datetime.fromisoformat(ts_raw)
187
+ except Exception:
188
+ ts = datetime.now(timezone.utc)
189
+ result = IntruderResult(
190
+ id=rd.get("id", ""),
191
+ attack_id=rd.get("attack_id", ""),
192
+ request_number=rd.get("request_number", 0),
193
+ payload_values=rd.get("payload_values", []),
194
+ request_raw=rd.get("request_raw", ""),
195
+ response_status=rd.get("response_status"),
196
+ response_length=rd.get("response_length"),
197
+ response_time_ms=rd.get("response_time_ms"),
198
+ error=rd.get("error"),
199
+ timestamp=ts,
200
+ )
201
+ if hasattr(self, "_restored_results"):
202
+ self._restored_results.append(result)
203
+ loaded += 1
204
+ except Exception as exc:
205
+ from pentool.core.logging import get_logger
206
+ get_logger(__name__).warning(
207
+ "IntruderAPI.import_project_data: skip result: %s", exc
208
+ )
209
+ return loaded