本系列文章通過對BurpLoader的幾個版本的逆向分析,分析Burpsuite的破解原理,分析Burpsuite認證體系存在的安全漏洞。
JD-GUI是一款從JAVA字節碼中還原JAVA源代碼的免費工具,一般情況下使用這款工具做JAVA逆向就足夠了,但是由于其原理是從JAVA字節碼中按照特定結構來還原對應的JAVA源代碼,因此一旦字節碼結構被打亂(比如說使用混淆器),那么JD-GUI就會失去它的作用,如圖為使用JD-GUI打開Burpsuite時的顯示:
顯然,JD-GUI沒能還原JAVA源代碼出來,因為Burpsuite使用了混淆器打亂了字節碼結構 所以,JD-GUI適用于‘沒有使用混淆器’的JAVA字節碼,而缺陷是一旦字節碼結構被打亂,則無法發揮它的作用
Java的字節碼并不像普通的二進制代碼在計算機中直接執行,它通過JVM引擎在不同的平臺和計算機中運行。
JVM是一個基于棧結構的虛擬計算機,使用的是JVM操作碼(及其助記符),在這一點上和普通二進制反匯編的過程非常相似。 對Java字節碼進行反編譯其實非常簡單,JDK內置的Javap工具即可完成這項任務。
示例:對Javar.class進行反編
注意javap的-c參數是顯示詳細代碼,否則只顯示method,而按照java的老規矩Javar不要加后綴名 同時你也可以使用eclipse的插件Bytecode Visualizer來反編譯字節碼
注意右面的流程圖,大家在上程序設計導論課時都畫過吧,現在發現它的用途了吧,一眼就看出是一個if-else結構,前兩句定義i變量,然后取i=2壓棧常數1,比對i和1以后就都java.lang.system.out了,一個輸出wooyun,一個輸出lxj616。
隨著Burpsuite的更新,BurpLoader也在跟著進行更新,我們從老版本的BurpLoader入手,簡要分析一下之前老版本的burpsuite破解原理。 本處選用了1.5.01版本的BurpLoader進行分析 首先試著用JD-GUI載入BurpLoader:
成功還原了BurpLoader源代碼,只可惜由于是對burpsuite的patch,所以burpsuite的混淆在burploader里仍然可讀性極差,不過可以推斷burploader本身沒有使用混淆工具。
public static void main(String[] args)
{
try
{
int ret = JOptionPane.showOptionDialog(null, "This program can not be used for commercial purposes!", "BurpLoader by [email protected]", 0, 2, null, new String[] { "I Accept", "I Decline" }, null);
//顯示選擇對話框:這程序是出于學習目的寫的,作者郵箱larry_lau(at)163.com
if (ret == 0) //選擇我同意
{
//以下用到的是java反射機制,不懂反射請百度
for (int i = 0; i < clzzData.length; i++)
{
Class clzz = Class.forName(clzzData[i]);
//是burpsuite的靜態類(名字被混淆過了,也沒必要列出了)
Field field = clzz.getDeclaredField(fieldData[i]);
//靜態類中的變量也被混淆過了,也不必列出了
field.setAccessible(true);
//訪問private必須先設置這個,不然會報錯
field.set(null, strData[i]);
//把變量設置成strData(具體那一長串到底是什么暫不討論)
}
Preferences prefs = Preferences.userNodeForPackage(StartBurp.class);
//明顯preferences是用來存儲設置信息的
for (int i = 0; i < keys.length; i++)
{
// key和val能猜出是什么吧
String v = prefs.get(keys[i], null);
if (!vals[i].equals(v))
{
prefs.put(keys[i], vals[i]);
}
}
StartBurp.main(args);
}
}
catch (Exception e)
{
JOptionPane.showMessageDialog(null, "This program can only run with burpsuite_pro_v1.5.01.jar", "BurpLoader by [email protected]",
0);
}
}
}
因此,BurpLoader的原理就是偽造有效的Key來通過檢測,Key的輸入是通過preference來注入的,而我猜測它為了固定Key的計算方法,通過反射把一些環境變量固定成常量了
以下用1.6beta版的BurpLoader進行分析: 首先用JD-GUI嘗試打開BurpLoader:
看來這個版本的BurpLoader對字節碼使用了混淆,這條路走不通了 于是直接讀字節碼吧!
大家可以看到這里的字符串都是混淆過的,每一個都jsr到151去解密
這段解密代碼特點非常明顯,一個switch走5條路,給221傳不同的解密key,這不就是Zelix KlassMaster的算法嗎? 簡單的異或而已,輕松寫出解密機:
public class Verify {
private static String decrypt(String str) {
char key[] = new char[] {73,25,85,1,29};
char arr[] = str.toCharArray();
for (int i = 0; i < arr.length; i++) {
arr[i] ^= key[i % 5];
}
return new String(arr);
}
public static void main (String args[]) {
System.out.println(decrypt("%x'sdgu4t3#x#`egj\"hs.7%m|/7;hp+l&/S t7tn\5v:j\'}_dx%"));
}
}
里面的5個密鑰就是上圖bipush的傳參,別忘了iconst_1的那個1 解密出來是:larry.lau.javax.swing.plaf.nimbus.NimbusLook:4
其實這里解密出字符串沒有什么用處,因為我們已經拿到老版本的源代碼了,不過在別的軟件逆向分析中可能會非常有用
以下為我修改后的BurpLoader,其中的惡意代碼我已經去除,并將修改前的原值輸出,大家可以在添加burpsuite jar包后編譯運行這段代碼
package stratburp;
import burp.StartBurp;
import java.lang.reflect.Field;
import java.util.prefs.Preferences;
import javax.swing.JOptionPane;
public class startburp
{
private static final String[] clzzData = { "burp.ecc", "burp.voc", "burp.jfc",
"burp.gtc", "burp.zi", "burp.q4c", "burp.pid", "burp.y0b" };
private static final String[] fieldData = { "b", "b", "c", "c", "c", "b", "c", "c" };
private static final String errortip = "This program can only run with burpsuite_pro_v1.5.01.jar";
private static final String[] keys = { "license1", "uG4NTkffOhFN/on7RT1nbw==" };
public static void main(String[] args)
{
try
{
for (int i = 0; i < clzzData.length; i++)
{
Class clzz = Class.forName(clzzData[i]);
Field field = clzz.getDeclaredField(fieldData[i]);
field.setAccessible(true);
//field.set(null, strData[i]);
System.out.println(field.get(null));
}
Preferences prefs = Preferences.userNodeForPackage(StartBurp.class);
for (int i = 0; i < keys.length; i++)
{
String v = prefs.get(keys[i], null);
System.out.println(prefs.get(keys[i], null));
}
StartBurp.main(args);
}
catch (Exception e)
{
JOptionPane.showMessageDialog(null, "This program can only run with burpsuite_pro_v1.5.01.jar", "Notice",0);
}
}
}
其效果如截圖所示
其中前8行輸出為之前BurpLoader惡意修改的目標原值(對我的計算機而言),同一臺設備運行多少遍都是不變的,后面的key由于我之前運行過BurpLoader因此是惡意修改后的值(但是由于前8行沒有修改因此不能通過Burpsuite驗證),可見BurpLoader其實是使用了同一個密鑰來注冊所有不同計算機的,只不過修改并固定了某些參與密鑰計算的環境變量而已,這大概就是Burpsuite破解的主要思路了,至于最初能用的license是怎么計算出來的,我們以后再研究