pentesting 0.1.6 → 0.1.9
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/index.js +203 -102
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import { render } from "ink";
|
|
|
5
5
|
import { Command } from "commander";
|
|
6
6
|
|
|
7
7
|
// src/cli/app.tsx
|
|
8
|
-
import { useState, useEffect, useCallback } from "react";
|
|
8
|
+
import { useState, useEffect, useCallback, useRef } from "react";
|
|
9
9
|
import { Box, Text, useInput, useApp, Static } from "ink";
|
|
10
10
|
import TextInput from "ink-text-input";
|
|
11
11
|
import Spinner from "ink-spinner";
|
|
@@ -2610,6 +2610,52 @@ var ASCII_BANNER = `
|
|
|
2610
2610
|
\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
|
|
2611
2611
|
`;
|
|
2612
2612
|
|
|
2613
|
+
// src/config/agent-constants.ts
|
|
2614
|
+
var AGENT_EVENT = {
|
|
2615
|
+
// Lifecycle
|
|
2616
|
+
PLUGINS_LOADED: "plugins_loaded",
|
|
2617
|
+
HOOKS_LOADED: "hooks_loaded",
|
|
2618
|
+
COMMANDS_LOADED: "commands_loaded",
|
|
2619
|
+
MCP_SERVER_ADDED: "mcp_server_added",
|
|
2620
|
+
// Execution
|
|
2621
|
+
ITERATION: "iteration",
|
|
2622
|
+
THOUGHT: "thought",
|
|
2623
|
+
RESPONSE: "response",
|
|
2624
|
+
TOOL_CALL: "tool_call",
|
|
2625
|
+
TOOL_RESULT: "tool_result",
|
|
2626
|
+
COMMAND_EXECUTE: "command_execute",
|
|
2627
|
+
// State changes
|
|
2628
|
+
TARGET_SET: "target_set",
|
|
2629
|
+
PHASE_CHANGE: "phase_change",
|
|
2630
|
+
AGENT_SWITCH: "agent_switch",
|
|
2631
|
+
// Discoveries
|
|
2632
|
+
FINDING: "finding",
|
|
2633
|
+
CREDENTIAL: "credential",
|
|
2634
|
+
COMPROMISED: "compromised",
|
|
2635
|
+
// Completion
|
|
2636
|
+
COMPLETE: "complete",
|
|
2637
|
+
REPORT: "report",
|
|
2638
|
+
ERROR: "error"
|
|
2639
|
+
};
|
|
2640
|
+
var CLI_COMMAND = {
|
|
2641
|
+
HELP: "help",
|
|
2642
|
+
TARGET: "target",
|
|
2643
|
+
START: "start",
|
|
2644
|
+
STOP: "stop",
|
|
2645
|
+
FINDINGS: "findings",
|
|
2646
|
+
CLEAR: "clear",
|
|
2647
|
+
EXIT: "exit"
|
|
2648
|
+
};
|
|
2649
|
+
var MESSAGE_TYPE = {
|
|
2650
|
+
USER: "user",
|
|
2651
|
+
ASSISTANT: "assistant",
|
|
2652
|
+
TOOL: "tool",
|
|
2653
|
+
THINKING: "thinking",
|
|
2654
|
+
ERROR: "error",
|
|
2655
|
+
SYSTEM: "system",
|
|
2656
|
+
RESULT: "result"
|
|
2657
|
+
};
|
|
2658
|
+
|
|
2613
2659
|
// src/cli/app.tsx
|
|
2614
2660
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2615
2661
|
var App = ({ autoApprove = false, target }) => {
|
|
@@ -2617,164 +2663,213 @@ var App = ({ autoApprove = false, target }) => {
|
|
|
2617
2663
|
const [messages, setMessages] = useState([]);
|
|
2618
2664
|
const [input, setInput] = useState("");
|
|
2619
2665
|
const [isProcessing, setIsProcessing] = useState(false);
|
|
2666
|
+
const [currentStatus, setCurrentStatus] = useState("");
|
|
2667
|
+
const [elapsedTime, setElapsedTime] = useState(0);
|
|
2620
2668
|
const [agent] = useState(() => new AutonomousHackingAgent(void 0, { autoApprove }));
|
|
2621
|
-
const
|
|
2669
|
+
const startTimeRef = useRef(0);
|
|
2670
|
+
const timerRef = useRef(null);
|
|
2671
|
+
const addMessage = useCallback((type, content, duration) => {
|
|
2622
2672
|
setMessages((prev) => [...prev, {
|
|
2623
2673
|
id: `${Date.now()}-${Math.random().toString(36).slice(2)}`,
|
|
2624
2674
|
type,
|
|
2625
2675
|
content,
|
|
2626
|
-
timestamp: /* @__PURE__ */ new Date()
|
|
2676
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
2677
|
+
duration
|
|
2627
2678
|
}]);
|
|
2628
2679
|
}, []);
|
|
2680
|
+
const startTimer = useCallback(() => {
|
|
2681
|
+
startTimeRef.current = Date.now();
|
|
2682
|
+
timerRef.current = setInterval(() => {
|
|
2683
|
+
setElapsedTime(Math.floor((Date.now() - startTimeRef.current) / 100) / 10);
|
|
2684
|
+
}, 100);
|
|
2685
|
+
}, []);
|
|
2686
|
+
const stopTimer = useCallback(() => {
|
|
2687
|
+
if (timerRef.current) {
|
|
2688
|
+
clearInterval(timerRef.current);
|
|
2689
|
+
timerRef.current = null;
|
|
2690
|
+
}
|
|
2691
|
+
const duration = Math.floor((Date.now() - startTimeRef.current) / 100) / 10;
|
|
2692
|
+
setElapsedTime(0);
|
|
2693
|
+
return duration;
|
|
2694
|
+
}, []);
|
|
2629
2695
|
useEffect(() => {
|
|
2630
|
-
addMessage(
|
|
2696
|
+
addMessage(MESSAGE_TYPE.SYSTEM, "Pentesting Agent initialized. Type /help for commands.");
|
|
2631
2697
|
if (target) {
|
|
2632
2698
|
agent.setTarget(target);
|
|
2633
|
-
addMessage(
|
|
2699
|
+
addMessage(MESSAGE_TYPE.SYSTEM, `Target: ${target}`);
|
|
2634
2700
|
}
|
|
2635
|
-
agent.on(
|
|
2636
|
-
|
|
2701
|
+
agent.on(AGENT_EVENT.THOUGHT, (thought) => {
|
|
2702
|
+
setCurrentStatus(thought.content.slice(0, 60));
|
|
2703
|
+
});
|
|
2704
|
+
agent.on(AGENT_EVENT.TOOL_CALL, (data) => {
|
|
2705
|
+
const args = Object.entries(data.input).slice(0, 2).map(([k, v]) => `${k}=${typeof v === "string" ? v.slice(0, 30) : "..."}`).join(" ");
|
|
2706
|
+
setCurrentStatus(`Running ${data.name}...`);
|
|
2707
|
+
addMessage(MESSAGE_TYPE.TOOL, `\u25B6 ${data.name} ${args}`);
|
|
2708
|
+
});
|
|
2709
|
+
agent.on(AGENT_EVENT.TOOL_RESULT, (data) => {
|
|
2710
|
+
const icon = data.result.success ? "\u2713" : "\u2717";
|
|
2711
|
+
const preview = data.result.output?.slice(0, 100).replace(/\n/g, " ") || "";
|
|
2712
|
+
addMessage(MESSAGE_TYPE.RESULT, `${icon} ${preview}`);
|
|
2637
2713
|
});
|
|
2638
|
-
agent.on(
|
|
2639
|
-
|
|
2640
|
-
addMessage("tool", `\u25B6 ${data.name} ${inputStr}`);
|
|
2714
|
+
agent.on(AGENT_EVENT.ITERATION, (data) => {
|
|
2715
|
+
setCurrentStatus(`Phase: ${data.phase} (iteration ${data.current})`);
|
|
2641
2716
|
});
|
|
2642
|
-
agent.on(
|
|
2643
|
-
|
|
2644
|
-
const output = data.result.output?.slice(0, 200) || "";
|
|
2645
|
-
addMessage("tool", `${status} ${data.name}: ${output}`);
|
|
2717
|
+
agent.on(AGENT_EVENT.FINDING, (finding) => {
|
|
2718
|
+
addMessage(MESSAGE_TYPE.SYSTEM, `\u{1F3AF} [${finding.severity.toUpperCase()}] ${finding.title}`);
|
|
2646
2719
|
});
|
|
2647
|
-
agent.on(
|
|
2648
|
-
|
|
2720
|
+
agent.on(AGENT_EVENT.COMPLETE, () => {
|
|
2721
|
+
const duration = stopTimer();
|
|
2722
|
+
addMessage(MESSAGE_TYPE.SYSTEM, `\u2713 Complete (${duration}s)`);
|
|
2723
|
+
setIsProcessing(false);
|
|
2724
|
+
setCurrentStatus("");
|
|
2649
2725
|
});
|
|
2650
|
-
agent.on(
|
|
2651
|
-
|
|
2726
|
+
agent.on(AGENT_EVENT.ERROR, (error) => {
|
|
2727
|
+
stopTimer();
|
|
2728
|
+
addMessage(MESSAGE_TYPE.ERROR, error.message);
|
|
2729
|
+
setIsProcessing(false);
|
|
2652
2730
|
});
|
|
2653
|
-
|
|
2731
|
+
return () => {
|
|
2732
|
+
if (timerRef.current) clearInterval(timerRef.current);
|
|
2733
|
+
};
|
|
2734
|
+
}, [agent, target, addMessage, stopTimer]);
|
|
2654
2735
|
const handleSubmit = useCallback(async (value) => {
|
|
2655
2736
|
const trimmed = value.trim();
|
|
2656
2737
|
if (!trimmed || isProcessing) return;
|
|
2657
2738
|
setInput("");
|
|
2658
|
-
addMessage(
|
|
2739
|
+
addMessage(MESSAGE_TYPE.USER, trimmed);
|
|
2659
2740
|
if (trimmed.startsWith("/")) {
|
|
2660
2741
|
const [cmd, ...args] = trimmed.slice(1).split(" ");
|
|
2661
2742
|
switch (cmd) {
|
|
2662
|
-
case
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2743
|
+
case CLI_COMMAND.HELP:
|
|
2744
|
+
case "h":
|
|
2745
|
+
addMessage(
|
|
2746
|
+
MESSAGE_TYPE.SYSTEM,
|
|
2747
|
+
`/target <ip> Set target
|
|
2748
|
+
/start [goal] Start pentest
|
|
2749
|
+
/stop Stop operation
|
|
2750
|
+
/findings Show findings
|
|
2751
|
+
/clear Clear screen
|
|
2752
|
+
/exit Exit`
|
|
2753
|
+
);
|
|
2670
2754
|
return;
|
|
2671
|
-
case
|
|
2755
|
+
case CLI_COMMAND.TARGET:
|
|
2756
|
+
case "t":
|
|
2672
2757
|
if (args[0]) {
|
|
2673
2758
|
agent.setTarget(args[0]);
|
|
2674
|
-
addMessage(
|
|
2759
|
+
addMessage(MESSAGE_TYPE.SYSTEM, `Target \u2192 ${args[0]}`);
|
|
2675
2760
|
} else {
|
|
2676
|
-
addMessage(
|
|
2761
|
+
addMessage(MESSAGE_TYPE.ERROR, "Usage: /target <ip>");
|
|
2677
2762
|
}
|
|
2678
2763
|
return;
|
|
2679
|
-
case
|
|
2680
|
-
|
|
2764
|
+
case CLI_COMMAND.START:
|
|
2765
|
+
case "s":
|
|
2681
2766
|
setIsProcessing(true);
|
|
2682
|
-
|
|
2767
|
+
startTimer();
|
|
2768
|
+
const objective = args.join(" ") || "Perform comprehensive penetration testing";
|
|
2769
|
+
setCurrentStatus("Initializing...");
|
|
2683
2770
|
try {
|
|
2684
|
-
await agent.
|
|
2771
|
+
await agent.runAutonomous(objective);
|
|
2685
2772
|
} catch (e) {
|
|
2686
|
-
addMessage(
|
|
2773
|
+
addMessage(MESSAGE_TYPE.ERROR, e instanceof Error ? e.message : String(e));
|
|
2687
2774
|
}
|
|
2775
|
+
stopTimer();
|
|
2688
2776
|
setIsProcessing(false);
|
|
2777
|
+
setCurrentStatus("");
|
|
2689
2778
|
return;
|
|
2690
|
-
case
|
|
2691
|
-
agent.
|
|
2692
|
-
|
|
2779
|
+
case CLI_COMMAND.STOP:
|
|
2780
|
+
agent.pause();
|
|
2781
|
+
stopTimer();
|
|
2782
|
+
addMessage(MESSAGE_TYPE.SYSTEM, "Stopped.");
|
|
2693
2783
|
setIsProcessing(false);
|
|
2784
|
+
setCurrentStatus("");
|
|
2694
2785
|
return;
|
|
2695
|
-
case
|
|
2786
|
+
case CLI_COMMAND.FINDINGS:
|
|
2787
|
+
case "f":
|
|
2696
2788
|
const findings = agent.getState().findings;
|
|
2697
2789
|
if (findings.length === 0) {
|
|
2698
|
-
addMessage(
|
|
2790
|
+
addMessage(MESSAGE_TYPE.SYSTEM, "No findings.");
|
|
2699
2791
|
} else {
|
|
2700
|
-
findings.forEach((f) => {
|
|
2701
|
-
addMessage("system", `[${f.severity.toUpperCase()}] ${f.title}`);
|
|
2702
|
-
});
|
|
2792
|
+
findings.forEach((f) => addMessage(MESSAGE_TYPE.SYSTEM, `[${f.severity}] ${f.title}`));
|
|
2703
2793
|
}
|
|
2704
2794
|
return;
|
|
2705
|
-
case
|
|
2795
|
+
case CLI_COMMAND.CLEAR:
|
|
2796
|
+
case "c":
|
|
2706
2797
|
setMessages([]);
|
|
2707
|
-
addMessage("system", "Cleared.");
|
|
2708
2798
|
return;
|
|
2709
|
-
case
|
|
2799
|
+
case CLI_COMMAND.EXIT:
|
|
2710
2800
|
case "quit":
|
|
2801
|
+
case "q":
|
|
2711
2802
|
exit();
|
|
2712
2803
|
return;
|
|
2713
2804
|
default:
|
|
2714
|
-
addMessage(
|
|
2805
|
+
addMessage(MESSAGE_TYPE.ERROR, `Unknown: ${cmd}`);
|
|
2715
2806
|
return;
|
|
2716
2807
|
}
|
|
2717
2808
|
}
|
|
2718
2809
|
setIsProcessing(true);
|
|
2810
|
+
startTimer();
|
|
2811
|
+
setCurrentStatus("Thinking...");
|
|
2719
2812
|
try {
|
|
2720
|
-
await agent.
|
|
2813
|
+
await agent.processUserHint(trimmed);
|
|
2814
|
+
addMessage(MESSAGE_TYPE.SYSTEM, "Hint received.");
|
|
2721
2815
|
} catch (e) {
|
|
2722
|
-
addMessage(
|
|
2816
|
+
addMessage(MESSAGE_TYPE.ERROR, e instanceof Error ? e.message : String(e));
|
|
2723
2817
|
}
|
|
2818
|
+
stopTimer();
|
|
2724
2819
|
setIsProcessing(false);
|
|
2725
|
-
|
|
2820
|
+
setCurrentStatus("");
|
|
2821
|
+
}, [agent, isProcessing, addMessage, exit, startTimer, stopTimer]);
|
|
2726
2822
|
useInput((input2, key) => {
|
|
2727
2823
|
if (key.ctrl && input2 === "c") {
|
|
2728
2824
|
if (isProcessing) {
|
|
2729
|
-
agent.
|
|
2825
|
+
agent.pause();
|
|
2826
|
+
stopTimer();
|
|
2730
2827
|
setIsProcessing(false);
|
|
2731
|
-
|
|
2828
|
+
setCurrentStatus("");
|
|
2829
|
+
addMessage(MESSAGE_TYPE.SYSTEM, "Interrupted.");
|
|
2732
2830
|
} else {
|
|
2733
2831
|
exit();
|
|
2734
2832
|
}
|
|
2735
2833
|
}
|
|
2736
2834
|
});
|
|
2737
|
-
const
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
|
|
2741
|
-
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
return THEME.text.muted;
|
|
2749
|
-
default:
|
|
2750
|
-
return THEME.text.primary;
|
|
2751
|
-
}
|
|
2752
|
-
};
|
|
2753
|
-
const getPrefix = (type) => {
|
|
2754
|
-
switch (type) {
|
|
2755
|
-
case "user":
|
|
2756
|
-
return "\u276F";
|
|
2757
|
-
case "assistant":
|
|
2758
|
-
return "\u25C8";
|
|
2759
|
-
case "tool":
|
|
2760
|
-
return "\u2699";
|
|
2761
|
-
case "error":
|
|
2762
|
-
return "\u2717";
|
|
2763
|
-
case "system":
|
|
2764
|
-
return "\u2022";
|
|
2765
|
-
default:
|
|
2766
|
-
return " ";
|
|
2767
|
-
}
|
|
2835
|
+
const getStyle = (type) => {
|
|
2836
|
+
const styles = {
|
|
2837
|
+
[MESSAGE_TYPE.USER]: { color: THEME.text.accent, prefix: "\u276F" },
|
|
2838
|
+
[MESSAGE_TYPE.ASSISTANT]: { color: THEME.text.primary, prefix: "\u25C8" },
|
|
2839
|
+
[MESSAGE_TYPE.TOOL]: { color: THEME.text.muted, prefix: " ", dim: true },
|
|
2840
|
+
[MESSAGE_TYPE.RESULT]: { color: THEME.text.muted, prefix: " ", dim: true },
|
|
2841
|
+
[MESSAGE_TYPE.THINKING]: { color: THEME.status.running, prefix: "\u25CB" },
|
|
2842
|
+
[MESSAGE_TYPE.ERROR]: { color: THEME.status.error, prefix: "\u2717" },
|
|
2843
|
+
[MESSAGE_TYPE.SYSTEM]: { color: THEME.text.muted, prefix: "\u2022" }
|
|
2844
|
+
};
|
|
2845
|
+
return styles[type] || styles[MESSAGE_TYPE.SYSTEM];
|
|
2768
2846
|
};
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2847
|
+
const state = agent.getState();
|
|
2848
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", paddingX: 1, children: [
|
|
2849
|
+
/* @__PURE__ */ jsx(Box, { flexDirection: "column", marginBottom: 1, children: /* @__PURE__ */ jsx(Static, { items: messages.slice(-40), children: (msg) => {
|
|
2850
|
+
const style = getStyle(msg.type);
|
|
2851
|
+
return /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsxs(Text, { color: style.color, dimColor: style.dim, children: [
|
|
2852
|
+
style.prefix,
|
|
2853
|
+
" ",
|
|
2854
|
+
msg.content,
|
|
2855
|
+
msg.duration && /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
2856
|
+
" (",
|
|
2857
|
+
msg.duration,
|
|
2858
|
+
"s)"
|
|
2859
|
+
] })
|
|
2860
|
+
] }) }, msg.id);
|
|
2861
|
+
} }) }),
|
|
2862
|
+
isProcessing ? /* @__PURE__ */ jsxs(Box, { children: [
|
|
2863
|
+
/* @__PURE__ */ jsx(Text, { color: THEME.status.running, children: /* @__PURE__ */ jsx(Spinner, { type: "dots" }) }),
|
|
2864
|
+
/* @__PURE__ */ jsxs(Text, { color: THEME.text.muted, children: [
|
|
2865
|
+
" ",
|
|
2866
|
+
currentStatus,
|
|
2867
|
+
elapsedTime > 0 && /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
2868
|
+
" (",
|
|
2869
|
+
elapsedTime,
|
|
2870
|
+
"s)"
|
|
2871
|
+
] })
|
|
2872
|
+
] })
|
|
2778
2873
|
] }) : /* @__PURE__ */ jsxs(Box, { children: [
|
|
2779
2874
|
/* @__PURE__ */ jsx(Text, { color: THEME.status.success, children: "\u276F " }),
|
|
2780
2875
|
/* @__PURE__ */ jsx(
|
|
@@ -2783,17 +2878,23 @@ var App = ({ autoApprove = false, target }) => {
|
|
|
2783
2878
|
value: input,
|
|
2784
2879
|
onChange: setInput,
|
|
2785
2880
|
onSubmit: handleSubmit,
|
|
2786
|
-
placeholder: "
|
|
2881
|
+
placeholder: "Message or /help..."
|
|
2787
2882
|
}
|
|
2788
2883
|
)
|
|
2789
|
-
] })
|
|
2790
|
-
/* @__PURE__ */
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2884
|
+
] }),
|
|
2885
|
+
/* @__PURE__ */ jsxs(Box, { marginTop: 1, justifyContent: "space-between", children: [
|
|
2886
|
+
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
2887
|
+
state.target.primary || "No target",
|
|
2888
|
+
" \u2502",
|
|
2889
|
+
state.findings.length,
|
|
2890
|
+
" findings \u2502",
|
|
2891
|
+
state.currentPhase !== "idle" && ` ${state.currentPhase} \u2502`
|
|
2892
|
+
] }),
|
|
2893
|
+
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
2894
|
+
"/help \u2502 Ctrl+C ",
|
|
2895
|
+
isProcessing ? "stop" : "exit"
|
|
2896
|
+
] })
|
|
2897
|
+
] })
|
|
2797
2898
|
] });
|
|
2798
2899
|
};
|
|
2799
2900
|
var app_default = App;
|