实现效果
如HaE在你浏览请求响应的时候,会把匹配到的 markinfo
用一个新的 Tab 给展示出来。所以新增一个Tab,要求实现如下功能:
- 获取
data=<base64编码>
的内容并base64解码后展示 - 编辑base64解码后的内容,发送数据包时会自动编码回去
涉及接口:
- IMessageEditorTabFactory
- IMessageEditorTab
实现代码
创建项目过程省略,直接从代码入手,使用旧版API开发。
package burp;
import java.awt.*;
public class BurpExtender implements IBurpExtender, IMessageEditorTabFactory {
// 回调对象
private IBurpExtenderCallbacks callbacks;
// 辅助类,一般用于辅助分析数据包结构
private IExtensionHelpers helpers;
// 实现 IBurpExtender 接口函数
@Override
public void registerExtenderCallbacks(IBurpExtenderCallbacks callbacks) {
// 设置插件名字
callbacks.setExtensionName("Demo");
// callbacks到处都要用,搞成类变量
this.callbacks = callbacks;
// 辅助类,一般用于辅助分析数据包结构,类变量方便其他函数调用
helpers = callbacks.getHelpers();
// 注册 MessageEditorTabFactory ,必须要注册了burp有新消息才会通知你
callbacks.registerMessageEditorTabFactory(this);
}
/**
* 创建新的Tab
*
* @param controller IMessageEditorController 对象,新建的标签页可以通过它查询当前显示的消息的详细信息。对于扩展调用的消息编辑器,如果扩展未提供编辑器控制器,该对象可能为 null。
* @param editable 当前请求和响应是否可编辑(如在History中显示就不可编辑,在repeater中显示就可以编辑)
* @return 新的Tab对象
*/
@Override
public IMessageEditorTab createNewInstance(IMessageEditorController controller, boolean editable) {
return new CustomMessageTab(controller, editable);
}
private class CustomMessageTab implements IMessageEditorTab {
private IMessageEditorController controller;
private boolean editable;
private ITextEditor textEditor;
public CustomMessageTab(IMessageEditorController controller, boolean editable) {
this.controller = controller;
this.editable = editable;
// 用callback创建一个text编辑组件
textEditor = callbacks.createTextEditor();
textEditor.setEditable(editable);
}
// 显示的标题
@Override
public String getTabCaption() {
return "b64Decode";
}
// 展示的组件
@Override
public Component getUiComponent() {
return textEditor.getComponent();
}
// 是否启用/显示tab
@Override
public boolean isEnabled(byte[] content, boolean isRequest) {
// 如果是请求数据包 且 参数中含有data 就显示这个tab
return isRequest && helpers.getRequestParameter(content, "data") != null;
}
// 设置新tab中展示的内容
@Override
public void setMessage(byte[] content, boolean isRequest) {
// 如果数据包内容为空,就给内容设置为空且不可编辑
if (content == null) {
textEditor.setText(null);
textEditor.setEditable(false);
} else {
// 获取data参数
IParameter data = helpers.getRequestParameter(content, "data");
// base64解码并设置到组件中
textEditor.setText(helpers.base64Decode(helpers.urlDecode(data.getValue())));
textEditor.setEditable(editable);
}
}
// 返回原来面板显示的内容(每次从新建的tab点回原始数据的时候会触发)
@Override
public byte[] getMessage() {
// 如果新面板中的数据被修改了,那么原始数据也要进行响应的修改
if (textEditor.isTextModified()) {
// 新的data参数的值
String newData = helpers.urlEncode(helpers.base64Encode(textEditor.getText()));
// 更新data参数并返回
return helpers.updateParameter(controller.getRequest(), helpers.buildParameter("data", newData, IParameter.PARAM_URL));
} else { // 返回原始数据
return controller.getRequest();
}
}
@Override
public boolean isModified() {
return textEditor.isTextModified();
}
@Override
public byte[] getSelectedData() {
return textEditor.getSelectedText();
}
}
}
实现测试
点击回原始数据,可见数据也同步更新
扩展总结
- 实现
IMessageEditorTabFactory
接口即可 - ui组件可以用callbacks提供的
callbacks.createTextEditor()
来创建 - 除了用
controller.getRequest()
来获取原始请求,也可以在getMessage()
时将原始请求保存到类变量中