从0到1编写Unicode解码Burp插件

admin 2023年12月25日22:57:33评论63 views字数 6639阅读22分7秒阅读模式

为什么要写uncicode解码插件,在日常工作中遇到数据包中unicode编码,编写插件方便自己处理工作遇到的问题,Github上也有写好的插件,但是哪里有自己造轮子有意思。


搭建环境

java环境:openjdk20

使用IDEA 新建java项目

从0到1编写Unicode解码Burp插件

项目名称 自定义

从0到1编写Unicode解码Burp插件

从0到1编写Unicode解码Burp插件

从0到1编写Unicode解码Burp插件

Maven配置

搭建Add Framework

从0到1编写Unicode解码Burp插件

从0到1编写Unicode解码Burp插件

首先,创建一个新的Maven项目,并添加Montoya API的依赖项,如下所示。

    <dependencies>
      <dependency><groupId>net.portswigger.burp.extensions</groupId>
          <artifactId>montoya-api</artifactId>
          <version>LATEST</version>
      </dependency>
  </dependencies>

从0到1编写Unicode解码Burp插件

配置好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

从0到1编写Unicode解码Burp插件

点击Maven -> Lifecycle -> install 即可编译编译出来在 target目录下jar文件

从0到1编写Unicode解码Burp插件

导入burp成功

从0到1编写Unicode解码Burp插件

进阶-编写unicode解码插件

首先实现Unicode解码功能

主要实现方法decodeUnicodeString

  1. StringBuilder decodedString = new StringBuilder();: 创建一个 StringBuilder 对象,用于存储解码后的字符串。StringBuilder 用于在循环中动态构建字符串,比直接使用字符串拼接更有效率。

  2. String[] hexCodes = unicodeString.split("\\u");: 使用 split 方法将输入的字符串按 u 拆分为数组。这样就得到了一个数组,其中每个元素都包含一个 Unicode 编码。

  3. for (String hexCode : hexCodes) {: 循环遍历 Unicode 编码数组。

  4. if (!hexCode.isEmpty()) {: 跳过第一个空字符串,因为在开始位置有两个反斜杠。这是因为在拆分字符串时,第一个元素为空,因为字符串以 u 开头。

  5. int hexValue = Integer.parseInt(hexCode, 16);: 将十六进制字符串转换为整数。

  6. decodedString.append((char) hexValue);: 将整数转换为字符,并追加到 decodedString 中。

  7. 最后,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 接口中的两个方法 handleHttpRequestToBeSenthandleHttpResponseReceived。这些方法用于处理即将发送的 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";
?>

实现结果展示

没有加载插件的效果

从0到1编写Unicode解码Burp插件

从0到1编写Unicode解码Burp插件

加载插件

从0到1编写Unicode解码Burp插件

从0到1编写Unicode解码Burp插件

从0到1编写Unicode解码Burp插件

缺点

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插件

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年12月25日22:57:33
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   从0到1编写Unicode解码Burp插件https://cn-sec.com/archives/2238426.html

发表评论

匿名网友 填写信息