为什么要写uncicode解码插件,在日常工作中遇到数据包中unicode编码,编写插件方便自己处理工作遇到的问题,Github上也有写好的插件,但是哪里有自己造轮子有意思。
搭建环境
java环境:openjdk20
使用IDEA 新建java项目
项目名称 自定义
Maven配置
搭建Add Framework
首先,创建一个新的Maven项目,并添加Montoya API的依赖项,如下所示。
<dependencies>
<dependency><groupId>net.portswigger.burp.extensions</groupId>
<artifactId>montoya-api</artifactId>
<version>LATEST</version>
</dependency>
</dependencies>
配置好Maven项目,就可以开始写burp插件代码了
简单的HelloWorld
在java项目中,创建一个HelloWorld类,并引入burp api包
package bp;
import burp.api.montoya.BurpExtension;
import burp.api.montoya.MontoyaApi;
import burp.api.montoya.logging.Logging;
//Burp will auto-detect and load any class that extends BurpExtension.
public class HelloWorld implements BurpExtension
{
@Override
public void initialize(MontoyaApi api)
{
// 设置插件的名称
api.extension().setName("Hello world extension");
Logging logging = api.logging();
// 日志输出
logging.logToOutput("Hello output.");
// write a message to our error stream
logging.logToError("Hello error.");
// write a message to the Burp alerts tab
logging.raiseInfoEvent("Hello info event.");
logging.raiseDebugEvent("Hello debug event.");
logging.raiseErrorEvent("Hello error event.");
logging.raiseCriticalEvent("Hello critical event.");
// throw an exception that will appear in our error stream
throw new RuntimeException("Hello exception.");
}
}
编译jar导入burp
点击Maven -> Lifecycle -> install 即可编译编译出来在 target目录下jar文件
导入burp成功
进阶-编写unicode解码插件
首先实现Unicode解码功能
主要实现方法decodeUnicodeString
-
StringBuilder decodedString = new StringBuilder();
: 创建一个StringBuilder
对象,用于存储解码后的字符串。StringBuilder
用于在循环中动态构建字符串,比直接使用字符串拼接更有效率。 -
String[] hexCodes = unicodeString.split("\\u");
: 使用split
方法将输入的字符串按u
拆分为数组。这样就得到了一个数组,其中每个元素都包含一个 Unicode 编码。 -
for (String hexCode : hexCodes) {
: 循环遍历 Unicode 编码数组。 -
if (!hexCode.isEmpty()) {
: 跳过第一个空字符串,因为在开始位置有两个反斜杠。这是因为在拆分字符串时,第一个元素为空,因为字符串以u
开头。 -
int hexValue = Integer.parseInt(hexCode, 16);
: 将十六进制字符串转换为整数。 -
decodedString.append((char) hexValue);
: 将整数转换为字符,并追加到decodedString
中。 -
最后,
return decodedString.toString();
返回最终的解码后的字符串。
public class unicode {
public static void main(String[] args) {
// 包含Unicode转义序列的字符串
String unicodeString = "\u8be5\u7528\u6237\u4e0d\u5b58\u5728\uff01";
// 解码Unicode字符串
String decodedString = decodeUnicodeString(unicodeString);
// 输出解码后的字符串
System.out.println(decodedString);
}
// 解码包含Unicode转义序列的字符串的方法
public static String decodeUnicodeString(String unicodeString) {
StringBuilder decodedString = new StringBuilder();
// 将Unicode转义序列拆分为单个编码单元
String[] hexCodes = unicodeString.split("\\u");
// 跳过第一个空字符串,因为在开始位置有两个反斜杠
for (String hexCode : hexCodes) {
if (!hexCode.isEmpty()) {
// 解析16进制编码,并将其转换为字符
int hexValue = Integer.parseInt(hexCode, 16);
decodedString.append((char) hexValue);
}
}
return decodedString.toString();
}
}
ok Unicode解码功能写好了,开始实现burp api
创建插件主体
package main;
import burp.api.montoya.*;
import burp.api.montoya.MontoyaApi;
import burp.api.montoya.logging.Logging;
public class HelloWorld implements BurpExtension
{
MontoyaApi api;
Logging logging;
@Override
public void initialize(MontoyaApi api)
{
// Save a reference to the MontoyaApi object
this.api = api;
// api.logging() returns an object that we can use to print messages to stdout and stderr
this.logging = api.logging();
// Set the name of the extension
api.extension().setName("Unicode解码插件");
// Print a message to the stdout
this.logging.logToOutput("unicode解码插件载入成功!");
api.http().registerHttpHandler(new CustomHttpHandler(api));
}
}
api.http().registerHttpHandler(new CustomHttpHandler(api));
通过api调用CustomHttpHandler
类, 为主要实现功能的类
CustomHttpHandler
初始类
import burp.api.montoya.http.handler.*;
public class CustomHttpHandler implements HttpHandler {
@Override
public RequestToBeSentAction handleHttpRequestToBeSent(HttpRequestToBeSent requestToBeSent) {
return null;
}
@Override
public ResponseReceivedAction handleHttpResponseReceived(HttpResponseReceived responseReceived) {
return null;
}
}
实现了 HttpHandler
接口中的两个方法 handleHttpRequestToBeSent
和 handleHttpResponseReceived
。这些方法用于处理即将发送的 HTTP 请求和已经接收到的 HTTP 响应。
具体实现功能
主要用到handleHttpResponseReceived
方法,下面是实现功能具体代码
package main;
import burp.api.montoya.core.ByteArray;
import burp.api.montoya.http.handler.*;
import burp.api.montoya.*;
import burp.api.montoya.http.message.*;
import burp.api.montoya.http.message.responses.HttpResponse;
import burp.api.montoya.logging.Logging;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class CustomHttpHandler implements HttpHandler {
MontoyaApi api;
Logging logging;
public CustomHttpHandler(MontoyaApi api) {
// Save a reference to the MontoyaApi object
this.api = api;
// api.logging() returns an object that we can use to print messages to stdout and stderr
this.logging = api.logging();
}
@Override
public RequestToBeSentAction handleHttpRequestToBeSent(HttpRequestToBeSent requestToBeSent) {
return null;
}
@Override
public ResponseReceivedAction handleHttpResponseReceived(HttpResponseReceived responseReceived) {
ByteArray body = responseReceived.body();
// Convert ByteArray to string
String responseBody = body.toString();
// Regular expression pattern for matching Unicode escape sequences
String regex = "(\\u[\d\w]{4})+";
// Compile the regular expression
Pattern pattern = Pattern.compile(regex);
// Create a matcher for the response body
Matcher matcher = pattern.matcher(responseBody);
Boolean matched = matcher.find();
// Find and replace Unicode escape sequences
//StringBuffer decodedBody = new StringBuffer();
if (matched) {
String matchedValue = matcher.group(0);
String decodedString = decodeUnicodeString(matchedValue);
logging.logToOutput("Original Response Body: " + responseReceived.body());
logging.logToOutput("Decoded Response Body: " + decodedString);
return ResponseReceivedAction.continueWith(responseReceived.withBody(decodedString));
} else {
// 如果没有匹配,继续处理原始响应
return ResponseReceivedAction.continueWith(responseReceived);
}
}
// 解码包含Unicode转义序列的字符串的方法
public static String decodeUnicodeString(String unicodeString) {
StringBuilder decodedString = new StringBuilder();
// 将Unicode转义序列拆分为单个编码单元
String[] hexCodes = unicodeString.split("\\u");
// 跳过第一个空字符串,因为在开始位置有两个反斜杠
for (String hexCode : hexCodes) {
if (!hexCode.isEmpty()) {
// 解析16进制编码,并将其转换为字符
int hexValue = Integer.parseInt(hexCode, 16);
decodedString.append((char) hexValue);
}
}
return decodedString.toString();
}
}
Unicode插件效果
demo
<?php
echo "u6211u662fu4e2du6587";
echo "u0031u0031u0031u0031u0031u0031u0031u0031u0031u0031u0031u0031u0031u0031u0031u0031u0031u0031u0031";
?>
实现结果展示
没有加载插件的效果
加载插件
缺点
withBody
方法返回数据,处理中文有问题,还是得看看官方文档
参考文章
https://portswigger.net/burp/documentation/desktop/extensions/creating
https://github.com/federicodotta
https://github.com/PortSwigger/burp-extensions-montoya-api-examples
原文始发于微信公众号(安全逐梦人):从0到1编写Unicode解码Burp插件
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论