briar-pentest 0.3.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 (57) hide show
  1. briar_pentest-0.3.0/LICENSE +18 -0
  2. briar_pentest-0.3.0/PKG-INFO +178 -0
  3. briar_pentest-0.3.0/README.md +138 -0
  4. briar_pentest-0.3.0/briar/__init__.py +2 -0
  5. briar_pentest-0.3.0/briar/__main__.py +3 -0
  6. briar_pentest-0.3.0/briar/agents/__init__.py +25 -0
  7. briar_pentest-0.3.0/briar/agents/analyzer.py +81 -0
  8. briar_pentest-0.3.0/briar/agents/api.py +94 -0
  9. briar_pentest-0.3.0/briar/agents/auth.py +141 -0
  10. briar_pentest-0.3.0/briar/agents/authz.py +95 -0
  11. briar_pentest-0.3.0/briar/agents/csrf.py +76 -0
  12. briar_pentest-0.3.0/briar/agents/injection.py +120 -0
  13. briar_pentest-0.3.0/briar/agents/rce.py +109 -0
  14. briar_pentest-0.3.0/briar/agents/recon.py +104 -0
  15. briar_pentest-0.3.0/briar/agents/secrets.py +37 -0
  16. briar_pentest-0.3.0/briar/agents/ssrf.py +99 -0
  17. briar_pentest-0.3.0/briar/agents/traversal.py +91 -0
  18. briar_pentest-0.3.0/briar/agents/upload.py +85 -0
  19. briar_pentest-0.3.0/briar/agents/xss.py +96 -0
  20. briar_pentest-0.3.0/briar/charts/__init__.py +0 -0
  21. briar_pentest-0.3.0/briar/charts/generator.py +55 -0
  22. briar_pentest-0.3.0/briar/cli.py +377 -0
  23. briar_pentest-0.3.0/briar/config.py +35 -0
  24. briar_pentest-0.3.0/briar/core/__init__.py +2 -0
  25. briar_pentest-0.3.0/briar/core/http.py +115 -0
  26. briar_pentest-0.3.0/briar/core/validator.py +78 -0
  27. briar_pentest-0.3.0/briar/core/workspace.py +72 -0
  28. briar_pentest-0.3.0/briar/exploits/__init__.py +2 -0
  29. briar_pentest-0.3.0/briar/exploits/browser.py +86 -0
  30. briar_pentest-0.3.0/briar/providers/__init__.py +24 -0
  31. briar_pentest-0.3.0/briar/providers/anthropic.py +25 -0
  32. briar_pentest-0.3.0/briar/providers/custom.py +13 -0
  33. briar_pentest-0.3.0/briar/providers/deepseek.py +22 -0
  34. briar_pentest-0.3.0/briar/providers/google.py +15 -0
  35. briar_pentest-0.3.0/briar/providers/groq.py +24 -0
  36. briar_pentest-0.3.0/briar/providers/mistral.py +24 -0
  37. briar_pentest-0.3.0/briar/providers/ollama.py +42 -0
  38. briar_pentest-0.3.0/briar/providers/openai.py +24 -0
  39. briar_pentest-0.3.0/briar/providers/openrouter.py +15 -0
  40. briar_pentest-0.3.0/briar/providers/together.py +12 -0
  41. briar_pentest-0.3.0/briar/providers/xai.py +15 -0
  42. briar_pentest-0.3.0/briar/reports/__init__.py +0 -0
  43. briar_pentest-0.3.0/briar/reports/generator.py +164 -0
  44. briar_pentest-0.3.0/briar/reports/obsidian.py +88 -0
  45. briar_pentest-0.3.0/briar/slides/__init__.py +0 -0
  46. briar_pentest-0.3.0/briar/slides/pptx_gen.py +150 -0
  47. briar_pentest-0.3.0/briar/web.py +148 -0
  48. briar_pentest-0.3.0/briar/worker.py +69 -0
  49. briar_pentest-0.3.0/briar_pentest.egg-info/PKG-INFO +178 -0
  50. briar_pentest-0.3.0/briar_pentest.egg-info/SOURCES.txt +55 -0
  51. briar_pentest-0.3.0/briar_pentest.egg-info/dependency_links.txt +1 -0
  52. briar_pentest-0.3.0/briar_pentest.egg-info/entry_points.txt +2 -0
  53. briar_pentest-0.3.0/briar_pentest.egg-info/requires.txt +13 -0
  54. briar_pentest-0.3.0/briar_pentest.egg-info/top_level.txt +1 -0
  55. briar_pentest-0.3.0/pyproject.toml +48 -0
  56. briar_pentest-0.3.0/setup.cfg +4 -0
  57. briar_pentest-0.3.0/setup.py +27 -0
