首页
社区
课程
招聘
[原创]Burp Suite Pro 破解
发表于: 2022-6-13 08:22 28083

[原创]Burp Suite Pro 破解

2022-6-13 08:22
28083

感谢scz、surferxyz、h3110w0r1d-y等各位老师傅在前面开路,这篇文章只是跟着前面的老师傅脚步走,用了自己的方式(ClassFileTransformer)开刀。

基于burpsuite_pro_v2022.3.9.jar

cfr - 反编译工具

jadx - 反编译gui工具,可以查找引用

btrace - 运行状态跟踪工具

arthas - 用起来比btrace更方便的跟踪工具

IDEA

这里直接用h3110w0r1d-y老师傅的jar开看

启动方式:java -javaagent:BurpLoaderKeygen.jar -noverify -jar burpsuite_pro_v2022.3.9.jar

关于javaagent的详细介绍,可以看知道创宇的paper 认识 JavaAgent

上jadx,先看看老师傅们都搞了啥.

这里很明显,找到Class里面包含751a8be34c1a9ed9633d04be3ba075a7的Class文件进行修改,变量p以及p2是负责定位要修改的位置,找到位置后进行patch.

先照搬进IDEA看看到底干了啥

这里可以看到,修改的地方其实很相近,那就dump整个class下来看看情况.

dump的办法

然后调用下

得到两个class文件

还记得之前的启动参数么,-noverify,由于这里简单粗暴的修改了原class的byte,导致jvm的字节码校验失败,根据这个道理,很容易就能找到师傅们干了什么,直接上图把.

用cfr反编译后,直接找empty

两个if被改成empty了,但是到这里我们还是不知道老师傅这么干的道理,继续往下走把.

根据之前cfr反编译出来的源码,能看到两个超级混淆的办法,void a以及bool b,知道类名跟方法名了,直接写个btrace,把调用链弄出来.

过滤后,得到以下输出

这里能看出,很多类都是动态加载进去的,想知道怎么调用还是得看看上一个调用类干了什么.

还记得之前的javaagent工程里面写了writeModifyClass方法不,把他放到最外层,然后修改下即可dump整个burp加载的class.

分析后发现...pev.class其实就是把nls.class从string数组变成byte数组然后解密加载

无实质性进展..尝试硬啃混淆过的验证类

首先,nls里面有两个核心方法,一个void a,另外一个boolean b

这里看到b方法,直接调用了a方法,其中var_9是new的object array,内容是var3_3的byte array,整个传入a方法第一个参数就是object [][],第二个参数就是固定的一串字符串

再查找整个nls.a调用,发现整个文件就两次调用,第二次调用也是差不多

那就可以认定,nls.a的第二个参数是固定的字符串,第一个参数是object [][]类型,具体传入了什么上arthas看看传入

由于是Windows,写个bat放到arthas的目录方便arthas attach到burp的进程

这里有个小技巧,如果burp调用太快手速不够,可以进入主界面后,用help->License->Update License来触发验证类的调用

用老师傅的jar先启动,然后运行bat就行

这里监控用watch 类名 方法名 -b -s -x 4

先输入个错误的license key,看看nls类里面方法a跟b什么情况

这里输入的是abcd,所以对着的是97,98,99,100,那就知道了其实nls.a传入的是字符串的byte array再放进Object[]

再尝试正确的License Key,根据之前代码进行分析得到下面的结论

结合注册流程,可以得知

有了以上信息,尝试构造nls.a的调用

之前有dump过破解跟原版的验证class,使用破解后的class用jar打包

jar -cvf burp.jar burp/nls.class

作为依赖塞进IDEA的工程,这里注意Run的配置要加上jvm参数-noverify

这里能成功解密了,现在就是这串License Key是怎么生成的问题了

继续用jadx查看Loader的注册机部分

这里很明显了,DES加密,key在最顶上是祖传的burpr0x!

大体流程就是字符串数组然后转成byte array用0作为分隔,再进行DES加密,最后base64

那么我们就可以根据这个流程反向写出解密函数

这里没什么好说的,直接跟着原理,先base64解码,然后des解密成byte array,转化成字符串后再用0分割成字符串数组

这里注意,解密出来的字符串数组长度会比原生的nls.a解密出来的字符串数组长,需要根据字符串数组长度删减返回的数组长度

其中长度是7的是License Key解密,长度10的是Activation Respond解密

到这里就差不多了,可以开始写自己的javaagent了

要把上面的java代码覆盖到原来的文件,我用的org.ow2.asm这个库,当然你用其他的库也可以,例如bytebuddy.

首先把java方法变成asm库的代码,这里我直接用asm库里面的asmifier(org.ow2.asm:asm-util:9.3)

在manifest定义Premain-Class以及Agent-Class

实现接口ClassFileTransformer

覆写激活类的方法

代码部分我就不详说了,有兴趣的可以自己围观

测试版本burpsuite_pro_v2022.5.1.jar

自己还是太菜不会用动态debug,只能用这样的笨方法来研究,代码附上,成品附上,欢迎各位大佬指导.

在这里感谢各位老师傅的路子,让刀burp不用找具体激活类具体是哪个,方便我这种后来破解的小白.

