pentesting 0.73.12 → 0.73.14
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 +5 -0
- package/dist/{agent-tool-RTF2W3GB.js → agent-tool-MMDCBQ74.js} +3 -3
- package/dist/{chunk-4DUF6JX2.js → chunk-4KLVUP3C.js} +118 -67
- package/dist/{chunk-5JXATHQ3.js → chunk-AEQNELCQ.js} +272 -85
- package/dist/{chunk-S5ZMXFHR.js → chunk-YZNPWDNS.js} +12 -8
- package/dist/main.js +319 -206
- package/dist/{persistence-DC6QI7XQ.js → persistence-IGAKJZJ3.js} +2 -2
- package/dist/{process-registry-4Y3HB4YQ.js → process-registry-DNEZX4S5.js} +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -44,9 +44,14 @@ docker run -it --rm \
|
|
|
44
44
|
-e PENTEST_API_KEY="your_key" \
|
|
45
45
|
-e PENTEST_BASE_URL="https://api.z.ai/api/anthropic" \
|
|
46
46
|
-e PENTEST_MODEL="glm-4.7" \
|
|
47
|
+
-v pentesting-data:/tmp/.pentesting \
|
|
47
48
|
agnusdei1207/pentesting
|
|
48
49
|
```
|
|
49
50
|
|
|
51
|
+
Docker stores workspace state under `/tmp/.pentesting` inside the container.
|
|
52
|
+
The entrypoint resets that directory on each fresh container start to avoid mixing stale state into a new run.
|
|
53
|
+
Mount that path if you want access to `.pentesting/turns`, `.pentesting/sessions`, `.pentesting/memory`, and workspace artifacts after an OOM or while the same container is still alive.
|
|
54
|
+
|
|
50
55
|
### 🐉 Kali Linux (Native)
|
|
51
56
|
|
|
52
57
|
```bash
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
createContextExtractor,
|
|
6
6
|
getLLMClient,
|
|
7
7
|
getShellSupervisorLifecycleSnapshot
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-4KLVUP3C.js";
|
|
9
9
|
import {
|
|
10
10
|
AGENT_ROLES,
|
|
11
11
|
EVENT_TYPES,
|
|
@@ -13,14 +13,14 @@ import {
|
|
|
13
13
|
TOOL_NAMES,
|
|
14
14
|
getProcessOutput,
|
|
15
15
|
listBackgroundProcesses
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-AEQNELCQ.js";
|
|
17
17
|
import {
|
|
18
18
|
DETECTION_PATTERNS,
|
|
19
19
|
PROCESS_EVENTS,
|
|
20
20
|
PROCESS_ROLES,
|
|
21
21
|
getActiveProcessSummary,
|
|
22
22
|
getProcessEventLog
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-YZNPWDNS.js";
|
|
24
24
|
|
|
25
25
|
// src/engine/agent-tool/completion-box.ts
|
|
26
26
|
function createCompletionBox() {
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
DANGER_LEVELS,
|
|
11
11
|
DANGER_LEVEL_MAP,
|
|
12
12
|
DEFAULTS,
|
|
13
|
+
DEFAULT_MODEL,
|
|
13
14
|
DISPLAY_LIMITS,
|
|
14
15
|
DynamicTechniqueLibrary,
|
|
15
16
|
EVENT_TYPES,
|
|
@@ -52,11 +53,19 @@ import {
|
|
|
52
53
|
generateId,
|
|
53
54
|
generatePrefixedId,
|
|
54
55
|
getActiveSessionRuntime,
|
|
56
|
+
getApiKey,
|
|
57
|
+
getBaseUrl,
|
|
55
58
|
getErrorMessage,
|
|
59
|
+
getModel,
|
|
56
60
|
getProcessOutput,
|
|
61
|
+
getSearchApiKey,
|
|
62
|
+
getSearchApiUrl,
|
|
63
|
+
getThinkingBudget,
|
|
57
64
|
getTorBrowserArgs,
|
|
58
65
|
getUsedPorts,
|
|
59
66
|
isBranchMemoryEnabled,
|
|
67
|
+
isThinkingEnabled,
|
|
68
|
+
isZaiProvider,
|
|
60
69
|
listBackgroundProcesses,
|
|
61
70
|
llmNodeCooldownPolicy,
|
|
62
71
|
llmNodeOutputParsing,
|
|
@@ -69,7 +78,7 @@ import {
|
|
|
69
78
|
startBackgroundProcess,
|
|
70
79
|
stopBackgroundProcess,
|
|
71
80
|
writeFileContent
|
|
72
|
-
} from "./chunk-
|
|
81
|
+
} from "./chunk-AEQNELCQ.js";
|
|
73
82
|
import {
|
|
74
83
|
DETECTION_PATTERNS,
|
|
75
84
|
HEALTH_CONFIG,
|
|
@@ -83,59 +92,7 @@ import {
|
|
|
83
92
|
__require,
|
|
84
93
|
getProcessEventLog,
|
|
85
94
|
logEvent
|
|
86
|
-
} from "./chunk-
|
|
87
|
-
|
|
88
|
-
// src/shared/utils/config/env.ts
|
|
89
|
-
var ENV_KEYS = {
|
|
90
|
-
API_KEY: "PENTEST_API_KEY",
|
|
91
|
-
BASE_URL: "PENTEST_BASE_URL",
|
|
92
|
-
MODEL: "PENTEST_MODEL",
|
|
93
|
-
SEARCH_API_KEY: "SEARCH_API_KEY",
|
|
94
|
-
SEARCH_API_URL: "SEARCH_API_URL",
|
|
95
|
-
THINKING: "PENTEST_THINKING",
|
|
96
|
-
THINKING_BUDGET: "PENTEST_THINKING_BUDGET",
|
|
97
|
-
SCOPE_MODE: "PENTEST_SCOPE_MODE",
|
|
98
|
-
APPROVAL_MODE: "PENTEST_APPROVAL_MODE",
|
|
99
|
-
CONTAINERIZED: "PENTEST_CONTAINERIZED",
|
|
100
|
-
APP_VERSION: "PENTESTING_VERSION"
|
|
101
|
-
};
|
|
102
|
-
var DEFAULT_THINKING_BUDGET = 8e3;
|
|
103
|
-
var DEFAULT_SEARCH_API_URL = "https://api.search.brave.com/res/v1/web/search";
|
|
104
|
-
var DEFAULT_MODEL = "glm-4.7";
|
|
105
|
-
function getApiKey() {
|
|
106
|
-
return process.env[ENV_KEYS.API_KEY] || "";
|
|
107
|
-
}
|
|
108
|
-
function getOptionalEnv(key) {
|
|
109
|
-
const value = process.env[key];
|
|
110
|
-
return value && value !== "" ? value : void 0;
|
|
111
|
-
}
|
|
112
|
-
function getBaseUrl() {
|
|
113
|
-
return getOptionalEnv(ENV_KEYS.BASE_URL);
|
|
114
|
-
}
|
|
115
|
-
function getModel() {
|
|
116
|
-
return process.env[ENV_KEYS.MODEL] || "";
|
|
117
|
-
}
|
|
118
|
-
function getSearchApiKey() {
|
|
119
|
-
const explicitKey = getOptionalEnv(ENV_KEYS.SEARCH_API_KEY);
|
|
120
|
-
if (explicitKey) {
|
|
121
|
-
return explicitKey;
|
|
122
|
-
}
|
|
123
|
-
return getOptionalEnv(ENV_KEYS.API_KEY);
|
|
124
|
-
}
|
|
125
|
-
function getSearchApiUrl() {
|
|
126
|
-
return process.env[ENV_KEYS.SEARCH_API_URL] || DEFAULT_SEARCH_API_URL;
|
|
127
|
-
}
|
|
128
|
-
function isZaiProvider() {
|
|
129
|
-
const baseUrl = getBaseUrl() || "";
|
|
130
|
-
return baseUrl.includes("z.ai");
|
|
131
|
-
}
|
|
132
|
-
function isThinkingEnabled() {
|
|
133
|
-
return process.env[ENV_KEYS.THINKING] !== "false";
|
|
134
|
-
}
|
|
135
|
-
function getThinkingBudget() {
|
|
136
|
-
const val = parseInt(process.env[ENV_KEYS.THINKING_BUDGET] || "", 10);
|
|
137
|
-
return isNaN(val) ? DEFAULT_THINKING_BUDGET : Math.max(1024, val);
|
|
138
|
-
}
|
|
95
|
+
} from "./chunk-YZNPWDNS.js";
|
|
139
96
|
|
|
140
97
|
// src/shared/constants/llm/api.ts
|
|
141
98
|
var LLM_API = {
|
|
@@ -558,14 +515,42 @@ var LLMClient = class {
|
|
|
558
515
|
const currentBlockRef = { value: null };
|
|
559
516
|
const toolCallsMap = /* @__PURE__ */ new Map();
|
|
560
517
|
let totalChars = 0;
|
|
518
|
+
let storedContentChars = 0;
|
|
519
|
+
let storedReasoningChars = 0;
|
|
520
|
+
let contentWasTruncated = false;
|
|
521
|
+
let reasoningWasTruncated = false;
|
|
561
522
|
let wasAborted = false;
|
|
562
523
|
context.onContent = (text) => {
|
|
563
|
-
contentChunks.push(text);
|
|
564
524
|
totalChars += text.length;
|
|
525
|
+
const remaining = LLM_LIMITS.streamStoredContentChars - storedContentChars;
|
|
526
|
+
if (remaining <= 0) {
|
|
527
|
+
contentWasTruncated = true;
|
|
528
|
+
return;
|
|
529
|
+
}
|
|
530
|
+
const slice = text.slice(0, remaining);
|
|
531
|
+
if (slice) {
|
|
532
|
+
contentChunks.push(slice);
|
|
533
|
+
storedContentChars += slice.length;
|
|
534
|
+
}
|
|
535
|
+
if (slice.length < text.length) {
|
|
536
|
+
contentWasTruncated = true;
|
|
537
|
+
}
|
|
565
538
|
};
|
|
566
539
|
context.onReasoning = (text) => {
|
|
567
|
-
reasoningChunks.push(text);
|
|
568
540
|
totalChars += text.length;
|
|
541
|
+
const remaining = LLM_LIMITS.streamStoredReasoningChars - storedReasoningChars;
|
|
542
|
+
if (remaining <= 0) {
|
|
543
|
+
reasoningWasTruncated = true;
|
|
544
|
+
return;
|
|
545
|
+
}
|
|
546
|
+
const slice = text.slice(0, remaining);
|
|
547
|
+
if (slice) {
|
|
548
|
+
reasoningChunks.push(slice);
|
|
549
|
+
storedReasoningChars += slice.length;
|
|
550
|
+
}
|
|
551
|
+
if (slice.length < text.length) {
|
|
552
|
+
reasoningWasTruncated = true;
|
|
553
|
+
}
|
|
569
554
|
};
|
|
570
555
|
context.onUsage = (u) => {
|
|
571
556
|
usage = u;
|
|
@@ -578,7 +563,13 @@ var LLMClient = class {
|
|
|
578
563
|
throw new DOMException("Aborted string generation", "AbortError");
|
|
579
564
|
}
|
|
580
565
|
const toolCalls = resolveToolCalls(toolCallsMap);
|
|
581
|
-
const
|
|
566
|
+
const truncatedContent = contentWasTruncated ? `${contentChunks.join("")}
|
|
567
|
+
|
|
568
|
+
...[assistant output truncated for memory safety]` : contentChunks.join("");
|
|
569
|
+
const truncatedReasoning = reasoningWasTruncated ? `${reasoningChunks.join("")}
|
|
570
|
+
|
|
571
|
+
...[reasoning truncated for memory safety]` : reasoningChunks.join("");
|
|
572
|
+
const stripped = stripThinkTags(truncatedContent, truncatedReasoning);
|
|
582
573
|
if (usage.input_tokens > 0 || usage.output_tokens > 0) {
|
|
583
574
|
addGlobalTokenUsage(usage);
|
|
584
575
|
}
|
|
@@ -2015,8 +2006,8 @@ var PASSTHROUGH_THRESHOLD = 2e3;
|
|
|
2015
2006
|
var PREPROCESS_THRESHOLD = 3e3;
|
|
2016
2007
|
var MAX_PREPROCESSED_LINES = 800;
|
|
2017
2008
|
var MAX_DUPLICATE_DISPLAY = 3;
|
|
2018
|
-
var ANALYST_MAX_INPUT_CHARS =
|
|
2019
|
-
var FALLBACK_MAX_CHARS =
|
|
2009
|
+
var ANALYST_MAX_INPUT_CHARS = 4e4;
|
|
2010
|
+
var FALLBACK_MAX_CHARS = 15e3;
|
|
2020
2011
|
var NOISE_PATTERNS = [
|
|
2021
2012
|
/^\s*$/,
|
|
2022
2013
|
// blank lines
|
|
@@ -2345,6 +2336,8 @@ function getAnalystSystemPrompt() {
|
|
|
2345
2336
|
}
|
|
2346
2337
|
function createLLMDigestFn(llmClient) {
|
|
2347
2338
|
return async (text, context) => {
|
|
2339
|
+
const cappedText = text.length > ANALYST_MAX_INPUT_CHARS ? `${text.slice(0, ANALYST_MAX_INPUT_CHARS)}
|
|
2340
|
+
... [truncated at ${ANALYST_MAX_INPUT_CHARS} chars before Analyst request]` : text;
|
|
2348
2341
|
const messages = [{
|
|
2349
2342
|
role: LLM_ROLES.USER,
|
|
2350
2343
|
content: `Analyze this pentesting tool output and extract actionable intelligence.
|
|
@@ -2352,7 +2345,7 @@ function createLLMDigestFn(llmClient) {
|
|
|
2352
2345
|
Context: ${context}
|
|
2353
2346
|
|
|
2354
2347
|
--- OUTPUT START ---
|
|
2355
|
-
${
|
|
2348
|
+
${cappedText}
|
|
2356
2349
|
--- OUTPUT END ---`
|
|
2357
2350
|
}];
|
|
2358
2351
|
const response = await llmClient.generateResponse(
|
|
@@ -3751,15 +3744,18 @@ var HealthMonitor = class {
|
|
|
3751
3744
|
check() {
|
|
3752
3745
|
const processes = this.checkProcesses();
|
|
3753
3746
|
const ports = this.checkPorts();
|
|
3754
|
-
const
|
|
3747
|
+
const memory = this.checkMemory();
|
|
3748
|
+
const recommendations = this.generateRecommendations(memory);
|
|
3755
3749
|
const overall = this.calculateOverall({
|
|
3756
3750
|
zombies: processes.zombies,
|
|
3751
|
+
memoryStatus: memory.status,
|
|
3757
3752
|
recommendations
|
|
3758
3753
|
});
|
|
3759
3754
|
return {
|
|
3760
3755
|
overall,
|
|
3761
3756
|
processes,
|
|
3762
3757
|
ports,
|
|
3758
|
+
memory,
|
|
3763
3759
|
recommendations
|
|
3764
3760
|
};
|
|
3765
3761
|
}
|
|
@@ -3795,10 +3791,42 @@ var HealthMonitor = class {
|
|
|
3795
3791
|
}
|
|
3796
3792
|
return { inUse, conflicts };
|
|
3797
3793
|
}
|
|
3794
|
+
/**
|
|
3795
|
+
* Check Node.js process memory health.
|
|
3796
|
+
*/
|
|
3797
|
+
checkMemory() {
|
|
3798
|
+
const usage = process.memoryUsage();
|
|
3799
|
+
const heapUsedRatio = usage.heapTotal > 0 ? usage.heapUsed / usage.heapTotal : 0;
|
|
3800
|
+
if (heapUsedRatio >= HEALTH_CONFIG.MEMORY_CRITICAL_HEAP_RATIO || usage.rss >= HEALTH_CONFIG.MEMORY_CRITICAL_RSS_BYTES) {
|
|
3801
|
+
return {
|
|
3802
|
+
rssBytes: usage.rss,
|
|
3803
|
+
heapUsedBytes: usage.heapUsed,
|
|
3804
|
+
heapTotalBytes: usage.heapTotal,
|
|
3805
|
+
heapUsedRatio,
|
|
3806
|
+
status: HEALTH_STATUS.CRITICAL
|
|
3807
|
+
};
|
|
3808
|
+
}
|
|
3809
|
+
if (heapUsedRatio >= HEALTH_CONFIG.MEMORY_WARNING_HEAP_RATIO || usage.rss >= HEALTH_CONFIG.MEMORY_WARNING_RSS_BYTES) {
|
|
3810
|
+
return {
|
|
3811
|
+
rssBytes: usage.rss,
|
|
3812
|
+
heapUsedBytes: usage.heapUsed,
|
|
3813
|
+
heapTotalBytes: usage.heapTotal,
|
|
3814
|
+
heapUsedRatio,
|
|
3815
|
+
status: HEALTH_STATUS.WARNING
|
|
3816
|
+
};
|
|
3817
|
+
}
|
|
3818
|
+
return {
|
|
3819
|
+
rssBytes: usage.rss,
|
|
3820
|
+
heapUsedBytes: usage.heapUsed,
|
|
3821
|
+
heapTotalBytes: usage.heapTotal,
|
|
3822
|
+
heapUsedRatio,
|
|
3823
|
+
status: HEALTH_STATUS.HEALTHY
|
|
3824
|
+
};
|
|
3825
|
+
}
|
|
3798
3826
|
/**
|
|
3799
3827
|
* Generate recommendations based on current state
|
|
3800
3828
|
*/
|
|
3801
|
-
generateRecommendations() {
|
|
3829
|
+
generateRecommendations(memory) {
|
|
3802
3830
|
const recs = [];
|
|
3803
3831
|
const procs = listBackgroundProcesses();
|
|
3804
3832
|
for (const proc of procs) {
|
|
@@ -3810,6 +3838,15 @@ var HealthMonitor = class {
|
|
|
3810
3838
|
recs.push(`[${proc.id}] ${proc.role} running for ${durMin}min`);
|
|
3811
3839
|
}
|
|
3812
3840
|
}
|
|
3841
|
+
if (memory.status === HEALTH_STATUS.CRITICAL) {
|
|
3842
|
+
recs.push(
|
|
3843
|
+
`Memory critical: heap ${(memory.heapUsedRatio * 100).toFixed(0)}% (${this.formatBytes(memory.heapUsedBytes)}/${this.formatBytes(memory.heapTotalBytes)}), rss ${this.formatBytes(memory.rssBytes)} - reduce prompt/output volume immediately`
|
|
3844
|
+
);
|
|
3845
|
+
} else if (memory.status === HEALTH_STATUS.WARNING) {
|
|
3846
|
+
recs.push(
|
|
3847
|
+
`Memory warning: heap ${(memory.heapUsedRatio * 100).toFixed(0)}% (${this.formatBytes(memory.heapUsedBytes)}/${this.formatBytes(memory.heapTotalBytes)}), rss ${this.formatBytes(memory.rssBytes)}`
|
|
3848
|
+
);
|
|
3849
|
+
}
|
|
3813
3850
|
return recs;
|
|
3814
3851
|
}
|
|
3815
3852
|
/**
|
|
@@ -3817,9 +3854,21 @@ var HealthMonitor = class {
|
|
|
3817
3854
|
*/
|
|
3818
3855
|
calculateOverall(data) {
|
|
3819
3856
|
if (data.zombies > 0) return HEALTH_STATUS.CRITICAL;
|
|
3857
|
+
if (data.memoryStatus === HEALTH_STATUS.CRITICAL) return HEALTH_STATUS.CRITICAL;
|
|
3858
|
+
if (data.memoryStatus === HEALTH_STATUS.WARNING) return HEALTH_STATUS.WARNING;
|
|
3820
3859
|
if (data.recommendations.length > HEALTH_CONFIG.MAX_RECOMMENDATIONS_FOR_HEALTHY) return HEALTH_STATUS.WARNING;
|
|
3821
3860
|
return HEALTH_STATUS.HEALTHY;
|
|
3822
3861
|
}
|
|
3862
|
+
formatBytes(bytes) {
|
|
3863
|
+
const units = ["B", "KB", "MB", "GB"];
|
|
3864
|
+
let value = bytes;
|
|
3865
|
+
let unitIndex = 0;
|
|
3866
|
+
while (value >= 1024 && unitIndex < units.length - 1) {
|
|
3867
|
+
value /= 1024;
|
|
3868
|
+
unitIndex++;
|
|
3869
|
+
}
|
|
3870
|
+
return `${value.toFixed(unitIndex === 0 ? 0 : 1)}${units[unitIndex]}`;
|
|
3871
|
+
}
|
|
3823
3872
|
};
|
|
3824
3873
|
|
|
3825
3874
|
// src/engine/resource/zombie-hunter.ts
|
|
@@ -3905,6 +3954,9 @@ async function executeBgStatus() {
|
|
|
3905
3954
|
}
|
|
3906
3955
|
lines.push(`
|
|
3907
3956
|
## Health: ${health.overall.toUpperCase()}`);
|
|
3957
|
+
lines.push(
|
|
3958
|
+
`Memory: ${health.memory.status.toUpperCase()} heap=${(health.memory.heapUsedRatio * 100).toFixed(0)}% (${Math.round(health.memory.heapUsedBytes / 1024 / 1024)}MB/${Math.round(health.memory.heapTotalBytes / 1024 / 1024)}MB) rss=${Math.round(health.memory.rssBytes / 1024 / 1024)}MB`
|
|
3959
|
+
);
|
|
3908
3960
|
if (health.recommendations.length > 0) {
|
|
3909
3961
|
lines.push("Recommendations:");
|
|
3910
3962
|
for (const r of health.recommendations) {
|
|
@@ -3976,6 +4028,9 @@ async function executeHealthCheck() {
|
|
|
3976
4028
|
const lines = [];
|
|
3977
4029
|
lines.push(`Health: ${status.overall.toUpperCase()}`);
|
|
3978
4030
|
lines.push(`Processes: ${status.processes.running}/${status.processes.total} running`);
|
|
4031
|
+
lines.push(
|
|
4032
|
+
`Memory: ${status.memory.status.toUpperCase()} heap=${(status.memory.heapUsedRatio * 100).toFixed(0)}% (${Math.round(status.memory.heapUsedBytes / 1024 / 1024)}MB/${Math.round(status.memory.heapTotalBytes / 1024 / 1024)}MB) rss=${Math.round(status.memory.rssBytes / 1024 / 1024)}MB`
|
|
4033
|
+
);
|
|
3979
4034
|
if (status.ports.inUse.length > 0) {
|
|
3980
4035
|
lines.push(`Ports in use: ${status.ports.inUse.join(", ")}`);
|
|
3981
4036
|
}
|
|
@@ -11084,7 +11139,7 @@ After completion: record key loot/findings from the sub-agent output to canonica
|
|
|
11084
11139
|
rootTaskId: activeExecution.rootTaskId
|
|
11085
11140
|
}
|
|
11086
11141
|
});
|
|
11087
|
-
const { AgentTool } = await import("./agent-tool-
|
|
11142
|
+
const { AgentTool } = await import("./agent-tool-MMDCBQ74.js");
|
|
11088
11143
|
const executor = new AgentTool(state, events, scopeGuard, approvalGate);
|
|
11089
11144
|
try {
|
|
11090
11145
|
const result = await executor.execute(input);
|
|
@@ -11363,10 +11418,6 @@ function buildShellSupervisorLifecycleSection() {
|
|
|
11363
11418
|
}
|
|
11364
11419
|
|
|
11365
11420
|
export {
|
|
11366
|
-
ENV_KEYS,
|
|
11367
|
-
DEFAULT_MODEL,
|
|
11368
|
-
getApiKey,
|
|
11369
|
-
getModel,
|
|
11370
11421
|
getTimeAdaptiveStrategy,
|
|
11371
11422
|
SharedState,
|
|
11372
11423
|
HealthMonitor,
|