
在"吾爱破解"上看到两个贴子:
1.7.37版
https://www.52pojie.cn/thread-691448-1-1.html
2.0.11版
https://www.52pojie.cn/thread-909706-1-1.html
注册机是surferxyz提供的。按Hmily当时的说法,通杀1.6.x到最新的1.7.31版本。后来实际通杀到2.0.11beta。
burp-loader-keygen.jar没有混淆,另有一个版本的破解方案使用了混淆。在网上看到过很多人质疑后者的可靠性,我没有逆向分析过后者,此处不评价。前者提供了非常清晰的Burp注册算法。随便用什么反编译器都成,重点看这几个函数:


licenseName由用户提供,activationRequest来自手工注册GUI。
prepareArray()对数据进行DES加密、BASE64编码,得到GUI可接受的形式。
decodeActivationRequest()对数据进行BASE64解码、DES解密,还原出原始字节流。
注册机最NB的地方是给了一个DES密钥,"burpr0x!"。说实话,我不知道作者是怎么得到这个字符串的。为了对抗逆向工程,Burp注册算法中没有使用原始的字符串形式的key,而是使用所谓的"working key",后者是原始key经标准算法打散后得到的。我不知道已知"working key"能否逆推出原始key,对这块不熟。假设不能逆推,还可以暴力穷举原始key,也可能早期版本Burp中用的就是原始key。
315569521000大约10年:
86400L * 365 * 10 * 1000 = 315360000000
它产生的License有效期从当前时间开始往后推10年。License数据中真正有用的就是过期时间,注册用户名没有参与太多License检查,主要供GUI显示。
"tdq...="实际是一个SHA1签名。由于没有私钥(n1,d1),注册机根本不可能生成有效SHA1签名,作者在这里填写了一个固定值的BASE64编码。
"xMo...=="是另一个SHA256签名。由于没有私钥(n2,d2),注册机根本不可能生成有效SHA256签名,作者在这里填写了另一个固定值的BASE64编码。
为了让几次签名校验得以通过,作者修改了java.math.BigInteger.compareTo():

这两个神密常数是怎么来的呢?

第一个大数是:
0xb5da...42b0

第二个大数是:
0xc4ca...7f7f
Burp注册算法用到了两个n,其10进制表示是:


这两个n都用了同一个e(65537)。
在Python里执行:
c1=0xb5da...42b0
e1=65537
n1=124738...4013
"%#u" % pow(c1,e1,n1)
c2=0xc4ca...7f7f
e2=65537
n2=256600...7661
"%#u" % pow(c2,e2,n2)
得到:


这就是compareTo()中神密常量的来龙去脉。
License和ActivationResponse中用两个常量冒充RSA签名,修改compareTo(),一旦发现在检查这两个c的pow(c,e,n)值,就返回0,表示相等。至于compareTo()中用equals()还是startsWith(),无关紧要,随便。某种意义相对于替换了两组n。
为了让这个针对compareTo()的修改生效,注册机提供的方案是:
java -Xbootclasspath/p:burp-loader-keygen.jar -jar burpsuite_pro_<ver>.jar
"-Xbootclasspath/p:"将修改过的BigInteger.class置于缺省引导类搜索路径之前,简单点说,先到的生效,后到的吃灰。据说Java 9不支持这个用法了,那就八仙过海各想他招吧。
2.1版Burp同样有混淆版破解方案,跟surferxyz不是一个流派,也有很多人在用,没有调查就没有发言权,未逆向分析过,不做评价。
为什么2.1版Burp不能用surferxyz这个注册机了呢?简单看了一眼,2.1版Burp注册算法中没有显式出现前述两个n,加密ActivationRequest所用"working key"倒是没变。今天没时间看了,我得去赶火车,回头有空再说。
http://scz.617.cn:8/misc/201909271517.txt
http://scz.617.cn/misc/201909271517.txt




