sicario-red-team 0.5.10 β 0.6.1
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 +41 -26
- package/dist/sicario.js +122 -0
- package/package.json +9 -24
- package/bin/sicario.js +0 -213
- package/convex/_generated/ai/ai-files.state.json +0 -13
- package/convex/_generated/ai/guidelines.md +0 -303
- package/convex/_generated/api.d.ts +0 -55
- package/convex/_generated/api.js +0 -23
- package/convex/_generated/dataModel.d.ts +0 -60
- package/convex/_generated/server.d.ts +0 -143
- package/convex/_generated/server.js +0 -93
- package/convex/crons.ts +0 -36
- package/convex/handler.ts +0 -141
- package/convex/missions.ts +0 -45
- package/convex/schema.ts +0 -79
- package/convex/siege.ts +0 -179
- package/src-cli/commands/hit.js +0 -294
- package/src-cli/commands/siege.js +0 -80
- package/src-cli/commands/watch.js +0 -59
- package/src-cli/nodes/breacher.js +0 -91
- package/src-cli/nodes/cartographer.js +0 -80
- package/src-cli/nodes/critic.js +0 -198
- package/src-cli/nodes/executor.js +0 -95
- package/src-cli/nodes/scout.js +0 -144
- package/src-cli/nodes/scribe.js +0 -47
- package/src-cli/services/breacher.js +0 -59
- package/src-cli/services/ghost.js +0 -34
- package/src-cli/services/handler.js +0 -60
- package/src-cli/services/keymaster.js +0 -70
- package/src-cli/services/scout.js +0 -50
- package/src-cli/utils/config.js +0 -38
- package/src-cli/utils/llm.js +0 -38
- package/src-cli/utils/simulator.js +0 -124
- package/src-cli/utils/theme.js +0 -25
package/README.md
CHANGED
|
@@ -1,48 +1,63 @@
|
|
|
1
|
-
#
|
|
1
|
+
# π― Sicario: Autonomous Red-Team Swarm
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**The AI Security Co-Founder for Modern Web Development.**
|
|
4
4
|
|
|
5
|
-
**
|
|
5
|
+
AI coding assistants (**Cursor, v0, GitHub Copilot**) allow you to ship full-stack applications in hours. But while they write beautiful React components, they frequently hallucinate critical **Business Logic Vulnerabilities**βlike allowing users to bypass paywalls, mutate cart prices, or escalate their own privileges.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Legacy vulnerability scanners (like Snyk or Burp Suite) are built for enterprise compliance, not rapid development. They read static code and output dense, 40-page PDFs.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
**Sicario** is different. It is an autonomous, locally-running AI swarm that plays your application like a video game. It hunts the logic flaws your AI generated, and gives you the exact prompt to fix them.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## π Zero-Friction Quickstart
|
|
14
|
+
|
|
15
|
+
No configuration files. No heavy desktop apps. No credit card required.
|
|
10
16
|
|
|
11
17
|
```bash
|
|
12
|
-
|
|
18
|
+
# Launch a continuous background siege on your local dev server
|
|
19
|
+
npx sicario-red-team@latest watch http://localhost:3000
|
|
13
20
|
```
|
|
14
21
|
|
|
15
22
|
---
|
|
16
23
|
|
|
17
|
-
##
|
|
24
|
+
## πͺ The Vanguard Features
|
|
25
|
+
|
|
26
|
+
### 1. Intent-Based Sieges
|
|
27
|
+
Stop writing complex testing configurations. Just tell Sicario what you want it to steal in plain English, and the Swarm figures out how to execute the attack.
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
npx sicario-red-team hit --target http://localhost:3000 --intent "Try to manipulate the checkout payload to get the Pro Plan for free."
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### 2. The Scribe (Prompt-to-Patch)
|
|
34
|
+
When Sicario confirms an exploit, it doesn't just give you a stack trace. The **Scribe Node** automatically generates a natural-language "Cursor-ready" prompt. Just copy and paste the Scribe's output back into your AI IDE, and it will write the patch for you.
|
|
18
35
|
|
|
19
|
-
|
|
36
|
+
### 3. Continuous Localhost Protection (The Lazy Watcher)
|
|
37
|
+
Run `sicario watch` in the background. Sicario uses a zero-cost local DOM-diffing engine to monitor your app. The moment you hit "Save" on a new form or feature, the Swarm wakes up, micro-sieges the new code for logic flaws, and goes back to sleep.
|
|
20
38
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
* **Breacher Node**: Analyzes the "internal monologue" of your appβs logic to find Action Limit Overruns, IDORs, and Price Manipulations.
|
|
39
|
+
### 4. DOM Supremacy
|
|
40
|
+
Modern web apps aren't static HTML pages. Sicario utilizes a headless Chromium engine to intercept asynchronous fetch requests, wait for React hydration, and pierce Web Component Shadow DOMs. It attacks your app exactly how a real human would.
|
|
24
41
|
|
|
25
42
|
---
|
|
26
43
|
|
|
27
|
-
## π‘οΈ
|
|
44
|
+
## π‘οΈ Swarm Architecture & Safety
|
|
28
45
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
* **CI/CD Ready**: Integrated GitHub Action support to scan every Pull Request automatically.
|
|
46
|
+
Sicario runs locally on your machine. By default, it operates in **SHADOW TIER** (Dry-Run mode), meaning it maps your application and simulates attacks without mutating your database.
|
|
47
|
+
|
|
48
|
+
To authorize active database mutations and live POST/PUT exploits on your local environment, pass the `--live-fire` flag.
|
|
33
49
|
|
|
34
50
|
---
|
|
35
51
|
|
|
36
|
-
##
|
|
52
|
+
## π Sicario Operator Tier
|
|
37
53
|
|
|
38
|
-
|
|
54
|
+
The free NPM package is powered by a rate-limited, free-tier Critic Cascade.
|
|
39
55
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
```
|
|
56
|
+
For professional engineering teams that require:
|
|
57
|
+
|
|
58
|
+
* **Unlimited Tokens** & Zero Rate Limits
|
|
59
|
+
* **Enterprise Auth Vaulting** (Bypass Okta/Auth0)
|
|
60
|
+
* **Unredacted Swarm Reasoning Logs**
|
|
61
|
+
* **CI/CD Pipeline Integration**
|
|
47
62
|
|
|
48
|
-
|
|
63
|
+
Upgrade your license at [sicario-red-team.com](https://sicario-red-team.com).
|
package/dist/sicario.js
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import{Command as rt}from"commander";import te from"path";import ye from"fs";import{fileURLToPath as nt}from"url";import ee from"picocolors";import we from"dotenv";import{createRequire as st}from"module";import{createRequire as Oe}from"module";import i from"picocolors";import"dotenv/config";import{ConvexClient as De}from"convex/browser";import{chromium as Te}from"playwright";import z from"fs";async function B(t,e={}){let o=await Te.launch({headless:!0}),r={};e.vault&&z.existsSync(e.vault)&&(r.storageState=e.vault);let c=await o.newContext(r);if(e.auth){let a=new URL(t).hostname,u=[];if(e.auth.endsWith(".json")&&z.existsSync(e.auth))try{let s=JSON.parse(z.readFileSync(e.auth,"utf-8"));u=Array.isArray(s)?s:[s],u=u.map(p=>({...p,domain:p.domain||a,path:p.path||"/"}))}catch(s){console.error(`Failed to parse cookie file: ${s.message}`)}else u=e.auth.split(";").map(p=>p.trim()).map(p=>{let[g,...S]=p.split("=");return{name:g.trim(),value:S.join("=").trim(),domain:a,path:"/"}});u.length>0&&await c.addCookies(u)}let l=await c.newPage();try{let a=await l.goto(t,{waitUntil:"networkidle"}),u=a?a.headers():{},s="Unknown";u["x-powered-by"]&&(s=u["x-powered-by"]),u.server&&(s+=` (${u.server})`),u["x-nextjs-cache"]&&(s="Next.js"),await l.waitForSelector("button, input",{timeout:1e4}).catch(()=>{});let p=await l.$("button.close-dialog");p&&await p.click();let g=await l.evaluate(()=>{let S=[],I=new Set,m=E=>{E.querySelectorAll("*").forEach(n=>{if(I.has(n))return;I.add(n);let w=n.tagName.toLowerCase(),k=window.getComputedStyle(n).cursor==="pointer"||n.getAttribute("onclick")||n.onclick,D=["button","link","input","form","checkbox","radio"].includes(n.getAttribute("role")),K=["input","select","textarea","button"].includes(w),q=w==="a",U=w==="input"&&n.type==="hidden";(n.offsetWidth>0&&n.offsetHeight>0&&(K||q||k||D)||U)&&S.push({tag:w,id:n.id||null,name:n.name||null,type:n.type||null,value:n.value||null,role:n.getAttribute("role")||null,isHighValueTarget:U&&n.value!=="",text:n.innerText?n.innerText.trim().substring(0,50):null,href:n.href||null,isShadow:E!==document}),n.shadowRoot&&m(n.shadowRoot)})};return m(document),S});return await o.close(),{elements:g,metadata:{techStack:s,url:t,timestamp:new Date().toISOString()}}}catch(a){throw await o.close(),new Error(`Scout failed to map perimeter: ${a.message}`)}}import be from"@cerebras/cerebras_cloud_sdk";import"dotenv/config";var Ae={ACCOUNTANT:`
|
|
3
|
+
You are 'The Accountant' node. Your primary focus is on financial logic, pricing, and quantities.
|
|
4
|
+
Look for: Negative value injections, Scientific notation (1e10) bypasses, Currency-decimal manipulation, and Action Limit overruns in financial flows.
|
|
5
|
+
`,ADMIN:`
|
|
6
|
+
You are 'The Admin' node. Your focus is on Privilege Escalation and Access Control.
|
|
7
|
+
Look for: Hidden /admin navigation links, accessible settings panels meant for high-privilege users, IDOR vectors in the DOM structure, and authentication bypass hints.
|
|
8
|
+
`,CHAOS_MONKEY:`
|
|
9
|
+
You are 'The Chaos Monkey'. Your focus is on Input Resilience and Error Handling bypasses.
|
|
10
|
+
Look for: Fields that lack character limits, unhandled edge-case inputs (emojis, 1GB strings), and state-manipulation vectors that could lead to crashes or unhandled server-side exceptions.
|
|
11
|
+
`,ARCHITECT:`
|
|
12
|
+
You are 'The Architect'. Your focus is on Business Workflow and State Bypass.
|
|
13
|
+
Look for: Multi-step process vulnerabilities (e.g. Step 1 -> Step 3 bypass), "Verification" flag manipulation in the DOM, and logical "shortcuts" that allow users to reach success states without completing prerequisites (like payment or approval).
|
|
14
|
+
`,GHOST:`
|
|
15
|
+
You are 'The Ghost' (Data Privacy Specialist). Your focus is on Data Leakage and PII.
|
|
16
|
+
Look for: Unmasked PII (emails, names, SSNs) in the DOM or secret metadata, raw API keys or tokens in data-attributes, and sensitive information leaked in hidden fields or commented-out source code meant for developers.
|
|
17
|
+
`};async function N(t,e="GENERAL"){let o=new be({apiKey:process.env.CEREBRAS_API_KEY}),c=`
|
|
18
|
+
You are a specialized node in the Sicario Autonomous Swarm.
|
|
19
|
+
${Ae[e]||"Evaluate the DOM for general business logic vulnerabilities."}
|
|
20
|
+
|
|
21
|
+
### VULNERABILITY TARGETING (DOM SUPREMACY MODE):
|
|
22
|
+
1. PIERCE THE SHADOW: Elements marked as 'isShadow: true' are encapsulated. Developers often leave internal fields (like price or user_id) unvalidated within custom Web Components.
|
|
23
|
+
2. BEHAVIORAL MAPPING: Analyze elements with custom roles (role="button") or pointer cursors. These are modern SPA action points that bypass traditional form-crawling scanners.
|
|
24
|
+
3. BEHAVIORAL TRIGGERS: Identify the specific trigger selector required to submit the payload (e.g., a <div> with role="button" or an ID like #sync-profile).
|
|
25
|
+
4. THE SNIPER RULE: Always prioritize basic Parameter Tampering. Mutate hidden HTML inputs (type='hidden') related to pricing, IDs, or roles to 0, "", or admin before attempting complex JS exploitation.
|
|
26
|
+
|
|
27
|
+
### PHASE 1: REASONING (THINK OUT LOUD)
|
|
28
|
+
Before providing JSON, analyze the DOM elements according to your specific persona.
|
|
29
|
+
|
|
30
|
+
### PHASE 2: DATA STRUCTURE
|
|
31
|
+
Return a VALID JSON object. DO NOT use "null".
|
|
32
|
+
{
|
|
33
|
+
"vulnerabilityFound": boolean,
|
|
34
|
+
"thoughtProcess": "Your specialized step-by-step reasoning",
|
|
35
|
+
"title": "Persona-specific flaw name",
|
|
36
|
+
"vector": "Technical path",
|
|
37
|
+
"severity": "LOW|MEDIUM|HIGH|CRITICAL",
|
|
38
|
+
"targetElement": "CSS selector or name",
|
|
39
|
+
"mutation": {
|
|
40
|
+
"selector": "The CSS selector for the hidden field or input to target",
|
|
41
|
+
"value": "The malicious value to inject (e.g. 0, -1, 'admin', '1e10')",
|
|
42
|
+
"trigger": "The CSS selector for the trigger element to click (div[role='button'], #submit, etc.)"
|
|
43
|
+
},
|
|
44
|
+
"mitigation": "Code-level fix"
|
|
45
|
+
}
|
|
46
|
+
`,l=`DOM Elements: ${JSON.stringify(t)}`;try{let a=await o.chat.completions.create({messages:[{role:"system",content:c},{role:"user",content:l}],model:"llama3.1-8b",temperature:0,response_format:{type:"json_object"}});return JSON.parse(a.choices[0].message.content)}catch(a){throw console.error("Breacher Error:",a),a}}import{chromium as Re}from"playwright";import Ie from"fs";import ie from"picocolors";async function re(t,e,o={}){let r=await Re.launch({headless:!0}),c={};o.vault&&Ie.existsSync(o.vault)&&(c.storageState=o.vault);let a=await(await r.newContext(c)).newPage();try{await a.goto(t);let u=e.mutation||{},s=u.selector||e.targetElement,p=u.value;if(s&&p!==void 0){console.log(ie.yellow(` [Executor] : Mutating ${s} -> ${p}`)),await a.locator(s).evaluate((w,y)=>{w.value=y,w.dispatchEvent(new Event("change",{bubbles:!0})),w.dispatchEvent(new Event("input",{bubbles:!0}))},p);let S="",I=async w=>{let y=w.request().resourceType();if(y==="fetch"||y==="xhr")try{let k=await w.text();S+=`[${w.status()}] ${w.url().split("/").pop()}: ${k.substring(0,500)} | `}catch{}};a.on("response",I);let m=u.trigger||'button[type="submit"], input[type="submit"], [role="button"], button';console.log(ie.red(` [Executor] : Pulling the trigger (${m})...`)),await Promise.all([Promise.all([a.waitForNavigation({timeout:1e4}).catch(()=>{}),a.waitForLoadState("networkidle",{timeout:1e4}).catch(()=>{})]),a.locator(m).first().click().catch(async()=>{await a.$eval("form",w=>w.submit()).catch(()=>{})})]),await new Promise(w=>setTimeout(w,1e3)),a.off("response",I);let E=await a.innerText("body"),b=`| NETWORK TRAFFIC |
|
|
47
|
+
${S||"No AJAX traffic detected."}
|
|
48
|
+
|
|
49
|
+
| DOM TEXT |
|
|
50
|
+
${E}`,n=await a.screenshot({type:"jpeg",quality:20});return await r.close(),{success:!0,evidence:b.substring(0,3e3),screenshot:n}}else return await r.close(),{success:!1,error:"No mutation metadata found."}}catch(u){return await r.close(),{success:!1,error:u.message}}}import ve from"@cerebras/cerebras_cloud_sdk";import"dotenv/config";import x from"picocolors";var G=class{constructor(e){this.ai=new ve({apiKey:e||process.env.CEREBRAS_API_KEY}),this.llamaModel="llama3.1-8b",this.qwenModel="qwen-3-235b-a22b-instruct-2507",this.lastRequestTime=0,this.minDelayMs=2100}async _throttle(){let o=Date.now()-this.lastRequestTime;o<this.minDelayMs&&await new Promise(r=>setTimeout(r,this.minDelayMs-o)),this.lastRequestTime=Date.now()}_tierZeroFilter(e){let o=[404,400,429];if(e.statusCode&&o.includes(e.statusCode))return!1;let r=(e.title||"").toUpperCase(),c=(e.thoughtProcess||e.body||"").toLowerCase(),l=(e.vector||"").toLowerCase();return!(r.includes("XSS")&&(c.includes("<")||l.includes("<"))||r.includes("ACCESSIBILITY")||r.includes("LABEL MISSING"))}async _tierOneTriage(e){await this._throttle();let o=(e.thoughtProcess||e.body||"").substring(0,800),r=`
|
|
51
|
+
You are a strict security analyst. Review this potential vulnerability finding:
|
|
52
|
+
Type: ${e.title}
|
|
53
|
+
Vector: ${e.vector}
|
|
54
|
+
Reasoning: ${o}
|
|
55
|
+
|
|
56
|
+
Is this explicitly a False Positive or AI Hallucination?
|
|
57
|
+
Reply ONLY with "YES" (if junk) or "NO" (if it deserves deep analysis).
|
|
58
|
+
`;try{return!(await this.ai.chat.completions.create({model:this.llamaModel,messages:[{role:"user",content:r}],temperature:.1,max_tokens:5})).choices[0].message.content.trim().toUpperCase().includes("YES")}catch{return console.warn(x.yellow(" [!] Llama Triage failed. Escalating to deep review...")),!0}}async _tierTwoJudgment(e,o){await this._throttle();let r=JSON.stringify(o).substring(0,4e3),c=`
|
|
59
|
+
You are the Lead Critic Node of the Sicario Red-Teaming Swarm.
|
|
60
|
+
Analyze this potential business logic vulnerability finding:
|
|
61
|
+
|
|
62
|
+
TITLE: ${e.title}
|
|
63
|
+
VECTOR: ${e.vector}
|
|
64
|
+
BREACHER REASONING: ${e.thoughtProcess}
|
|
65
|
+
DOM CONTEXT: ${r}
|
|
66
|
+
|
|
67
|
+
ACTIVE EXPLOIT EVIDENCE (SERVER RESPONSE):
|
|
68
|
+
${e.body||"No active fire evidence provided. Base judgment on DOM theorizing."}
|
|
69
|
+
|
|
70
|
+
CRITERIA:
|
|
71
|
+
1. Can this bypass authentication or financial logic? (e.g. getting a $499 plan for $0 is a CRITICAL BREACH).
|
|
72
|
+
2. If "ACTIVE EXPLOIT EVIDENCE" indicates a success message for an unauthorized action (like a price mutation), it is EXPLOITABLE.
|
|
73
|
+
3. Is it a real technical vulnerability or just a best-practice bug?
|
|
74
|
+
|
|
75
|
+
VERDICT: Provide a 1-sentence technical explanation, followed by "VERDICT: EXPLOITABLE" or "VERDICT: SAFE".
|
|
76
|
+
`;try{return console.log(x.magenta(`
|
|
77
|
+
--- AUTOPSY LOG: WHAT THE CRITIC SEES ---`)),console.log(x.cyan(`Finding: ${e.title}`)),console.log(x.cyan(`Mutation Payload: ${JSON.stringify(e.mutation||{})}`)),console.log(x.cyan(`Server Evidence: ${e.body?e.body.substring(0,500):"EMPTY (Possible Race Condition)"}`)),console.log(x.magenta(`------------------------------------------
|
|
78
|
+
`)),(await this.ai.chat.completions.create({model:this.qwenModel,messages:[{role:"user",content:c}],temperature:0})).choices[0].message.content}catch{return console.error(x.red(" [x] Critic Core (Qwen 235B) Offline: Rate Limit or Quota reached.")),"VERDICT: MANUAL_REVIEW_REQUIRED"}}async crossExamine(e,o){if(!this._tierZeroFilter(e))return{isReal:!1,reasoning:"Killed by Tier 0 (Local Heuristics)"};if(!await this._tierOneTriage(e))return{isReal:!1,reasoning:"Killed by Tier 1 (Llama 8B - High Skepticism)"};console.log(x.yellow(" [!] Finding flagged for Deep Analysis (Qwen 235B Critic)..."));let c=await this._tierTwoJudgment(e,o);return c.includes("EXPLOITABLE")?{isReal:!0,reasoning:c,enhancedMitigation:"Implement server-side state validation and cryptographic integrity checks."}:{isReal:!1,reasoning:c}}};import Ce from"@cerebras/cerebras_cloud_sdk";import"dotenv/config";async function ne(t,e,o={}){let r=new Ce({apiKey:process.env.CEREBRAS_API_KEY}),c=o.techStack||"Unknown",l=`
|
|
79
|
+
You are 'The Scribe' node of the Sicario Red-Teaming Swarm.
|
|
80
|
+
Your goal is to provide a "Cursor-ready" remediation prompt that a developer can paste into their AI code editor to fix a confirmed vulnerability.
|
|
81
|
+
|
|
82
|
+
VULNERABILITY: ${t.title}
|
|
83
|
+
VECTOR: ${t.vector}
|
|
84
|
+
CRITIC JUSTIFICATION: ${e.reasoning}
|
|
85
|
+
TARGET TECH STACK: ${c}
|
|
86
|
+
|
|
87
|
+
INSTRUCTIONS:
|
|
88
|
+
1. Provide a concise, clinical description of the fix.
|
|
89
|
+
2. Provide a "Cursor Prompt" (a prompt for another AI to use) enclosed in triple backticks.
|
|
90
|
+
3. Keep it brief to save on outbound tokens.
|
|
91
|
+
4. IMPORTANT: Ensure the remediation code snippet matches the Target Tech Stack.
|
|
92
|
+
5. If the Tech Stack is unknown or generic, default to JavaScript/Node.js (Express).
|
|
93
|
+
`;try{return(await r.chat.completions.create({messages:[{role:"system",content:l},{role:"user",content:"Generate remediation prompt."}],model:"llama3.1-8b",temperature:0,max_tokens:300})).choices[0].message.content}catch{return"Scribe node offline: Mitigation deferred to manual review."}}import xe from"@cerebras/cerebras_cloud_sdk";import"dotenv/config";async function se(t){let e=new xe({apiKey:process.env.CEREBRAS_API_KEY}),o=`
|
|
94
|
+
You are the "Swarm Strategist" for the Sicario Red-Teaming protocol.
|
|
95
|
+
The operator provided a target intent: "${t}".
|
|
96
|
+
|
|
97
|
+
Your task: Translate this intent into 5 specific, technical attack vectors that node-based agents (Accountant, Admin, Chaos Monkey, Architect, Ghost) should look for in a DOM structure.
|
|
98
|
+
|
|
99
|
+
REPLY ONLY WITH A COMMA-SEPARATED LIST OF 5 BRIEF TECHNICAL VECTORS.
|
|
100
|
+
`;try{return(await e.chat.completions.create({messages:[{role:"system",content:o},{role:"user",content:"Generate tactical vectors."}],model:"llama3.1-8b",temperature:0,max_tokens:100})).choices[0].message.content.trim().split(",").map(l=>l.trim())}catch{return["Session State Bypass","Hidden Field Manipulation","Horizontal Privilege Escalation","Input Sanitization Bypass","Logic State Machine Exploitation"]}}import d from"picocolors";var T={brand:t=>d.bold(d.red(t)),danger:t=>d.red(t),warning:t=>d.yellow(t),success:t=>d.green(t),info:t=>d.blue(t),dim:t=>d.gray(t),bold:t=>d.bold(t),italic:t=>d.italic(t),handler:t=>d.bgBlack(d.white(d.bold(" \u{1F5A5}\uFE0F THE HANDLER ")))+" "+d.dim(t),scout:t=>d.cyan(d.bold("[Scout]"))+" "+d.dim(`: ${t}`),ghost:t=>d.magenta(d.bold("[Ghost]"))+" "+d.dim(`: ${t}`),breacher:t=>d.red(d.bold("[Breacher]"))+" "+d.dim(`: ${t}`),cleaner:t=>d.gray(d.bold("[Cleaner]"))+" "+d.dim(`: ${t}`),exploit:t=>d.bgRed(d.white(d.bold(" \u26A0 EXPLOIT SUCCESSFUL ")))+" "+d.bold(d.red(t))};var ce=Oe(import.meta.url),Pe=ce("@clack/prompts"),{intro:Le,outro:Ne,log:h,note:Dt,text:Me,isCancel:ke,cancel:$e}=Pe,f=process.env.CONVEX_URL?new De(process.env.CONVEX_URL):null;async function H(t,e){let o=new G,r=t;r||(r=await Me({message:"Establish target lock",placeholder:"https://staging.example.com",validate:s=>{if(!s)return"Target is required";if(!s.startsWith("http"))return"Invalid URL format"}}),ke(r)&&($e("Operation aborted by user."),process.exit(0))),Le(T.brand("Project Sicario - Autonomous Swarm Protocol"));let c=(e.tier||"SHADOW").toUpperCase();h.info(i.magenta(`\u25C8 LICENSE TIER: ${i.bold(c)}`));let l=null;e.intent&&(h.step("[System] : Translating intent into specialized attack vectors..."),l=await se(e.intent),h.info(i.magenta(`\u25C8 INTENT VECTORS: ${l.join(", ")}`))),console.log(i.dim(`
|
|
101
|
+
\u250C AGENT PERMISSIONS MANIFEST \u2500\u2500\u2500 (READ-ONLY) \u2500\u2500\u2500\u2500\u2500\u2500\u256E`)),console.log(i.dim("\u2502 \u2713 DOM Observation : AUTHORIZED \u2502")),console.log(i.dim("\u2502 \u2713 GET / HEAD / OPTIONS : AUTHORIZED \u2502")),e.liveFire?console.log(i.red("\u2502 \u2713 POST / PUT : LIVE EXECUTION AUTHORIZED \u2502")):console.log(i.dim("\u2502 \u26A0 POST / PUT (Dry-Run) : SIMULATED \u2502")),console.log(i.dim("\u2502 \u2717 DB Write / Auth Mutate : DISABLED \u2502")),console.log(i.dim(`\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256F
|
|
102
|
+
`));let a=null,u={vulnerabilityFound:!1};try{if(f)try{a=await f.mutation("handler:startMission",{targetUrl:r})}catch(g){h.warn("Convex sync disabled or failed: "+g.message)}h.step("[Scout] : Initiating live reconnaissance..."),f&&a&&await f.mutation("handler:logMessage",{missionId:a,type:"Scout",message:"Initiating live reconnaissance..."});let s=[],p={};try{let g=await B(r,{auth:e.auth,vault:e.vault});s=g.elements,p=g.metadata,h.success(`[Scout] : Perimeter mapped. Tech Stack: ${p.techStack}`),f&&a&&await f.mutation("handler:logMessage",{missionId:a,type:"Scout",message:`Perimeter mapped. Stack: ${p.techStack}`}),f&&a&&await f.mutation("handler:syncPerimeter",{missionId:a,interactiveElements:s})}catch(g){throw h.error("[Scout] : Reconnaissance failed."),h.error(g.message),g}h.step("[Ghost] : WAF bypassed. Biometric jitter active."),f&&a&&await f.mutation("handler:logMessage",{missionId:a,type:"Ghost",message:"WAF bypassed. Biometric jitter active."}),await new Promise(g=>setTimeout(g,1e3)),h.success("[Ghost] : Obfuscation layer verified."),f&&a&&await f.mutation("handler:logMessage",{missionId:a,type:"Ghost",message:"Obfuscation layer verified."}),h.step("[Breacher] : Analyzing DOM for logic flaws via Cerebras..."),f&&a&&await f.mutation("handler:logMessage",{missionId:a,type:"Breacher",message:"Analyzing DOM for logic flaws via Cerebras..."});try{let g=[];if(e.swarm)h.info(i.magenta("\u{1F6F8} [System] : Deploying Specialized Task Force Swarm...")),g=(await Promise.all([N(s,"ACCOUNTANT"),N(s,"ADMIN"),N(s,"CHAOS_MONKEY"),N(s,"ARCHITECT"),N(s,"GHOST")])).filter(E=>E.vulnerabilityFound);else{let m=await N(s);m.vulnerabilityFound&&g.push(m)}h.success(`[Breacher] : Analysis complete. ${g.length} vulnerabilities isolated.`),f&&a&&await f.mutation("handler:logMessage",{missionId:a,type:"Breacher",message:`Analysis complete. Found ${g.length} vectors.`});let S=[];for(let m of g){let E=null;e.liveFire&&(h.step(`[Executor] : Launching Live-Fire mutation against ${m.title}...`),E=await re(r,m,e),E.success?(h.success(`[Executor] : Mutation executed. Captured ${E.evidence.length} bytes of evidence.`),m.body=E.evidence):h.warn(`[Executor] : Execution failed: ${E.error}`)),h.step(`[Critic] : Verifying ${m.title}...`);let b=await o.crossExamine(m,s),n=b.isReal;if(!n){h.info(i.yellow(`[System] : ${m.title} debunked by Critic Node. Ignoring.`));continue}S.push(m);let y=(A=>({title:A.title||"Unknown Logic Flaw",vector:A.vector||"Vector analysis inconclusive.",severity:A.severity||"MEDIUM",targetElement:A.targetElement||A.target||"General DOM Context",target:A.target||A.targetElement||"General DOM Context",mitigation:b.enhancedMitigation||A.mitigation||"Implement standard server-side validation guards.",thoughtProcess:b.reasoning||A.thoughtProcess||"Reasoning engine offline."}))(m),k=y.thoughtProcess.includes("Accountant")?"THE ACCOUNTANT":y.thoughtProcess.includes("Admin")?"THE ADMIN":y.thoughtProcess.includes("Chaos")?"THE CHAOS MONKEY":y.thoughtProcess.includes("Architect")?"THE ARCHITECT":y.thoughtProcess.includes("Ghost")?"THE GHOST NODE":"GENERAL BREACHER",D=null;n&&(h.step("[Scribe] : Automating remedial code patch..."),D=await ne(m,b,p)),console.log(`
|
|
103
|
+
`+i.bold(i.red(` \u26A0 EXPLOIT SUCCESSFUL [${y.title}]`))),console.log(i.cyan(` \u25C7 AGENT IDENTIFIED: ${k}`)),console.log(i.red(` Vector: ${y.vector}`)),console.log(i.red(` Target: ${y.targetElement}`)),console.log(i.red(` Severity: ${y.severity}
|
|
104
|
+
`)),f&&a&&await f.mutation("handler:logExploit",{missionId:a,...y});let K=y.mitigation,q=y.thoughtProcess,U=["OPERATOR","CARTEL","STATE_ACTOR"].includes(c);if(y.mitigation){let j=(L,v)=>L.match(new RegExp(`.{1,${v}}(\\s|$)`,"g"))||[L],P=(L,v)=>`\u2502 ${L.trim().padEnd(v-4)} \u2502`,ae=m.title.length>30?m.title.substring(0,27)+"...":m.title,Se=Math.max(0,37-ae.length);console.log(i.cyan(`\u25C7 SICARIO REASONING [${ae}] ${"\u2500".repeat(Se)}\u256E`)),U?j(q,56).forEach(v=>console.log(i.cyan(P(v,60)))):(console.log(i.yellow(P("\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 [REASONING REDACTED] \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588",60))),console.log(i.yellow(P("Upgrade to OPERATOR tier to unlock logic logs.",60)))),console.log(i.cyan(`\u251C${"\u2500".repeat(58)}\u2524`)),console.log(i.cyan(`\u2502 ${i.bold("FIX RECOMMENDATION").padEnd(56)} \u2502`)),U?j(K,56).forEach(v=>console.log(i.cyan(P(v,60)))):(console.log(i.red(P("\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 [MITIGATION REDACTED] \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588",60))),console.log(i.white(P("Visit sicario-red-team.com to unlock the patch.",60)))),D&&(console.log(i.green(`\u251C${"\u2500".repeat(58)}\u2524`)),console.log(i.green(`\u2502 ${i.bold("SCRIBE REMEDIATION PATCH (CURSOR-READY)").padEnd(56)} \u2502`)),j(D,56).forEach(v=>console.log(i.green(P(v,60))))),console.log(i.cyan(`\u251C${"\u2500".repeat(58)}\u256F`)+`
|
|
105
|
+
`)}}if(S.length===0){let m=s.filter(n=>n.tag==="form").length,E=s.filter(n=>n.tag==="input"||n.tag==="textarea").length,b=s.filter(n=>n.tag==="button"||n.tag==="a").length;h.info(T.dim("No high-value business logic targets identified.")),console.log(i.cyan(`
|
|
106
|
+
\u25C7 SWARM INTELLIGENCE REPORT \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256E`)),console.log(i.cyan(`\u2502 Attack Surface: ${i.bold(s.length)} potential entry points mapped. \u2502`)),console.log(i.cyan(`\u2502 Architecture: ${i.bold(m)} forms and ${i.bold(E)} input vectors identified. \u2502`)),console.log(i.cyan(`\u2502 Active Paths: ${i.bold(b)} state-changing actions logged. \u2502`)),console.log(i.cyan("\u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256F"))}let I=[`${T.dim("Target")} ${T.bold(r)}`,`${T.dim("Nodes Recalled")} ${T.bold(e.swarm?"7 (Scout, Ghost, Accountant, Admin, Chaos, Architect, Critic)":"3 (Scout, Ghost, Breacher)")}`,`${T.dim("Breaches Found")} ${S.length>0?i.red(i.bold(S.length)):T.bold("0")}`,`${T.dim("Status")} ${T.success("MISSION SUCCESSFUL")}`];console.log(i.green(`
|
|
107
|
+
\u250C MISSION DOSSIER \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256E`)),I.forEach(m=>console.log(i.green(`\u2502 ${m.padEnd(54)} \u2502`))),console.log(i.green("\u2514 Mission complete. Trace extraction successful. \u256F")),console.log(i.dim(`
|
|
108
|
+
SYSTEM SIGNATURE:`)),console.log(i.dim(`SHA-256: ${ce("crypto").createHash("sha256").update(r+Date.now()).digest("hex").substring(0,32)}`)),console.log(i.dim(`AGENT ID: ${Math.random().toString(36).substring(7).toUpperCase()}`)),console.log(i.dim(`TIMESTAMP: ${new Date().toISOString()}`))}catch(g){h.error("[Breacher] : Analysis node failure."),h.error(g.message)}}catch(s){h.error(`Mission failed: ${s.message}`)}finally{f&&a&&await f.mutation("handler:closeMission",{missionId:a}),Ne(T.brand("Mission complete. Trace extraction successful.")),process.exit(0)}}import{createRequire as Fe}from"module";import C from"picocolors";import"dotenv/config";import{ConvexClient as ze}from"convex/browser";import{chromium as Ue}from"playwright";import He from"crypto";async function le(t,e={depth:2,maxPages:20}){let o=await Ue.launch({headless:!0}),r=await o.newContext(),c=new URL(t).hostname,l=new Set,a=[{url:t,depth:0}],u=[];for(;a.length>0&&u.length<e.maxPages;){let{url:s,depth:p}=a.shift();if(!(l.has(s)||p>e.depth)){l.add(s),console.log(`[Cartographer] Mapping: ${s} (Depth: ${p})`);try{let g=await r.newPage();await g.goto(s,{waitUntil:"networkidle",timeout:3e4}),await g.waitForSelector("button, input, a",{timeout:5e3}).catch(()=>{});let S=await g.evaluate(()=>{let m=Array.from(document.querySelectorAll("a")).map(n=>n.href).filter(n=>n&&n.startsWith(window.location.origin)),E=Array.from(document.querySelectorAll("button, input, form, select")).map(n=>({tag:n.tagName.toLowerCase(),id:n.id||null,name:n.name||null,type:n.type||null,text:n.innerText?.trim().substring(0,30)||null})),b=document.body.innerHTML;return{links:m,elements:E,html:b}}),I=He.createHash("sha256").update(S.html).digest("hex");if(u.push({url:s,path:new URL(s).pathname,elements:S.elements,hash:I,timestamp:Date.now()}),p<e.depth)for(let m of S.links){let E=new URL(m).origin+new URL(m).pathname;l.has(E)||a.push({url:E,depth:p+1})}await g.close()}catch(g){console.error(`[Cartographer] Failed to map ${s}: ${g.message}`)}}}return await o.close(),u}var Be=Fe(import.meta.url),Ge=Be("@clack/prompts"),{intro:Ve,outro:_e,log:V,note:Ye,text:We,isCancel:Ke,cancel:qe,spinner:je}=Ge,X=process.env.CONVEX_URL?new ze(process.env.CONVEX_URL):null;async function me(t,e){let o=t;o||(o=await We({message:"Target for Sustained Siege",placeholder:"https://staging.example.com",validate:c=>{if(!c)return"Target is required";if(!c.startsWith("http"))return"Invalid URL format"}}),Ke(o)&&(qe("Siege aborted."),process.exit(0))),Ve(T.brand("Project Sicario - Sustained Siege Protocol")),V.info(C.magenta("\u25C8 MODE: CONTINUOUS MONITORING (24/7)")),V.info(C.magenta(`\u25C8 LICENSE TIER: ${C.bold("STATE-ACTOR")}`)),X||(V.error("Convex URL not found. Persistent Siege requires a backend."),process.exit(1));let r=je();r.start('Establishing "Invisible Employee" presence...');try{let c=await X.mutation("siege:startSiege",{url:o});r.message("Target locked. Initializing Cartographer node...");let l=await le(o,{depth:1,maxPages:10});r.message("Mapping results. Syncing to shadow map..."),await X.mutation("siege:syncMap",{targetId:c,siteMap:l}),r.stop(C.green("Siege Established. Trace extraction active.")),Ye(`Sicario has successfully entrenced in ${o}.
|
|
109
|
+
The "Observer" daemon will probe every 60 minutes.
|
|
110
|
+
Visit the War Room dashboard to view the shadow map.`,"SIEGE ACTIVE"),console.log(C.cyan(`
|
|
111
|
+
\u250C DEPLOYED PILLARS \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256E`)),console.log(C.cyan("\u2502 \u2713 Cartographer : Recursive Mapping Active \u2502")),console.log(C.cyan("\u2502 \u2713 Observer : Hourly Drift Detection Active \u2502")),console.log(C.cyan("\u2502 \u2713 Fuzzer : Slow-Drip Logic Testing Active \u2502")),console.log(C.cyan(`\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256F
|
|
112
|
+
`)),_e(T.brand("Mission initialized. Entrenchment complete.")),process.exit(0)}catch(c){r.stop("Siege deployment failed."),V.error(c.message),process.exit(1)}}import{createRequire as Xe}from"module";import Y from"picocolors";var Je=Xe(import.meta.url),Ze=Je("@clack/prompts"),{log:_}=Ze;async function ue(t,e){let o=null,r=15e3;_.step(Y.cyan(`[Watcher] : Initiating Lazy Watcher for ${t}...`)),_.info(Y.dim("Status: Monitoring structure. Min cooldown: 15s. API calls only on change."));try{await H(t,e)}catch{}for(;;)try{let{elements:c}=await B(t,e),l=c.map(u=>({tag:u.tag,id:u.id,name:u.name,type:u.type})),a=JSON.stringify(l);a!==o?(o!==null&&(_.step(Y.yellow(`
|
|
113
|
+
[Watcher] : Structural change detected. Initializing mini-siege...`)),await H(t,e)),o=a):process.stdout.write(Y.dim(".")),await new Promise(u=>setTimeout(u,r))}catch{_.error("[Watcher] : Connection error. Retrying..."),await new Promise(l=>setTimeout(l,5e3))}}import F from"fs";import de from"path";import Qe from"os";import ge from"ini";var J=de.join(Qe.homedir(),".sicario"),Z=de.join(J,"config");function pe(){if(!F.existsSync(Z))return{};try{let t=F.readFileSync(Z,"utf-8");return ge.parse(t)}catch{return{}}}function et(t){F.existsSync(J)||F.mkdirSync(J,{recursive:!0});let e=ge.stringify(t);F.writeFileSync(Z,e,"utf-8")}function he(){let t=pe();return process.env.CEREBRAS_API_KEY||t.CEREBRAS_API_KEY}function fe(t){let e=pe();e.CEREBRAS_API_KEY=t,et(e)}import{chromium as tt}from"playwright";import ot from"fs";import at from"readline";import it from"path";import M from"picocolors";var Q=it.join(process.cwd(),".sicario-vault.json"),R=class{constructor(){this.rl=at.createInterface({input:process.stdin,output:process.stdout})}async captureSession(e){console.log(`
|
|
114
|
+
${M.cyan("[?] Keymaster initiating manual breach on:")} ${M.bold(e)}`),console.log(` ${M.yellow("[!] Action Required: A browser will open. Log in, pass MFA, and navigate to the dashboard.")}`);try{let o=await tt.launch({headless:!1}),r=await o.newContext();await(await r.newPage()).goto(e),await new Promise(l=>{this.rl.question(`
|
|
115
|
+
${M.green("[+] Press [ENTER] here when you are fully logged in and ready for state extraction...")}`,l)}),await r.storageState({path:Q}),await o.close(),this.rl.close(),console.log(`
|
|
116
|
+
${M.green("[\u2714] Session Extracted and Vaulted successfully.")}`),console.log(` ${M.red("[!] CRITICAL: Ensure .sicario-vault.json is in your .gitignore")}
|
|
117
|
+
`)}catch(o){console.error(M.red(`
|
|
118
|
+
[X] Keymaster capture failed: ${o.message}`)),this.rl.close(),process.exit(1)}}static getVaultPath(){return Q}static hasVault(){return ot.existsSync(Q)}};var ct=st(import.meta.url),O=ct("@clack/prompts"),lt=nt(import.meta.url),mt=te.dirname(lt);we.config({quiet:!0});var Ee=te.resolve(process.cwd(),".env.local");ye.existsSync(Ee)&&we.config({path:Ee,override:!0,quiet:!0});var ut=process.env.PREFIX&&process.env.PREFIX.includes("com.termux"),$=new rt,dt=te.join(mt,"../package.json"),W=JSON.parse(ye.readFileSync(dt,"utf8"));$.name("sicario").description("Autonomous Agentic Red-Teaming Swarm Protocol").version(W.version);async function oe(){let t=["The Cartographer","The Ghost","The Breacher","The Accountant","The Admin","The Critic","The Scribe"];ut&&(console.log("\u{1F6F8} \x1B[32mSicario Detected: Termux Environment\x1B[0m"),console.log(` Note: Using native Chromium bridge for sieges.
|
|
119
|
+
`));for(let e of t)await new Promise(o=>setTimeout(o,100)),console.log(` \x1B[32m[\u2714]\x1B[0m Node Online: \x1B[1m${e}\x1B[0m`);console.log(`
|
|
120
|
+
\x1B[32m[!] Swarm Entrenched. Commencing Hit...\x1B[0m
|
|
121
|
+
`)}$.command("hit").description("Launch an autonomous swarm attack on a target").argument("[target]","Target URL (positional)").option("-t, --target <url>","Target URL (option)").option("--swarm","Deploy multiple specialized nodes in parallel").option("--tier <level>","Sicario Tier (SHADOW|OPERATOR|CARTEL)","SHADOW").option("--auth <string>","Session token or cookie string for authenticated scans").option("--intent <string>","Focus swarm on a specific red-team intent").option("--live-fire","DANGEROUS: Skip simulation and execute live POST/PUT mutations").action(async(t,e)=>{try{let o=t||e.target;if(e.target=o,!(process.env.CEREBRAS_API_KEY||he())){O.intro(ee.magenta(ee.bold("Project Sicario - First Run Onboarding"))),O.note(`Sicario requires a Cerebras inference engine to simulate business logic attacks.
|
|
122
|
+
`+ee.cyan("Get your free key here: https://cloud.cerebras.ai"),"IDENTITY REQUIRED");let c=await O.password({message:"Paste your Cerebras API Key",validate:l=>{if(!l)return"Key is required to proceed";if(!l.startsWith("csk-"))return"Invalid key format (should start with csk-)"}});O.isCancel(c)&&(O.cancel("Operation aborted."),process.exit(0)),fe(c),process.env.CEREBRAS_API_KEY=c}console.log(`\x1B[1m\x1B[32m[+] DEPLOYING SICARIO RED-TEAM SWARM v${W.version}\x1B[0m`),!e.auth&&R.hasVault()&&(console.log("\x1B[36m[*] Keymaster: Vaulted session detected. Injecting into swarm...\x1B[0m"),e.vault=R.getVaultPath()),await oe(),await H(e.target,e)}catch(o){console.error("Fatal: Failed to execute swarm mission."),console.error(o),process.exit(1)}});$.command("siege").description("Launch a Sustained Siege (Continuous Monitoring)").argument("[target]","Target URL").option("-t, --target <url>","Target URL").option("--intent <string>","Specific red-team intent for the siege").option("--live-fire","DANGEROUS: Skip simulation and execute live POST/PUT mutations").action(async(t,e)=>{try{e.target=t||e.target,console.log(`\x1B[1m\x1B[32m[+] INITIATING SUSTAINED SICARIO SIEGE v${W.version}\x1B[0m`),!e.auth&&R.hasVault()&&(console.log("\x1B[36m[*] Keymaster: Vaulted session detected. Injecting into siege overwatch...\x1B[0m"),e.vault=R.getVaultPath()),await oe(),await me(e.target,e)}catch(o){console.error("Fatal: Failed to execute sustained siege."),console.error(o),process.exit(1)}});$.command("auth").description("Human-in-the-loop session extraction (The Keymaster)").argument("[target]","Target login URL").action(async t=>{let e=new R,o=t||await O.text({message:"Establish breach point (Login URL)",placeholder:"https://example.com/login"});O.isCancel(o)&&(O.cancel("Operation aborted."),process.exit(0)),await e.captureSession(o)});$.command("watch").description("Continuous Localhost Siege (Lazy Watcher)").argument("[target]","Target URL").option("-t, --target <url>","Target URL").action(async(t,e)=>{try{e.target=t||e.target,console.log(`\x1B[1m\x1B[32m[+] ACTIVATING LAZY WATCHER v${W.version}\x1B[0m`),!e.auth&&R.hasVault()&&(console.log("\x1B[36m[*] Keymaster: Vaulted session detected. Injecting into watcher...\x1B[0m"),e.vault=R.getVaultPath()),await oe(),await ue(e.target,e)}catch(o){console.error("Fatal: Failed to activate watcher."),console.error(o),process.exit(1)}});try{$.parse(process.argv)}catch(t){console.error(t)}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sicario-red-team",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Autonomous Agentic Red-Teaming Swarm Protocol",
|
|
6
6
|
"repository": {
|
|
@@ -18,21 +18,18 @@
|
|
|
18
18
|
],
|
|
19
19
|
"author": "Project Sicario",
|
|
20
20
|
"license": "MIT",
|
|
21
|
+
"main": "dist/sicario.js",
|
|
21
22
|
"bin": {
|
|
22
|
-
"sicario": "./
|
|
23
|
-
"sicario-red-team": "./
|
|
23
|
+
"sicario": "./dist/sicario.js",
|
|
24
|
+
"sicario-red-team": "./dist/sicario.js"
|
|
24
25
|
},
|
|
25
26
|
"files": [
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"convex"
|
|
27
|
+
"dist",
|
|
28
|
+
"README.md"
|
|
29
29
|
],
|
|
30
30
|
"scripts": {
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
|
|
34
|
-
"preview": "vite preview",
|
|
35
|
-
"cli": "node bin/sicario.js"
|
|
31
|
+
"build:cli": "npx esbuild bin/sicario.js --bundle --platform=node --target=node18 --minify --banner:js=\"#!/usr/bin/env node\" --outfile=dist/sicario.js --external:playwright --external:framer-motion --external:vite --external:react --external:react-dom --external:convex",
|
|
32
|
+
"cli": "node dist/sicario.js"
|
|
36
33
|
},
|
|
37
34
|
"dependencies": {
|
|
38
35
|
"@cerebras/cerebras_cloud_sdk": "^1.0.0",
|
|
@@ -56,18 +53,6 @@
|
|
|
56
53
|
"tailwindcss-animate": "^1.0.7"
|
|
57
54
|
},
|
|
58
55
|
"devDependencies": {
|
|
59
|
-
"
|
|
60
|
-
"@types/react-dom": "^18.2.22",
|
|
61
|
-
"@typescript-eslint/eslint-plugin": "^7.2.0",
|
|
62
|
-
"@typescript-eslint/parser": "^7.2.0",
|
|
63
|
-
"@vitejs/plugin-react": "^4.2.1",
|
|
64
|
-
"autoprefixer": "^10.4.19",
|
|
65
|
-
"eslint": "^8.57.0",
|
|
66
|
-
"eslint-plugin-react-hooks": "^4.6.0",
|
|
67
|
-
"eslint-plugin-react-refresh": "^0.4.6",
|
|
68
|
-
"postcss": "^8.4.38",
|
|
69
|
-
"tailwindcss": "^3.4.3",
|
|
70
|
-
"typescript": "^5.2.2",
|
|
71
|
-
"vite": "^5.2.0"
|
|
56
|
+
"esbuild": "^0.20.0"
|
|
72
57
|
}
|
|
73
58
|
}
|
package/bin/sicario.js
DELETED
|
@@ -1,213 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import dotenv from 'dotenv';
|
|
3
|
-
import path from 'path';
|
|
4
|
-
import fs from 'fs';
|
|
5
|
-
|
|
6
|
-
// Detect Environment
|
|
7
|
-
const isTermux = process.env.PREFIX && process.env.PREFIX.includes('com.termux');
|
|
8
|
-
|
|
9
|
-
if (isTermux) {
|
|
10
|
-
console.log('πΈ \x1b[32mSicario Detected: Termux Environment\x1b[0m');
|
|
11
|
-
console.log(' Note: Using native Chromium bridge for sieges.\n');
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
// Silently initialize dotenv
|
|
15
|
-
dotenv.config({ quiet: true });
|
|
16
|
-
|
|
17
|
-
// Load .env.local if it exists (for Convex)
|
|
18
|
-
const envLocalPath = path.resolve(process.cwd(), '.env.local');
|
|
19
|
-
if (fs.existsSync(envLocalPath)) {
|
|
20
|
-
dotenv.config({ path: envLocalPath, override: true, quiet: true });
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
import { Command } from 'commander';
|
|
24
|
-
import { pathToFileURL, fileURLToPath } from 'url';
|
|
25
|
-
import pc from 'picocolors';
|
|
26
|
-
import { getApiKey, setApiKey } from '../src-cli/utils/config.js';
|
|
27
|
-
import { Keymaster } from '../src-cli/services/keymaster.js';
|
|
28
|
-
import { createRequire } from 'module';
|
|
29
|
-
const require = createRequire(import.meta.url);
|
|
30
|
-
const clack = require('@clack/prompts');
|
|
31
|
-
|
|
32
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
33
|
-
const __dirname = path.dirname(__filename);
|
|
34
|
-
|
|
35
|
-
const program = new Command();
|
|
36
|
-
|
|
37
|
-
// Version should ideally come from package.json
|
|
38
|
-
const pkgPath = path.join(__dirname, '../package.json');
|
|
39
|
-
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
40
|
-
|
|
41
|
-
program
|
|
42
|
-
.name('sicario')
|
|
43
|
-
.description('Autonomous Agentic Red-Teaming Swarm Protocol')
|
|
44
|
-
.version(pkg.version);
|
|
45
|
-
|
|
46
|
-
async function bootSwarm() {
|
|
47
|
-
const nodes = [
|
|
48
|
-
'The Cartographer', 'The Ghost', 'The Breacher',
|
|
49
|
-
'The Accountant', 'The Admin', 'The Critic', 'The Scribe'
|
|
50
|
-
];
|
|
51
|
-
|
|
52
|
-
for (const node of nodes) {
|
|
53
|
-
// A quick 100ms delay to make it feel like "loading"
|
|
54
|
-
await new Promise(r => setTimeout(r, 100));
|
|
55
|
-
console.log(` \x1b[32m[β]\x1b[0m Node Online: \x1b[1m${node}\x1b[0m`);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
console.log('\n\x1b[32m[!] Swarm Entrenched. Commencing Hit...\x1b[0m\n');
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
// Use a more robust way to import the command logic relative to this file
|
|
62
|
-
const hitCommandPath = pathToFileURL(path.join(__dirname, '../src-cli/commands/hit.js')).href;
|
|
63
|
-
|
|
64
|
-
program
|
|
65
|
-
.command('hit')
|
|
66
|
-
.description('Launch an autonomous swarm attack on a target')
|
|
67
|
-
.argument('[target]', 'Target URL (positional)')
|
|
68
|
-
.option('-t, --target <url>', 'Target URL (option)')
|
|
69
|
-
.option('--swarm', 'Deploy multiple specialized nodes in parallel')
|
|
70
|
-
.option('--tier <level>', 'Sicario Tier (SHADOW|OPERATOR|CARTEL)', 'SHADOW')
|
|
71
|
-
.option('--auth <string>', 'Session token or cookie string for authenticated scans')
|
|
72
|
-
.option('--intent <string>', 'Focus swarm on a specific red-team intent (e.g. "bypass billing")')
|
|
73
|
-
.option('--live-fire', 'DANGEROUS: Skip simulation and execute live POST/PUT mutations')
|
|
74
|
-
.action(async (posTarget, options) => {
|
|
75
|
-
try {
|
|
76
|
-
const finalTarget = posTarget || options.target; // Support both styles
|
|
77
|
-
options.target = finalTarget;
|
|
78
|
-
|
|
79
|
-
// API Key Check & Viral Hook
|
|
80
|
-
let apiKey = process.env.CEREBRAS_API_KEY || getApiKey();
|
|
81
|
-
|
|
82
|
-
if (!apiKey) {
|
|
83
|
-
clack.intro(pc.magenta(pc.bold('Project Sicario - First Run Onboarding')));
|
|
84
|
-
clack.note(
|
|
85
|
-
'Sicario requires a Cerebras inference engine to simulate business logic attacks.\n' +
|
|
86
|
-
pc.cyan('Get your free key here: https://cloud.cerebras.ai'),
|
|
87
|
-
'IDENTITY REQUIRED'
|
|
88
|
-
);
|
|
89
|
-
|
|
90
|
-
const key = await clack.password({
|
|
91
|
-
message: 'Paste your Cerebras API Key',
|
|
92
|
-
validate: (value) => {
|
|
93
|
-
if (!value) return 'Key is required to proceed';
|
|
94
|
-
if (!value.startsWith('csk-')) return 'Invalid key format (should start with csk-)';
|
|
95
|
-
},
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
if (clack.isCancel(key)) {
|
|
99
|
-
clack.cancel('Operation aborted. Sicario cannot hunt without a brain.');
|
|
100
|
-
process.exit(0);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
setApiKey(key);
|
|
104
|
-
process.env.CEREBRAS_API_KEY = key;
|
|
105
|
-
clack.log.success('Key saved to ~/.sicario/config. Resuming mission...');
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
console.log(`\x1b[1m\x1b[32m[+] DEPLOYING SICARIO RED-TEAM SWARM v${pkg.version}\x1b[0m`);
|
|
109
|
-
|
|
110
|
-
// Auto-Vault Detection
|
|
111
|
-
if (!options.auth && Keymaster.hasVault()) {
|
|
112
|
-
console.log(`\x1b[36m[*] Keymaster: Vaulted session detected. Injecting into swarm...\x1b[0m`);
|
|
113
|
-
options.vault = Keymaster.getVaultPath();
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
// Premium Boot Sequence
|
|
117
|
-
await bootSwarm();
|
|
118
|
-
|
|
119
|
-
const { hitCommand } = await import(hitCommandPath);
|
|
120
|
-
await hitCommand(options.target, options);
|
|
121
|
-
} catch (err) {
|
|
122
|
-
console.error('Fatal: Failed to load command logic.');
|
|
123
|
-
console.error(err);
|
|
124
|
-
process.exit(1);
|
|
125
|
-
}
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
const siegeCommandPath = pathToFileURL(path.join(__dirname, '../src-cli/commands/siege.js')).href;
|
|
129
|
-
|
|
130
|
-
program
|
|
131
|
-
.command('siege')
|
|
132
|
-
.description('Launch a Sustained Siege (Continuous Monitoring)')
|
|
133
|
-
.argument('[target]', 'Target URL')
|
|
134
|
-
.option('-t, --target <url>', 'Target URL')
|
|
135
|
-
.option('--intent <string>', 'Specific red-team intent for the siege')
|
|
136
|
-
.option('--live-fire', 'DANGEROUS: Skip simulation and execute live POST/PUT mutations')
|
|
137
|
-
.action(async (posTarget, options) => {
|
|
138
|
-
try {
|
|
139
|
-
options.target = posTarget || options.target;
|
|
140
|
-
|
|
141
|
-
console.log(`\x1b[1m\x1b[32m[+] INITIATING SUSTAINED SICARIO SIEGE v${pkg.version}\x1b[0m`);
|
|
142
|
-
|
|
143
|
-
// Auto-Vault Detection
|
|
144
|
-
if (!options.auth && Keymaster.hasVault()) {
|
|
145
|
-
console.log(`\x1b[36m[*] Keymaster: Vaulted session detected. Injecting into siege overwatch...\x1b[0m`);
|
|
146
|
-
options.vault = Keymaster.getVaultPath();
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
// Premium Boot Sequence
|
|
150
|
-
await bootSwarm();
|
|
151
|
-
|
|
152
|
-
const { siegeCommand } = await import(siegeCommandPath);
|
|
153
|
-
await siegeCommand(options.target, options);
|
|
154
|
-
} catch (err) {
|
|
155
|
-
console.error('Fatal: Failed to load siege command logic.');
|
|
156
|
-
console.error(err);
|
|
157
|
-
process.exit(1);
|
|
158
|
-
}
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
program
|
|
162
|
-
.command('auth')
|
|
163
|
-
.description('Human-in-the-loop session extraction (The Keymaster)')
|
|
164
|
-
.argument('[target]', 'Target login URL')
|
|
165
|
-
.action(async (target) => {
|
|
166
|
-
const keymaster = new Keymaster();
|
|
167
|
-
const finalTarget = target || await clack.text({
|
|
168
|
-
message: 'Establish breach point (Login URL)',
|
|
169
|
-
placeholder: 'https://example.com/login'
|
|
170
|
-
});
|
|
171
|
-
|
|
172
|
-
if (clack.isCancel(finalTarget)) {
|
|
173
|
-
clack.cancel('Operation aborted.');
|
|
174
|
-
process.exit(0);
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
await keymaster.captureSession(finalTarget);
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
const watchCommandPath = pathToFileURL(path.join(__dirname, '../src-cli/commands/watch.js')).href;
|
|
181
|
-
|
|
182
|
-
program
|
|
183
|
-
.command('watch')
|
|
184
|
-
.description('Continuous Localhost Siege (Lazy Watcher)')
|
|
185
|
-
.argument('[target]', 'Target URL')
|
|
186
|
-
.option('-t, --target <url>', 'Target URL')
|
|
187
|
-
.action(async (posTarget, options) => {
|
|
188
|
-
try {
|
|
189
|
-
options.target = posTarget || options.target;
|
|
190
|
-
|
|
191
|
-
console.log(`\x1b[1m\x1b[32m[+] ACTIVATING LAZY WATCHER v${pkg.version}\x1b[0m`);
|
|
192
|
-
|
|
193
|
-
if (!options.auth && Keymaster.hasVault()) {
|
|
194
|
-
console.log(`\x1b[36m[*] Keymaster: Vaulted session detected. Injecting into watcher...\x1b[0m`);
|
|
195
|
-
options.vault = Keymaster.getVaultPath();
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
await bootSwarm();
|
|
199
|
-
|
|
200
|
-
const { watchCommand } = await import(watchCommandPath);
|
|
201
|
-
await watchCommand(options.target, options);
|
|
202
|
-
} catch (err) {
|
|
203
|
-
console.error('Fatal: Failed to load watcher command logic.');
|
|
204
|
-
console.error(err);
|
|
205
|
-
process.exit(1);
|
|
206
|
-
}
|
|
207
|
-
});
|
|
208
|
-
|
|
209
|
-
try {
|
|
210
|
-
program.parse(process.argv);
|
|
211
|
-
} catch (err) {
|
|
212
|
-
console.error(err);
|
|
213
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"guidelinesHash": "deca8f973b701e27f65ab9d2b189201fcbcefcf524e9bc44c413ab3109e35993",
|
|
3
|
-
"agentsMdSectionHash": "bbf30bd25ceea0aefd279d62e1cb2b4c207fcb712b69adf26f3d02b296ffc7b2",
|
|
4
|
-
"claudeMdHash": "bbf30bd25ceea0aefd279d62e1cb2b4c207fcb712b69adf26f3d02b296ffc7b2",
|
|
5
|
-
"agentSkillsSha": "cd697e02ca46ccbc445418785e03ad87a35617c9",
|
|
6
|
-
"installedSkillNames": [
|
|
7
|
-
"convex-create-component",
|
|
8
|
-
"convex-migration-helper",
|
|
9
|
-
"convex-performance-audit",
|
|
10
|
-
"convex-quickstart",
|
|
11
|
-
"convex-setup-auth"
|
|
12
|
-
]
|
|
13
|
-
}
|