@pensar/apex 0.0.114 → 0.0.115-canary.03ce611f
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.
- package/README.md +7 -55
- package/build/agent-g4kgeqr1.js +17 -0
- package/build/agent-pq1r5cb0.js +227 -0
- package/build/{auth-g7qfrmqn.js → auth-02092efh.js} +4 -4
- package/build/{authentication-h92927qz.js → authentication-pjvxd8fn.js} +29 -20
- package/build/blackboxAgent-5dyd2w7c.js +18 -0
- package/build/{blackboxPentest-34sfsskq.js → blackboxPentest-003c4jv6.js} +19 -14
- package/build/{cli-tj25jvz6.js → cli-0rr5jtdr.js} +14 -3
- package/build/cli-3y0dgy56.js +48 -0
- package/build/{cli-s1dd4n9x.js → cli-5adb0fz5.js} +7 -3
- package/build/{cli-phajnhzs.js → cli-76xp25as.js} +3046 -564
- package/build/cli-93gea200.js +645 -0
- package/build/{cli-23qtjsce.js → cli-9ye88x6c.js} +1 -1
- package/build/{cli-mx8pfb29.js → cli-b14ndse6.js} +60 -51
- package/build/cli-fw5r7pfj.js +19 -0
- package/build/{cli-z1s5njxn.js → cli-jh1w0wee.js} +819 -28
- package/build/{cli-xj88naps.js → cli-jxr5nn2z.js} +1 -1
- package/build/cli-n3m0s3xq.js +524 -0
- package/build/cli-n7s94289.js +7637 -0
- package/build/cli-r8cerdwk.js +1423 -0
- package/build/{cli-27bnjky6.js → cli-sqgjfaet.js} +1 -1
- package/build/{cli-9hp2khjx.js → cli-t5q926sn.js} +22 -8
- package/build/{cli-vnydvy0r.js → cli-vak6e1jc.js} +2 -415
- package/build/{cli-49cd9yfk.js → cli-wszshs5e.js} +1 -1
- package/build/cli-xft5a1h6.js +1172 -0
- package/build/cli-yz80qkzn.js +60 -0
- package/build/{cli-zz9wwkqh.js → cli-z7v6c0rf.js} +1 -1
- package/build/cli.js +240 -37
- package/build/{fixes-d3mb7zr3.js → fixes-p4sy6a0z.js} +4 -4
- package/build/{index-rd11fk7h.js → index-h2hj2hj9.js} +14 -14
- package/build/{index-gm4427rc.js → index-hpz98sjn.js} +2 -2
- package/build/{index-mefzr77w.js → index-mvzk4cbk.js} +21 -15
- package/build/{index-zyrn6ava.js → index-pcj15xce.js} +6104 -7027
- package/build/{issues-gsfpfmwx.js → issues-2jqfpjh0.js} +4 -4
- package/build/{logs-mgbbrr4b.js → logs-kya1zw8m.js} +4 -4
- package/build/{multipart-parser-r38qdp5v.js → multipart-parser-6zd16497.js} +2 -2
- package/build/pentest-61p7d9kz.js +28 -0
- package/build/{pentests-ey20zzez.js → pentests-jf19pbb4.js} +4 -4
- package/build/{projects-1z5x1bxj.js → projects-z9hscjp7.js} +4 -4
- package/build/targetedPentest-6v9n8baj.js +34 -0
- package/build/threatModel-jyjj4nzj.js +63 -0
- package/build/{uninstall-b26ez5zf.js → uninstall-81ms31rt.js} +1 -1
- package/build/{utils-9fhmzzzh.js → utils-zvr7bcyw.js} +8 -4
- package/package.json +7 -3
- package/build/agent-jr0kf32x.js +0 -206
- package/build/agent-q0mhy72n.js +0 -16
- package/build/blackboxAgent-bgqz7n74.js +0 -17
- package/build/cli-0r7qwt2h.js +0 -307
- package/build/cli-0tpx8khk.js +0 -1358
- package/build/cli-5d6cs4dq.js +0 -53
- package/build/cli-xtccf5qk.js +0 -1498
- package/build/pentest-1cntf5yv.js +0 -25
- package/build/targetedPentest-yatr7brn.js +0 -32
package/README.md
CHANGED
|
@@ -22,36 +22,6 @@ Want to run from the cloud or integrate it with your CI/CD? See <a href="https:/
|
|
|
22
22
|
<img src="screenshot.png" alt="Pensar Apex Screenshot" width="800">
|
|
23
23
|
</p> -->
|
|
24
24
|
|
|
25
|
-
## What is Apex?
|
|
26
|
-
|
|
27
|
-
Apex is an autonomous penetration testing agent that runs directly in your terminal.
|
|
28
|
-
|
|
29
|
-
It doesn't wrap existing scanners or chain shell scripts. Apex deploys a **swarm of specialized AI agents** — each with domain expertise in reconnaissance, authentication analysis, exploitation, and code review — that coordinate a real penetration test against your application. Every finding comes with CVSS 4.0 scoring, CWE classification, evidence, and a validated proof-of-concept.
|
|
30
|
-
|
|
31
|
-
The result is a pentest that runs like `npm test` — but thinks like a red team.
|
|
32
|
-
|
|
33
|
-
## Why Apex?
|
|
34
|
-
|
|
35
|
-
Traditional scanners execute signatures. Apex executes a methodology.
|
|
36
|
-
|
|
37
|
-
- **Swarm architecture** - Specialized agents run in parallel across your attack surface, the same way a real red team divides and conquers. Up to 10 concurrent agents, each scoped to a specific objective.
|
|
38
|
-
- **Structured, auditable output** - Every vulnerability is automatically scored (CVSS 4.0), classified (CWE), and documented with evidence and remediation steps. No raw tool dumps.
|
|
39
|
-
- **Real exploitation, not guesswork** - Apex writes, runs, and validates proof-of-concept scripts. If the PoC doesn't succeed, it pivots to a different technique.
|
|
40
|
-
- **Blackbox and whitebox** - Test a live target with no source access, or analyze your codebase to map endpoints and test them against a running instance.
|
|
41
|
-
- **30+ built-in tools** - Browser automation, shell execution, HTTP requests, file analysis, web search for CVE lookups, authenticated crawling, and more. Optional Kali Linux container adds 25+ offensive security tools (nmap, sqlmap, hydra, hashcat, gobuster, and others).
|
|
42
|
-
|
|
43
|
-
## Two Modes
|
|
44
|
-
|
|
45
|
-
### `/pentest` — Autonomous
|
|
46
|
-
|
|
47
|
-
Fire and forget. Apex runs a full engagement end-to-end: attack surface discovery, parallel swarm testing, and a structured report with findings in Markdown and JSON. No security expertise required.
|
|
48
|
-
|
|
49
|
-
### `/operator` — Interactive
|
|
50
|
-
|
|
51
|
-
Full control. Steer the agent step by step, approve each action, chain exploits manually, and dig deep into specific targets. Every tool is available. The approval gate holds until you say go.
|
|
52
|
-
|
|
53
|
-
Start with `/pentest` to get coverage, then reopen the session in `/operator` to investigate specific findings — all context carries over.
|
|
54
|
-
|
|
55
25
|
## Use Cases
|
|
56
26
|
|
|
57
27
|
### Developers
|
|
@@ -69,30 +39,12 @@ Start with `/pentest` to get coverage, then reopen the session in `/operator` to
|
|
|
69
39
|
|
|
70
40
|
## Installation
|
|
71
41
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
#### Homebrew
|
|
79
|
-
|
|
80
|
-
```bash
|
|
81
|
-
brew tap pensarai/tap
|
|
82
|
-
brew install apex
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
#### npm
|
|
86
|
-
|
|
87
|
-
```bash
|
|
88
|
-
npm install -g @pensar/apex
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
#### Windows (PowerShell)
|
|
92
|
-
|
|
93
|
-
```powershell
|
|
94
|
-
irm https://www.pensarai.com/apex.ps1 | iex
|
|
95
|
-
```
|
|
42
|
+
| Method | Command |
|
|
43
|
+
| ------------------------------- | ---------------------------------------------------- |
|
|
44
|
+
| **Quick Install** (macOS/Linux) | `curl -fsSL https://pensarai.com/install.sh \| bash` |
|
|
45
|
+
| **Homebrew** | `brew tap pensarai/tap && brew install apex` |
|
|
46
|
+
| **npm** | `npm install -g @pensar/apex` |
|
|
47
|
+
| **Windows** (PowerShell) | `irm https://www.pensarai.com/apex.ps1 \| iex` |
|
|
96
48
|
|
|
97
49
|
## Usage
|
|
98
50
|
|
|
@@ -123,5 +75,5 @@ pensar
|
|
|
123
75
|
|
|
124
76
|
### ⚠️ Responsible Use
|
|
125
77
|
|
|
126
|
-
This repository contains tools for **authorized security testing** only.
|
|
78
|
+
This repository contains tools for **authorized security testing** only.
|
|
127
79
|
Before use, please read and agree to the [Responsible Use Disclosure](./RESPONSIBLE_USE.md).
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CodeAgent
|
|
3
|
+
} from "./cli-t5q926sn.js";
|
|
4
|
+
import"./cli-76xp25as.js";
|
|
5
|
+
import"./cli-vak6e1jc.js";
|
|
6
|
+
import"./cli-3y0dgy56.js";
|
|
7
|
+
import"./cli-jh1w0wee.js";
|
|
8
|
+
import"./cli-z7v6c0rf.js";
|
|
9
|
+
import"./cli-sqgjfaet.js";
|
|
10
|
+
import"./cli-jxr5nn2z.js";
|
|
11
|
+
import"./cli-5adb0fz5.js";
|
|
12
|
+
import"./cli-r8cerdwk.js";
|
|
13
|
+
import"./cli-7ckctq7a.js";
|
|
14
|
+
import"./cli-8rxa073f.js";
|
|
15
|
+
export {
|
|
16
|
+
CodeAgent
|
|
17
|
+
};
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import {
|
|
2
|
+
WhiteboxAttackSurfaceResultSchema
|
|
3
|
+
} from "./cli-0rr5jtdr.js";
|
|
4
|
+
import {
|
|
5
|
+
OffensiveSecurityAgent
|
|
6
|
+
} from "./cli-76xp25as.js";
|
|
7
|
+
import"./cli-vak6e1jc.js";
|
|
8
|
+
import"./cli-3y0dgy56.js";
|
|
9
|
+
import {
|
|
10
|
+
hasToolCall,
|
|
11
|
+
tool
|
|
12
|
+
} from "./cli-jh1w0wee.js";
|
|
13
|
+
import"./cli-z7v6c0rf.js";
|
|
14
|
+
import"./cli-sqgjfaet.js";
|
|
15
|
+
import"./cli-jxr5nn2z.js";
|
|
16
|
+
import"./cli-5adb0fz5.js";
|
|
17
|
+
import"./cli-r8cerdwk.js";
|
|
18
|
+
import"./cli-7ckctq7a.js";
|
|
19
|
+
import"./cli-8rxa073f.js";
|
|
20
|
+
|
|
21
|
+
// src/core/agents/specialized/whiteboxAttackSurface/prompts.ts
|
|
22
|
+
var WHITEBOX_ATTACK_SURFACE_SYSTEM_PROMPT = `You are an expert source-code analyst and orchestrator. Your mission is to comprehensively map the attack surface of a codebase by analyzing its source code directly.
|
|
23
|
+
|
|
24
|
+
You operate completely autonomously. Do not ask for permission or wait for user input.
|
|
25
|
+
|
|
26
|
+
# Your Goal
|
|
27
|
+
|
|
28
|
+
Given a codebase path, you must:
|
|
29
|
+
1. Identify the repository structure (monorepo vs single app, package manager, etc.)
|
|
30
|
+
2. Discover every application/service defined in the repo
|
|
31
|
+
3. For each app, enumerate ALL web pages and ALL API endpoints defined in the source code
|
|
32
|
+
4. For each endpoint, generate specific pentest objectives
|
|
33
|
+
|
|
34
|
+
# Tools at Your Disposal
|
|
35
|
+
|
|
36
|
+
## list_files
|
|
37
|
+
List directories to understand project structure. Start here.
|
|
38
|
+
|
|
39
|
+
## read_file
|
|
40
|
+
Read config files, entry points, route definitions, etc.
|
|
41
|
+
|
|
42
|
+
## grep
|
|
43
|
+
Your primary search tool. Use it to find route definitions, middleware, controllers, etc.
|
|
44
|
+
|
|
45
|
+
## document_app
|
|
46
|
+
**Use this to document each application/service you identify.** Each call persists a JSON record to the session's apps directory. Document:
|
|
47
|
+
- Each application/service you identify (appType: "web_application" or "api")
|
|
48
|
+
- Notable subdomains hosting distinct services (appType: "subdomain")
|
|
49
|
+
- Cloud resources like S3 buckets, cloud storage, CDN origins (appType: "cloud_resource" or "storage")
|
|
50
|
+
- For S3 buckets: set \`domain\` to the **canonical virtual-hosted-style** endpoint (e.g. "https://bucket-name.s3.amazonaws.com") and use appType "storage". Do NOT use path-style URLs (e.g. "https://s3.amazonaws.com/bucket-name").
|
|
51
|
+
- For other cloud resources: set \`domain\` to the primary/canonical resource endpoint and use appType "cloud_resource"
|
|
52
|
+
- If known domains are provided, set the \`domain\` field to associate the app with the correct domain
|
|
53
|
+
|
|
54
|
+
## document_endpoint
|
|
55
|
+
**This is your primary output tool for endpoints.** Each call persists a JSON record to the session's endpoints directory, organized by app. Document:
|
|
56
|
+
- Individual API endpoints and web pages
|
|
57
|
+
|
|
58
|
+
**CRITICAL — endpoint documentation rules:**
|
|
59
|
+
- **ONE endpoint per unique route path.** Do NOT create separate entries for different HTTP methods on the same path. If \`/api/users\` supports GET, POST, and DELETE, that is ONE entry with \`method: ["GET", "POST", "DELETE"]\`.
|
|
60
|
+
- **Use \`method: "PAGE"\`** for web pages and views.
|
|
61
|
+
- **Always set \`appName\`** to group endpoints under the correct application.
|
|
62
|
+
- **Always set \`routePath\`** to the HTTP route (e.g., \`/api/users\`). This is the URL path a client requests — NOT a source-file path.
|
|
63
|
+
- **Always set \`file\`** to the source-code file (e.g., \`src/routes/users.ts\`). This is NOT the HTTP route.
|
|
64
|
+
- **Always set \`handler\`** to the function name, and \`authRequired\` to indicate auth requirements.
|
|
65
|
+
|
|
66
|
+
Call these tools throughout your analysis as you discover apps and endpoints — don't wait until the end.
|
|
67
|
+
|
|
68
|
+
## spawn_coding_agent
|
|
69
|
+
**This is your key tool for scaling out analysis.** Spawn coding sub-agents to analyze individual apps in parallel for higher fidelity. Each sub-agent has full filesystem access (read_file, list_files, grep, execute_command) and the document_app/document_endpoint tools.
|
|
70
|
+
|
|
71
|
+
## submit_results
|
|
72
|
+
Call this LAST with your complete structured results. This ends your run.
|
|
73
|
+
|
|
74
|
+
# Methodology
|
|
75
|
+
|
|
76
|
+
## Phase 1: REPO IDENTIFICATION (do this yourself — it's fast)
|
|
77
|
+
1. List the root directory
|
|
78
|
+
2. Read the top-level config files to determine:
|
|
79
|
+
- Package manager (package.json → npm/yarn/pnpm, requirements.txt → pip, Cargo.toml → cargo, go.mod → go, etc.)
|
|
80
|
+
- Repo structure (workspaces field in package.json → monorepo, multiple service dirs → multi-package, etc.)
|
|
81
|
+
3. Identify all apps/services — look for:
|
|
82
|
+
- Monorepo workspace packages with their own entry points
|
|
83
|
+
- Separate service directories with their own configs
|
|
84
|
+
- A single app at the root
|
|
85
|
+
4. Discover cloud resources and external infrastructure referenced in the code:
|
|
86
|
+
- S3 buckets, GCS buckets, Azure Blob Storage (search for bucket names, s3://, storage URLs)
|
|
87
|
+
- CDN distributions (CloudFront, Cloudflare)
|
|
88
|
+
- Infrastructure-as-code definitions (Terraform, CloudFormation, CDK, SST, Pulumi, serverless.yml)
|
|
89
|
+
- Document each as an app with appType "cloud_resource" or "storage" and set the \`domain\` to the **canonical** resource endpoint
|
|
90
|
+
- **S3 canonical URL:** Always use virtual-hosted-style "https://bucket-name.s3.amazonaws.com" (or with region: "https://bucket-name.s3.us-east-1.amazonaws.com"). Never use path-style "https://s3.amazonaws.com/bucket-name".
|
|
91
|
+
- **Do NOT document alternative URL formats** as separate endpoints — only document the canonical/primary URL and any distinct functional paths under it
|
|
92
|
+
|
|
93
|
+
## Phase 2: APP ANALYSIS (delegate to coding agents)
|
|
94
|
+
For each app you identified, spawn a coding agent with a detailed objective. The objective should instruct the agent to:
|
|
95
|
+
|
|
96
|
+
1. **Identify the framework** — read the app's config/entry point to determine the web framework
|
|
97
|
+
2. **Document the application** — call \`document_app\` with the app name, type, and framework
|
|
98
|
+
3. **Find ALL web pages** — search for page/view/route definitions and document each with \`document_endpoint\` using \`method: "PAGE"\`
|
|
99
|
+
4. **Find ALL API endpoints** — search for route/endpoint definitions and document each unique path with \`document_endpoint\`, listing ALL HTTP methods in \`method\`
|
|
100
|
+
5. **For each endpoint, include** in the document_endpoint call:
|
|
101
|
+
- HTTP route in \`routePath\` (e.g., \`/api/users\`) — this is the URL path, NOT a file path
|
|
102
|
+
- ALL HTTP methods in \`method\` (consolidated — one entry per path)
|
|
103
|
+
- Handler function in \`handler\`
|
|
104
|
+
- Source-code file in \`file\` (e.g., \`src/routes/users.ts\`) — this is NOT the route
|
|
105
|
+
- Line number in \`line\`
|
|
106
|
+
- Auth requirement in \`authRequired\`
|
|
107
|
+
|
|
108
|
+
**IMPORTANT:** Tell each coding agent to set \`appName\` on every \`document_endpoint\` call so endpoints are organized by application.
|
|
109
|
+
|
|
110
|
+
## Phase 3: COLLECT AND SUBMIT (do this yourself)
|
|
111
|
+
1. Parse the output from all coding agents
|
|
112
|
+
2. Assemble the complete structured result
|
|
113
|
+
3. Call \`submit_results\` with the full data
|
|
114
|
+
|
|
115
|
+
# Guidelines
|
|
116
|
+
- Be thorough — every endpoint matters. Don't skip files or directories.
|
|
117
|
+
- Delegate aggressively — spawn coding agents for each app to get high-fidelity results.
|
|
118
|
+
- Give coding agents VERY detailed objectives — they work best with specific instructions about what to search for and how to report it.
|
|
119
|
+
- Don't duplicate work — let the coding agents do the deep file-by-file analysis.
|
|
120
|
+
- When in doubt about repo structure, read more config files before deciding.
|
|
121
|
+
`;
|
|
122
|
+
|
|
123
|
+
// src/core/agents/specialized/whiteboxAttackSurface/agent.ts
|
|
124
|
+
class WhiteboxAttackSurfaceAgent extends OffensiveSecurityAgent {
|
|
125
|
+
constructor(opts) {
|
|
126
|
+
const {
|
|
127
|
+
model,
|
|
128
|
+
codebasePath,
|
|
129
|
+
session,
|
|
130
|
+
authConfig,
|
|
131
|
+
onStepFinish,
|
|
132
|
+
abortSignal,
|
|
133
|
+
eventBus,
|
|
134
|
+
subagentId,
|
|
135
|
+
attackSurfaceRegistry,
|
|
136
|
+
domains,
|
|
137
|
+
enableThinking
|
|
138
|
+
} = opts;
|
|
139
|
+
let capturedResult = null;
|
|
140
|
+
const submitResultsTool = tool({
|
|
141
|
+
description: `Submit the final whitebox attack surface analysis results.
|
|
142
|
+
|
|
143
|
+
Call this ONCE at the end with your complete structured findings.
|
|
144
|
+
This ends the agent run — make sure all data is included.`,
|
|
145
|
+
inputSchema: WhiteboxAttackSurfaceResultSchema,
|
|
146
|
+
execute: async (results) => {
|
|
147
|
+
capturedResult = results;
|
|
148
|
+
return { success: true, message: "Results submitted." };
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
super({
|
|
152
|
+
system: WHITEBOX_ATTACK_SURFACE_SYSTEM_PROMPT,
|
|
153
|
+
prompt: buildPrompt(codebasePath, domains, session.config?.prompt),
|
|
154
|
+
model,
|
|
155
|
+
session,
|
|
156
|
+
authConfig,
|
|
157
|
+
onStepFinish,
|
|
158
|
+
abortSignal,
|
|
159
|
+
eventBus,
|
|
160
|
+
subagentId,
|
|
161
|
+
attackSurfaceRegistry,
|
|
162
|
+
enableThinking,
|
|
163
|
+
activeTools: [
|
|
164
|
+
"read_file",
|
|
165
|
+
"list_files",
|
|
166
|
+
"grep",
|
|
167
|
+
"document_app",
|
|
168
|
+
"document_endpoint",
|
|
169
|
+
"spawn_coding_agent",
|
|
170
|
+
"submit_results"
|
|
171
|
+
],
|
|
172
|
+
extraTools: {
|
|
173
|
+
submit_results: submitResultsTool
|
|
174
|
+
},
|
|
175
|
+
stopWhen: hasToolCall("submit_results"),
|
|
176
|
+
resolveResult: () => {
|
|
177
|
+
if (capturedResult) {
|
|
178
|
+
return capturedResult;
|
|
179
|
+
}
|
|
180
|
+
return {
|
|
181
|
+
repoType: "unknown",
|
|
182
|
+
packageManager: "unknown",
|
|
183
|
+
apps: [],
|
|
184
|
+
summary: {
|
|
185
|
+
totalApps: 0,
|
|
186
|
+
totalPages: 0,
|
|
187
|
+
totalApiEndpoints: 0,
|
|
188
|
+
totalPentestObjectives: 0
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
function buildPrompt(codebasePath, domains, operatorPrompt) {
|
|
196
|
+
const domainSection = domains?.length ? `
|
|
197
|
+
## Known Domains
|
|
198
|
+
The following domains are associated with this project. When documenting apps, set the \`domain\` field on \`document_app\` if you can determine which domain serves the app:
|
|
199
|
+
${domains.map((d) => `- ${d}`).join(`
|
|
200
|
+
`)}
|
|
201
|
+
` : "";
|
|
202
|
+
const operatorGuidanceBlock = operatorPrompt ? `
|
|
203
|
+
## Operator Guidance
|
|
204
|
+
${operatorPrompt}
|
|
205
|
+
` : "";
|
|
206
|
+
return `# Whitebox Attack Surface Analysis
|
|
207
|
+
|
|
208
|
+
## Codebase
|
|
209
|
+
- **Path:** ${codebasePath}
|
|
210
|
+
${domainSection}${operatorGuidanceBlock}
|
|
211
|
+
## Task
|
|
212
|
+
Analyze this codebase and produce a complete attack surface map:
|
|
213
|
+
1. Identify the repo type and package manager
|
|
214
|
+
2. Discover all apps/services
|
|
215
|
+
3. Discover cloud resources and external infrastructure referenced in the code (S3 buckets, cloud storage, CDN origins, etc.) — document these as apps with the appropriate type
|
|
216
|
+
4. For each app, find all web pages and API endpoints
|
|
217
|
+
5. For each endpoint, generate pentest objectives
|
|
218
|
+
|
|
219
|
+
Use \`spawn_coding_agent\` to delegate app-level analysis for higher fidelity.
|
|
220
|
+
|
|
221
|
+
When finished, call \`submit_results\` with the complete structured output.
|
|
222
|
+
|
|
223
|
+
Begin now.`;
|
|
224
|
+
}
|
|
225
|
+
export {
|
|
226
|
+
WhiteboxAttackSurfaceAgent
|
|
227
|
+
};
|
|
@@ -8,14 +8,14 @@ import {
|
|
|
8
8
|
pollWorkOSToken,
|
|
9
9
|
selectWorkspace,
|
|
10
10
|
startDeviceFlow
|
|
11
|
-
} from "./cli-
|
|
11
|
+
} from "./cli-z7v6c0rf.js";
|
|
12
12
|
import {
|
|
13
13
|
config,
|
|
14
14
|
getPensarApiUrl,
|
|
15
15
|
getPensarConsoleUrl
|
|
16
|
-
} from "./cli-
|
|
17
|
-
import"./cli-
|
|
18
|
-
import"./cli-
|
|
16
|
+
} from "./cli-sqgjfaet.js";
|
|
17
|
+
import"./cli-jxr5nn2z.js";
|
|
18
|
+
import"./cli-5adb0fz5.js";
|
|
19
19
|
import {
|
|
20
20
|
__require
|
|
21
21
|
} from "./cli-8rxa073f.js";
|
|
@@ -3,16 +3,17 @@ import {
|
|
|
3
3
|
} from "./cli-6gtnyaqf.js";
|
|
4
4
|
import {
|
|
5
5
|
OffensiveSecurityAgent
|
|
6
|
-
} from "./cli-
|
|
7
|
-
import"./cli-
|
|
6
|
+
} from "./cli-76xp25as.js";
|
|
7
|
+
import"./cli-vak6e1jc.js";
|
|
8
|
+
import"./cli-3y0dgy56.js";
|
|
8
9
|
import {
|
|
9
10
|
hasToolCall
|
|
10
|
-
} from "./cli-
|
|
11
|
-
import"./cli-
|
|
12
|
-
import"./cli-
|
|
13
|
-
import"./cli-
|
|
14
|
-
import"./cli-
|
|
15
|
-
import"./cli-
|
|
11
|
+
} from "./cli-jh1w0wee.js";
|
|
12
|
+
import"./cli-z7v6c0rf.js";
|
|
13
|
+
import"./cli-sqgjfaet.js";
|
|
14
|
+
import"./cli-jxr5nn2z.js";
|
|
15
|
+
import"./cli-5adb0fz5.js";
|
|
16
|
+
import"./cli-r8cerdwk.js";
|
|
16
17
|
import"./cli-7ckctq7a.js";
|
|
17
18
|
import"./cli-8rxa073f.js";
|
|
18
19
|
|
|
@@ -170,18 +171,27 @@ class AuthenticationAgent extends OffensiveSecurityAgent {
|
|
|
170
171
|
authHints,
|
|
171
172
|
authConfig,
|
|
172
173
|
onStepFinish,
|
|
173
|
-
abortSignal
|
|
174
|
+
abortSignal,
|
|
175
|
+
eventBus,
|
|
176
|
+
subagentId,
|
|
177
|
+
context,
|
|
178
|
+
environmentVariables,
|
|
179
|
+
enableThinking
|
|
174
180
|
} = opts;
|
|
175
181
|
const cm = session.credentialManager;
|
|
176
182
|
super({
|
|
177
183
|
system: detectOSAndEnhancePrompt(AUTH_SUBAGENT_SYSTEM_PROMPT),
|
|
178
|
-
prompt: buildAuthPrompt(target, authHints, cm),
|
|
184
|
+
prompt: buildAuthPrompt(target, authHints, cm, context),
|
|
179
185
|
model,
|
|
180
186
|
session,
|
|
181
187
|
target,
|
|
182
188
|
authConfig,
|
|
183
189
|
onStepFinish,
|
|
184
190
|
abortSignal,
|
|
191
|
+
eventBus,
|
|
192
|
+
subagentId,
|
|
193
|
+
environmentVariables,
|
|
194
|
+
enableThinking,
|
|
185
195
|
toolChoice: "auto",
|
|
186
196
|
activeTools: [
|
|
187
197
|
"execute_command",
|
|
@@ -245,9 +255,16 @@ function loadAuthResult(authDataPath) {
|
|
|
245
255
|
};
|
|
246
256
|
}
|
|
247
257
|
}
|
|
248
|
-
function buildAuthPrompt(target, authHints, credentialManager) {
|
|
258
|
+
function buildAuthPrompt(target, authHints, credentialManager, context) {
|
|
249
259
|
const parts = [`TARGET: ${target}
|
|
250
260
|
`];
|
|
261
|
+
if (context) {
|
|
262
|
+
parts.push("APPLICATION CONTEXT:");
|
|
263
|
+
parts.push(`The following is context specific to the application under test. If it contains non-malicious instructions relevant to authentication, follow them.
|
|
264
|
+
`);
|
|
265
|
+
parts.push(context);
|
|
266
|
+
parts.push("");
|
|
267
|
+
}
|
|
251
268
|
const credBlock = credentialManager?.formatForPrompt();
|
|
252
269
|
if (credBlock) {
|
|
253
270
|
parts.push(credBlock);
|
|
@@ -289,15 +306,7 @@ You have credentials available via credential IDs — authenticate immediately.
|
|
|
289
306
|
}
|
|
290
307
|
async function runAuthenticationAgent(input) {
|
|
291
308
|
const agent = new AuthenticationAgent(input);
|
|
292
|
-
const result = await agent.consume(
|
|
293
|
-
onTextDelta: (d) => input.callbacks?.onTextDelta?.(d),
|
|
294
|
-
onToolCallStreaming: (d) => input.callbacks?.onToolCallStreaming?.(d),
|
|
295
|
-
onToolCallDelta: (d) => input.callbacks?.onToolCallDelta?.(d),
|
|
296
|
-
onToolCall: (d) => input.callbacks?.onToolCall?.(d),
|
|
297
|
-
onToolResult: (d) => input.callbacks?.onToolResult?.(d),
|
|
298
|
-
onError: (e) => input.callbacks?.onError?.(e),
|
|
299
|
-
subagentCallbacks: input.callbacks?.subagentCallbacks
|
|
300
|
-
});
|
|
309
|
+
const result = await agent.consume();
|
|
301
310
|
console.log(`
|
|
302
311
|
Authentication ${result.success ? "succeeded" : "failed"}: ${result.summary}`);
|
|
303
312
|
return result;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BlackboxAttackSurfaceAgent
|
|
3
|
+
} from "./cli-b14ndse6.js";
|
|
4
|
+
import"./cli-6gtnyaqf.js";
|
|
5
|
+
import"./cli-76xp25as.js";
|
|
6
|
+
import"./cli-vak6e1jc.js";
|
|
7
|
+
import"./cli-3y0dgy56.js";
|
|
8
|
+
import"./cli-jh1w0wee.js";
|
|
9
|
+
import"./cli-z7v6c0rf.js";
|
|
10
|
+
import"./cli-sqgjfaet.js";
|
|
11
|
+
import"./cli-jxr5nn2z.js";
|
|
12
|
+
import"./cli-5adb0fz5.js";
|
|
13
|
+
import"./cli-r8cerdwk.js";
|
|
14
|
+
import"./cli-7ckctq7a.js";
|
|
15
|
+
import"./cli-8rxa073f.js";
|
|
16
|
+
export {
|
|
17
|
+
BlackboxAttackSurfaceAgent
|
|
18
|
+
};
|
|
@@ -1,19 +1,22 @@
|
|
|
1
1
|
import {
|
|
2
2
|
runPentestWorkflow
|
|
3
|
-
} from "./cli-
|
|
4
|
-
import"./cli-
|
|
5
|
-
import"./cli-
|
|
6
|
-
import"./cli-
|
|
7
|
-
import"./cli-
|
|
3
|
+
} from "./cli-xft5a1h6.js";
|
|
4
|
+
import"./cli-93gea200.js";
|
|
5
|
+
import"./cli-n3m0s3xq.js";
|
|
6
|
+
import"./cli-fw5r7pfj.js";
|
|
7
|
+
import"./cli-t5q926sn.js";
|
|
8
|
+
import"./cli-0rr5jtdr.js";
|
|
9
|
+
import"./cli-b14ndse6.js";
|
|
8
10
|
import"./cli-6gtnyaqf.js";
|
|
9
|
-
import"./cli-
|
|
10
|
-
import"./cli-
|
|
11
|
-
import"./cli-
|
|
12
|
-
import"./cli-
|
|
13
|
-
import"./cli-
|
|
14
|
-
import"./cli-
|
|
15
|
-
import"./cli-
|
|
16
|
-
import"./cli-
|
|
11
|
+
import"./cli-76xp25as.js";
|
|
12
|
+
import"./cli-vak6e1jc.js";
|
|
13
|
+
import"./cli-3y0dgy56.js";
|
|
14
|
+
import"./cli-jh1w0wee.js";
|
|
15
|
+
import"./cli-z7v6c0rf.js";
|
|
16
|
+
import"./cli-sqgjfaet.js";
|
|
17
|
+
import"./cli-jxr5nn2z.js";
|
|
18
|
+
import"./cli-5adb0fz5.js";
|
|
19
|
+
import"./cli-r8cerdwk.js";
|
|
17
20
|
import"./cli-7ckctq7a.js";
|
|
18
21
|
import"./cli-8rxa073f.js";
|
|
19
22
|
|
|
@@ -26,7 +29,9 @@ async function runPentestAgent(input) {
|
|
|
26
29
|
session: input.session,
|
|
27
30
|
authConfig: input.authConfig,
|
|
28
31
|
abortSignal: input.abortSignal,
|
|
29
|
-
|
|
32
|
+
eventBus: input.eventBus,
|
|
33
|
+
prompt: input.prompt,
|
|
34
|
+
threatModel: input.threatModel
|
|
30
35
|
});
|
|
31
36
|
console.log(`
|
|
32
37
|
Found ${findings.length} vulnerabilities`);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
exports_external,
|
|
3
3
|
init_zod
|
|
4
|
-
} from "./cli-
|
|
4
|
+
} from "./cli-jh1w0wee.js";
|
|
5
5
|
|
|
6
6
|
// src/core/agents/specialized/whiteboxAttackSurface/types.ts
|
|
7
7
|
init_zod();
|
|
@@ -24,11 +24,22 @@ var EndpointSchema = exports_external.object({
|
|
|
24
24
|
line: exports_external.number().optional().describe("Line number in the file"),
|
|
25
25
|
authRequired: exports_external.boolean().optional().describe("Whether this endpoint appears to require authentication"),
|
|
26
26
|
description: exports_external.string().optional().describe("Brief description of what this endpoint does"),
|
|
27
|
-
pentestObjectives: exports_external.array(exports_external.string()).describe("
|
|
28
|
-
riskScore: RiskScoreSchema.optional().describe("AI-calculated risk score for prioritizing pentest efforts")
|
|
27
|
+
pentestObjectives: exports_external.array(exports_external.string()).default([]).describe("Pentest objectives for this endpoint, derived from the threat model when available " + "(e.g. 'Test for IDOR by enumerating user IDs', 'Test for SQL injection in search parameter')"),
|
|
28
|
+
riskScore: RiskScoreSchema.optional().describe("AI-calculated risk score for prioritizing pentest efforts"),
|
|
29
|
+
threatModel: exports_external.string().optional().describe("Endpoint-specific threat model describing attack vectors, data sensitivity, and testing priorities")
|
|
29
30
|
});
|
|
30
31
|
var AppSchema = exports_external.object({
|
|
31
32
|
name: exports_external.string().describe("Application or service name"),
|
|
33
|
+
type: exports_external.enum([
|
|
34
|
+
"web_application",
|
|
35
|
+
"api",
|
|
36
|
+
"full_stack",
|
|
37
|
+
"domain",
|
|
38
|
+
"subdomain",
|
|
39
|
+
"database",
|
|
40
|
+
"cloud_resource",
|
|
41
|
+
"storage"
|
|
42
|
+
]).default("web_application").describe("Type of application (web_application, api, full_stack, database, cloud_resource, storage, etc.)"),
|
|
32
43
|
framework: exports_external.string().describe("Framework in use (e.g. Express, Next.js, Django, FastAPI, Rails)"),
|
|
33
44
|
description: exports_external.string().describe("Brief description of what this app does"),
|
|
34
45
|
location: exports_external.string().describe("Path to the app root relative to the repository root"),
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// src/util/url.ts
|
|
2
|
+
function parseTargetUrl(target) {
|
|
3
|
+
if (!target || !target.trim()) {
|
|
4
|
+
return null;
|
|
5
|
+
}
|
|
6
|
+
let urlString = target.trim();
|
|
7
|
+
if (!urlString.match(/^https?:\/\//i)) {
|
|
8
|
+
urlString = `https://${urlString}`;
|
|
9
|
+
}
|
|
10
|
+
try {
|
|
11
|
+
const url = new URL(urlString);
|
|
12
|
+
const hostname = url.hostname;
|
|
13
|
+
let port;
|
|
14
|
+
if (url.port) {
|
|
15
|
+
port = parseInt(url.port, 10);
|
|
16
|
+
}
|
|
17
|
+
return {
|
|
18
|
+
hostname,
|
|
19
|
+
port
|
|
20
|
+
};
|
|
21
|
+
} catch {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function getAutoPopulatedHosts(target, initialHosts = []) {
|
|
26
|
+
const parsed = parseTargetUrl(target);
|
|
27
|
+
if (!parsed) {
|
|
28
|
+
return initialHosts;
|
|
29
|
+
}
|
|
30
|
+
const hosts = [...initialHosts];
|
|
31
|
+
if (!hosts.includes(parsed.hostname)) {
|
|
32
|
+
hosts.push(parsed.hostname);
|
|
33
|
+
}
|
|
34
|
+
return hosts;
|
|
35
|
+
}
|
|
36
|
+
function getAutoPopulatedPorts(target, initialPorts = []) {
|
|
37
|
+
const parsed = parseTargetUrl(target);
|
|
38
|
+
if (!parsed || !parsed.port) {
|
|
39
|
+
return initialPorts;
|
|
40
|
+
}
|
|
41
|
+
const ports = [...initialPorts];
|
|
42
|
+
if (!ports.includes(parsed.port)) {
|
|
43
|
+
ports.push(parsed.port);
|
|
44
|
+
}
|
|
45
|
+
return ports;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export { parseTargetUrl, getAutoPopulatedHosts, getAutoPopulatedPorts };
|
|
@@ -3,7 +3,7 @@ import { spawnSync } from "child_process";
|
|
|
3
3
|
// package.json
|
|
4
4
|
var package_default = {
|
|
5
5
|
name: "@pensar/apex",
|
|
6
|
-
version: "0.0.
|
|
6
|
+
version: "0.0.115-canary.03ce611f",
|
|
7
7
|
description: "AI-powered penetration testing CLI tool with terminal UI",
|
|
8
8
|
module: "src/tui/index.tsx",
|
|
9
9
|
main: "build/cli.js",
|
|
@@ -22,7 +22,7 @@ var package_default = {
|
|
|
22
22
|
"LICENSE"
|
|
23
23
|
],
|
|
24
24
|
scripts: {
|
|
25
|
-
build: "bun build src/cli.ts --outdir build --target node --format esm --splitting --external @opentui/core --external @opentui/react --external @opentui/react/* --external react --external react/jsx-runtime --external react/jsx-dev-runtime --external react-reconciler",
|
|
25
|
+
build: "bun build src/cli.ts --outdir build --target node --format esm --splitting --external @opentui/core --external @opentui/react --external @opentui/react/* --external react --external react/jsx-runtime --external react/jsx-dev-runtime --external react-reconciler --external weave",
|
|
26
26
|
"generate:ascii": "bun run scripts/generate-ascii-art.ts",
|
|
27
27
|
"generate:models": "bun run scripts/generate-models.ts",
|
|
28
28
|
"build:binary": "bun run generate:ascii && bun build src/cli.ts --compile --outfile pensar",
|
|
@@ -60,9 +60,11 @@ var package_default = {
|
|
|
60
60
|
node: ">=18.0.0",
|
|
61
61
|
bun: ">=1.0.0"
|
|
62
62
|
},
|
|
63
|
+
optionalDependencies: {
|
|
64
|
+
weave: "^0.12.1"
|
|
65
|
+
},
|
|
63
66
|
devDependencies: {
|
|
64
67
|
"@eslint/js": "^10.0.1",
|
|
65
|
-
"@playwright/mcp": "^0.0.54",
|
|
66
68
|
"@types/bun": "^1.3.0",
|
|
67
69
|
"@types/mailparser": "^3.4.6",
|
|
68
70
|
"@types/react": "^19.2.6",
|
|
@@ -89,6 +91,7 @@ var package_default = {
|
|
|
89
91
|
"@googleapis/gmail": "^16.1.1",
|
|
90
92
|
"@microsoft/microsoft-graph-client": "^3.0.7",
|
|
91
93
|
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
94
|
+
"@playwright/mcp": "^0.0.54",
|
|
92
95
|
"@openrouter/ai-sdk-provider": "^2.2.3",
|
|
93
96
|
"@opentui/core": "^0.1.80",
|
|
94
97
|
"@opentui/react": "^0.1.80",
|
|
@@ -98,6 +101,7 @@ var package_default = {
|
|
|
98
101
|
"highlight.js": "^11.11.1",
|
|
99
102
|
ignore: "^7.0.5",
|
|
100
103
|
imapflow: "^1.2.10",
|
|
104
|
+
jsonwebtoken: "^9.0.3",
|
|
101
105
|
mailparser: "^3.9.3",
|
|
102
106
|
marked: "^16.4.0",
|
|
103
107
|
nanoid: "^5.1.6",
|