@pensar/apex 2.4.0 → 2.5.0-canary.2bbb0f6f
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/build/agent-20hb6mg7.js +20 -0
- package/build/{agent-5ejt5vpz.js → agent-71sn1cjn.js} +9 -8
- package/build/{agent-nhs1w5w0.js → agent-xnrz4bhp.js} +11 -10
- package/build/{apps-17wvz1d7.js → apps-ghf7kp1s.js} +72 -31
- package/build/{auth-z3h9859n.js → auth-p1nrv7re.js} +25 -20
- package/build/authentication-m1vj2f0s.js +20 -0
- package/build/blackboxAgent-hjfzgk93.js +20 -0
- package/build/blackboxPentest-9snp9gvp.js +70 -0
- package/build/{cli-0n4r54hq.js → cli-08fcc6d8.js} +1 -1
- package/build/{cli-gq40s5b3.js → cli-14j00zfh.js} +5 -3
- package/build/{cli-vnynf0js.js → cli-3bmqdcfh.js} +10 -4
- package/build/{cli-mavved45.js → cli-3ew5fs3f.js} +46 -25
- package/build/{cli-xshasbwe.js → cli-4mgj070h.js} +30 -4
- package/build/{cli-repbyhkk.js → cli-4vwnsyep.js} +1141 -525
- package/build/cli-53rm0rrz.js +15 -0
- package/build/cli-68260ckj.js +12136 -0
- package/build/cli-7q3ae3ft.js +6 -0
- package/build/{cli-5k33webc.js → cli-7sqb16dd.js} +45 -43
- package/build/{cli-9rhzhgx2.js → cli-8pk8znhw.js} +1 -1
- package/build/cli-9pbk8m32.js +32 -0
- package/build/{cli-72cvcqhg.js → cli-9ya3yktn.js} +1 -1
- package/build/{cli-vq52kp7j.js → cli-a8n64cef.js} +23 -5
- package/build/{cli-qqt4gj1w.js → cli-a9vq54sx.js} +5 -3
- package/build/{cli-swpbx60z.js → cli-avmhkjtv.js} +1 -1481
- package/build/{cli-tkc598ey.js → cli-f47dgye3.js} +411 -280
- package/build/{cli-k8kc47pq.js → cli-fw7sp0fp.js} +3 -3
- package/build/{cli-32z0017y.js → cli-g3cb8pj5.js} +2 -2
- package/build/{cli-tznv8pf1.js → cli-gbch9xmy.js} +1 -1
- package/build/cli-knd276ed.js +1485 -0
- package/build/{cli-2cbwdk78.js → cli-t7rhyqx5.js} +1 -1
- package/build/{cli-b1adytsy.js → cli-yge44bmk.js} +28 -5
- package/build/cli.js +641 -95
- package/build/{config-f1mj4nhd.js → config-cqw98n5y.js} +18 -15
- package/build/{doctor-ekneewa3.js → doctor-vzh1wmfa.js} +8 -7
- package/build/{fastStrike-8zka43xs.js → fastStrike-f441e9nr.js} +13 -10
- package/build/{fixes-b89s5haw.js → fixes-xxz52cf2.js} +25 -20
- package/build/getMachineId-bsd-xj3bn2fv.js +36 -0
- package/build/getMachineId-darwin-07jzjcx6.js +36 -0
- package/build/getMachineId-linux-ahngynxd.js +29 -0
- package/build/getMachineId-unsupported-vy43b44z.js +19 -0
- package/build/getMachineId-win-8x66cynz.js +38 -0
- package/build/{index-ghwf5z3v.js → index-23jj0234.js} +3 -3
- package/build/{index-6d22pyxt.js → index-3gavwzay.js} +1756 -1213
- package/build/{index-4ad3sdwk.js → index-4v5jc2td.js} +4 -4
- package/build/{index-mtq7kmxz.js → index-5wh7gq37.js} +4 -2
- package/build/{index-sf16jm0m.js → index-e7kq5rrd.js} +9 -7
- package/build/{index-rbzhk712.js → index-fxx38nc9.js} +11 -10
- package/build/{index-hqjdg6fg.js → index-j3dc7dks.js} +17 -9
- package/build/{index-y5w6n3tb.js → index-yc1dnj3n.js} +2 -2
- package/build/{issues-xx5bs4md.js → issues-zdag9ayw.js} +82 -26
- package/build/{logs-qtxe51w2.js → logs-f492cjgt.js} +25 -20
- package/build/{offesecAgent-b9e2xm6v.js → offesecAgent-pr0cmrqb.js} +10 -9
- package/build/pentest-1g3fzah5.js +30 -0
- package/build/{pentests-6ks3szc4.js → pentests-vstpzh9j.js} +26 -21
- package/build/{targetedPentest-s1ptvq8e.js → targetedPentest-wj3ae355.js} +11 -10
- package/build/{targets-sxygyj87.js → targets-806zxf1n.js} +27 -22
- package/build/threatModel-dc4jbhkf.js +29 -0
- package/build/{uninstall-tvsh81v8.js → uninstall-58ak2e2v.js} +6 -3
- package/build/{upload-7wdyyqmr.js → upload-kkktzh83.js} +8 -7
- package/build/{utils-7fwdkqk6.js → utils-1sawtwbj.js} +7 -6
- package/package.json +8 -2
- package/build/agent-mvpgvgks.js +0 -19
- package/build/authentication-3s97cpk4.js +0 -19
- package/build/blackboxAgent-gw0a1ca4.js +0 -19
- package/build/blackboxPentest-44333zss.js +0 -37
- package/build/main-mmjp338j.js +0 -324
- package/build/pentest-xtc1sjdw.js +0 -29
- package/build/threatModel-xsm6fwk5.js +0 -27
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
createReportErrorTool,
|
|
6
6
|
isMemoryEnabled,
|
|
7
7
|
readPlan
|
|
8
|
-
} from "./cli-
|
|
8
|
+
} from "./cli-4vwnsyep.js";
|
|
9
9
|
import {
|
|
10
10
|
createLogger,
|
|
11
11
|
hasToolCall,
|
|
@@ -13,11 +13,11 @@ import {
|
|
|
13
13
|
init_lazyLogger,
|
|
14
14
|
init_structured,
|
|
15
15
|
scopedLogger
|
|
16
|
-
} from "./cli-
|
|
16
|
+
} from "./cli-f47dgye3.js";
|
|
17
17
|
import {
|
|
18
18
|
exports_external,
|
|
19
19
|
init_zod
|
|
20
|
-
} from "./cli-
|
|
20
|
+
} from "./cli-avmhkjtv.js";
|
|
21
21
|
|
|
22
22
|
// src/core/agents/specialized/pentest/agent.ts
|
|
23
23
|
init_dist();
|
|
@@ -27,8 +27,12 @@ import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
|
27
27
|
import { join } from "node:path";
|
|
28
28
|
init_lazyLogger();
|
|
29
29
|
var log = scopedLogger(() => createLogger("pentest-agent"));
|
|
30
|
-
function resolvePentestAgentRole(mode = "default", role = "orchestrator") {
|
|
31
|
-
|
|
30
|
+
function resolvePentestAgentRole(mode = "default", role = "orchestrator", disableSubagents = false) {
|
|
31
|
+
if (mode === "fast-strike")
|
|
32
|
+
return "worker";
|
|
33
|
+
if (disableSubagents)
|
|
34
|
+
return "worker";
|
|
35
|
+
return role;
|
|
32
36
|
}
|
|
33
37
|
var ObjectiveResultSchema = exports_external.object({
|
|
34
38
|
objective: exports_external.string().describe("The objective text, exactly as it was provided or a refined version"),
|
|
@@ -55,6 +59,7 @@ class TargetedPentestAgent extends OffensiveSecurityAgent {
|
|
|
55
59
|
authConfig,
|
|
56
60
|
onStepFinish,
|
|
57
61
|
onCacheMetrics,
|
|
62
|
+
forwardUsageCallbacksToSpawnedAgents,
|
|
58
63
|
abortSignal,
|
|
59
64
|
eventBus,
|
|
60
65
|
subagentId,
|
|
@@ -72,18 +77,21 @@ class TargetedPentestAgent extends OffensiveSecurityAgent {
|
|
|
72
77
|
browserSession,
|
|
73
78
|
display
|
|
74
79
|
} = opts;
|
|
75
|
-
const effectiveRole = resolvePentestAgentRole(mode, role);
|
|
80
|
+
const effectiveRole = resolvePentestAgentRole(mode, role, session.config?.disableSubagents ?? false);
|
|
81
|
+
const systemScope = opts.systemScope;
|
|
76
82
|
let reportedError = null;
|
|
77
83
|
super({
|
|
78
|
-
system: buildPentestSystemPrompt(session, effectiveRole, mode),
|
|
84
|
+
system: buildPentestSystemPrompt(session, effectiveRole, mode, systemScope),
|
|
79
85
|
prompt: buildPentestPrompt(target, objectives, session, findingsRegistry, context, environmentVariables ? Object.keys(environmentVariables) : undefined, subagentId, effectiveRole, session.credentialManager?.formatForPrompt(), grpc, mode),
|
|
80
86
|
model,
|
|
81
87
|
session,
|
|
82
88
|
target,
|
|
83
89
|
grpc,
|
|
90
|
+
systemScope,
|
|
84
91
|
authConfig,
|
|
85
92
|
onStepFinish,
|
|
86
93
|
onCacheMetrics,
|
|
94
|
+
forwardUsageCallbacksToSpawnedAgents,
|
|
87
95
|
abortSignal,
|
|
88
96
|
eventBus,
|
|
89
97
|
subagentId,
|
|
@@ -204,13 +212,13 @@ var SECTION_BROWSER_INTERACTION = `Browser Interaction:
|
|
|
204
212
|
- Screenshots are cheap — prefer taking one and not needing it over skipping one and losing visibility. Do NOT attempt to conserve tokens by skipping screenshots during browser-driven testing.
|
|
205
213
|
- Screenshots are automatically stored and displayed alongside your tool call logs, so each one directly improves the user's ability to follow the test in real time.`;
|
|
206
214
|
var SECTION_AUTHENTICATION = `Authentication:
|
|
207
|
-
- If the prompt includes an "Existing Authentication Session" section,
|
|
215
|
+
- If the prompt includes an "Existing Authentication Session" section, use those cookies/headers on requests to the origin they authorize and do NOT re-authenticate up front there. Verify them against a protected resource on your assigned origin. A 401/403 from one resource does not by itself prove authentication failure. Verify the session against a known protected or session endpoint and re-authenticate on the assigned origin only if needed. Call report_error with reason "authentication_failed" only if required authentication cannot be established and this blocks the assigned objective or all further testing; otherwise continue any reachable testing.
|
|
208
216
|
- Otherwise, if the target requires authentication, log in yourself. When an "Available Credentials" section is present, follow the authentication instructions in each credential's Context exactly — use the method it describes (for example, a token/API exchange driven with execute_command or http_request) instead of defaulting to a browser login. Only fall back to driving the login flow in the browser with browser_navigate + browser_fill when the Context does not specify how to authenticate. Prefer credentialId + credentialField so secrets are resolved securely; injected credential environment variables are also available inside execute_command.
|
|
209
217
|
- After a successful login, capture the resulting session credentials and reuse them for raw requests. For a browser login, call browser_get_cookies to extract the session cookies (including httpOnly ones) — pass them as the Cookie header to http_request, or as -H "Cookie: ..." / -b flags to execute_command (curl). Any worker you spawn automatically inherits a snapshot of your authenticated browser session.
|
|
210
218
|
- For http_request: include the captured Cookie and any Authorization headers on every call. For execute_command (curl): include -H "Cookie: ..." and/or -H "Authorization: ..." flags.
|
|
211
|
-
- If a request returns 401/403 after you logged in yourself,
|
|
212
|
-
- Do NOT spin your wheels on authentication. If you have followed the credential Context instructions and still cannot authenticate, do NOT try to work around it — do NOT register a new account, self-sign-up, or fabricate credentials to authenticate. Those are not the credentials under test and only pollute results. (Registering a throwaway account is acceptable only as a disposable *target* for destructive-flow POCs per the blast-radius rungs below — never as a substitute for authenticating as the credential under test.) Make at most a couple of genuine attempts,
|
|
213
|
-
- If
|
|
219
|
+
- If a request returns 401/403 after you logged in yourself, verify the session against a known protected or session endpoint. Re-authenticate the same way you did originally and refresh your session cookies/tokens only when that verification shows the session is missing or expired.
|
|
220
|
+
- Do NOT spin your wheels on authentication. If you have followed the credential Context instructions and still cannot authenticate, do NOT try to work around it — do NOT register a new account, self-sign-up, or fabricate credentials to authenticate. Those are not the credentials under test and only pollute results. (Registering a throwaway account is acceptable only as a disposable *target* for destructive-flow POCs per the blast-radius rungs below — never as a substitute for authenticating as the credential under test.) Make at most a couple of genuine attempts. If required authentication still cannot be established and blocks the assigned objective or all further testing, call report_error with reason "authentication_failed" and a specific message describing exactly what you tried and how it failed; otherwise continue reachable testing and include the limitation in your final response.
|
|
221
|
+
- If unavailable authentication or another runtime condition blocks the assigned objective or all further testing, call report_error with a clear, specific message instead of giving up silently or documenting a non-finding. Do not abort for a non-blocking limitation.
|
|
214
222
|
- Build verifiable POCs, but bound the blast radius. Prove impact with the least-invasive action that still demonstrates the flaw, preferring earlier rungs:
|
|
215
223
|
1. Prove a broken-authorization / privileged-role / IDOR boundary with a READ, or with a benign, reversible write to a low-impact field (e.g. your own display name). That a privileged call is accepted against an object you should not be able to reach is usually the finding — prefer this over disabling security controls, changing quotas/limits, or mutating another user.
|
|
216
224
|
2. If a reversible state-changing write is the only convincing proof, capture the current value, make the change, capture evidence (response/screenshot), then immediately restore the original value — and prefer your own account or a throwaway account you registered for this test over a shared or provided account. Do NOT rely on end-of-run cleanup alone; a crash mid-run can strip it before it runs.
|
|
@@ -495,7 +503,7 @@ function destructiveSection(allow) {
|
|
|
495
503
|
function rateLimitTestingSection(allow) {
|
|
496
504
|
return allow ? SECTION_RATE_LIMITING_TESTING_ALLOWED : SECTION_RATE_LIMITING_TESTING_BLOCKED;
|
|
497
505
|
}
|
|
498
|
-
function buildPentestSystemPrompt(session, role = "orchestrator", mode = "default") {
|
|
506
|
+
function buildPentestSystemPrompt(session, role = "orchestrator", mode = "default", systemScope) {
|
|
499
507
|
const destructive = destructiveSection(session.config?.allowDestructiveActions);
|
|
500
508
|
const rateLimitTesting = rateLimitTestingSection(session.config?.allowRateLimitTesting);
|
|
501
509
|
const guardrails = `${destructive}
|
|
@@ -503,10 +511,13 @@ function buildPentestSystemPrompt(session, role = "orchestrator", mode = "defaul
|
|
|
503
511
|
${rateLimitTesting}
|
|
504
512
|
|
|
505
513
|
${SECTION_SIDE_EFFECT_SAFETY}`;
|
|
514
|
+
const systemSection = systemScope && systemScope.memberHosts.length > 0 ? `
|
|
515
|
+
|
|
516
|
+
${SECTION_SYSTEM_SCOPE(systemScope.memberHosts)}` : "";
|
|
506
517
|
if (mode === "fast-strike") {
|
|
507
518
|
const withGuardrails2 = `${PENTEST_SYSTEM_PROMPT_STRIKE}
|
|
508
519
|
|
|
509
|
-
${guardrails}`;
|
|
520
|
+
${guardrails}${systemSection}`;
|
|
510
521
|
return session.config?.promptInjectionLibrarySource ? `${withGuardrails2}
|
|
511
522
|
|
|
512
523
|
${SECTION_PROMPT_INJECTION}` : withGuardrails2;
|
|
@@ -514,27 +525,34 @@ ${SECTION_PROMPT_INJECTION}` : withGuardrails2;
|
|
|
514
525
|
if (role === "orchestrator") {
|
|
515
526
|
return `${PENTEST_SYSTEM_PROMPT_ORCHESTRATOR}
|
|
516
527
|
|
|
517
|
-
${guardrails}`;
|
|
528
|
+
${guardrails}${systemSection}`;
|
|
518
529
|
}
|
|
519
530
|
const taskDriven = session.config?.taskDriven ?? false;
|
|
520
531
|
const exfilMode = session.config?.exfilMode ?? false;
|
|
521
532
|
const base = taskDriven ? exfilMode ? PENTEST_SYSTEM_PROMPT_TASK_DRIVEN_EXFIL : PENTEST_SYSTEM_PROMPT_TASK_DRIVEN : exfilMode ? PENTEST_SYSTEM_PROMPT_EXFIL : PENTEST_SYSTEM_PROMPT_BASE;
|
|
522
533
|
const withGuardrails = `${base}
|
|
523
534
|
|
|
524
|
-
${guardrails}`;
|
|
535
|
+
${guardrails}${systemSection}`;
|
|
525
536
|
return session.config?.promptInjectionLibrarySource ? `${withGuardrails}
|
|
526
537
|
|
|
527
538
|
${SECTION_PROMPT_INJECTION}` : withGuardrails;
|
|
528
539
|
}
|
|
540
|
+
var SECTION_SYSTEM_SCOPE = (memberHosts) => `System Scope (structured):
|
|
541
|
+
- This engagement covers a multi-application System. Member hosts already present in session targets: ${memberHosts.join(", ")}.
|
|
542
|
+
- Declared relationships in the application context prioritize investigation order; undeclared paths between members remain in scope when discovered.
|
|
543
|
+
- For cross-service follow-ups, an orchestrator MAY set a worker \`target\` to a full URL on another member host listed above. Workers receive this same System Scope. Do not invent hosts outside that set.
|
|
544
|
+
- Authentication state is origin-specific. Before dispatching an authenticated cross-service follow-up, the orchestrator must establish and verify a session on that member origin. The worker must verify access on its assigned origin and follow the Authentication rules below if access is denied.
|
|
545
|
+
- When a confirmed finding spans multiple members, populate the \`attackPath\` argument of \`document_vulnerability\` with the ordered member-to-member hop chain. Do not leave the chain only in the narrative.`;
|
|
529
546
|
var SECTION_ORCHESTRATOR_DELEGATION = `Sub-Agent Delegation Rules:
|
|
530
547
|
- You DO NOT call document_vulnerability directly. Findings are documented by the workers you spawn.
|
|
531
548
|
- You DO NOT execute deep exploitation attempts yourself. Your tools (execute_command, http_request, browser_*) are for INITIAL RECON only — fingerprinting, sanity-checking the target, observing baseline behavior.
|
|
532
549
|
- Each spawn_pentest_agent call MUST cover exactly ONE objective from the assignment, plus optional supporting context. Do not batch multiple objectives into one spawn — the UI surfaces each spawn as its own timeline, and per-objective spawns give each worker a clean, focused context window.
|
|
533
|
-
- Target URL propagation:
|
|
534
|
-
- After all per-objective workers complete, spawn ONE final "chain & explore" worker. Pass it: a brief summary of what earlier workers found (or didn't find), plus any anomalous behaviors observed during recon. Its job is to chain confirmed findings into higher-impact attacks AND probe for additional vulnerabilities that fall outside the original objective list. Send it the same endpoint URL unless an earlier worker confirmed a vulnerability on a sibling endpoint that the chain depends on
|
|
550
|
+
- Target URL propagation: use the full assigned URL by default and never strip it to a bare domain. A worker may receive a recon-supported sibling endpoint that belongs to its follow-up objective. Change hosts only for a cross-service follow-up when the structured System Scope explicitly lists that member host. Always send a full URL, and never invent a host or endpoint outside the authorized session scope.
|
|
551
|
+
- After all per-objective workers complete, spawn ONE final "chain & explore" worker. Pass it: a brief summary of what earlier workers found (or didn't find), plus any anomalous behaviors observed during recon. Its job is to chain confirmed findings into higher-impact attacks AND probe for additional vulnerabilities that fall outside the original objective list. Send it the same endpoint URL unless an earlier worker confirmed a vulnerability on a related sibling endpoint — including an explicitly listed System Scope member — that the chain depends on; then pass that endpoint's full URL.
|
|
535
552
|
- Do not call spawn_pentest_agent before stating your plan in plain text. The plan must be visible to the user as an assistant message, not just inferred from tool calls.
|
|
536
553
|
- Cloned browser session — every worker you spawn gets its OWN isolated Chromium, seeded at spawn time with a snapshot of your current cookies and per-origin localStorage. Practical implications:
|
|
537
|
-
- If authentication is required,
|
|
554
|
+
- If authentication is required, authenticate in YOUR browser during recon. Workers assigned to an origin you authenticated will start with that state, so do NOT instruct them to re-authenticate up front.
|
|
555
|
+
- Authentication does not automatically carry to another origin. Before spawning a cross-service worker that needs authenticated access, establish and verify a session on its target origin. Tell the worker which origin was verified; if access is denied, it must follow the Authentication rules below rather than treating one 401/403 as a blocking authentication failure.
|
|
538
556
|
- Worker browser actions are LOCAL to the worker's clone. A worker's navigations, form fills, \`browser_evaluate\` mutations, and \`localStorage\`/\`sessionStorage\` writes are NOT visible to you or to sibling workers. So workers can fire payloads, trigger alerts, or clobber DOM state without breaking each other or you.
|
|
539
557
|
- Conversely, if you want state to be visible to the next worker, set it up in YOUR browser before spawning. Each worker sees the snapshot of your browser AT THE MOMENT YOU CALL spawn_pentest_agent — later mutations in your browser propagate to subsequent spawns but not to in-flight workers.
|
|
540
558
|
- Worker sessions are torn down when the worker finishes, so any cookies the worker acquired during testing (post-auth flows, OAuth callbacks, etc.) are discarded. If a worker discovers a useful login flow, summarize the credentials in your final response or repeat the flow in YOUR browser before the next spawn.`;
|
|
@@ -550,7 +568,7 @@ Your methodology:
|
|
|
550
568
|
3. RECON & AUTHENTICATE — Perform LIGHT initial reconnaissance to confirm the target is reachable and understand baseline behavior. Use http_request for a handful of probes, browser_navigate + browser_snapshot to see the surface, and execute_command sparingly. Do NOT begin exploitation here — that is the workers' job. Note any anomalies (unusual error responses, exposed headers, framework fingerprints, surprising endpoint behavior) for the final exploratory worker.
|
|
551
569
|
- If authentication is required (an "Existing Authentication Session" section is absent and the target / objectives need a logged-in session), you MUST authenticate NOW, in YOUR browser, BEFORE any fan-out. Follow the "Available Credentials" instructions exactly — use the method each credential's Context describes (e.g. a token/API exchange via execute_command or http_request) rather than defaulting to a browser login; only drive the browser login flow (browser_navigate + browser_fill with credentialId/credentialField) when the Context does not specify how.
|
|
552
570
|
- VERIFY the session before fanning out: request a protected resource and confirm it does NOT return 401/403. Use browser_get_cookies to capture the session cookies for reuse in raw http_request / curl calls.
|
|
553
|
-
- Authenticating HERE (not in the workers) is critical: each worker you spawn inherits
|
|
571
|
+
- Authenticating HERE (not in the workers) is critical: each worker you spawn inherits YOUR browser's cookies + localStorage for origins where you established a session. Before an authenticated cross-service spawn, establish and verify the session on that member origin too. Do NOT instruct a worker to re-authenticate up front for an origin you already verified; if access is denied, it must follow the Authentication rules below.
|
|
554
572
|
- If you cannot authenticate and the objectives require it, call report_error with reason "authentication_failed" and a specific message BEFORE spawning any workers — do not fan out unauthenticated workers that will all fail, and do not report non-findings.
|
|
555
573
|
4. FAN OUT — For EACH objective, call spawn_pentest_agent EXACTLY ONCE. Each spawn dispatches a focused worker that will perform the full PLAN → VERIFY → PREPARE → TEST → EXPLOIT → DOCUMENT loop on its objective. Workers write findings to the shared findings registry — you do NOT need to forward findings between them.
|
|
556
574
|
5. CHAIN & EXPLORE — After all per-objective workers complete, call spawn_pentest_agent ONE FINAL TIME with a synthesized objective that:
|
|
@@ -588,7 +606,7 @@ function buildPentestPrompt(target, objectives, session, findingsRegistry, conte
|
|
|
588
606
|
const parts = [
|
|
589
607
|
`
|
|
590
608
|
## Existing Authentication Session`,
|
|
591
|
-
`An authenticated session already exists
|
|
609
|
+
`An authenticated session already exists. Use these credentials on the origin they authorize and do not re-authenticate up front there. On another structured System member origin, verify protected access first; if access is denied, follow the system Authentication rules.
|
|
592
610
|
`
|
|
593
611
|
];
|
|
594
612
|
if (authData.cookies) {
|
|
@@ -690,18 +708,19 @@ Do NOT discover or enumerate other endpoints or services. Focus exclusively on t
|
|
|
690
708
|
1. Call list_memories to review any prior knowledge relevant to this target or engagement.
|
|
691
709
|
2. State the objectives and outline your orchestration plan in plain text BEFORE any tool calls — one bullet per objective, briefly naming the attack class each worker should focus on.
|
|
692
710
|
3. Perform LIGHT initial recon (a handful of http_request probes, browser_navigate + browser_snapshot to see the surface). Do NOT begin exploitation here — that is the workers' job. Note any anomalies you observe for the final exploratory worker.
|
|
693
|
-
- AUTHENTICATE FIRST if the target/objectives need a logged-in session and no "Existing Authentication Session" is provided:
|
|
711
|
+
- AUTHENTICATE FIRST if the target/objectives need a logged-in session and no "Existing Authentication Session" is provided: authenticate in YOUR browser during this recon step, following the "Available Credentials" instructions exactly (prefer the credential Context's method; use credentialId/credentialField so secrets resolve securely). Verify the session with a protected request (expect NOT 401/403) and capture cookies via browser_get_cookies. Workers inherit auth only for origins where you established it. Before an authenticated cross-service spawn, establish and verify a session on that member origin too. Do not have workers re-authenticate up front on a verified origin; if access is denied, the worker must follow the system Authentication rules. If you cannot authenticate and the objectives require it, call report_error with reason "authentication_failed" instead of fanning out.
|
|
694
712
|
4. Call spawn_pentest_agent EXACTLY ONCE PER OBJECTIVE. For every spawn:
|
|
695
|
-
-
|
|
713
|
+
- Use the FULL URL from the assignment above (domain + endpoint path) by default; never strip it to a bare domain. A recon-supported sibling endpoint may be used when it belongs to the objective. Rewrite the host only for a cross-service follow-up when the structured System Scope explicitly lists that member host. Always pass a full URL and never invent a host or endpoint outside the authorized session scope.
|
|
714
|
+
- Authentication state is origin-specific. If an authenticated cross-service follow-up changes origins, establish and verify auth on that member origin before spawning. Tell the worker which origin was verified and whether authenticated access is still required.
|
|
696
715
|
- Pass the matching objective in the \`objectives\` array (a single-element array).
|
|
697
716
|
- Use the \`context\` field to forward any recon insights specific to that objective. If your earlier browser actions left state the worker should know about (already logged in as X, certain modal already dismissed), call that out in \`context\` — each worker is seeded with a snapshot of YOUR browser's cookies and localStorage at the moment of the spawn call.
|
|
698
|
-
5. After all per-objective workers complete, call spawn_pentest_agent ONE FINAL TIME with a synthesized "chain & explore" objective: summarize what earlier workers confirmed/ruled out, call out unaddressed anomalies, and direct the worker to chain confirmed findings AND probe for additional vulnerabilities outside the original objective list. Send it the same endpoint URL as your assignment unless an earlier worker's confirmed finding on a sibling endpoint is what makes the chain possible.
|
|
717
|
+
5. After all per-objective workers complete, call spawn_pentest_agent ONE FINAL TIME with a synthesized "chain & explore" objective: summarize what earlier workers confirmed/ruled out, call out unaddressed anomalies, and direct the worker to chain confirmed findings AND probe for additional vulnerabilities outside the original objective list. Send it the same endpoint URL as your assignment unless an earlier worker's confirmed finding on a related sibling endpoint — including an explicitly listed System Scope member — is what makes the chain possible.
|
|
699
718
|
6. Use add_memory to save reusable learnings from this engagement.
|
|
700
719
|
7. Call the response tool with your final summary. Compile objectiveResults from worker reports, and populate newObjectives directly from the coverage you orchestrated (worker outcomes, confirmed/ruled-out results, unexplored recon anomalies, technology fingerprints) — a small focused set of objectives for the next run that are not already tested this run or completed in your context. Empty array only if the endpoint is genuinely exhausted.
|
|
701
720
|
|
|
702
721
|
If your assignment lists ZERO open objectives (everything is already completed), skip steps 4-5, do light recon only, then finish — still populating newObjectives so the run is productive rather than re-testing completed objectives.
|
|
703
722
|
|
|
704
|
-
Do NOT call document_vulnerability — that is the workers' job. Do NOT discover or enumerate other endpoints or services beyond the assigned target.`;
|
|
723
|
+
Do NOT call document_vulnerability — that is the workers' job. Do NOT discover or enumerate other endpoints or services beyond the assigned target except for cross-service follow-ups explicitly authorized by the structured System Scope.`;
|
|
705
724
|
const instructions = role === "orchestrator" ? orchestratorInstructions : taskDriven ? taskDrivenInstructions : exfilMode ? `## Goal
|
|
706
725
|
Your target is a flag with the format FLAG{...}. Locate and extract it.
|
|
707
726
|
|
|
@@ -728,7 +747,8 @@ Your target is a flag with the format FLAG{...}. Locate and extract it.
|
|
|
728
747
|
Do NOT discover or enumerate other endpoints or services. Focus exclusively on the target and objectives above.`;
|
|
729
748
|
const credentialSection = credentialContext ? `
|
|
730
749
|
## Available Credentials
|
|
731
|
-
The operator provided the following credentials and authentication instructions for this engagement. Authenticate by following the instructions in each credential's Context exactly — use the method it describes (for example, a token/API exchange via execute_command or http_request) rather than defaulting to a browser login. Treat the Context as the source of truth for how to authenticate, and how to re-authenticate if a provided session expires. When a tool needs a secret value and supports it (e.g. browser_fill), reference it by credentialId + credentialField so the secret resolves securely at execution time instead of hardcoding it. If
|
|
750
|
+
The operator provided the following credentials and authentication instructions for this engagement. Authenticate by following the instructions in each credential's Context exactly — use the method it describes (for example, a token/API exchange via execute_command or http_request) rather than defaulting to a browser login. Treat the Context as the source of truth for how to authenticate, and how to re-authenticate if a provided session expires. When a tool needs a secret value and supports it (e.g. browser_fill), reference it by credentialId + credentialField so the secret resolves securely at execution time instead of hardcoding it. If required authentication cannot be established and blocks the assigned objective or all further testing, call report_error with reason "authentication_failed" and a specific message; otherwise continue reachable testing and report the limitation in your final response.
|
|
751
|
+
When a credential has additional field phoneNumber, phone is the login identifier (not MFA-after-password). Fill credentialField="phoneNumber", click send-code, sleep with execute_command, then sms_list_messages with sinceMs from that click (claim=true once a message is present). If the list stays empty, stop and report — do not hang. Do not report phone_verification as a barrier. TOTP-via-environment-variable for authenticator MFA is unchanged.
|
|
732
752
|
|
|
733
753
|
${credentialContext}
|
|
734
754
|
` : "";
|
|
@@ -806,6 +826,7 @@ var SHARED_PENTEST_TOOLS = [
|
|
|
806
826
|
"email_search_messages",
|
|
807
827
|
"email_get_message",
|
|
808
828
|
"send_email",
|
|
829
|
+
"sms_list_messages",
|
|
809
830
|
"list_memories",
|
|
810
831
|
"get_memory",
|
|
811
832
|
"add_memory",
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
OffensiveSecurityAgent
|
|
3
|
-
} from "./cli-
|
|
3
|
+
} from "./cli-4vwnsyep.js";
|
|
4
4
|
import {
|
|
5
5
|
detectOSAndEnhancePrompt
|
|
6
|
-
} from "./cli-
|
|
6
|
+
} from "./cli-gbch9xmy.js";
|
|
7
7
|
import {
|
|
8
8
|
createLogger,
|
|
9
9
|
hasToolCall,
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
init_lazyLogger,
|
|
12
12
|
init_structured,
|
|
13
13
|
scopedLogger
|
|
14
|
-
} from "./cli-
|
|
14
|
+
} from "./cli-f47dgye3.js";
|
|
15
15
|
|
|
16
16
|
// src/core/agents/specialized/authenticationAgent/agent.ts
|
|
17
17
|
init_dist();
|
|
@@ -141,6 +141,23 @@ every 30 seconds, so run this immediately before filling the field. If the code
|
|
|
141
141
|
retry once (you may have crossed a period boundary). Only report an MFA barrier if no seed is available
|
|
142
142
|
or two fresh codes are both rejected.
|
|
143
143
|
|
|
144
|
+
# SMS passwordless (phone as login)
|
|
145
|
+
|
|
146
|
+
If a credential has a \`phoneNumber\` additional field, the phone number IS the login identifier — not MFA
|
|
147
|
+
after a password. Do **not** report \`phone_verification\` as a barrier for this flow.
|
|
148
|
+
|
|
149
|
+
1. \`browser_fill\` with \`credentialId\` and \`credentialField="phoneNumber"\` (never type the number).
|
|
150
|
+
2. Click the target's send-code / text-me control. Note \`Date.now()\` at that click as \`sinceMs\`.
|
|
151
|
+
3. \`execute_command\` \`sleep 5\`, then call \`sms_list_messages\` with that \`credentialId\` and \`sinceMs\`.
|
|
152
|
+
If the list is empty, sleep and list again a few times. If it stays empty or returns an error, stop
|
|
153
|
+
and report what you observed — do not hang in a wait loop. Set \`claim=true\` once a message is present
|
|
154
|
+
so other runs cannot reuse the OTP.
|
|
155
|
+
4. \`browser_fill\` the OTP from the claimed/listed result (\`code\`, or parse \`body\` if \`code\` is null).
|
|
156
|
+
5. Continue the login and call \`complete_authentication\`.
|
|
157
|
+
|
|
158
|
+
TOTP-via-environment-variable above is unchanged and still applies when the login asks for an authenticator
|
|
159
|
+
app code.
|
|
160
|
+
|
|
144
161
|
# Error Recovery
|
|
145
162
|
|
|
146
163
|
If authentication fails, try these mechanical fixes (they are login mechanics, not credential changes):
|
|
@@ -243,6 +260,7 @@ class AuthenticationAgent extends OffensiveSecurityAgent {
|
|
|
243
260
|
"email_search_messages",
|
|
244
261
|
"email_get_message",
|
|
245
262
|
"send_email",
|
|
263
|
+
"sms_list_messages",
|
|
246
264
|
"web_search",
|
|
247
265
|
"get_page"
|
|
248
266
|
],
|
|
@@ -328,6 +346,14 @@ function buildAuthPrompt(target, authHints, credentialManager, context, envVarNa
|
|
|
328
346
|
parts.push("");
|
|
329
347
|
}
|
|
330
348
|
if (credBlock) {
|
|
349
|
+
const hasSmsPasswordless = credentialManager?.listReferences().some((ref) => ref.additionalFieldKeys?.includes("phoneNumber"));
|
|
350
|
+
const smsInstructions = hasSmsPasswordless ? `
|
|
351
|
+
If a credential has a phoneNumber additional field (Mobile OTP / sms-passwordless), phone is the login
|
|
352
|
+
identifier — not MFA-after-password. browser_fill credentialField="phoneNumber", click send-code, then
|
|
353
|
+
execute_command \`sleep 5\` and call sms_list_messages with sinceMs = Date.now() at that click (claim=true
|
|
354
|
+
once a message is present). If the list is empty, sleep and list again; if it stays empty, fail with what
|
|
355
|
+
you observed — do not hang waiting. Then browser_fill the OTP. Do NOT report phone_verification as a
|
|
356
|
+
barrier for this flow. TOTP-via-env for authenticator MFA is unchanged.` : "";
|
|
331
357
|
parts.push(`INSTRUCTIONS:
|
|
332
358
|
You have credentials available via credential IDs — authenticate immediately.
|
|
333
359
|
1. For API/form logins, use execute_command (curl) to submit credentials and capture the Set-Cookie / token response
|
|
@@ -335,7 +361,7 @@ You have credentials available via credential IDs — authenticate immediately.
|
|
|
335
361
|
pass credentialId + credentialField (e.g. credentialField="password") instead of the raw value —
|
|
336
362
|
the secret is resolved securely at execution time. NEVER type a password directly.
|
|
337
363
|
3. Call complete_authentication with exported cookies/headers to persist credentials and end the run
|
|
338
|
-
|
|
364
|
+
${smsInstructions}
|
|
339
365
|
The credentials above were provided to you and have already been verified — they are SHARED across runs, so
|
|
340
366
|
do not modify them or their account settings. NEVER change the password, complete a password reset /
|
|
341
367
|
forced-password-change / account-recovery flow, or modify MFA/2FA settings (enrolling, disabling, or
|