截至写完本文,2022.5.1还能这么刀

 
文件名称: E:\xxx\burp_latest\BurpLoaderKeygen.jar
文件大小: 18.1 KB (18,580 字节)
修改时间: 20210723日,10:20:48
MD5: B7E345B5594331516F49A709C04A3E41
SHA1: B9F4E9CA60E7493E459E21019441D115D2F43D98
SHA256: 63BE39F1AEEBEA9B86477ACEBBEFEE469A7562216BA8B253A4BB87B0A7A68566
CRC32: BCF7BD4F
计算时间: 0.00s
文件名称: E:\xxx\burp_latest\BurpLoaderKeygen.jar
文件大小: 18.1 KB (18,580 字节)
修改时间: 20210723日,10:20:48
MD5: B7E345B5594331516F49A709C04A3E41
SHA1: B9F4E9CA60E7493E459E21019441D115D2F43D98
SHA256: 63BE39F1AEEBEA9B86477ACEBBEFEE469A7562216BA8B253A4BB87B0A7A68566
CRC32: BCF7BD4F
计算时间: 0.00s
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
import org.openjdk.btrace.core.annotations.*;
import org.openjdk.btrace.core.BTraceUtils;
 
 
@BTrace(unsafe = true)
public class nls {
 
    @OnMethod(clazz="burp.nls", method="a")
    public static void void_a(Object[] var1, Object var2) {
        BTraceUtils.println("calleded void a");
        BTraceUtils.println("1st arg");
        BTraceUtils.println("arg length: " + var1.length);
        BTraceUtils.printArray(var1);
        byte[] my_var1 = (byte [])var1[0];
        BTraceUtils.println(new String(my_var1));
 
        BTraceUtils.println("2nd arg");
        String var2_str = String.valueOf(var2);
        BTraceUtils.println(var2_str);
        BTraceUtils.println("-----------");
    }
 
 
    @OnMethod(clazz="burp.nls", method="b")
    public static void bool_b(Object[] var1, Object var2) {
        BTraceUtils.println("called boolean b");
        BTraceUtils.println("1st arg");
        BTraceUtils.println("arg length: " + var1.length);
        BTraceUtils.printArray(var1);
 
        BTraceUtils.println("2nd arg");
        String var2_str = String.valueOf(oos);
        BTraceUtils.print(var2_str);
        BTraceUtils.jstack();
        BTraceUtils.println("-----------");
    }
}
import org.openjdk.btrace.core.annotations.*;
import org.openjdk.btrace.core.BTraceUtils;
 
 
@BTrace(unsafe = true)
public class nls {
 
    @OnMethod(clazz="burp.nls", method="a")
    public static void void_a(Object[] var1, Object var2) {
        BTraceUtils.println("calleded void a");
        BTraceUtils.println("1st arg");
        BTraceUtils.println("arg length: " + var1.length);
        BTraceUtils.printArray(var1);
        byte[] my_var1 = (byte [])var1[0];
        BTraceUtils.println(new String(my_var1));
 
        BTraceUtils.println("2nd arg");
        String var2_str = String.valueOf(var2);
        BTraceUtils.println(var2_str);
        BTraceUtils.println("-----------");
    }
 
 
    @OnMethod(clazz="burp.nls", method="b")
    public static void bool_b(Object[] var1, Object var2) {
        BTraceUtils.println("called boolean b");
        BTraceUtils.println("1st arg");
        BTraceUtils.println("arg length: " + var1.length);
        BTraceUtils.printArray(var1);

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2023-1-16 16:47 被kanxue编辑 ,原因:
上传的附件:
收藏
免费 28
支持
分享
最新回复 (14)
雪    币: 5734
活跃值: (1453)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
感谢分享。
2022-6-13 10:54
0
雪    币: 8073
活跃值: (6364)
能力值: ( LV12,RANK:207 )
在线值:
发帖
回帖
粉丝
3
感谢分享!
2022-6-13 14:59
0
雪    币: 1066
活跃值: (1483)
能力值: ( LV6,RANK:149 )
在线值:
发帖
回帖
粉丝
4
真的强!
2022-6-13 16:21
0
雪    币: 1379
活跃值: (7234)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
非常感谢,境界高啊!
2022-6-14 08:44
0
雪    币: 15170
活跃值: (16832)
能力值: (RANK:730 )
在线值:
发帖
回帖
粉丝
6
感谢分享宝贵思路和过程,分析过程远比最后的成品重要,支持~
2022-6-14 09:34
0
雪    币: 631
活跃值: (3006)
能力值: ( LV4,RANK:45 )
在线值:
发帖
回帖
粉丝
7
mark
2022-6-14 12:33
0
雪    币: 3888
活跃值: (163295)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
感谢分享
2022-7-7 11:17
0
雪    币: 5734
活跃值: (1453)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
感谢分享
2022-7-7 15:38
0
雪    币: 427
活跃值: (64)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
Mark
2022-7-7 16:45
0
雪    币: 698
活跃值: (2365)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
11
2022.11 破解失败了,我需要一些时间看看
2022-11-8 12:33
0
雪    币: 1102
活跃值: (4182)
能力值: ( LV5,RANK:69 )
在线值:
发帖
回帖
粉丝
12
说是新版有了一丢丢变化
2022-11-8 13:05
0
雪    币: 1102
活跃值: (4182)
能力值: ( LV5,RANK:69 )
在线值:
发帖
回帖
粉丝
13

重复了

最后于 2022-11-8 13:10 被小菜鸟一编辑 ,原因:
2022-11-8 13:06
0
雪    币: 1482
活跃值: (2528)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
感谢分享。
2022-12-27 10:24
0
雪    币: 192
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
15
新版字符串混淆了,代码也混淆了,反编译读不懂,不过也简单,加了几行判断其实就是占位,不做任何事情,不参与代码逻辑,但是会让反编译器摸不着头脑。
字符串混淆就更简单了,不管怎么混淆总是不可能把字符串内容都改了吧?所以一定会在某处用到。java的hook大法,通杀一切。
2022-12-27 11:58
1
游客
登录 | 注册 方可回帖
返回
//