@@ -0,0 +1,18 @@
1
+ GNU AFFERO GENERAL PUBLIC LICENSE
2
+ Version 3, 19 November 2007
3
+
4
+ Copyright (C) 2026 Stiimy (Keran JOBLON)
5
+
6
+ Briar — Autonomous AI Pentester
7
+ This program is free software: you can redistribute it and/or modify
8
+ it under the terms of the GNU Affero General Public License as published
9
+ by the Free Software Foundation, either version 3 of the License, or
10
+ (at your option) any later version.
11
+
12
+ This program is distributed in the hope that it will be useful,
13
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ GNU Affero General Public License for more details.
16
+
17
+ You should have received a copy of the GNU Affero General Public License
18
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
@@ -0,0 +1,178 @@
1
+ Metadata-Version: 2.4
2
+ Name: briar-pentest
3
+ Version: 0.3.0
4
+ Summary: Autonomous AI Pentester — find vulnerabilities before hackers do
5
+ Home-page: https://github.com/Stiimy/briar
6
+ Author: Stiimy
7
+ Author-email: Stiimy <keran.joblon@outlook.fr>
8
+ License: AGPL-3.0
9
+ Project-URL: Homepage, https://github.com/Stiimy/briar
10
+ Project-URL: Repository, https://github.com/Stiimy/briar
11
+ Project-URL: Issues, https://github.com/Stiimy/briar/issues
12
+ Keywords: security,pentest,vulnerability,owasp,ai,ollama
13
+ Classifier: Development Status :: 3 - Alpha
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Intended Audience :: Information Technology
16
+ Classifier: License :: OSI Approved :: GNU Affero General Public License v3
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.14
20
+ Classifier: Topic :: Security
21
+ Requires-Python: >=3.10
22
+ Description-Content-Type: text/markdown
23
+ License-File: LICENSE
24
+ Requires-Dist: requests>=2.31
25
+ Requires-Dist: click>=8.1
26
+ Requires-Dist: rich>=13.7
27
+ Requires-Dist: fastapi>=0.115
28
+ Requires-Dist: uvicorn>=0.30
29
+ Provides-Extra: full
30
+ Requires-Dist: python-docx>=1.1; extra == "full"
31
+ Requires-Dist: openpyxl>=3.1; extra == "full"
32
+ Requires-Dist: python-pptx>=0.6; extra == "full"
33
+ Requires-Dist: matplotlib>=3.8; extra == "full"
34
+ Requires-Dist: plotly>=5.18; extra == "full"
35
+ Requires-Dist: selenium>=4.15; extra == "full"
36
+ Dynamic: author
37
+ Dynamic: home-page
38
+ Dynamic: license-file
39
+ Dynamic: requires-python
40
+
41
+ # 🥀 Briar — Autonomous AI Pentester
42
+
43
+ > *Find vulnerabilities before hackers do. Free. Open Source. No Docker required.*
44
+
45
+ [![Python](https://img.shields.io/badge/Python-3.10+-blue?logo=python)](https://python.org)
46
+ [![License](https://img.shields.io/badge/License-AGPL--3.0-green)](LICENSE)
47
+ [![Ollama](https://img.shields.io/badge/Ollama-Free-%23cba6f7)](https://ollama.ai)
48
+ [![Version](https://img.shields.io/badge/version-0.3.0-purple)](https://github.com/Stiimy/briar/releases)
49
+
50
+ Briar is an autonomous AI pentester. It scans web applications, injects real payloads, validates exploits, and generates professional security reports — powered by **11 AI providers** including a completely free local mode via Ollama.
51
+
52
+ ---
53
+
54
+ ## Quick Start
55
+
56
+ ```bash
57
+ pip install briar
58
+ briar setup # Pick your AI provider (Ollama = free)
59
+ briar scan -u https://target.com --quick
60
+ briar serve # Web dashboard → http://localhost:8233
61
+ ```
62
+
63
+ ---
64
+
65
+ ## Features
66
+
67
+ | Category | Details |
68
+ |----------|---------|
69
+ | 🤖 **11 AI Providers** | Ollama (free, local), OpenAI, Claude, DeepSeek, Groq, Mistral, xAI/Grok, Google/Gemini, OpenRouter, Together, Custom |
70
+ | 🛡️ **10 OWASP Agents** | Recon, Injection, XSS, SSRF, Auth, AuthZ, CSRF, Upload, Traversal, RCE, API, Secrets |
71
+ | 🎯 **No Exploit, No Report** | Every High/Critical finding is replayed and confirmed before reporting |
72
+ | 🔌 **Blackbox + Whitebox** | Works with just a URL. Add `-r /path/to/source` for code-aware analysis |
73
+ | 📡 **Port Scanning** | 24 common ports scanned during recon phase |
74
+ | 📄 **Reports** | Markdown, Word (.docx), Excel (.xlsx), Obsidian vault + canvas mindmap |
75
+ | 🎨 **Slides** | PowerPoint (.pptx) + HTML presentation |
76
+ | 📊 **Charts** | Severity pie chart, agent bar chart |
77
+ | 🌐 **Dashboard** | Web UI on port 8233 (FastAPI) with scan launcher |
78
+ | 💾 **Workspaces** | Resume interrupted scans, checkpoint after every agent |
79
+ | ⚙️ **YAML Config** | Authenticated scanning, login flows, custom rules (avoid/focus paths) |
80
+ | 🐳 **No Docker Required** | Native Python. pip install and go. Docker optional for server mode. |
81
+
82
+ ---
83
+
84
+ ## Usage
85
+
86
+ ```bash
87
+ # Quick scan (4 agents)
88
+ briar scan -u https://target.com --quick
89
+
90
+ # Standard scan (8 agents)
91
+ briar scan -u https://target.com
92
+
93
+ # Deep scan (all 12 agents + browser exploits)
94
+ briar scan -u https://target.com --deep
95
+
96
+ # With source code (whitebox mode)
97
+ briar scan -u https://target.com -r /path/to/repo
98
+
99
+ # With DeepSeek provider (set env var first)
100
+ export DEEPSEEK_API_KEY=sk-xxx
101
+ briar scan -u https://target.com -p deepseek
102
+
103
+ # With config file (authenticated scanning)
104
+ briar scan -c juice-shop.yaml
105
+
106
+ # Resume an interrupted scan
107
+ briar scan --resume workspace-name
108
+
109
+ # List saved workspaces
110
+ briar workspaces
111
+ ```
112
+
113
+ ---
114
+
115
+ ## Config File (YAML)
116
+
117
+ ```yaml
118
+ # juice-shop.yaml — example for OWASP Juice Shop
119
+ target:
120
+ url: http://localhost:3000
121
+
122
+ provider: deepseek
123
+ mode: deep
124
+ output: ./reports/juice-shop
125
+
126
+ authentication:
127
+ login_url: /rest/user/login
128
+ method: json
129
+ credentials:
130
+ email: test@test.com
131
+ password: test123
132
+ success_condition: "status=200"
133
+
134
+ rules:
135
+ avoid:
136
+ - path: /logout
137
+ - path: /score-board
138
+ focus:
139
+ - path: /api
140
+ - path: /rest
141
+ ```
142
+
143
+ ---
144
+
145
+ ## Architecture
146
+
147
+ ```
148
+ briar/
149
+ ├── agents/ 12 security agents (recon, injection, xss, ssrf,
150
+ │ auth, authz, csrf, upload, traversal, rce, api, secrets)
151
+ ├── providers/ 11 AI backends (Ollama, OpenAI, Claude, DeepSeek, ...)
152
+ ├── core/ HTTP client, exploit validator, workspace manager
153
+ ├── exploits/ Selenium browser exploits + CLI payload injector
154
+ ├── reports/ Markdown, Word, Excel, Obsidian generators
155
+ ├── charts/ Pie chart + bar chart (matplotlib)
156
+ ├── slides/ PowerPoint + HTML slide decks
157
+ ├── cli.py Main CLI (click + rich)
158
+ ├── web.py FastAPI dashboard (port 8233)
159
+ ├── worker.py Background job queue worker
160
+ └── config.py YAML config loader
161
+ ```
162
+
163
+ ---
164
+
165
+ ## Install from Source
166
+
167
+ ```bash
168
+ git clone https://github.com/Stiimy/briar
169
+ cd briar
170
+ pip install -e .
171
+ briar setup
172
+ ```
173
+
174
+ ---
175
+
176
+ > *"No exploit, no report."* — Briar validates every High/Critical finding before you see it.
177
+
178
+ **License:** AGPL-3.0 — Free. Forever.
@@ -0,0 +1,138 @@
1
+ # 🥀 Briar — Autonomous AI Pentester
2
+
3
+ > *Find vulnerabilities before hackers do. Free. Open Source. No Docker required.*
4
+
5
+ [![Python](https://img.shields.io/badge/Python-3.10+-blue?logo=python)](https://python.org)
6
+ [![License](https://img.shields.io/badge/License-AGPL--3.0-green)](LICENSE)
7
+ [![Ollama](https://img.shields.io/badge/Ollama-Free-%23cba6f7)](https://ollama.ai)
8
+ [![Version](https://img.shields.io/badge/version-0.3.0-purple)](https://github.com/Stiimy/briar/releases)
9
+
10
+ Briar is an autonomous AI pentester. It scans web applications, injects real payloads, validates exploits, and generates professional security reports — powered by **11 AI providers** including a completely free local mode via Ollama.
11
+
12
+ ---
13
+
14
+ ## Quick Start
15
+
16
+ ```bash
17
+ pip install briar
18
+ briar setup # Pick your AI provider (Ollama = free)
19
+ briar scan -u https://target.com --quick
20
+ briar serve # Web dashboard → http://localhost:8233
21
+ ```
22
+
23
+ ---
24
+
25
+ ## Features
26
+
27
+ | Category | Details |
28
+ |----------|---------|
29
+ | 🤖 **11 AI Providers** | Ollama (free, local), OpenAI, Claude, DeepSeek, Groq, Mistral, xAI/Grok, Google/Gemini, OpenRouter, Together, Custom |
30
+ | 🛡️ **10 OWASP Agents** | Recon, Injection, XSS, SSRF, Auth, AuthZ, CSRF, Upload, Traversal, RCE, API, Secrets |
31
+ | 🎯 **No Exploit, No Report** | Every High/Critical finding is replayed and confirmed before reporting |
32
+ | 🔌 **Blackbox + Whitebox** | Works with just a URL. Add `-r /path/to/source` for code-aware analysis |
33
+ | 📡 **Port Scanning** | 24 common ports scanned during recon phase |
34
+ | 📄 **Reports** | Markdown, Word (.docx), Excel (.xlsx), Obsidian vault + canvas mindmap |
35
+ | 🎨 **Slides** | PowerPoint (.pptx) + HTML presentation |
36
+ | 📊 **Charts** | Severity pie chart, agent bar chart |
37
+ | 🌐 **Dashboard** | Web UI on port 8233 (FastAPI) with scan launcher |
38
+ | 💾 **Workspaces** | Resume interrupted scans, checkpoint after every agent |
39
+ | ⚙️ **YAML Config** | Authenticated scanning, login flows, custom rules (avoid/focus paths) |
40
+ | 🐳 **No Docker Required** | Native Python. pip install and go. Docker optional for server mode. |
41
+
42
+ ---
43
+
44
+ ## Usage
45
+
46
+ ```bash
47
+ # Quick scan (4 agents)
48
+ briar scan -u https://target.com --quick
49
+
50
+ # Standard scan (8 agents)
51
+ briar scan -u https://target.com
52
+
53
+ # Deep scan (all 12 agents + browser exploits)
54
+ briar scan -u https://target.com --deep
55
+
56
+ # With source code (whitebox mode)
57
+ briar scan -u https://target.com -r /path/to/repo
58
+
59
+ # With DeepSeek provider (set env var first)
60
+ export DEEPSEEK_API_KEY=sk-xxx
61
+ briar scan -u https://target.com -p deepseek
62
+
63
+ # With config file (authenticated scanning)
64
+ briar scan -c juice-shop.yaml
65
+
66
+ # Resume an interrupted scan
67
+ briar scan --resume workspace-name
68
+
69
+ # List saved workspaces
70
+ briar workspaces
71
+ ```
72
+
73
+ ---
74
+
75
+ ## Config File (YAML)
76
+
77
+ ```yaml
78
+ # juice-shop.yaml — example for OWASP Juice Shop
79
+ target:
80
+ url: http://localhost:3000
81
+
82
+ provider: deepseek
83
+ mode: deep
84
+ output: ./reports/juice-shop
85
+
86
+ authentication:
87
+ login_url: /rest/user/login
88
+ method: json
89
+ credentials:
90
+ email: test@test.com
91
+ password: test123
92
+ success_condition: "status=200"
93
+
94
+ rules:
95
+ avoid:
96
+ - path: /logout
97
+ - path: /score-board
98
+ focus:
99
+ - path: /api
100
+ - path: /rest
101
+ ```
102
+
103
+ ---
104
+
105
+ ## Architecture
106
+
107
+ ```
108
+ briar/
109
+ ├── agents/ 12 security agents (recon, injection, xss, ssrf,
110
+ │ auth, authz, csrf, upload, traversal, rce, api, secrets)
111
+ ├── providers/ 11 AI backends (Ollama, OpenAI, Claude, DeepSeek, ...)
112
+ ├── core/ HTTP client, exploit validator, workspace manager
113
+ ├── exploits/ Selenium browser exploits + CLI payload injector
114
+ ├── reports/ Markdown, Word, Excel, Obsidian generators
115
+ ├── charts/ Pie chart + bar chart (matplotlib)
116
+ ├── slides/ PowerPoint + HTML slide decks
117
+ ├── cli.py Main CLI (click + rich)
118
+ ├── web.py FastAPI dashboard (port 8233)
119
+ ├── worker.py Background job queue worker
120
+ └── config.py YAML config loader
121
+ ```
122
+
123
+ ---
124
+
125
+ ## Install from Source
126
+
127
+ ```bash
128
+ git clone https://github.com/Stiimy/briar
129
+ cd briar
130
+ pip install -e .
131
+ briar setup
132
+ ```
133
+
134
+ ---
135
+
136
+ > *"No exploit, no report."* — Briar validates every High/Critical finding before you see it.
137
+
138
+ **License:** AGPL-3.0 — Free. Forever.
@@ -0,0 +1,2 @@
1
+ """Briar — Autonomous AI Pentester 🥀"""
2
+ __version__ = "0.1.0"
@@ -0,0 +1,3 @@
1
+ """Allow running as: python -m briar"""
2
+ from briar.cli import cli
3
+ cli()
@@ -0,0 +1,25 @@
1
+ from .analyzer import SecurityAnalyzer
2
+ from .recon import ReconAgent
3
+ from .injection import InjectionAgent
4
+ from .xss import XSSAgent
5
+ from .ssrf import SSRFAgent
6
+ from .auth import AuthAgent
7
+ from .authz import AuthZAgent
8
+ from .csrf import CSRFAgent
9
+ from .upload import UploadAgent
10
+ from .traversal import TraversalAgent
11
+ from .rce import RCEAgent
12
+ from .api import APIAgent
13
+ from .secrets import SecretsAgent
14
+
15
+ AGENTS = {
16
+ "recon": ReconAgent, "injection": InjectionAgent, "xss": XSSAgent, "ssrf": SSRFAgent,
17
+ "auth": AuthAgent, "authz": AuthZAgent, "csrf": CSRFAgent,
18
+ "upload": UploadAgent, "traversal": TraversalAgent,
19
+ "rce": RCEAgent, "api": APIAgent, "secrets": SecretsAgent,
20
+ }
21
+
22
+ def run_agent(name, provider="ollama", **kwargs):
23
+ if name not in AGENTS:
24
+ return {"error": f"Agent '{name}' not found. Available: {list(AGENTS.keys())}"}
25
+ return AGENTS[name](provider).scan(**kwargs)
@@ -0,0 +1,81 @@
1
+ """Briar AI Analysis Engine — the brain of the pentest 🧠"""
2
+ from typing import Optional
3
+ from briar.providers import get_provider
4
+
5
+ SECURITY_ANALYST_PROMPT = """You are an elite security researcher performing a penetration test.
6
+ Analyze the target and identify vulnerabilities. For each finding, provide:
7
+
8
+ 1. VULNERABILITY TYPE (OWASP category)
9
+ 2. SEVERITY (Critical/High/Medium/Low)
10
+ 3. CVSS SCORE (0.0-10.0)
11
+ 4. ENDPOINT / LOCATION
12
+ 5. DESCRIPTION (what the vuln is)
13
+ 6. EXPLOIT STEPS (how to reproduce)
14
+ 7. IMPACT (what an attacker can do)
15
+ 8. REMEDIATION (how to fix)
16
+
17
+ Be specific. Include exact URLs, parameters, payloads. Think like an attacker."""
18
+
19
+ class SecurityAnalyzer:
20
+ """Core AI security analysis engine"""
21
+
22
+ def __init__(self, provider: str = "ollama", model: Optional[str] = None):
23
+ self.provider = get_provider(provider, model=model) if model else get_provider(provider)
24
+
25
+ def analyze_endpoint(self, url: str, method: str = "GET", source_hint: str = "") -> dict:
26
+ """Analyze a single endpoint for vulnerabilities"""
27
+ prompt = f"""Analyze this endpoint for security vulnerabilities:
28
+
29
+ URL: {url}
30
+ Method: {method}
31
+ {f'Source code context: {source_hint}' if source_hint else ''}
32
+
33
+ List ALL potential vulnerabilities you find. For each one, provide the full details as specified."""
34
+
35
+ messages = [{"role": "user", "content": prompt}]
36
+ response = self.provider.chat(messages, system=SECURITY_ANALYST_PROMPT, max_tokens=4096)
37
+ return {"url": url, "analysis": response, "raw": response}
38
+
39
+ def analyze_code(self, code: str, filepath: str = "") -> dict:
40
+ """Analyze source code for vulnerabilities"""
41
+ prompt = f"""Analyze this source code for security vulnerabilities:
42
+
43
+ File: {filepath}
44
+
45
+ ```
46
+ {code[:8000]}
47
+ ```
48
+
49
+ Find: SQL injection, XSS, SSRF, command injection, path traversal, auth bypass,
50
+ deserialization, hardcoded secrets, unsafe eval, etc.
51
+
52
+ For each finding, specify the exact line and how to exploit it."""
53
+
54
+ messages = [{"role": "user", "content": prompt}]
55
+ response = self.provider.chat(messages, system=SECURITY_ANALYST_PROMPT, max_tokens=4096)
56
+ return {"file": filepath, "analysis": response}
57
+
58
+ def generate_report(self, findings: list, target: str) -> str:
59
+ """Generate a comprehensive security report"""
60
+ findings_text = "\n\n---\n\n".join([
61
+ f"## Finding {i+1}\n{f.get('analysis', f.get('raw',''))}"
62
+ for i, f in enumerate(findings)
63
+ ])
64
+
65
+ prompt = f"""Generate a PROFESSIONAL penetration test report for {target}.
66
+
67
+ Findings:
68
+ {findings_text[:6000]}
69
+
70
+ Create a structured report with:
71
+ 1. Executive Summary
72
+ 2. Methodology
73
+ 3. Findings (detailed per vulnerability)
74
+ 4. Risk Matrix
75
+ 5. Recommendations
76
+ 6. Conclusion
77
+
78
+ Format in Markdown. Be professional and precise."""
79
+
80
+ messages = [{"role": "user", "content": prompt}]
81
+ return self.provider.chat(messages, system="You are a senior security consultant writing a pentest report.", max_tokens=8192)
@@ -0,0 +1,94 @@
1
+ """API Security Agent — GraphQL, REST, OpenAPI detection 📡"""
2
+ from briar.agents.analyzer import SecurityAnalyzer
3
+ from briar.core.http import HTTPClient
4
+
5
+ class APIAgent:
6
+ """Detects API endpoints and tests for common misconfigurations"""
7
+
8
+ API_PATHS = [
9
+ ("/graphql", "GraphQL endpoint"),
10
+ ("/graphiql", "GraphQL IDE"),
11
+ ("/api", "REST API"),
12
+ ("/api/v1", "REST API v1"),
13
+ ("/api/v2", "REST API v2"),
14
+ ("/swagger.json", "Swagger/OpenAPI spec"),
15
+ ("/openapi.json", "OpenAPI 3.0 spec"),
16
+ ("/api-docs", "API docs"),
17
+ ("/docs", "API docs"),
18
+ ("/.well-known/openid-configuration", "OIDC config"),
19
+ ("/wp-json/", "WordPress REST API"),
20
+ ("/v1/", "API v1 prefix"),
21
+ ]
22
+
23
+ GRAPHQL_INTROSPECTION = {
24
+ "query": "{ __schema { types { name fields { name } } } }"
25
+ }
26
+
27
+ def __init__(self, provider="ollama"):
28
+ self.analyzer = SecurityAnalyzer(provider)
29
+ self.http = HTTPClient(timeout=10)
30
+ self.name = "API"
31
+
32
+ def scan(self, url: str, **kwargs) -> dict:
33
+ """Detect API endpoints and test security"""
34
+ findings = []
35
+ discovered = []
36
+
37
+ # Check common API paths
38
+ for path, desc in self.API_PATHS:
39
+ try:
40
+ full_url = url.rstrip("/") + path
41
+ resp = self.http.get(full_url)
42
+ if resp.status_code in [200, 301, 302, 401, 403]:
43
+ discovered.append({"path": path, "desc": desc, "status": resp.status_code, "length": len(resp.text)})
44
+
45
+ # GraphQL introspection test
46
+ if "graphql" in path.lower() and resp.status_code == 200:
47
+ try:
48
+ intro_resp = self.http.post(full_url, json=self.GRAPHQL_INTROSPECTION)
49
+ if "__schema" in intro_resp.text or "types" in intro_resp.text:
50
+ findings.append({
51
+ "type": "GraphQL Introspection Enabled",
52
+ "severity": "Medium",
53
+ "endpoint": full_url,
54
+ "detail": "Schema fully exposed via introspection query",
55
+ })
56
+ except:
57
+ pass
58
+
59
+ # Rate limiting check
60
+ if "api" in path.lower() and resp.status_code == 200:
61
+ for _ in range(5):
62
+ try:
63
+ r = self.http.get(full_url)
64
+ if r.status_code == 429:
65
+ findings.append({
66
+ "type": "Rate Limiting Active",
67
+ "severity": "Info",
68
+ "endpoint": full_url,
69
+ })
70
+ break
71
+ except:
72
+ pass
73
+
74
+ except:
75
+ pass
76
+
77
+ analysis = f"API scan complete for {url}\n\n"
78
+ analysis += f"Endpoints discovered: {len(discovered)}\n\n"
79
+ for d in discovered:
80
+ analysis += f"- `{d['path']}` — {d['desc']} (HTTP {d['status']})\n"
81
+
82
+ if findings:
83
+ analysis += f"\n**{len(findings)} API security issues found:**\n\n"
84
+ for f in findings:
85
+ analysis += f"- **{f['type']}**: {f.get('endpoint','?')} — {f.get('detail','')}\n"
86
+ analysis += "\n---\n\nLLM analysis of real API findings:\n"
87
+
88
+ result = self.analyzer.analyze_endpoint(url, "GET", analysis)
89
+ result["real_findings"] = findings
90
+ result["discovered_endpoints"] = [d["path"] for d in discovered]
91
+ result["agent"] = self.name
92
+ result["type"] = "API Security"
93
+ result["severity"] = "Medium" if findings else "Info"
94
+ return result
@@ -0,0 +1,141 @@
1
+ """Authentication Attack Agent — JWT, brute force, token analysis 🔐"""
2
+ import re
3
+ from briar.agents.analyzer import SecurityAnalyzer
4
+ from briar.core.http import HTTPClient
5
+
6
+ class AuthAgent:
7
+ """Discovers authentication vulnerabilities"""
8
+
9
+ WEAK_CREDS = [
10
+ ("admin", "admin"), ("admin", "password"), ("admin", "123456"),
11
+ ("test", "test"), ("guest", "guest"), ("user", "user"),
12
+ ("root", "root"), ("admin", ""), ("administrator", "administrator"),
13
+ ]
14
+
15
+ def __init__(self, provider="ollama"):
16
+ self.analyzer = SecurityAnalyzer(provider)
17
+ self.http = HTTPClient(timeout=10)
18
+ self.name = "Authentication"
19
+
20
+ def _detect_login_form(self, html: str) -> list:
21
+ """Find login forms by looking for password inputs"""
22
+ login_forms = []
23
+ forms = self.http.extract_forms(html)
24
+ for form in forms:
25
+ if any("pass" in i.lower() for i in form["inputs"]):
26
+ login_forms.append(form)
27
+ return login_forms
28
+
29
+ def _test_jwt(self, jwt_str: str) -> list:
30
+ """Test JWT for common vulnerabilities"""
31
+ import base64, json
32
+ findings = []
33
+ try:
34
+ parts = jwt_str.split(".")
35
+ if len(parts) != 3:
36
+ return findings
37
+
38
+ # Decode without verification
39
+ for i, part in enumerate(parts[:2]):
40
+ # Add padding
41
+ padded = part + "=" * (4 - len(part) % 4)
42
+ try:
43
+ decoded = base64.urlsafe_b64decode(padded)
44
+ findings.append({
45
+ "type": "JWT decoded without verification",
46
+ "severity": "Low",
47
+ "part": "header" if i == 0 else "payload",
48
+ "content": decoded.decode("utf-8", errors="replace")[:200],
49
+ })
50
+ except:
51
+ pass
52
+
53
+ # Check alg:none
54
+ header = parts[0]
55
+ padded = header + "=" * (4 - len(header) % 4)
56
+ decoded_header = base64.urlsafe_b64decode(padded).decode("utf-8", errors="replace")
57
+ if '"none"' in decoded_header.lower() or '"None"' in decoded_header:
58
+ findings.append({
59
+ "type": "JWT alg:none accepted",
60
+ "severity": "Critical",
61
+ "detail": "Algorithm allows 'none' — signature bypass possible",
62
+ })
63
+
64
+ except:
65
+ pass
66
+ return findings
67
+
68
+ def scan(self, url: str, auth_type: str = "unknown", **kwargs) -> dict:
69
+ """Scan for authentication vulnerabilities"""
70
+ findings = []
71
+
72
+ try:
73
+ resp = self.http.get(url)
74
+ html = resp.text
75
+
76
+ # Check for JWT in cookies/headers
77
+ jwt_pattern = r'[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+'
78
+ for header_val in resp.headers.values():
79
+ for match in re.finditer(jwt_pattern, header_val):
80
+ jwt_findings = self._test_jwt(match.group(0))
81
+ findings.extend(jwt_findings)
82
+ for match in re.finditer(jwt_pattern, resp.text[:2000]):
83
+ jwt_findings = self._test_jwt(match.group(0))
84
+ findings.extend(jwt_findings)
85
+
86
+ # Find login forms and test weak creds
87
+ login_forms = self._detect_login_form(html)
88
+ for form in login_forms:
89
+ form_url = form["action"] or url
90
+ for username, password in self.WEAK_CREDS[:5]:
91
+ try:
92
+ data = {}
93
+ for inp in form["inputs"]:
94
+ if "user" in inp.lower() or "email" in inp.lower() or "login" in inp.lower():
95
+ data[inp] = username
96
+ elif "pass" in inp.lower():
97
+ data[inp] = password
98
+ else:
99
+ data[inp] = username
100
+
101
+ login_resp = self.http.post(form_url, data=data, allow_redirects=False)
102
+ if login_resp.status_code in [302, 200]:
103
+ # Check if login succeeded (no error message, redirect to dashboard)
104
+ text_lower = login_resp.text.lower()
105
+ if not any(e in text_lower for e in ["invalid", "incorrect", "wrong", "error", "failed"]):
106
+ findings.append({
107
+ "type": "Weak credentials",
108
+ "severity": "Critical",
109
+ "endpoint": form_url,
110
+ "credentials": f"{username}:{password}",
111
+ "response_status": login_resp.status_code,
112
+ })
113
+ break
114
+ except:
115
+ pass
116
+
117
+ if findings:
118
+ break # Found vuln, stop brute force
119
+
120
+ if not login_forms:
121
+ findings.append({"type": "No login form found", "severity": "Info"})
122
+
123
+ except Exception as e:
124
+ findings.append({"type": "Auth scan error", "error": str(e)})
125
+
126
+ analysis = f"Authentication scan complete for {url}\n\n"
127
+ if findings:
128
+ analysis += f"**{len(findings)} authentication issues found:**\n\n"
129
+ for f in findings:
130
+ if "credential" in str(f.get("type", "")).lower():
131
+ analysis += f"- **Weak credentials**: `{f.get('credentials','?')}` → {f.get('endpoint','?')}\n"
132
+ elif "jwt" in str(f.get("type", "")).lower():
133
+ analysis += f"- **{f['type']}**: {f.get('detail', f.get('content',''))}\n"
134
+ analysis += "\n---\n\nLLM analysis of auth findings:\n"
135
+
136
+ result = self.analyzer.analyze_endpoint(url, "GET/POST", analysis)
137
+ result["real_findings"] = findings
138
+ result["agent"] = self.name
139
+ result["type"] = "Authentication"
140
+ result["severity"] = "Critical" if any(f["severity"] == "Critical" for f in findings) else ("High" if findings else "Info")
141
+ return result