Skip to content

Commit

Permalink
添加主域名{{mdomain}}动态变量;新增QPS限制,限制每秒的请求数;优化配置面板,页面支持上下滚动;版本号更新至0.4.3版本。
Browse files Browse the repository at this point in the history
  • Loading branch information
vaycore committed Feb 23, 2023
1 parent 839e6fd commit 18424cb
Show file tree
Hide file tree
Showing 18 changed files with 515 additions and 49 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ Request配置界面如下
```text
{{host}} - 原请求头中的Host
{{domain}} - 原请求头中的Host(不包含端口号)
{{mdomain}} - 主域名(如果domain是IP地址,那么该值也是IP地址)
{{protocol}} - 原请求头中的协议(http、https)
{{timestamp}} - Unix时间戳(单位:秒)
{{random.ip}} - 随机IPv4值
Expand All @@ -94,6 +95,7 @@ Other配置界面如下

![](imgs/config_other.png)

- `QPS` QPS限制,限制每秒请求的数量,最大值 `9999`
- `Web name collect` Web目录名收集(例如:`http://xxx.com/wapi/xxx.html` 会将该 url 中的 `wapi` 写入到指定的文件中)
- `Json field collect` Json字段收集(收集json格式响应包中的所有key值,保存到指定目录)
- `Exclude suffix` 排除指定后缀的数据包
Expand Down
Binary file modified imgs/config_other.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>burp.vaycore</groupId>
<artifactId>onescan</artifactId>
<version>0.4.2</version>
<version>0.4.3</version>

<properties>
<jdk.version>8</jdk.version>
Expand Down
67 changes: 52 additions & 15 deletions src/main/java/burp/BurpExtender.java
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
package burp;

import burp.vaycore.common.helper.DomainHelper;
import burp.vaycore.common.helper.QpsLimiter;
import burp.vaycore.common.log.Logger;
import burp.vaycore.common.utils.*;
import burp.vaycore.hae.HaE;
import burp.vaycore.onescan.OneScan;
import burp.vaycore.onescan.bean.TaskData;
import burp.vaycore.onescan.common.Config;
import burp.vaycore.onescan.common.Constants;
import burp.vaycore.onescan.common.OnTabEventListener;
import burp.vaycore.onescan.ui.payloadlist.PayloadItem;
import burp.vaycore.onescan.ui.payloadlist.PayloadRule;
import burp.vaycore.onescan.ui.tab.ConfigPanel;
import burp.vaycore.onescan.ui.tab.DataBoardTab;
import burp.vaycore.onescan.ui.tab.config.OtherTab;
import burp.vaycore.onescan.ui.widget.TaskTable;
import org.json.HTTP;
import org.json.JSONArray;
import org.json.JSONObject;

