Skip to content

Commit

Permalink
增强 Payload Processing 功能(重新启用合并请求选项、新增条件检查规则);优化数据看板 From 字段的内容展示
Browse files Browse the repository at this point in the history
  • Loading branch information
vaycore committed Jun 6, 2024
1 parent 499b160 commit b45f30f
Show file tree
Hide file tree
Showing 8 changed files with 182 additions and 68 deletions.
131 changes: 80 additions & 51 deletions src/main/java/burp/BurpExtender.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
import java.util.Vector;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

/**
* 插件入口
Expand Down Expand Up @@ -461,7 +460,29 @@ private void runScanTask(IHttpRequestResponse httpReqResp, IRequestInfo info, St
return;
}
// 对扫描的任务发起请求
doBurpRequest(service, url, request, from);
if (!mDataBoardTab.hasPayloadProcessing()) {
doBurpRequest(service, url, request, from);
return;
}
// 先检测规则是否为空
List<ProcessingItem> processList = getPayloadProcess()
.stream().filter(ProcessingItem::isEnabledAndMerge).toList();
if (processList.isEmpty()) {
doBurpRequest(service, url, request, from);
} else {
byte[] requestBytes = request;
for (ProcessingItem item : processList) {
ArrayList<PayloadItem> items = item.getItems();
requestBytes = handlePayloadProcess(service, requestBytes, items);
}
if (requestBytes != null) {
// 检测是否未进行任何处理
boolean equals = Arrays.equals(request, requestBytes);
// 未进行任何处理时,不变更 from 值
String newFrom = equals ? from : from + "(Process)";
doBurpRequest(service, url, requestBytes, newFrom);
}
}
// 运行 Payload Processing 任务
runPayloadProcessingTask(service, url, request);
}
Expand All @@ -478,26 +499,21 @@ private void runPayloadProcessingTask(IHttpService service, String url, byte[] r
if (!mDataBoardTab.hasPayloadProcessing()) {
return;
}
// 进行 Payload Processing 处理后,再次请求数据包
ArrayList<ProcessingItem> processList = Config.getPayloadProcessList();
if (processList == null || processList.isEmpty()) {
return;
}
String from = "Process";
// 遍历规则列表
processList.parallelStream().filter(ProcessingItem::isEnabled).forEach((item) -> {
ArrayList<PayloadItem> items = item.getItems();
byte[] requestBytes = handlePayloadProcess(service, reqRawBytes, items);
if (requestBytes == null) {
return;
}
// 检测是否未进行任何处理
boolean equals = Arrays.equals(reqRawBytes, requestBytes);
if (equals) {
return;
}
doBurpRequest(service, url, requestBytes, from);
});
// 遍历规则列表,进行 Payload Processing 处理后,再次请求数据包
getPayloadProcess().parallelStream()
.filter(ProcessingItem::isEnabledWithoutMerge).forEach((item) -> {
ArrayList<PayloadItem> items = item.getItems();
byte[] requestBytes = handlePayloadProcess(service, reqRawBytes, items);
if (requestBytes == null) {
return;
}
// 检测是否未进行任何处理
boolean equals = Arrays.equals(reqRawBytes, requestBytes);
if (equals) {
return;
}
doBurpRequest(service, url, requestBytes, "Process" + "(" + item.getName() + ")");
});
}

/**
Expand Down Expand Up @@ -646,7 +662,7 @@ private byte[] handleHeader(IHttpRequestResponse httpReqResp, IRequestInfo info,
return configHeaderKey.equals(key);
}
return false;
}).collect(Collectors.toList());
}).toList();
// 配置中存在匹配项,替换为配置中的数据
if (matchList.size() > 0) {
for (String matchItem : matchList) {
Expand Down Expand Up @@ -699,6 +715,14 @@ private List<String> getExcludeHeader() {
return WordlistManager.getExcludeHeader();
}

private List<ProcessingItem> getPayloadProcess() {
ArrayList<ProcessingItem> list = Config.getPayloadProcessList();
if (list == null) {
return new ArrayList<>();
}
return list.stream().filter(ProcessingItem::isEnabled).toList();
}

/**
* 从配置中获取请求重试次数
*/
Expand Down Expand Up @@ -834,34 +858,39 @@ private byte[] handlePayloadProcess(IHttpService service, byte[] requestBytes, L
for (PayloadItem item : list) {
// 只调用启用的规则
PayloadRule rule = item.getRule();
switch (item.getScope()) {
case PayloadRule.SCOPE_URL:
String newUrl = rule.handleProcess(url);
// 截取请求头第一行,用于定位要处理的位置
String temp = header.substring(0, header.indexOf("\r\n"));
int start = temp.indexOf("/");
int end = temp.lastIndexOf(" ");
// 分隔要插入数据的位置
String left = header.substring(0, start);
String right = header.substring(end);
// 拼接处理好的数据
header = left + newUrl + right;
request = header + "\r\n\r\n" + body;
url = newUrl;
break;
case PayloadRule.SCOPE_HEADER:
String newHeader = rule.handleProcess(header);
header = newHeader;
request = newHeader + "\r\n\r\n" + body;
break;
case PayloadRule.SCOPE_BODY:
String newBody = rule.handleProcess(body);
request = header + "\r\n\r\n" + newBody;
body = newBody;
break;
case PayloadRule.SCOPE_REQUEST:
request = rule.handleProcess(request);
break;
try {
switch (item.getScope()) {
case PayloadRule.SCOPE_URL:
String newUrl = rule.handleProcess(url);
// 截取请求头第一行,用于定位要处理的位置
String temp = header.substring(0, header.indexOf("\r\n"));
int start = temp.indexOf("/");
int end = temp.lastIndexOf(" ");
// 分隔要插入数据的位置
String left = header.substring(0, start);
String right = header.substring(end);
// 拼接处理好的数据
header = left + newUrl + right;
request = header + "\r\n\r\n" + body;
url = newUrl;
break;
case PayloadRule.SCOPE_HEADER:
String newHeader = rule.handleProcess(header);
header = newHeader;
request = newHeader + "\r\n\r\n" + body;
break;
case PayloadRule.SCOPE_BODY:
String newBody = rule.handleProcess(body);
request = header + "\r\n\r\n" + newBody;
body = newBody;
break;
case PayloadRule.SCOPE_REQUEST:
request = rule.handleProcess(request);
break;
}
} catch (Exception e) {
Logger.debug("handlePayloadProcess exception: " + e.getMessage());
return null;
}
}
// 更新 Content-Length
Expand Down
1 change: 1 addition & 0 deletions src/main/java/burp/vaycore/onescan/common/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@ private static void preparePayloadProcessList() {
for (LinkedTreeMap<String, Object> mapItem : items) {
ProcessingItem item = new ProcessingItem();
item.setEnabled((Boolean) mapItem.get("enabled"));
item.setMerge((Boolean) mapItem.get("merge"));
String name = String.valueOf(mapItem.get("name"));
item.setName(name);
ArrayList<LinkedTreeMap<String, Object>> payloadMapItems =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,5 +92,5 @@ public String[] getParamValues() {
* @param content 原始数据(作用域不同,原始数据也不同)
* @return 处理后的数据
*/
public abstract String handleProcess(String content);
public abstract String handleProcess(String content) throws IllegalStateException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
public class ProcessingItem {

private boolean enabled;
private boolean merge;
private String name;
private ArrayList<PayloadItem> items;

Expand All @@ -21,6 +22,22 @@ public void setEnabled(boolean enabled) {
this.enabled = enabled;
}

public boolean isMerge() {
return merge;
}

public void setMerge(boolean merge) {
this.merge = merge;
}

public boolean isEnabledAndMerge() {
return this.isEnabled() && this.isMerge();
}

public boolean isEnabledWithoutMerge() {
return this.isEnabled() && !this.isMerge();
}

public String getName() {
return name;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
*/
public class ProcessingListModel extends AbstractTableModel {

private final String[] COLUMN_NAMES = new String[]{"", "RuleName", "RuleCount"};
private final String[] COLUMN_NAMES = new String[]{"Enabled", "Merge", "RuleName", "RuleCount"};
private final Vector<ProcessingItem> mData;

public ProcessingListModel() {
Expand Down Expand Up @@ -85,8 +85,10 @@ public Object getValueAt(int rowIndex, int columnIndex) {
case 0:
return data.isEnabled();
case 1:
return data.getName();
return data.isMerge();
case 2:
return data.getName();
case 3:
ArrayList<PayloadItem> items = data.getItems();
int count = items == null ? 0 : items.size();
return String.valueOf(count);
Expand All @@ -98,9 +100,10 @@ public Object getValueAt(int rowIndex, int columnIndex) {
public Class<?> getColumnClass(int columnIndex) {
switch (columnIndex) {
case 0:
return Boolean.class;
case 1:
return Boolean.class;
case 2:
case 3:
return String.class;
}
return String.class;
Expand All @@ -113,16 +116,17 @@ public String getColumnName(int column) {

@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return columnIndex == 0;
return columnIndex == 0 || columnIndex == 1;
}

@Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
if (columnIndex != 0) {
return;
}
ProcessingItem item = get(rowIndex);
item.setEnabled((Boolean) aValue);
if (columnIndex == 0) {
item.setEnabled((Boolean) aValue);
} else if (columnIndex == 1) {
item.setMerge((Boolean) aValue);
}
set(rowIndex, item);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import burp.vaycore.common.widget.HintTextField;
import burp.vaycore.onescan.ui.widget.payloadlist.rule.AddPrefix;
import burp.vaycore.onescan.ui.widget.payloadlist.rule.AddSuffix;
import burp.vaycore.onescan.ui.widget.payloadlist.rule.ConditionCheck;
import burp.vaycore.onescan.ui.widget.payloadlist.rule.MatchReplace;

import javax.swing.*;
Expand All @@ -29,6 +30,7 @@ public class SimplePayloadList extends JPanel implements ActionListener {
AddPrefix.class,
AddSuffix.class,
MatchReplace.class,
ConditionCheck.class,
};

private final PayloadListModel mListModel;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ private void initView() {
setPreferredSize(new Dimension(0, 200));

add(newLeftPanel(), "85px");
add(newRightPanel(), "400px");
add(newRightPanel(), "460px");
}

private JPanel newLeftPanel() {
Expand Down Expand Up @@ -112,10 +112,12 @@ private JPanel newRightPanel() {

mListView = new JTable(mListModel);
UIHelper.setTableHeaderAlign(mListView, SwingConstants.CENTER);
mListView.getColumnModel().getColumn(0).setMinWidth(32);
mListView.getColumnModel().getColumn(0).setMaxWidth(32);
mListView.getColumnModel().getColumn(2).setMinWidth(75);
mListView.getColumnModel().getColumn(2).setMaxWidth(75);
mListView.getColumnModel().getColumn(0).setMinWidth(65);
mListView.getColumnModel().getColumn(0).setMaxWidth(65);
mListView.getColumnModel().getColumn(1).setMinWidth(65);
mListView.getColumnModel().getColumn(1).setMaxWidth(65);
mListView.getColumnModel().getColumn(3).setMinWidth(75);
mListView.getColumnModel().getColumn(3).setMaxWidth(75);
mListView.getTableHeader().setReorderingAllowed(false);
JScrollPane scrollPane = new JScrollPane(mListView);
panel.add(scrollPane, "1w");
Expand Down Expand Up @@ -189,21 +191,25 @@ private ProcessingItem showItemOptionPane(boolean hasCreate, ProcessingItem item
title = "Edit payload processing";
}
// 布局
JPanel panel = new JPanel();
JPanel panel = new JPanel(new VLayout(5));
panel.setPreferredSize(new Dimension(490, 260));
panel.setLayout(new VLayout(10));
// 规则名
JPanel namePanel = new JPanel(new HLayout(5, true));
namePanel.add(new JLabel("Rule Name:"));
JTextField nameUI = new JTextField();
namePanel.add(nameUI, "1w");
panel.add(namePanel);
// 合并到请求
JCheckBox mergeUI = new JCheckBox("Merge to request");
panel.add(mergeUI);
panel.add(new JPanel(), "5px");
// 规则表UI
SimplePayloadList listUI = new SimplePayloadList();
panel.add(listUI);
// 数据填充
if (item != null) {
nameUI.setText(item.getName());
mergeUI.setSelected(item.isMerge());
listUI.setListData(item.getItems());
}
// 显示对话框
Expand All @@ -218,13 +224,17 @@ private ProcessingItem showItemOptionPane(boolean hasCreate, ProcessingItem item
}
// 参数提醒
StringBuilder errorTips = new StringBuilder();
// 检测参数
// 检测 name 参数
String name = nameUI.getText();
if (StringUtils.isEmpty(name)) {
errorTips.append("Rule Name is empty.\n");
} else {
item.setName(name);
}
// 参数 merge 直接赋值
boolean merge = mergeUI.isSelected();
item.setMerge(merge);
// 检测 Rule list 参数
ArrayList<PayloadItem> payloadItems = listUI.getDataList();
if (payloadItems.isEmpty()) {
errorTips.append("Payload rule list is empty.");
Expand Down
Loading

0 comments on commit b45f30f

Please sign in to comment.