漯河网站建设e,wordpress 图片链接下载,wordpress可视化文章,2022麻豆区区区三区四区本文会包括BP插件开发流程及打包#xff0c;API#xff0c;javaswing#xff08;UI#xff09;部分的内容。阅读完本文后#xff0c;读者将初步具有开发BP插件的能力。1 开始开发我们使用IDEA作为开发工具#xff08;使用其他IDE也绰绰有余#xff09;。引入依赖包…本文会包括BP插件开发流程及打包APIjavaswingUI部分的内容。阅读完本文后读者将初步具有开发BP插件的能力。1 开始开发我们使用IDEA作为开发工具使用其他IDE也绰绰有余。引入依赖包net.portswigger.burp.extender:burp-extender-api包的版本见https://mvnrepository.com/artifact/net.portswigger.burp.extender/burp-extender-api如果使用Gradle管理包可以这样书写build.gradleplugins {id java
}group burp
version 1.0-SNAPSHOTrepositories {mavenCentral()
}dependencies {implementation net.portswigger.burp.extender:burp-extender-api:1.7.13 //重点部分
}test {useJUnitPlatform()
}也就是IDEA新建一个gradle项目然后将上文替换build.gradle文件然后点击构建即可如果新建的gradle项目中没有类似这样的结构就是放java文件的地方请参考https://blog.csdn.net/qq_40548227/article/details/1247413112 API文档首先BP本身自带了一个API DOC在这里它有几个缺点全英文没有代码示例其次PortSwigger自己在github上有很多示例插件如https://github.com/PortSwigger/example-hello-world它也有缺点全英文所以最重要的还是英语要好- -。3 代码规范与基础插件构建首先BP插件有两个规范插件的主类名为BurpExtender实现接口IBurpExtender插件的包名为burp一个基础的BP插件结构及代码如下所示在这个基础上我们开始构建一个基础的插件。3.1 插件注册时指的即是插件的“入口函数”registerExtenderCallbacks执行时。一般可以在此函数执行时打印作者信息并获取IExtensionHelpers用于分析请求和响应。这是一段示例代码package burp;import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;public class BurpExtender implements IBurpExtender{private static IExtensionHelpers helpers;private static PrintWriter so;Overridepublic void registerExtenderCallbacks(IBurpExtenderCallbacks callbacks) {BurpExtender.helperscallbacks.getHelpers(); //获取helpersBurpExtender.sonew PrintWriter(callbacks.getStdout(), true); //获取输出callbacks.setExtensionName(示例插件);BurpExtender.so.println(name 示例插件);BurpExtender.so.println(author AugustTheodor);}
}将输入输出与扩展帮助对象PrintWriter so与IExtensionHelpers helpers存储为类变量这样可以在其他类中直接进行调用。3.2 监听请求与响应负责监听请求与相应的监听器为IHttpListener我们需要在主函数中注册监听器如callbacks.registerHttpListener(new IHttpListener() {Overridepublic void processHttpMessage(int toolFlag, boolean messageIsRequest, IHttpRequestResponse messageInfo) {}
}); //注册HTTP监听器继承此接口后需要实现方法processHttpMessage这个方法在每个请求经过时被调用传入int toolFlag请求经过的组件对应的id如proxy、repeater其值定义在IBurpExtenderCallbacks、boolean messageIsRequest这个包是否是请求包false则为响应、IHttpRequestResponse messageInfo包的具体信息可用于分析。以下是一个processHttpMessage处理HTTP请求与相应的范例它会将所有经过PROXY的请求与相应打印到输出界面需要注意的是getRequest与getResponse返回的是byte[]而非String需要进行处理才能够读取到字符串形式Override
public void processHttpMessage(int toolFlag, boolean messageIsRequest, IHttpRequestResponse messageInfo) {if(messageIsRequest){//处理请求if(toolFlagIBurpExtenderCallbacks.TOOL_PROXY){//过滤PROXY之外的请求只处理经过PROXY的请求BurpExtender.so.println(new String(messageInfo.getRequest(), StandardCharsets.UTF_8).intern());}}else{//处理响应if(toolFlagIBurpExtenderCallbacks.TOOL_PROXY){BurpExtender.so.println(new String(messageInfo.getResponse(), StandardCharsets.UTF_8).intern());}}
}当然我们不光可以监听请求与相应还可以修改它们。我们使用以下的方法设置请求与响应在处理响应时不可设置请求并且这里设置的也是byte[]的形式messageInfo.setResponse();
messageInfo.setRequest();#3.3 修改Content-Length在修改修改请求与响应的body部分中有一个非常容易被忽略的步骤修改Content-Length。如果不修改此头部就很容易导致服务器响应异常和浏览器解析异常。所以在更新完body内容后需要重新计算body长度并修改Content-Length头的内容。以下是一段处理响应中body并更新Content-Length头的代码对于请求的处理方式是相同的Override
public void processHttpMessage(int toolFlag, boolean messageIsRequest, IHttpRequestResponse messageInfo) {if(messageIsRequest){//处理请求byte[] responsemessageInfo.getResponse();//获取response的byteIResponseInfo infoBurpExtender.helpers.analyzeResponse(response);//获取响应相关信息String headnew String(Arrays.copyOfRange(response,0,info.getBodyOffset()),StandardCharsets.UTF_8).intern();String bodynew String(Arrays.copyOfRange(response,info.getBodyOffset(),response.length), StandardCharsets.UTF_8).intern();//分别获取head与body的String内容bodydo_sth_with_body(body);//处理bodyString ori_CL;//用于保存原本的Content-LengthListString headershelpers.analyzeResponse(response).getHeaders();for (String h:headers) {if(h.contains(Content-Length)){ori_CLh;break;}}//获取Content-Length的原值String new_CLContent-Length: String.valueOf(body.getBytes().length);//新的Content-Lengthheadhead.replace(ori_CL,new_CL);//替换头部byte[] new_response(headbody).getBytes();messageInfo.setResponse(new_response);}
}我们可以将这个过程简化成一个工具函数byte[] tool_update_content_length(String head,String body,String new_body){//此函数自动更新Content-LengthString ori_CL;String new_CL;ListString headers List.of(head.split(\n));for (String h:headers) {if(h.contains(Content-Length)){ori_CLh;break;}}new_CLContent-Length: new_body.getBytes().length;//新的Content-Lengthheadhead.replace(ori_CL,new_CL);//替换头部return (headbody).getBytes();
}3.4 打包使用下图的命令即可./gradlew build4 UI这个部分没有什么详细说的必要就跟大学大作业画面板差不多。需要提的也就是几个踩雷点。4.1 如何创建插件自己的标签页需要使用ITab接口并在入口函数中添加标签页call.addSuiteTab(this);示例public class BurpExtender implements IBurpExtender,ITab{private static IExtensionHelpers helpers;private static PrintWriter so;Overridepublic void registerExtenderCallbacks(IBurpExtenderCallbacks callbacks) {BurpExtender.helperscallbacks.getHelpers(); //获取helpersBurpExtender.sonew PrintWriter(callbacks.getStdout(), true); //获取输出callbacks.setExtensionName(示例插件);callbacks.addSuiteTab(this); //一个插件可以有好几个Tab比如我这里使用两次就会有两个TabBurpExtender.so.println(name 示例插件);BurpExtender.so.println(author AugustTheodor);}Overridepublic String getTabCaption() {return 标签页名字;}Overridepublic Component getUiComponent() {//返回的是一个JAVA UI 组件作为标签页显示的内容return null;}
}4.2 AWT与SWINGjava有两个UI组件包一个是awt一个是swing。这两个组件包里的组件混用时可能会出现意想不到的BUG比如说JComboBox的选项一直弹不出来。4.3 JTable我们可能会使用JTable绘制表格实现类似Proxy中列表的效果如但原始表格里的元素默认是表现为TextField的。下面给出在表格中插入选择框与复选框的一个方法4.3.1 复选框这个东西继承JTableModel将需要类型为复选框的列Class置为Booleanpublic class ATableModel extends DefaultTableModel{private final Class[] tableClass{Boolean.class,String.class,String.class,String.class,String.class,String.class};//需要表现为复选框的列类型为BooleanOverridepublic int getColumnCount() {return this.tableClass.length;}Overridepublic String getColumnName(int columnIndex) {return L18n.getInstance().columns[columnIndex];}Overridepublic Class? getColumnClass(int columnIndex) {return this.tableClass[columnIndex];}}然后在实例化JTable时传入此Model的实例JTable tablenew JTable(new ATableModel());4.3.2 选择框这个使用此语句table.getColumnModel().getColumn(1).setCellEditor(new DefaultCellEditor(new JComboBox(L18n.getInstance().operator)));