Expand All @@ -32,23 +37,25 @@
* Created by vaycore on 2022-08-07.
*/
public class BurpExtender implements IBurpExtender, IProxyListener, IMessageEditorController,
TaskTable.OnTaskTableEventListener, ITab {
TaskTable.OnTaskTableEventListener, ITab, OnTabEventListener {

private IBurpExtenderCallbacks mCallbacks;
private OneScan mOneScan;
private DataBoardTab mDataBoardTab;
private ConfigPanel mConfigTab;
private IMessageEditor mRequestTextEditor;
private IMessageEditor mResponseTextEditor;
private ExecutorService mThreadPool;
private IHttpRequestResponse mCurrentReqResp;
private static final Vector<String> sRepeatFilter = new Vector<>();
private QpsLimiter mQpsLimit;

@Override
public void registerExtenderCallbacks(IBurpExtenderCallbacks callbacks) {
initData(callbacks);
initView();
initEvent();
Logger.debug("register Extender ok! Log: " + Constants.PLUGIN_VERSION.contains("debug"));
Logger.debug("register Extender ok! Log: " + Constants.DEBUG);
// 加载HaE插件
HaE.loadPlugin(Config.getFilePath(Config.KEY_HAE_PLUGIN_PATH));
}
Expand All @@ -58,24 +65,37 @@ private void initData(IBurpExtenderCallbacks callbacks) {
this.mThreadPool = Executors.newFixedThreadPool(50);
this.mCallbacks.setExtensionName(Constants.PLUGIN_NAME + " v" + Constants.PLUGIN_VERSION);
// 初始化日志打印
Logger.init(Constants.PLUGIN_VERSION.contains("debug"), mCallbacks.getStdout(), mCallbacks.getStderr());
Logger.init(Constants.DEBUG, mCallbacks.getStdout(), mCallbacks.getStderr());
// 初始化默认配置
Config.init();
// 初始化域名辅助类
DomainHelper.init("public_suffix_list.json");
// 初始化HaE插件
HaE.init(this);
// 初始化QPS限制器
initQpsLimiter();
}

private void initQpsLimiter() {
// 检测范围,如果不符合条件,不创建限制器
int limit = StringUtils.parseInt(Config.get(Config.KEY_QPS_LIMIT));
if (limit > 0 && limit <= 9999) {
this.mQpsLimit = new QpsLimiter(limit);
}
}

private void initView() {
mOneScan = new OneScan();
mDataBoardTab = mOneScan.getDataBoardTab();
mConfigTab = mOneScan.getConfigPanel();
mCallbacks.addSuiteTab(this);
// 创建请求和响应控件
mRequestTextEditor = mCallbacks.createMessageEditor(this, false);
mResponseTextEditor = mCallbacks.createMessageEditor(this, false);
mDataBoardTab.init(mRequestTextEditor.getComponent(), mResponseTextEditor.getComponent());
mDataBoardTab.getTaskTable().setOnTaskTableEventListener(this);
// 注册事件
mConfigTab.getOtherTab().setOnTabEventListener(this);
}

private void initEvent() {
Expand Down Expand Up @@ -301,6 +321,10 @@ private void doBurpRequest(IHttpRequestResponse httpReqResp, byte[] request) {
sRepeatFilter.add(url);
// 给每个任务创建线程
mThreadPool.execute(() -> {
// 限制QPS
if (mQpsLimit != null) {
mQpsLimit.limit();
}
Logger.debug("Do Send Request url: " + url);
// 发起请求
IHttpRequestResponse newReqResp = mCallbacks.makeHttpRequest(service, requestBytes);
Expand All @@ -322,7 +346,7 @@ private String buildRequestHeader(IHttpService service, String urlPath) {
ArrayList<String> headerList = getHeaderList();
StringBuilder request = new StringBuilder();
// 请求头构造
request.append("GET ").append(urlPath).append(" HTTP/1.1").append("\r\n");
request.append("GET ").append(urlPath).append(" HTTP/1.1").append(HTTP.CRLF);
// 如果存在配置,直接加载配置的值,否则使用默认值
if (headerList.size() > 0) {
for (String headerItem : headerList) {
Expand All @@ -332,20 +356,20 @@ private String buildRequestHeader(IHttpService service, String urlPath) {
}
String headerKey = headerItem.substring(0, splitIndex);
String headerValue = headerItem.substring(splitIndex + 2);
request.append(headerKey).append(": ").append(headerValue).append("\r\n");
request.append(headerKey).append(": ").append(headerValue).append(HTTP.CRLF);
}
} else {
String referer = getHostByIHttpService(service) + "/";
request.append("Host: {{host}}").append("\r\n");
request.append("User-Agent: ").append("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4495.0 Safari/537.36").append("\r\n");
request.append("Referer: ").append(referer).append("\r\n");
request.append("Accept: ").append("text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9").append("\r\n");
request.append("Accept-Language: ").append("zh-CN,zh;q=0.9,en;q=0.8").append("\r\n");
request.append("Accept-Encoding: ").append("gzip, deflate").append("\r\n");
request.append("Origin: ").append("https://www.baidu.com").append("\r\n");
request.append("Cache-Control: ").append("max-age=0").append("\r\n");
}
request.append("\r\n");
request.append("Host: {{host}}").append(HTTP.CRLF);
request.append("User-Agent: ").append("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4495.0 Safari/537.36").append(HTTP.CRLF);
request.append("Referer: ").append(referer).append(HTTP.CRLF);
request.append("Accept: ").append("text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9").append(HTTP.CRLF);
request.append("Accept-Language: ").append("zh-CN,zh;q=0.9,en;q=0.8").append(HTTP.CRLF);
request.append("Accept-Encoding: ").append("gzip, deflate").append(HTTP.CRLF);
request.append("Origin: ").append("https://www.baidu.com").append(HTTP.CRLF);
request.append("Cache-Control: ").append("max-age=0").append(HTTP.CRLF);
}
request.append(HTTP.CRLF);
// 请求头构建完成后,设置里面包含的变量
return setupVariable(service, request.toString());
}
Expand All @@ -360,9 +384,11 @@ private String setupVariable(IHttpService service, String request) {
String timestamp = String.valueOf(DateUtils.getTimestamp());
String randomIP = IPUtils.randomIPv4();
String randomUA = Utils.getRandomItem(Config.getList(Config.KEY_UA_LIST));
String mainDomain = DomainHelper.getDomain(domain);
// 替换变量
request = request.replace("{{host}}", host);
request = request.replace("{{domain}}", domain);
request = request.replace("{{mdomain}}", mainDomain);
request = request.replace("{{protocol}}", protocol);
request = request.replace("{{timestamp}}", timestamp);
request = request.replace("{{random.ip}}", randomIP);
Expand Down Expand Up @@ -641,4 +667,15 @@ public void onSendToRepeater(ArrayList<TaskData> list) {
}
}
}

@Override
public void onTabEventMethod(String action, Object... params) {
switch (action) {
case OtherTab.EVENT_QPS_LIMIT:
String limit = (String) params[0];
mQpsLimit = new QpsLimiter(StringUtils.parseInt(limit));
Logger.debug("Event: change qps limit: " + limit);
break;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

import java.io.File;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

/**
Expand Down
63 changes: 63 additions & 0 deletions src/main/java/burp/vaycore/common/helper/QpsLimiter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package burp.vaycore.common.helper;

/**
* QPS 限制器
* <p>
* Created by vaycore on 2023-02-23.
*/
public class QpsLimiter {

/**
* 以每秒的间隔计算
*/
private static final long PERIOD = 1000;

/**
* 接受请求时间窗口
*/
private final long[] accessTime;

/**
* 限制数量,最低为1
*/
private final int limit;

/**
* 指向最早请求时间的位置
*/
private int position;

public QpsLimiter(int limit) {
if (limit <= 0) {
throw new IllegalArgumentException("Illegal limit value: " + limit);
}
this.position = 0;
this.limit = limit;
this.accessTime = new long[limit];
}

/**
* 对执行点进行限制
*/
public void limit() {
long sleepMillis = 0;
synchronized (QpsLimiter.class) {
long curTime = System.currentTimeMillis();
if (curTime - this.accessTime[this.position] < PERIOD) {
// 未达到处理间隔, 计算休眠间隔剩余时间
sleepMillis = PERIOD - (curTime - this.accessTime[this.position]) + 1;
curTime = System.currentTimeMillis() + sleepMillis;
}
this.accessTime[this.position++] = curTime;
this.position = this.position % this.limit;
}
// 如果为0,没必要sleep
if (sleepMillis > 0) {
try {
Thread.sleep(sleepMillis);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Loading

0 comments on commit 18424cb

Please sign in to comment.