mirror of
https://github.com/Ed1s0nZ/CyberStrikeAI.git
synced 2026-07-10 14:28:43 +02:00
Add files via upload
This commit is contained in:
@@ -2,16 +2,18 @@
|
||||
|
||||
### 功能概述
|
||||
|
||||
- 在 Burp 的 `CyberStrikeAI` 标签页中配置 **Host、端口、密码、单/多 Agent**
|
||||
- 在 Burp 的 `CyberStrikeAI` 标签页中配置 **Host、端口、密码**
|
||||
- 点击 **Validate(验证)**:
|
||||
- 调用 `POST /api/auth/login` 用密码换取 Token
|
||||
- 调用 `GET /api/auth/validate` 校验 Token
|
||||
- 验证通过后 Token 会保存在插件内存中(本次 Burp 会话有效)
|
||||
- 右键任意 HTTP 请求包 → **Send to CyberStrikeAI (stream test)**:
|
||||
- 将该 HTTP 请求(含 headers/body;若存在响应则附带截断片段)发送到 CyberStrikeAI
|
||||
- 以 **SSE 流式**接收返回内容,并在标签页中实时展示
|
||||
- 单 Agent:`POST /api/eino-agent/stream`
|
||||
- 多 Agent:`POST /api/multi-agent/stream`(需 `multi_agent.enabled: true`,请求体 `orchestration`)
|
||||
- 弹出发送对话框,可针对**当前流量**选择:
|
||||
- **项目**(`GET /api/projects`,新建对话时绑定 `projectId`)
|
||||
- **角色**(`GET /api/roles`)
|
||||
- **对话模式**(Eino 单代理 / Deep / Plan-Execute / Supervisor,按次选择并记住上次取值)
|
||||
- **测试指令**(可编辑 prompt 前缀)
|
||||
- 选择会记住上次取值,便于连续测同类流量
|
||||
- **测试历史侧边栏(可搜索)**:每次发送都会新增一条记录,方便回看与对比
|
||||
- **Output 分区**:`Progress`(可折叠)+ `Final Response`(主区域)
|
||||
- **Markdown 渲染**:最终输出可在 Output 主区域渲染为富文本(可开关)
|
||||
@@ -83,13 +85,13 @@ cd plugins/burp-suite/cyberstrikeai-burp-extension
|
||||
- **Port**:例如 `8080`
|
||||
- **HTTPS**:默认勾选(对接 `config.yaml` 中 `tls_enabled` / 自签证书);插件会自动信任本地自签证书,无需导入
|
||||
- **Password**:你的 CyberStrikeAI 登录密码(对应服务端 `auth.password`)
|
||||
- **Agent mode**:选择 `Single Agent` 或 `Multi Agent`
|
||||
3) 点击 **Validate**
|
||||
- 成功:状态显示 `OK (token saved)`
|
||||
- 失败:状态会显示错误原因(例如密码错误、服务不可达、401/403 等)
|
||||
4) 在 Burp 的 Proxy/HTTP history/Repeater 等列表中选中一条 HTTP 包
|
||||
5) 右键 → **Send to CyberStrikeAI (stream test)**
|
||||
6) 每次发送后会在 `CyberStrikeAI` 标签页左侧显示一个“测试记录”(请求标题 + 单/多 Agent + 状态);点击对应记录即可在右侧查看该次的流式输出结果
|
||||
6) 在弹出框中按需选择**项目、角色、对话模式**,并编辑测试指令后点确定
|
||||
7) 每次发送后会在 `CyberStrikeAI` 标签页左侧显示一个“测试记录”(请求标题 + 模式/角色 + 状态);点击对应记录即可在右侧查看该次的流式输出结果
|
||||
|
||||
### 常见问题(排错)
|
||||
|
||||
|
||||
BIN
Binary file not shown.
+15
-42
@@ -1,7 +1,6 @@
|
||||
package burp;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -56,19 +55,26 @@ public class BurpExtender implements IBurpExtender, IContextMenuFactory {
|
||||
return;
|
||||
}
|
||||
|
||||
String instruction = showInstructionEditor(tab.getUiComponent(), lastInstruction);
|
||||
if (instruction == null) {
|
||||
SendOptionsDialog.Result options = SendOptionsDialog.show(
|
||||
tab.getUiComponent(), client, cfg, token, lastInstruction);
|
||||
if (options == null) {
|
||||
return;
|
||||
}
|
||||
lastInstruction = instruction;
|
||||
lastInstruction = options.instruction;
|
||||
|
||||
String prompt = HttpMessageFormatter.toPrompt(helpers, msg, instruction);
|
||||
String prompt = HttpMessageFormatter.toPrompt(helpers, msg, options.instruction);
|
||||
String title = HttpMessageFormatter.getRequestTitle(helpers, msg);
|
||||
String agentModeStr = cfg.agentMode.displayName;
|
||||
String runId = tab.startNewRun(title, agentModeStr, msg);
|
||||
tab.appendProgressToRun(runId, "\n[server] " + cfg.baseUrl + "\n\n");
|
||||
String agentModeStr = options.agentMode.displayName;
|
||||
String roleLabel = options.role.isEmpty() ? "默认" : options.role;
|
||||
String runId = tab.startNewRun(title, agentModeStr + " · " + roleLabel, msg);
|
||||
tab.appendProgressToRun(runId, "\n[server] " + cfg.baseUrl);
|
||||
if (!options.projectId.isEmpty()) {
|
||||
tab.appendProgressToRun(runId, "\n[project] " + options.projectId);
|
||||
}
|
||||
tab.appendProgressToRun(runId, "\n\n");
|
||||
|
||||
client.streamTest(cfg, token, prompt, new CyberStrikeAIClient.StreamListener() {
|
||||
client.streamTest(cfg, token, prompt, options.role, options.projectId, options.agentMode,
|
||||
new CyberStrikeAIClient.StreamListener() {
|
||||
@Override
|
||||
public void onEvent(String type, String message, String rawJson) {
|
||||
if (type == null) type = "";
|
||||
@@ -190,38 +196,5 @@ public class BurpExtender implements IBurpExtender, IContextMenuFactory {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static String showInstructionEditor(Component parent, String initialValue) {
|
||||
JTextArea editor = new JTextArea(
|
||||
initialValue == null || initialValue.trim().isEmpty()
|
||||
? HttpMessageFormatter.defaultInstruction()
|
||||
: initialValue,
|
||||
6,
|
||||
70
|
||||
);
|
||||
editor.setLineWrap(true);
|
||||
editor.setWrapStyleWord(true);
|
||||
editor.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 13));
|
||||
|
||||
JPanel panel = new JPanel(new BorderLayout(0, 8));
|
||||
panel.add(new JLabel("Edit instruction before sending:"), BorderLayout.NORTH);
|
||||
panel.add(new JScrollPane(editor), BorderLayout.CENTER);
|
||||
|
||||
int result = JOptionPane.showConfirmDialog(
|
||||
parent,
|
||||
panel,
|
||||
"Customize Prompt Instruction",
|
||||
JOptionPane.OK_CANCEL_OPTION,
|
||||
JOptionPane.PLAIN_MESSAGE
|
||||
);
|
||||
if (result != JOptionPane.OK_OPTION) {
|
||||
return null;
|
||||
}
|
||||
String value = editor.getText();
|
||||
if (value == null || value.trim().isEmpty()) {
|
||||
return HttpMessageFormatter.defaultInstruction();
|
||||
}
|
||||
return value.trim();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+100
-7
@@ -10,7 +10,9 @@ import java.net.HttpURLConnection;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
@@ -28,12 +30,10 @@ final class CyberStrikeAIClient {
|
||||
static final class Config {
|
||||
final String baseUrl; // e.g. http://127.0.0.1:8080
|
||||
final String password;
|
||||
final AgentMode agentMode;
|
||||
|
||||
Config(String baseUrl, String password, AgentMode agentMode) {
|
||||
Config(String baseUrl, String password) {
|
||||
this.baseUrl = baseUrl;
|
||||
this.password = password;
|
||||
this.agentMode = agentMode;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,6 +54,36 @@ final class CyberStrikeAIClient {
|
||||
}
|
||||
}
|
||||
|
||||
static final class ProjectOption {
|
||||
final String id;
|
||||
final String label;
|
||||
|
||||
ProjectOption(String id, String label) {
|
||||
this.id = id == null ? "" : id;
|
||||
this.label = label == null || label.isEmpty() ? this.id : label;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return label.isEmpty() ? "(无)" : label;
|
||||
}
|
||||
}
|
||||
|
||||
static final class RoleOption {
|
||||
final String name;
|
||||
final String label;
|
||||
|
||||
RoleOption(String name, String label) {
|
||||
this.name = name == null ? "" : name;
|
||||
this.label = label == null || label.isEmpty() ? (this.name.isEmpty() ? "默认" : this.name) : label;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return label;
|
||||
}
|
||||
}
|
||||
|
||||
interface StreamListener {
|
||||
void onEvent(String type, String message, String rawJson);
|
||||
void onError(String message, Exception e);
|
||||
@@ -207,15 +237,75 @@ final class CyberStrikeAIClient {
|
||||
}
|
||||
}
|
||||
|
||||
List<ProjectOption> fetchProjects(Config cfg, String token) throws IOException {
|
||||
String resp = authorizedGet(cfg.baseUrl, token, "/api/projects?limit=500");
|
||||
List<ProjectOption> out = new ArrayList<>();
|
||||
out.add(new ProjectOption("", "(无)"));
|
||||
for (String obj : SimpleJson.extractObjectArray(resp, "projects")) {
|
||||
String id = SimpleJson.extractStringField(obj, "id");
|
||||
if (id.isEmpty()) continue;
|
||||
String name = SimpleJson.extractStringField(obj, "name");
|
||||
String status = SimpleJson.extractStringField(obj, "status");
|
||||
String label = name.isEmpty() ? id : name;
|
||||
if ("archived".equalsIgnoreCase(status)) {
|
||||
label = label + " [已归档]";
|
||||
}
|
||||
out.add(new ProjectOption(id, label));
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
List<RoleOption> fetchRoles(Config cfg, String token) throws IOException {
|
||||
String resp = authorizedGet(cfg.baseUrl, token, "/api/roles");
|
||||
List<RoleOption> out = new ArrayList<>();
|
||||
out.add(new RoleOption("", "默认"));
|
||||
for (String obj : SimpleJson.extractObjectArray(resp, "roles")) {
|
||||
if (!SimpleJson.extractBooleanField(obj, "enabled", true)) {
|
||||
continue;
|
||||
}
|
||||
String name = SimpleJson.extractStringField(obj, "name");
|
||||
if (name.isEmpty()) continue;
|
||||
out.add(new RoleOption(name, name));
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
private String authorizedGet(String baseUrl, String token, String path) throws IOException {
|
||||
URL url = new URL(baseUrl + path);
|
||||
HttpURLConnection conn = SslTrustAll.open(url, AUTH_CONNECT_TIMEOUT_MS, AUTH_READ_TIMEOUT_MS);
|
||||
try {
|
||||
conn.setRequestMethod("GET");
|
||||
conn.setRequestProperty("Accept", "application/json");
|
||||
conn.setRequestProperty("Authorization", "Bearer " + token);
|
||||
int code = conn.getResponseCode();
|
||||
String resp = readAll(code >= 200 && code < 300 ? conn.getInputStream() : conn.getErrorStream());
|
||||
if (code < 200 || code >= 300) {
|
||||
throw new IOException("GET " + path + " failed (" + code + "): " + resp);
|
||||
}
|
||||
return resp;
|
||||
} finally {
|
||||
conn.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
void streamTest(Config cfg, String token, String message, StreamListener listener) {
|
||||
String urlStr = cfg.baseUrl + cfg.agentMode.streamPath;
|
||||
streamTest(cfg, token, message, "", "", AgentMode.EINO_SINGLE, listener);
|
||||
}
|
||||
|
||||
void streamTest(Config cfg, String token, String message, String role, String projectId,
|
||||
AgentMode agentMode, StreamListener listener) {
|
||||
AgentMode mode = agentMode != null ? agentMode : AgentMode.EINO_SINGLE;
|
||||
String urlStr = cfg.baseUrl + mode.streamPath;
|
||||
|
||||
Map<String, Object> payload = new HashMap<>();
|
||||
payload.put("message", message);
|
||||
payload.put("conversationId", "");
|
||||
payload.put("role", "");
|
||||
if (cfg.agentMode.orchestration != null) {
|
||||
payload.put("orchestration", cfg.agentMode.orchestration);
|
||||
payload.put("role", role == null ? "" : role);
|
||||
if (projectId != null && !projectId.trim().isEmpty()) {
|
||||
payload.put("projectId", projectId.trim());
|
||||
}
|
||||
if (mode.orchestration != null) {
|
||||
payload.put("orchestration", mode.orchestration);
|
||||
}
|
||||
|
||||
Thread worker = new Thread(() -> {
|
||||
@@ -319,6 +409,9 @@ final class CyberStrikeAIClient {
|
||||
sb.append("\"message\":\"").append(escapeJson(message)).append("\",");
|
||||
sb.append("\"conversationId\":\"").append(escapeJson(conversationId)).append("\",");
|
||||
sb.append("\"role\":\"").append(escapeJson(role)).append("\"");
|
||||
if (payload.containsKey("projectId") && payload.get("projectId") != null) {
|
||||
sb.append(",\"projectId\":\"").append(escapeJson(String.valueOf(payload.get("projectId")))).append("\"");
|
||||
}
|
||||
if (payload.containsKey("orchestration") && payload.get("orchestration") != null) {
|
||||
sb.append(",\"orchestration\":\"").append(escapeJson(String.valueOf(payload.get("orchestration")))).append("\"");
|
||||
}
|
||||
|
||||
+1
-20
@@ -16,16 +16,6 @@ final class CyberStrikeAITab implements ITab {
|
||||
private final JTextField portField = new JTextField("8080");
|
||||
private final JCheckBox useHttpsBox = new JCheckBox("HTTPS", true);
|
||||
private final JPasswordField passwordField = new JPasswordField();
|
||||
private final JComboBox<String> agentModeBox = new JComboBox<>(agentModeLabels());
|
||||
private static String[] agentModeLabels() {
|
||||
CyberStrikeAIClient.AgentMode[] modes = CyberStrikeAIClient.AgentMode.values();
|
||||
String[] labels = new String[modes.length];
|
||||
for (int i = 0; i < modes.length; i++) {
|
||||
labels[i] = modes[i].displayName;
|
||||
}
|
||||
return labels;
|
||||
}
|
||||
|
||||
private final JButton validateButton = new JButton("Validate");
|
||||
private final JButton clearButton = new JButton("Clear Output");
|
||||
private final JButton stopButton = new JButton("Stop");
|
||||
@@ -113,7 +103,6 @@ final class CyberStrikeAITab implements ITab {
|
||||
hostField.setColumns(14);
|
||||
portField.setColumns(6);
|
||||
passwordField.setColumns(12);
|
||||
agentModeBox.setPreferredSize(new Dimension(200, agentModeBox.getPreferredSize().height));
|
||||
|
||||
JPanel row1 = new JPanel(new FlowLayout(FlowLayout.LEFT, 8, 2));
|
||||
row1.add(new JLabel("Host"));
|
||||
@@ -128,8 +117,6 @@ final class CyberStrikeAITab implements ITab {
|
||||
row1.add(statusLabel);
|
||||
|
||||
JPanel row2 = new JPanel(new FlowLayout(FlowLayout.LEFT, 8, 2));
|
||||
row2.add(new JLabel("Agent"));
|
||||
row2.add(agentModeBox);
|
||||
row2.add(stopButton);
|
||||
row2.add(copyButton);
|
||||
row2.add(clearButton);
|
||||
@@ -550,19 +537,13 @@ final class CyberStrikeAITab implements ITab {
|
||||
renderMarkdownBox.addActionListener(e -> refreshOutputView());
|
||||
}
|
||||
|
||||
private static final CyberStrikeAIClient.AgentMode[] AGENT_MODES = CyberStrikeAIClient.AgentMode.values();
|
||||
|
||||
CyberStrikeAIClient.Config currentConfig() {
|
||||
String host = hostField.getText().trim();
|
||||
String port = portField.getText().trim();
|
||||
String password = new String(passwordField.getPassword());
|
||||
String scheme = useHttpsBox.isSelected() ? "https" : "http";
|
||||
String baseUrl = scheme + "://" + host + ":" + port;
|
||||
int idx = agentModeBox.getSelectedIndex();
|
||||
CyberStrikeAIClient.AgentMode mode = (idx >= 0 && idx < AGENT_MODES.length)
|
||||
? AGENT_MODES[idx]
|
||||
: CyberStrikeAIClient.AgentMode.EINO_SINGLE;
|
||||
return new CyberStrikeAIClient.Config(baseUrl, password, mode);
|
||||
return new CyberStrikeAIClient.Config(baseUrl, password);
|
||||
}
|
||||
|
||||
String getToken() {
|
||||
|
||||
+210
@@ -0,0 +1,210 @@
|
||||
package burp;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Per-request send dialog: project, role, agent mode, and custom instruction.
|
||||
*/
|
||||
final class SendOptionsDialog {
|
||||
private SendOptionsDialog() {}
|
||||
|
||||
static final class Result {
|
||||
final String instruction;
|
||||
final String projectId;
|
||||
final String role;
|
||||
final CyberStrikeAIClient.AgentMode agentMode;
|
||||
|
||||
Result(String instruction, String projectId, String role, CyberStrikeAIClient.AgentMode agentMode) {
|
||||
this.instruction = instruction;
|
||||
this.projectId = projectId == null ? "" : projectId;
|
||||
this.role = role == null ? "" : role;
|
||||
this.agentMode = agentMode;
|
||||
}
|
||||
}
|
||||
|
||||
private static String lastProjectId = "";
|
||||
private static String lastRole = "";
|
||||
private static CyberStrikeAIClient.AgentMode lastAgentMode = null;
|
||||
|
||||
static Result show(
|
||||
Component parent,
|
||||
CyberStrikeAIClient client,
|
||||
CyberStrikeAIClient.Config cfg,
|
||||
String token,
|
||||
String defaultInstruction
|
||||
) {
|
||||
CyberStrikeAIClient.AgentMode defaultMode = lastAgentMode != null
|
||||
? lastAgentMode
|
||||
: CyberStrikeAIClient.AgentMode.EINO_SINGLE;
|
||||
|
||||
JPanel panel = new JPanel(new BorderLayout(0, 10));
|
||||
panel.setBorder(BorderFactory.createEmptyBorder(4, 4, 0, 4));
|
||||
|
||||
JPanel selectors = new JPanel(new GridBagLayout());
|
||||
GridBagConstraints gc = new GridBagConstraints();
|
||||
gc.insets = new Insets(4, 6, 4, 6);
|
||||
gc.fill = GridBagConstraints.HORIZONTAL;
|
||||
gc.weighty = 0;
|
||||
|
||||
JComboBox<CyberStrikeAIClient.ProjectOption> projectBox = new JComboBox<>();
|
||||
projectBox.addItem(new CyberStrikeAIClient.ProjectOption("", "加载中..."));
|
||||
projectBox.setEnabled(false);
|
||||
|
||||
JComboBox<CyberStrikeAIClient.RoleOption> roleBox = new JComboBox<>();
|
||||
roleBox.addItem(new CyberStrikeAIClient.RoleOption("", "加载中..."));
|
||||
roleBox.setEnabled(false);
|
||||
|
||||
JComboBox<CyberStrikeAIClient.AgentMode> agentBox = new JComboBox<>(CyberStrikeAIClient.AgentMode.values());
|
||||
agentBox.setSelectedItem(defaultMode);
|
||||
agentBox.setRenderer(new DefaultListCellRenderer() {
|
||||
@Override
|
||||
public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
|
||||
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
|
||||
if (value instanceof CyberStrikeAIClient.AgentMode) {
|
||||
setText(((CyberStrikeAIClient.AgentMode) value).displayName);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
});
|
||||
|
||||
// Row 0: labels — 项目 | 角色 | 对话
|
||||
gc.gridy = 0;
|
||||
gc.weightx = 1.0;
|
||||
|
||||
gc.gridx = 0;
|
||||
selectors.add(new JLabel("项目"), gc);
|
||||
gc.gridx = 1;
|
||||
selectors.add(new JLabel("角色"), gc);
|
||||
gc.gridx = 2;
|
||||
selectors.add(new JLabel("对话"), gc);
|
||||
|
||||
// Row 1: dropdowns
|
||||
gc.gridy = 1;
|
||||
|
||||
gc.gridx = 0;
|
||||
selectors.add(projectBox, gc);
|
||||
gc.gridx = 1;
|
||||
selectors.add(roleBox, gc);
|
||||
gc.gridx = 2;
|
||||
selectors.add(agentBox, gc);
|
||||
|
||||
JTextArea editor = new JTextArea(
|
||||
defaultInstruction == null || defaultInstruction.trim().isEmpty()
|
||||
? HttpMessageFormatter.defaultInstruction()
|
||||
: defaultInstruction,
|
||||
7,
|
||||
70
|
||||
);
|
||||
editor.setLineWrap(true);
|
||||
editor.setWrapStyleWord(true);
|
||||
editor.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 13));
|
||||
|
||||
JPanel instructionPanel = new JPanel(new BorderLayout(0, 6));
|
||||
instructionPanel.add(new JLabel("测试指令(可针对当前流量修改):"), BorderLayout.NORTH);
|
||||
instructionPanel.add(new JScrollPane(editor), BorderLayout.CENTER);
|
||||
|
||||
panel.add(selectors, BorderLayout.NORTH);
|
||||
panel.add(instructionPanel, BorderLayout.CENTER);
|
||||
|
||||
Thread loader = new Thread(() -> {
|
||||
try {
|
||||
List<CyberStrikeAIClient.ProjectOption> projects = client.fetchProjects(cfg, token);
|
||||
List<CyberStrikeAIClient.RoleOption> roles = client.fetchRoles(cfg, token);
|
||||
SwingUtilities.invokeLater(() -> populateProjects(projectBox, projects, lastProjectId));
|
||||
SwingUtilities.invokeLater(() -> populateRoles(roleBox, roles, lastRole));
|
||||
} catch (Exception ex) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
projectBox.removeAllItems();
|
||||
projectBox.addItem(new CyberStrikeAIClient.ProjectOption("", "(加载失败)"));
|
||||
projectBox.setEnabled(true);
|
||||
roleBox.removeAllItems();
|
||||
roleBox.addItem(new CyberStrikeAIClient.RoleOption("", "默认"));
|
||||
roleBox.setEnabled(true);
|
||||
JOptionPane.showMessageDialog(parent,
|
||||
"加载项目/角色失败: " + ex.getMessage(),
|
||||
"CyberStrikeAI", JOptionPane.WARNING_MESSAGE);
|
||||
});
|
||||
}
|
||||
}, "CyberStrikeAI-LoadCatalog");
|
||||
loader.start();
|
||||
|
||||
int result = JOptionPane.showConfirmDialog(
|
||||
parent,
|
||||
panel,
|
||||
"发送到 CyberStrikeAI",
|
||||
JOptionPane.OK_CANCEL_OPTION,
|
||||
JOptionPane.PLAIN_MESSAGE
|
||||
);
|
||||
if (result != JOptionPane.OK_OPTION) {
|
||||
return null;
|
||||
}
|
||||
|
||||
CyberStrikeAIClient.ProjectOption project = (CyberStrikeAIClient.ProjectOption) projectBox.getSelectedItem();
|
||||
CyberStrikeAIClient.RoleOption role = (CyberStrikeAIClient.RoleOption) roleBox.getSelectedItem();
|
||||
CyberStrikeAIClient.AgentMode agentMode = (CyberStrikeAIClient.AgentMode) agentBox.getSelectedItem();
|
||||
if (agentMode == null) {
|
||||
agentMode = defaultMode;
|
||||
}
|
||||
|
||||
String instruction = editor.getText();
|
||||
if (instruction == null || instruction.trim().isEmpty()) {
|
||||
instruction = HttpMessageFormatter.defaultInstruction();
|
||||
} else {
|
||||
instruction = instruction.trim();
|
||||
}
|
||||
|
||||
lastProjectId = project != null ? project.id : "";
|
||||
lastRole = role != null ? role.name : "";
|
||||
lastAgentMode = agentMode;
|
||||
|
||||
return new Result(instruction, lastProjectId, lastRole, agentMode);
|
||||
}
|
||||
|
||||
private static void populateProjects(JComboBox<CyberStrikeAIClient.ProjectOption> box,
|
||||
List<CyberStrikeAIClient.ProjectOption> items,
|
||||
String selectId) {
|
||||
box.removeAllItems();
|
||||
for (CyberStrikeAIClient.ProjectOption item : items) {
|
||||
box.addItem(item);
|
||||
}
|
||||
selectComboById(box, selectId);
|
||||
box.setEnabled(true);
|
||||
}
|
||||
|
||||
private static void populateRoles(JComboBox<CyberStrikeAIClient.RoleOption> box,
|
||||
List<CyberStrikeAIClient.RoleOption> items,
|
||||
String selectName) {
|
||||
box.removeAllItems();
|
||||
for (CyberStrikeAIClient.RoleOption item : items) {
|
||||
box.addItem(item);
|
||||
}
|
||||
selectComboByName(box, selectName);
|
||||
box.setEnabled(true);
|
||||
}
|
||||
|
||||
private static void selectComboById(JComboBox<CyberStrikeAIClient.ProjectOption> box, String id) {
|
||||
if (id == null) id = "";
|
||||
for (int i = 0; i < box.getItemCount(); i++) {
|
||||
CyberStrikeAIClient.ProjectOption item = box.getItemAt(i);
|
||||
if (item != null && id.equals(item.id)) {
|
||||
box.setSelectedIndex(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
box.setSelectedIndex(0);
|
||||
}
|
||||
|
||||
private static void selectComboByName(JComboBox<CyberStrikeAIClient.RoleOption> box, String name) {
|
||||
if (name == null) name = "";
|
||||
for (int i = 0; i < box.getItemCount(); i++) {
|
||||
CyberStrikeAIClient.RoleOption item = box.getItemAt(i);
|
||||
if (item != null && name.equals(item.name)) {
|
||||
box.setSelectedIndex(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
box.setSelectedIndex(0);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
package burp;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@@ -76,5 +78,70 @@ final class SimpleJson {
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
static boolean extractBooleanField(String json, String key, boolean defaultValue) {
|
||||
if (json == null || key == null) return defaultValue;
|
||||
String needle = "\"" + key + "\"";
|
||||
int k = json.indexOf(needle);
|
||||
if (k < 0) return defaultValue;
|
||||
int colon = json.indexOf(':', k + needle.length());
|
||||
if (colon < 0) return defaultValue;
|
||||
int i = colon + 1;
|
||||
while (i < json.length() && Character.isWhitespace(json.charAt(i))) i++;
|
||||
if (i >= json.length()) return defaultValue;
|
||||
if (json.startsWith("true", i)) return true;
|
||||
if (json.startsWith("false", i)) return false;
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
/** Extracts each top-level object inside a JSON array field, e.g. projects / roles. */
|
||||
static List<String> extractObjectArray(String json, String arrayKey) {
|
||||
List<String> out = new ArrayList<>();
|
||||
if (json == null || arrayKey == null) return out;
|
||||
String needle = "\"" + arrayKey + "\"";
|
||||
int k = json.indexOf(needle);
|
||||
if (k < 0) return out;
|
||||
int bracket = json.indexOf('[', k);
|
||||
if (bracket < 0) return out;
|
||||
int i = bracket + 1;
|
||||
while (i < json.length()) {
|
||||
while (i < json.length() && Character.isWhitespace(json.charAt(i))) i++;
|
||||
if (i >= json.length()) break;
|
||||
char c = json.charAt(i);
|
||||
if (c == ']') break;
|
||||
if (c == ',') {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if (c != '{') {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
int start = i;
|
||||
int depth = 0;
|
||||
boolean inStr = false;
|
||||
boolean esc = false;
|
||||
for (; i < json.length(); i++) {
|
||||
char ch = json.charAt(i);
|
||||
if (inStr) {
|
||||
if (esc) esc = false;
|
||||
else if (ch == '\\') esc = true;
|
||||
else if (ch == '"') inStr = false;
|
||||
continue;
|
||||
}
|
||||
if (ch == '"') inStr = true;
|
||||
else if (ch == '{') depth++;
|
||||
else if (ch == '}') {
|
||||
depth--;
|
||||
if (depth == 0) {
|
||||
out.add(json.substring(start, i + 1));
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
+5
@@ -1,11 +1,15 @@
|
||||
burp/SslTrustAll.class
|
||||
burp/CyberStrikeAIClient$ProjectOption.class
|
||||
burp/CyberStrikeAIClient$RoleOption.class
|
||||
burp/SslTrustAll$TimeoutSslSocketFactory.class
|
||||
burp/CyberStrikeAIClient$StreamListener.class
|
||||
burp/CyberStrikeAIClient$Config.class
|
||||
burp/CyberStrikeAIClient$AgentMode.class
|
||||
burp/MarkdownRenderer.class
|
||||
burp/SimpleJson.class
|
||||
burp/SendOptionsDialog.class
|
||||
burp/CyberStrikeAIClient.class
|
||||
burp/SendOptionsDialog$1.class
|
||||
burp/CyberStrikeAIClient$1.class
|
||||
burp/CyberStrikeAITab$DotIcon.class
|
||||
burp/CyberStrikeAITab.class
|
||||
@@ -13,6 +17,7 @@ burp/CyberStrikeAITab$1.class
|
||||
burp/SslTrustAll$1.class
|
||||
burp/BurpExtender$1.class
|
||||
burp/BurpExtender.class
|
||||
burp/SendOptionsDialog$Result.class
|
||||
burp/CyberStrikeAITab$TestRun.class
|
||||
burp/CyberStrikeAITab$TestRunCellRenderer.class
|
||||
burp/HttpMessageFormatter.class
|
||||
|
||||
+8
-7
@@ -1,7 +1,8 @@
|
||||
/Users/temp/Downloads/CyberStrikeAI-main/plugins/burp-suite/cyberstrikeai-burp-extension/src/main/java/burp/BurpExtender.java
|
||||
/Users/temp/Downloads/CyberStrikeAI-main/plugins/burp-suite/cyberstrikeai-burp-extension/src/main/java/burp/CyberStrikeAIClient.java
|
||||
/Users/temp/Downloads/CyberStrikeAI-main/plugins/burp-suite/cyberstrikeai-burp-extension/src/main/java/burp/CyberStrikeAITab.java
|
||||
/Users/temp/Downloads/CyberStrikeAI-main/plugins/burp-suite/cyberstrikeai-burp-extension/src/main/java/burp/HttpMessageFormatter.java
|
||||
/Users/temp/Downloads/CyberStrikeAI-main/plugins/burp-suite/cyberstrikeai-burp-extension/src/main/java/burp/MarkdownRenderer.java
|
||||
/Users/temp/Downloads/CyberStrikeAI-main/plugins/burp-suite/cyberstrikeai-burp-extension/src/main/java/burp/SimpleJson.java
|
||||
/Users/temp/Downloads/CyberStrikeAI-main/plugins/burp-suite/cyberstrikeai-burp-extension/src/main/java/burp/SslTrustAll.java
|
||||
/Users/yifan.zhao/Downloads/CyberStrikeAI-main/plugins/burp-suite/cyberstrikeai-burp-extension/src/main/java/burp/SimpleJson.java
|
||||
/Users/yifan.zhao/Downloads/CyberStrikeAI-main/plugins/burp-suite/cyberstrikeai-burp-extension/src/main/java/burp/CyberStrikeAITab.java
|
||||
/Users/yifan.zhao/Downloads/CyberStrikeAI-main/plugins/burp-suite/cyberstrikeai-burp-extension/src/main/java/burp/MarkdownRenderer.java
|
||||
/Users/yifan.zhao/Downloads/CyberStrikeAI-main/plugins/burp-suite/cyberstrikeai-burp-extension/src/main/java/burp/SendOptionsDialog.java
|
||||
/Users/yifan.zhao/Downloads/CyberStrikeAI-main/plugins/burp-suite/cyberstrikeai-burp-extension/src/main/java/burp/SslTrustAll.java
|
||||
/Users/yifan.zhao/Downloads/CyberStrikeAI-main/plugins/burp-suite/cyberstrikeai-burp-extension/src/main/java/burp/HttpMessageFormatter.java
|
||||
/Users/yifan.zhao/Downloads/CyberStrikeAI-main/plugins/burp-suite/cyberstrikeai-burp-extension/src/main/java/burp/CyberStrikeAIClient.java
|
||||
/Users/yifan.zhao/Downloads/CyberStrikeAI-main/plugins/burp-suite/cyberstrikeai-burp-extension/src/main/java/burp/BurpExtender.java
|
||||
|
||||
Reference in New Issue
Block a user