exaai-agent 2.0.5__py3-none-any.whl → 2.0.8__py3-none-any.whl
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.
- {exaai_agent-2.0.5.dist-info → exaai_agent-2.0.8.dist-info}/METADATA +55 -52
- {exaai_agent-2.0.5.dist-info → exaai_agent-2.0.8.dist-info}/RECORD +19 -11
- exaai_agent-2.0.8.dist-info/entry_points.txt +5 -0
- exaaiagnt/interface/main.py +92 -50
- exaaiagnt/interface/tui.py +17 -3
- exaaiagnt/llm/__init__.py +13 -0
- exaaiagnt/llm/llm.py +14 -3
- exaaiagnt/llm/llm_traffic_controller.py +351 -0
- exaaiagnt/prompts/auto_loader.py +104 -0
- exaaiagnt/prompts/cloud/aws_cloud_security.jinja +235 -0
- exaaiagnt/prompts/frameworks/modern_js_frameworks.jinja +194 -0
- exaaiagnt/prompts/vulnerabilities/react2shell.jinja +187 -0
- exaaiagnt/tools/__init__.py +58 -0
- exaaiagnt/tools/response_analyzer.py +294 -0
- exaaiagnt/tools/smart_fuzzer.py +286 -0
- exaaiagnt/tools/tool_prompts.py +210 -0
- exaaiagnt/tools/vuln_validator.py +412 -0
- exaai_agent-2.0.5.dist-info/entry_points.txt +0 -3
- {exaai_agent-2.0.5.dist-info → exaai_agent-2.0.8.dist-info}/WHEEL +0 -0
- {exaai_agent-2.0.5.dist-info → exaai_agent-2.0.8.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: exaai-agent
|
|
3
|
-
Version: 2.0.
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 2.0.8
|
|
4
|
+
Summary: ExaAi - Advanced AI Security Agent for Comprehensive Penetration Testing
|
|
5
5
|
License: Apache-2.0
|
|
6
6
|
License-File: LICENSE
|
|
7
7
|
Keywords: cybersecurity,security,vulnerability,scanner,pentest,agent,ai,cli
|
|
8
|
-
Author:
|
|
8
|
+
Author: ExaAi Team
|
|
9
9
|
Author-email: mahmedhleli@gmail.com
|
|
10
10
|
Requires-Python: >=3.12,<4.0
|
|
11
11
|
Classifier: Development Status :: 3 - Alpha
|
|
@@ -53,48 +53,58 @@ Description-Content-Type: text/markdown
|
|
|
53
53
|
[](https://pypi.org/project/exaai-agent/)
|
|
54
54
|
[](https://pypi.org/project/exaai-agent/)
|
|
55
55
|
[](LICENSE)
|
|
56
|
-
[]()
|
|
57
57
|
|
|
58
58
|
</div>
|
|
59
59
|
|
|
60
60
|
<br>
|
|
61
61
|
|
|
62
62
|
> [!TIP]
|
|
63
|
-
>
|
|
63
|
+
> **🚀 v2.1.0 Released!** React2Shell Detection (CVE-2025-55182), Cloud Security Testing, Smart Fuzzing, and CLI improvements with `exaai` command!
|
|
64
64
|
|
|
65
65
|
---
|
|
66
66
|
|
|
67
|
-
## 🔥 What's New in v2.0
|
|
67
|
+
## 🔥 What's New in v2.1.0
|
|
68
68
|
|
|
69
|
-
|
|
70
|
-
|---------|-------------|
|
|
71
|
-
| 🛡️ **Agent Supervisor** | Self-healing, heartbeat, auto-recovery, priority levels |
|
|
72
|
-
| 🧠 **Shared Memory** | Inter-agent coordination, URL deduplication |
|
|
73
|
-
| 🎭 **Scan Modes** | Stealth (10/min) • Standard (60/min) • Aggressive (300/min) |
|
|
74
|
-
| 🔓 **WAF Bypass** | Cloudflare, Akamai, Imperva detection & bypass |
|
|
75
|
-
| ⚡ **80% Less Tokens** | Smart output processing, summarization |
|
|
69
|
+
### 🚨 React2Shell Detection (CVE-2025-55182)
|
|
76
70
|
|
|
77
|
-
|
|
71
|
+
New critical vulnerability scanner for **React Server Components**:
|
|
72
|
+
|
|
73
|
+
- **CVSS 10.0** - Unauthenticated RCE via RSC Flight protocol
|
|
74
|
+
- Auto-detects Next.js 15.x/16.x, React 19.x applications
|
|
75
|
+
- Complete exploitation methodology and PoC generation
|
|
76
|
+
- WAF bypass techniques included
|
|
77
|
+
|
|
78
|
+
### ☁️ AWS & Cloud Security
|
|
78
79
|
|
|
79
|
-
|
|
80
|
+
Comprehensive cloud infrastructure testing:
|
|
80
81
|
|
|
81
|
-
|
|
82
|
+
- **AWS**: EC2 Metadata SSRF, S3 buckets, IAM escalation, Lambda
|
|
83
|
+
- **Azure**: Blob storage, Managed Identity, Azure AD
|
|
84
|
+
- **GCP**: Cloud Storage, Service Account abuse
|
|
85
|
+
- **Kubernetes**: RBAC, Secrets, Pod escape
|
|
82
86
|
|
|
83
|
-
|
|
87
|
+
### � Smart Security Tools
|
|
84
88
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
-
|
|
89
|
+
| Tool | Capability |
|
|
90
|
+
|------|------------|
|
|
91
|
+
| **Smart Fuzzer** | Context-aware payloads, parameter type detection |
|
|
92
|
+
| **Response Analyzer** | SQL errors, stack traces, sensitive data detection |
|
|
93
|
+
| **Vuln Validator** | PoC generation, CVSS scoring, remediation advice |
|
|
94
|
+
| **WAF Bypass** | Multi-layer bypass techniques |
|
|
88
95
|
|
|
89
|
-
###
|
|
96
|
+
### ⚡ CLI Improvements
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
# New command (shorter!)
|
|
100
|
+
exaai --target https://example.com
|
|
90
101
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
| `subdomain_takeover` | AWS, Azure, GitHub, Heroku takeover |
|
|
102
|
+
# Version check
|
|
103
|
+
exaai --version
|
|
104
|
+
|
|
105
|
+
# TUI mode
|
|
106
|
+
exaai tui
|
|
107
|
+
```
|
|
98
108
|
|
|
99
109
|
---
|
|
100
110
|
|
|
@@ -158,7 +168,7 @@ export EXAAI_LLM="ollama/llama3"
|
|
|
158
168
|
export LLM_API_BASE="http://localhost:11434"
|
|
159
169
|
|
|
160
170
|
# Run your first security assessment (auto-detects modules!)
|
|
161
|
-
|
|
171
|
+
exaai --target https://your-app.com
|
|
162
172
|
```
|
|
163
173
|
|
|
164
174
|
> [!NOTE]
|
|
@@ -212,46 +222,46 @@ Advanced multi-agent orchestration for comprehensive security testing:
|
|
|
212
222
|
|
|
213
223
|
```bash
|
|
214
224
|
# Scan a local codebase
|
|
215
|
-
|
|
225
|
+
exaai --target ./app-directory
|
|
216
226
|
|
|
217
227
|
# Security review of a GitHub repository
|
|
218
|
-
|
|
228
|
+
exaai --target https://github.com/org/repo
|
|
219
229
|
|
|
220
230
|
# Black-box web application assessment
|
|
221
|
-
|
|
231
|
+
exaai --target https://your-app.com
|
|
222
232
|
```
|
|
223
233
|
|
|
224
234
|
### Smart Auto-Loading (New in v2.0!)
|
|
225
235
|
|
|
226
236
|
```bash
|
|
227
237
|
# GraphQL endpoint - auto-loads graphql_security
|
|
228
|
-
|
|
238
|
+
exaai --target https://api.example.com/graphql
|
|
229
239
|
|
|
230
240
|
# WebSocket - auto-loads websocket_security
|
|
231
|
-
|
|
241
|
+
exaai --target wss://chat.example.com/socket
|
|
232
242
|
|
|
233
243
|
# OAuth endpoint - auto-loads oauth_oidc
|
|
234
|
-
|
|
244
|
+
exaai --target https://auth.example.com/oauth/authorize
|
|
235
245
|
|
|
236
246
|
# Subdomain recon - auto-loads subdomain_takeover
|
|
237
|
-
|
|
247
|
+
exaai --target example.com --instruction "enumerate subdomains"
|
|
238
248
|
```
|
|
239
249
|
|
|
240
250
|
### Advanced Testing Scenarios
|
|
241
251
|
|
|
242
252
|
```bash
|
|
243
253
|
# Grey-box authenticated testing
|
|
244
|
-
|
|
254
|
+
exaai --target https://your-app.com --instruction "Perform authenticated testing using credentials: user:pass"
|
|
245
255
|
|
|
246
256
|
# Multi-target testing (source code + deployed app)
|
|
247
|
-
|
|
257
|
+
exaai -t https://github.com/org/app -t https://your-app.com
|
|
248
258
|
|
|
249
259
|
# With specific modules (overrides auto-detection)
|
|
250
|
-
|
|
260
|
+
exaai --target https://api.example.com --prompt-modules graphql_security waf_bypass
|
|
251
261
|
|
|
252
262
|
# Lightweight mode (reduced token consumption)
|
|
253
263
|
export EXAAI_LIGHTWEIGHT_MODE=true
|
|
254
|
-
|
|
264
|
+
exaai --target https://example.com --instruction "quick security scan"
|
|
255
265
|
```
|
|
256
266
|
|
|
257
267
|
### 🤖 Headless Mode
|
|
@@ -259,13 +269,13 @@ exaaiagnt --target https://example.com --instruction "quick security scan"
|
|
|
259
269
|
Run ExaAiAgent programmatically without interactive UI:
|
|
260
270
|
|
|
261
271
|
```bash
|
|
262
|
-
|
|
272
|
+
exaai -n --target https://your-app.com
|
|
263
273
|
```
|
|
264
274
|
|
|
265
275
|
### 🔄 CI/CD (GitHub Actions)
|
|
266
276
|
|
|
267
277
|
```yaml
|
|
268
|
-
name:
|
|
278
|
+
name: exaai-security-test
|
|
269
279
|
|
|
270
280
|
on:
|
|
271
281
|
pull_request:
|
|
@@ -283,7 +293,7 @@ jobs:
|
|
|
283
293
|
env:
|
|
284
294
|
EXAAI_LLM: ${{ secrets.EXAAI_LLM }}
|
|
285
295
|
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
|
|
286
|
-
run:
|
|
296
|
+
run: exaai -n -t ./
|
|
287
297
|
```
|
|
288
298
|
|
|
289
299
|
### ⚙️ Configuration
|
|
@@ -334,20 +344,13 @@ export PERPLEXITY_API_KEY="key" # For search capabilities
|
|
|
334
344
|
|
|
335
345
|
## 🆕 Changelog
|
|
336
346
|
|
|
337
|
-
### v2.0.
|
|
338
|
-
|
|
339
|
-
- 🛡️ **Agent Supervisor** - Self-healing with heartbeat & auto-recovery
|
|
340
|
-
- 🧠 **Shared Memory** - Inter-agent coordination, URL deduplication
|
|
341
|
-
- 🎭 **Scan Modes** - Stealth / Standard / Aggressive
|
|
342
|
-
- 🔓 **WAF Bypass** - Cloudflare, Akamai, Imperva detection & bypass
|
|
343
|
-
- ⚡ **80% Token Reduction** - Smart output processing
|
|
344
|
-
|
|
345
|
-
### v2.0.0
|
|
347
|
+
### v2.0.0 (Latest)
|
|
346
348
|
|
|
347
349
|
- ✨ **Smart Auto-Module Loading** - Automatically detects target type
|
|
348
350
|
- ⚡ **Token Optimization** - Lightweight mode & task scaling
|
|
349
351
|
- 🛡️ **5 New Security Modules** - GraphQL, WebSocket, OAuth, WAF, Subdomain
|
|
350
352
|
- 🎨 **New UI/Branding** - Fresh ExaAi logo with Cyan/Purple theme
|
|
353
|
+
- 📊 **Improved Performance** - Reduced unnecessary LLM calls
|
|
351
354
|
|
|
352
355
|
### v1.0.0
|
|
353
356
|
|
|
@@ -11,7 +11,7 @@ exaaiagnt/agents/state.py,sha256=Tzjdegq3L4IS26XPlK9GQDcwqf6X-KKvih9_4LcXPYw,588
|
|
|
11
11
|
exaaiagnt/interface/__init__.py,sha256=ww23sFOQhICEIrIo0MtwWv2qHW5qUprvPj8QVjv3SM0,44
|
|
12
12
|
exaaiagnt/interface/assets/tui_styles.tcss,sha256=iwhx72f5bIiSg72168ifyR_Q0TKfL3Bf0lU6cyJw1Bg,12114
|
|
13
13
|
exaaiagnt/interface/cli.py,sha256=MxcxxgFBj3DdYVRsQ2qFSzXhtrJVhU-7xyJk5b4vD-k,8451
|
|
14
|
-
exaaiagnt/interface/main.py,sha256=
|
|
14
|
+
exaaiagnt/interface/main.py,sha256=Sn25MV1wmnSnmu2lB2onc7wXXdGzcdZ8zTPjlZJ2Ddw,19085
|
|
15
15
|
exaaiagnt/interface/tool_components/__init__.py,sha256=Dz5ci3VMzvhlPOwQ2x9Nd11cmFzx1OP7sdlpZPMTT4k,935
|
|
16
16
|
exaaiagnt/interface/tool_components/agents_graph_renderer.py,sha256=eVFRqmJ-TxyxZ-hssLTweDAio4UvsZZgxo2dKky0N1U,4399
|
|
17
17
|
exaaiagnt/interface/tool_components/base_renderer.py,sha256=P0zYeRnbkr2NYoE8KDQmj1TzrAGX6r7qLMb4Sw7AoTI,1905
|
|
@@ -28,23 +28,26 @@ exaaiagnt/interface/tool_components/terminal_renderer.py,sha256=-ORL2vBH5XImUZrI
|
|
|
28
28
|
exaaiagnt/interface/tool_components/thinking_renderer.py,sha256=-MQLkKCgOJksrustULFf2jhAjJrP5bbfS2BQ6zgNKCc,927
|
|
29
29
|
exaaiagnt/interface/tool_components/user_message_renderer.py,sha256=6gHJ1hG-pwcTsxLM7JuYZuaDu8cZ2MeOuUDF3LGy-4I,1432
|
|
30
30
|
exaaiagnt/interface/tool_components/web_search_renderer.py,sha256=JnJa22ACIcRksfxxdenesUo8Th9cHSxo-fej9YcuYHs,911
|
|
31
|
-
exaaiagnt/interface/tui.py,sha256=
|
|
31
|
+
exaaiagnt/interface/tui.py,sha256=t3ZbYyiGfjEab0fd6Lk4hbpbWVKGxcLnifCKonTK61c,49777
|
|
32
32
|
exaaiagnt/interface/utils.py,sha256=xp6eDOC8C0c3cjt791S_jBDs1B-xp_ydIb74QnMLEt8,20219
|
|
33
|
-
exaaiagnt/llm/__init__.py,sha256=
|
|
33
|
+
exaaiagnt/llm/__init__.py,sha256=hUVixjSSIUtwIP2I5D_9e6Kdxhhunnajgxx_2DEYNww,1095
|
|
34
34
|
exaaiagnt/llm/config.py,sha256=HQ0skwQxtHwiDLDWBCU1Fp4UoQ8tbrTNQw9s7JGVaiY,3303
|
|
35
35
|
exaaiagnt/llm/fallback.py,sha256=oPS0PGRxEHnyyBgS4yP9zdwSf4JFJh4dYZ3g8OFwWEE,11413
|
|
36
|
-
exaaiagnt/llm/llm.py,sha256=
|
|
36
|
+
exaaiagnt/llm/llm.py,sha256=EEPte4O37YVhCrJleHS8uU5eaYw_WDXKIEwlK2USJgE,18606
|
|
37
|
+
exaaiagnt/llm/llm_traffic_controller.py,sha256=HZ0OZcbfr5XLVSpuW8EQLn3gQht3rjY1n6SGRFpBZa0,12187
|
|
37
38
|
exaaiagnt/llm/memory_compressor.py,sha256=_At7e5QlDv2vrUDUJMEwm4CjNJ2uGYQsOBhiHiQvVr8,7054
|
|
38
39
|
exaaiagnt/llm/output_processor.py,sha256=JC3TtzYj9DJhJRuKzz_VV3WIwAyYhUdZeY1N9c4SzVw,13568
|
|
39
40
|
exaaiagnt/llm/request_queue.py,sha256=niwJVzWyvNcOl9uVYABO55c6ZReMxY_GIUhKXh946dI,9195
|
|
40
41
|
exaaiagnt/llm/utils.py,sha256=0Z0r6qo9IfUSOJt5FJsq3X-veXrA8A09frc2VIy-aS4,2540
|
|
41
42
|
exaaiagnt/prompts/README.md,sha256=Svgjx8pO1W0aVzC9z0Fxs88-NBA1whEqU8zrGBDqO0M,3813
|
|
42
43
|
exaaiagnt/prompts/__init__.py,sha256=nUs1powNe_6sWmM5_KkAIxZj97t5IiMMgNrL39WwUjg,5042
|
|
43
|
-
exaaiagnt/prompts/auto_loader.py,sha256=
|
|
44
|
+
exaaiagnt/prompts/auto_loader.py,sha256=SNCewvdqfsIXydOcBNVcEE_x_w_j0Pl7ebOeOSNJ94E,12008
|
|
44
45
|
exaaiagnt/prompts/cloud/.gitkeep,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
46
|
+
exaaiagnt/prompts/cloud/aws_cloud_security.jinja,sha256=ObimikftsoqGzxhrvI6pQLVRQ4MmkJpjwexORS7P7uo,6768
|
|
45
47
|
exaaiagnt/prompts/coordination/root_agent.jinja,sha256=05VUZKnBX_7-FjEYilEq_OJG4u01_56bf4mzGNbFtJc,1996
|
|
46
48
|
exaaiagnt/prompts/custom/.gitkeep,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
47
49
|
exaaiagnt/prompts/frameworks/fastapi.jinja,sha256=zXa08RDG9tVQu6MZetKCcOUPuDDKJJF1anTei7_2TZg,10200
|
|
50
|
+
exaaiagnt/prompts/frameworks/modern_js_frameworks.jinja,sha256=UmqpJeXF87wsBpU-Nfg7KK9ftUtz4ug9LXw_2g3RXLk,5752
|
|
48
51
|
exaaiagnt/prompts/frameworks/nextjs.jinja,sha256=AhfKOUl2bQzRWqqCw5lrjrXaKIkZ3CEEjVJwPJF8nP8,8175
|
|
49
52
|
exaaiagnt/prompts/protocols/graphql.jinja,sha256=Tm538OmlFOJvuOwd4MXYQ4KYR7k4bJ4r-z4yoFcF6-8,10454
|
|
50
53
|
exaaiagnt/prompts/reconnaissance/.gitkeep,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -74,6 +77,7 @@ exaaiagnt/prompts/vulnerabilities/privilege_escalation.jinja,sha256=XY0atQ4nEkGs
|
|
|
74
77
|
exaaiagnt/prompts/vulnerabilities/prototype_pollution.jinja,sha256=g-I6ouqaZpxqoTa4MyGHaUKxwlM-gFrPo_F1T8r_ASI,6486
|
|
75
78
|
exaaiagnt/prompts/vulnerabilities/race_conditions.jinja,sha256=ZHxdZc7v7yvhmUWJK3P3kIzOz3oaYRb2OJEzG1momcg,8372
|
|
76
79
|
exaaiagnt/prompts/vulnerabilities/rce.jinja,sha256=tgmocWH3Y9FJ3fBeR9DTR7ViBcuH5salGis8vywJ2h8,8425
|
|
80
|
+
exaaiagnt/prompts/vulnerabilities/react2shell.jinja,sha256=ZO4lxSpyXm6pVgBw4kUNqWVttSBa04LhqYy6NTj3RQo,6862
|
|
77
81
|
exaaiagnt/prompts/vulnerabilities/reconnaissance_osint.jinja,sha256=Bify6rb6cQGeP-q-PnD9GfOU2dunI0inATpf_IERaik,5552
|
|
78
82
|
exaaiagnt/prompts/vulnerabilities/sql_injection.jinja,sha256=tdFjkbu5p_di0Zui95o2Eh1v-Ulvwg1qcENDNLswv1Q,8426
|
|
79
83
|
exaaiagnt/prompts/vulnerabilities/ssrf.jinja,sha256=XMRAclYIyq0JhVSXopTsbZAm-wRxz-zZfDHdaFgVeiw,7899
|
|
@@ -90,7 +94,7 @@ exaaiagnt/runtime/tool_manager.py,sha256=CMUYlOC3Ez-9eqzz12tJO9tijdIBznFqCUwcT0h
|
|
|
90
94
|
exaaiagnt/runtime/tool_server.py,sha256=e23TJYL5w32gMqLS9UJ0xw3XZ4lM38ETBvHVHKk3APU,6835
|
|
91
95
|
exaaiagnt/telemetry/__init__.py,sha256=8QLHMvrVNLlGKezWTf3mTSmTOLIvDS5xVciry1KVS1Y,130
|
|
92
96
|
exaaiagnt/telemetry/tracer.py,sha256=DZuQ-xGdPWB2FKEn_rRPxP1RO2_acXQRkHzuhApAI88,12582
|
|
93
|
-
exaaiagnt/tools/__init__.py,sha256=
|
|
97
|
+
exaaiagnt/tools/__init__.py,sha256=tFPqL3VKFumF1LgYMhvaecwTQ9b7vHxk0hRArPp3z2U,3402
|
|
94
98
|
exaaiagnt/tools/agents_graph/__init__.py,sha256=FLJ2kGxXICY2pRKrC0sgIc3w3KhZo7VID7hbwYcgBfM,278
|
|
95
99
|
exaaiagnt/tools/agents_graph/agents_graph_actions.py,sha256=ujBj3R3MpOmIVsN4T3nekVhreu60xA2EEg9rYXCdz2c,21103
|
|
96
100
|
exaaiagnt/tools/agents_graph/agents_graph_actions_schema.xml,sha256=fczqDpNw2m58p2O_G0amBZso--EjEGZuK829lB-cXdE,12617
|
|
@@ -123,6 +127,8 @@ exaaiagnt/tools/registry.py,sha256=iBRwtiWLQr3fo1vSAOehWbIlr6cqnNPLB1dluXtsf8s,6
|
|
|
123
127
|
exaaiagnt/tools/reporting/__init__.py,sha256=_cYxb3OP0vZtCwO_ExLBjhAn1ECaG-SH1Z4wfGDyT1Y,110
|
|
124
128
|
exaaiagnt/tools/reporting/reporting_actions.py,sha256=aVEwfG5GgJ68bFJOicO_YD2yp5wCimxlnZzpXX3TJcQ,2200
|
|
125
129
|
exaaiagnt/tools/reporting/reporting_actions_schema.xml,sha256=y_g0iuyBuCh79fvA0ri8fOPlXY7uUd-P-mdzXLUyIJg,1629
|
|
130
|
+
exaaiagnt/tools/response_analyzer.py,sha256=ZBOGwGkH2VM96UH4ZrYhPYI8S_YZp0SG8EDThO7bAX0,10566
|
|
131
|
+
exaaiagnt/tools/smart_fuzzer.py,sha256=FQ3RQ8IYFRTEAsKzEtfephCpHbdmDRMm068AsEQ2B-k,12286
|
|
126
132
|
exaaiagnt/tools/terminal/__init__.py,sha256=xvflcrbLQ31o_K3cWFsIhTm7gxY5JF0nVnhOIadwFV0,80
|
|
127
133
|
exaaiagnt/tools/terminal/terminal_actions.py,sha256=5z3OTF0YwZL0n_CVsx1yLmbSx7oUQg-xD0Wv8IXsIlw,892
|
|
128
134
|
exaaiagnt/tools/terminal/terminal_actions_schema.xml,sha256=L7dzjvKNZpJA0qDGp1gCBuwXiY4mtjOq7T2tNDmUPA4,7257
|
|
@@ -131,12 +137,14 @@ exaaiagnt/tools/terminal/terminal_session.py,sha256=ExC2s0xyS6m157ENkWqAHzPp1Pv9
|
|
|
131
137
|
exaaiagnt/tools/thinking/__init__.py,sha256=-v4fG4fyFkqsTSWspDtCT6IRlyRM8zeUwEM-kscaxDE,58
|
|
132
138
|
exaaiagnt/tools/thinking/thinking_actions.py,sha256=Ynw1gBN4Z8iXGll0v9kObhkjQzc8-dEcHTWKeyFutAw,568
|
|
133
139
|
exaaiagnt/tools/thinking/thinking_actions_schema.xml,sha256=otD4dOhQx4uyudLnjA_HIP6EmUS5NvKG4l3CVFrg8go,2756
|
|
140
|
+
exaaiagnt/tools/tool_prompts.py,sha256=eQL7B8H8mo6d6mvtN_X9rmSfjwgz9Cuzfg7C7WH6TnU,5751
|
|
141
|
+
exaaiagnt/tools/vuln_validator.py,sha256=jgfPOVogjfMSVaorlzXTUA56N1RgYrpF1QshKeHQBn8,13944
|
|
134
142
|
exaaiagnt/tools/waf_bypass.py,sha256=71oPWnDHjn2EHi6I1SluZCKfqfXkA5j61oIkL5kNoSw,12047
|
|
135
143
|
exaaiagnt/tools/web_search/__init__.py,sha256=m5PCHXqeNVraLRLNIbh54Z2N4Y_75d-ftqwyq3dbCd0,70
|
|
136
144
|
exaaiagnt/tools/web_search/web_search_actions.py,sha256=jmlN2uIq8lRbhRnyaMQkC-44jhpfkLQZ_byYNlNNlOY,3111
|
|
137
145
|
exaaiagnt/tools/web_search/web_search_actions_schema.xml,sha256=Ihc3Gv4LaPI_MzBbwZOt3y4pwg9xmtl8KfPNvFihEP4,4805
|
|
138
|
-
exaai_agent-2.0.
|
|
139
|
-
exaai_agent-2.0.
|
|
140
|
-
exaai_agent-2.0.
|
|
141
|
-
exaai_agent-2.0.
|
|
142
|
-
exaai_agent-2.0.
|
|
146
|
+
exaai_agent-2.0.8.dist-info/METADATA,sha256=DQPnhLMYY4bBopzTdAK7M_jMZS1jcZZrIyx-k8pCqSQ,11959
|
|
147
|
+
exaai_agent-2.0.8.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
|
|
148
|
+
exaai_agent-2.0.8.dist-info/entry_points.txt,sha256=iLSTRDSjN8Zyc2Wo6WXmr4MtyEWkdqtZ1j_Hx73MiUs,137
|
|
149
|
+
exaai_agent-2.0.8.dist-info/licenses/LICENSE,sha256=RV6IGl0sWdfbbtJmjPr1w_qwGyGt2jv02PXsAzN_kNs,11460
|
|
150
|
+
exaai_agent-2.0.8.dist-info/RECORD,,
|
exaaiagnt/interface/main.py
CHANGED
|
@@ -240,69 +240,77 @@ async def warm_up_llm() -> None:
|
|
|
240
240
|
sys.exit(1)
|
|
241
241
|
|
|
242
242
|
|
|
243
|
+
def get_version() -> str:
|
|
244
|
+
"""Get the current ExaAi version."""
|
|
245
|
+
return "2.1.0"
|
|
246
|
+
|
|
247
|
+
|
|
243
248
|
def parse_arguments() -> argparse.Namespace:
|
|
244
249
|
parser = argparse.ArgumentParser(
|
|
245
|
-
description="
|
|
250
|
+
description="ExaAi - Advanced AI Cybersecurity Penetration Testing Tool",
|
|
246
251
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
247
252
|
epilog="""
|
|
248
253
|
Examples:
|
|
254
|
+
# Launch TUI interface
|
|
255
|
+
exaai tui
|
|
256
|
+
|
|
257
|
+
# Show version
|
|
258
|
+
exaai --version
|
|
259
|
+
|
|
249
260
|
# Web application penetration test
|
|
250
|
-
|
|
261
|
+
exaai --target https://example.com
|
|
262
|
+
exaai -t https://example.com
|
|
251
263
|
|
|
252
264
|
# GitHub repository analysis
|
|
253
|
-
|
|
254
|
-
exaaiagnt --target git@github.com:user/repo.git
|
|
265
|
+
exaai --target https://github.com/user/repo
|
|
255
266
|
|
|
256
267
|
# Local code analysis
|
|
257
|
-
|
|
268
|
+
exaai --target ./my-project
|
|
258
269
|
|
|
259
270
|
# Domain penetration test
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
# IP address penetration test
|
|
263
|
-
exaaiagnt --target 192.168.1.42
|
|
271
|
+
exaai --target example.com
|
|
264
272
|
|
|
265
|
-
# Multiple targets
|
|
266
|
-
|
|
267
|
-
exaaiagnt --target ./my-project --target https://staging.example.com --target https://prod.example.com
|
|
273
|
+
# Multiple targets
|
|
274
|
+
exaai -t https://github.com/user/repo -t https://example.com
|
|
268
275
|
|
|
269
|
-
# Custom instructions
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
# Custom instructions (from file)
|
|
273
|
-
exaaiagnt --target example.com --instruction ./instructions.txt
|
|
274
|
-
exaaiagnt --target https://app.com --instruction /path/to/detailed_instructions.md
|
|
276
|
+
# Custom instructions
|
|
277
|
+
exaai -t example.com -i "Focus on authentication vulnerabilities"
|
|
278
|
+
exaai -t example.com --instruction ./instructions.txt
|
|
275
279
|
""",
|
|
276
280
|
)
|
|
277
281
|
|
|
282
|
+
# Add version flag
|
|
283
|
+
parser.add_argument(
|
|
284
|
+
"-V",
|
|
285
|
+
"--version",
|
|
286
|
+
action="version",
|
|
287
|
+
version=f"ExaAi v{get_version()}",
|
|
288
|
+
)
|
|
289
|
+
|
|
290
|
+
# Main arguments (same as before, just renamed command)
|
|
278
291
|
parser.add_argument(
|
|
279
292
|
"-t",
|
|
280
293
|
"--target",
|
|
281
294
|
type=str,
|
|
282
|
-
required=True,
|
|
283
295
|
action="append",
|
|
284
296
|
help="Target to test (URL, repository, local directory path, domain name, or IP address). "
|
|
285
297
|
"Can be specified multiple times for multi-target scans.",
|
|
286
298
|
)
|
|
287
299
|
parser.add_argument(
|
|
300
|
+
"-i",
|
|
288
301
|
"--instruction",
|
|
289
302
|
type=str,
|
|
290
303
|
help="Custom instructions for the penetration test. This can be "
|
|
291
304
|
"specific vulnerability types to focus on (e.g., 'Focus on IDOR and XSS'), "
|
|
292
305
|
"testing approaches (e.g., 'Perform thorough authentication testing'), "
|
|
293
|
-
"test credentials (e.g., 'Use the following credentials
|
|
294
|
-
"
|
|
295
|
-
"or areas of interest (e.g., 'Check login API endpoint for security issues'). "
|
|
296
|
-
"You can also provide a path to a file containing detailed instructions "
|
|
297
|
-
"(e.g., '--instruction ./instructions.txt').",
|
|
306
|
+
"or test credentials (e.g., 'Use the following credentials: admin:password123'). "
|
|
307
|
+
"You can also provide a path to a file containing detailed instructions.",
|
|
298
308
|
)
|
|
299
|
-
|
|
300
309
|
parser.add_argument(
|
|
301
310
|
"--run-name",
|
|
302
311
|
type=str,
|
|
303
312
|
help="Custom name for this penetration test run",
|
|
304
313
|
)
|
|
305
|
-
|
|
306
314
|
parser.add_argument(
|
|
307
315
|
"-n",
|
|
308
316
|
"--non-interactive",
|
|
@@ -312,37 +320,56 @@ Examples:
|
|
|
312
320
|
"Default is interactive mode with TUI."
|
|
313
321
|
),
|
|
314
322
|
)
|
|
323
|
+
|
|
324
|
+
# TUI subcommand (optional - for launching TUI without target)
|
|
325
|
+
subparsers = parser.add_subparsers(dest="command")
|
|
326
|
+
subparsers.add_parser("tui", help="Launch the interactive TUI interface without a target")
|
|
315
327
|
|
|
316
328
|
args = parser.parse_args()
|
|
317
329
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
330
|
+
# Handle TUI command - launch directly without target
|
|
331
|
+
if args.command == "tui":
|
|
332
|
+
args.target = None
|
|
333
|
+
args.targets_info = []
|
|
334
|
+
args.instruction = None
|
|
335
|
+
args.run_name = None
|
|
336
|
+
args.non_interactive = False
|
|
337
|
+
args.local_sources = []
|
|
338
|
+
return args
|
|
339
|
+
|
|
340
|
+
# Handle scan command or legacy direct target
|
|
341
|
+
if args.command == "scan" or args.target:
|
|
342
|
+
if not args.target:
|
|
343
|
+
parser.error("--target is required for scanning. Use 'exaai tui' to launch TUI without a target.")
|
|
344
|
+
|
|
345
|
+
if args.instruction:
|
|
346
|
+
instruction_path = Path(args.instruction)
|
|
347
|
+
if instruction_path.exists() and instruction_path.is_file():
|
|
348
|
+
try:
|
|
349
|
+
with instruction_path.open(encoding="utf-8") as f:
|
|
350
|
+
args.instruction = f.read().strip()
|
|
351
|
+
if not args.instruction:
|
|
352
|
+
parser.error(f"Instruction file '{instruction_path}' is empty")
|
|
353
|
+
except Exception as e: # noqa: BLE001
|
|
354
|
+
parser.error(f"Failed to read instruction file '{instruction_path}': {e}")
|
|
355
|
+
|
|
356
|
+
args.targets_info = []
|
|
357
|
+
for target in args.target:
|
|
321
358
|
try:
|
|
322
|
-
|
|
323
|
-
args.instruction = f.read().strip()
|
|
324
|
-
if not args.instruction:
|
|
325
|
-
parser.error(f"Instruction file '{instruction_path}' is empty")
|
|
326
|
-
except Exception as e: # noqa: BLE001
|
|
327
|
-
parser.error(f"Failed to read instruction file '{instruction_path}': {e}")
|
|
328
|
-
|
|
329
|
-
args.targets_info = []
|
|
330
|
-
for target in args.target:
|
|
331
|
-
try:
|
|
332
|
-
target_type, target_dict = infer_target_type(target)
|
|
359
|
+
target_type, target_dict = infer_target_type(target)
|
|
333
360
|
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
361
|
+
if target_type == "local_code":
|
|
362
|
+
display_target = target_dict.get("target_path", target)
|
|
363
|
+
else:
|
|
364
|
+
display_target = target
|
|
338
365
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
366
|
+
args.targets_info.append(
|
|
367
|
+
{"type": target_type, "details": target_dict, "original": display_target}
|
|
368
|
+
)
|
|
369
|
+
except ValueError:
|
|
370
|
+
parser.error(f"Invalid target '{target}'")
|
|
344
371
|
|
|
345
|
-
|
|
372
|
+
assign_workspace_subdirs(args.targets_info)
|
|
346
373
|
|
|
347
374
|
return args
|
|
348
375
|
|
|
@@ -464,6 +491,21 @@ def main() -> None:
|
|
|
464
491
|
|
|
465
492
|
args = parse_arguments()
|
|
466
493
|
|
|
494
|
+
# Handle TUI-only mode (no target needed)
|
|
495
|
+
if args.command == "tui" or (not args.target and not args.command):
|
|
496
|
+
check_docker_installed()
|
|
497
|
+
pull_docker_image()
|
|
498
|
+
validate_environment()
|
|
499
|
+
asyncio.run(warm_up_llm())
|
|
500
|
+
|
|
501
|
+
# Launch TUI directly without scanning
|
|
502
|
+
args.run_name = "interactive_session"
|
|
503
|
+
args.targets_info = []
|
|
504
|
+
args.local_sources = []
|
|
505
|
+
asyncio.run(run_tui(args))
|
|
506
|
+
return
|
|
507
|
+
|
|
508
|
+
# Handle scan mode (target required)
|
|
467
509
|
check_docker_installed()
|
|
468
510
|
pull_docker_image()
|
|
469
511
|
|
exaaiagnt/interface/tui.py
CHANGED
|
@@ -80,7 +80,7 @@ class SplashScreen(Static): # type: ignore[misc]
|
|
|
80
80
|
NEON_ORANGE = "#ff8800"
|
|
81
81
|
SOFT_WHITE = "#e0e0e0"
|
|
82
82
|
|
|
83
|
-
#
|
|
83
|
+
# Enhanced ASCII Logo - ExaAi v2.0.4
|
|
84
84
|
BANNER = r"""
|
|
85
85
|
███████╗██╗ ██╗ █████╗ █████╗ ██╗
|
|
86
86
|
██╔════╝╚██╗██╔╝██╔══██╗ ██╔══██╗██║
|
|
@@ -97,7 +97,6 @@ class SplashScreen(Static): # type: ignore[misc]
|
|
|
97
97
|
▒███ ░░ █ ░▒██ ▀█▄ ▒██ ▀█▄ ▒██▒
|
|
98
98
|
▒▓█ ▄ ░ █ █ ▒ ░██▄▄▄▄██ ░██▄▄▄▄██ ░██░
|
|
99
99
|
░▒████▒▒██▒ ▒██▒ ▓█ ▓██▒ ▓█ ▓██▒░██░
|
|
100
|
-
░░ ▒░ ░▒▒ ░ ░▓ ░ ▒▒ ▓▒█░ ▒▒ ▓▒█░░▓
|
|
101
100
|
"""
|
|
102
101
|
|
|
103
102
|
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
|
@@ -105,7 +104,7 @@ class SplashScreen(Static): # type: ignore[misc]
|
|
|
105
104
|
self._animation_step = 0
|
|
106
105
|
self._animation_timer: Timer | None = None
|
|
107
106
|
self._panel_static: Static | None = None
|
|
108
|
-
self._version = "2.0
|
|
107
|
+
self._version = "2.1.0"
|
|
109
108
|
|
|
110
109
|
def compose(self) -> ComposeResult:
|
|
111
110
|
self._version = get_package_version()
|
|
@@ -145,6 +144,7 @@ class SplashScreen(Static): # type: ignore[misc]
|
|
|
145
144
|
Align.center(self._build_version_text()),
|
|
146
145
|
Align.center(self._build_tagline_text()),
|
|
147
146
|
Align.center(self._build_features_text()),
|
|
147
|
+
Align.center(self._build_new_features_text()),
|
|
148
148
|
Align.center(Text(" ")),
|
|
149
149
|
Align.center(start_line.copy()),
|
|
150
150
|
)
|
|
@@ -176,8 +176,22 @@ class SplashScreen(Static): # type: ignore[misc]
|
|
|
176
176
|
def _build_version_text(self) -> Text:
|
|
177
177
|
text = Text("v", style=Style(color=self.SOFT_WHITE, dim=True))
|
|
178
178
|
text.append(f"{self._version}", style=Style(color=self.NEON_GREEN, bold=True))
|
|
179
|
+
text.append(" ", style=Style(color=self.SOFT_WHITE))
|
|
180
|
+
text.append("• Adaptive LLM • Smart Fuzzing • WAF Bypass", style=Style(color=self.SOFT_WHITE, dim=True))
|
|
179
181
|
return text
|
|
180
182
|
|
|
183
|
+
def _build_new_features_text(self) -> Text:
|
|
184
|
+
"""Build new features highlight for v2.0.4."""
|
|
185
|
+
text = Text("🔥 ", style=Style(color=self.NEON_ORANGE))
|
|
186
|
+
text.append("NEW: ", style=Style(color=self.NEON_ORANGE, bold=True))
|
|
187
|
+
text.append("React2Shell", style=Style(color=self.NEON_PINK))
|
|
188
|
+
text.append(" • ", style=Style(color=self.SOFT_WHITE, dim=True))
|
|
189
|
+
text.append("Cloud Security", style=Style(color=self.NEON_CYAN))
|
|
190
|
+
text.append(" • ", style=Style(color=self.SOFT_WHITE, dim=True))
|
|
191
|
+
text.append("Auto-Discovery", style=Style(color=self.NEON_GREEN))
|
|
192
|
+
return text
|
|
193
|
+
|
|
194
|
+
|
|
181
195
|
def _build_tagline_text(self) -> Text:
|
|
182
196
|
text = Text("🔒 ", style=Style(color=self.NEON_ORANGE))
|
|
183
197
|
text.append("Advanced AI-Powered Cybersecurity Agent", style=Style(color=self.SOFT_WHITE, italic=True))
|
exaaiagnt/llm/__init__.py
CHANGED
|
@@ -14,6 +14,13 @@ from .output_processor import (
|
|
|
14
14
|
OutputConfig,
|
|
15
15
|
process_tool_output,
|
|
16
16
|
)
|
|
17
|
+
from .llm_traffic_controller import (
|
|
18
|
+
get_traffic_controller,
|
|
19
|
+
AdaptiveLLMController,
|
|
20
|
+
RequestPriority,
|
|
21
|
+
reset_traffic_controller,
|
|
22
|
+
with_traffic_control,
|
|
23
|
+
)
|
|
17
24
|
|
|
18
25
|
|
|
19
26
|
__all__ = [
|
|
@@ -29,6 +36,12 @@ __all__ = [
|
|
|
29
36
|
"OutputProcessor",
|
|
30
37
|
"OutputConfig",
|
|
31
38
|
"process_tool_output",
|
|
39
|
+
# Traffic Controller
|
|
40
|
+
"get_traffic_controller",
|
|
41
|
+
"AdaptiveLLMController",
|
|
42
|
+
"RequestPriority",
|
|
43
|
+
"reset_traffic_controller",
|
|
44
|
+
"with_traffic_control",
|
|
32
45
|
]
|
|
33
46
|
|
|
34
47
|
litellm._logging._disable_debugging()
|
exaaiagnt/llm/llm.py
CHANGED
|
@@ -17,7 +17,7 @@ from litellm.utils import supports_prompt_caching
|
|
|
17
17
|
|
|
18
18
|
from exaaiagnt.llm.config import LLMConfig
|
|
19
19
|
from exaaiagnt.llm.memory_compressor import MemoryCompressor
|
|
20
|
-
from exaaiagnt.llm.
|
|
20
|
+
from exaaiagnt.llm.llm_traffic_controller import get_traffic_controller, RequestPriority
|
|
21
21
|
from exaaiagnt.llm.utils import _truncate_to_first_function, parse_tool_invocations
|
|
22
22
|
from exaaiagnt.prompts import load_prompt_modules
|
|
23
23
|
from exaaiagnt.tools import get_tools_prompt
|
|
@@ -423,8 +423,19 @@ class LLM:
|
|
|
423
423
|
else:
|
|
424
424
|
completion_args["reasoning_effort"] = "high"
|
|
425
425
|
|
|
426
|
-
|
|
427
|
-
|
|
426
|
+
# Use Adaptive Traffic Controller for intelligent rate limiting
|
|
427
|
+
controller = get_traffic_controller()
|
|
428
|
+
agent_id = self.agent_id or "unknown_agent"
|
|
429
|
+
|
|
430
|
+
async def do_request():
|
|
431
|
+
from litellm import completion
|
|
432
|
+
return completion(**completion_args, stream=False)
|
|
433
|
+
|
|
434
|
+
response = await controller.queue_request(
|
|
435
|
+
do_request,
|
|
436
|
+
agent_id=agent_id,
|
|
437
|
+
priority=RequestPriority.NORMAL
|
|
438
|
+
)
|
|
428
439
|
|
|
429
440
|
self._total_stats.requests += 1
|
|
430
441
|
self._last_request_stats = RequestStats(requests=1)
|