<span id="7ztzv"></span>
<sub id="7ztzv"></sub>

<span id="7ztzv"></span><form id="7ztzv"></form>

<span id="7ztzv"></span>

        <address id="7ztzv"></address>

            原文地址:http://drops.wooyun.org/tips/2689

            0x00 摘要:


            本系列文章通過對BurpLoader的幾個版本的逆向分析,分析Burpsuite的破解原理,分析Burpsuite認證體系存在的安全漏洞。

            0x01 JD-GUI的用途與缺陷:


            JD-GUI是一款從JAVA字節碼中還原JAVA源代碼的免費工具,一般情況下使用這款工具做JAVA逆向就足夠了,但是由于其原理是從JAVA字節碼中按照特定結構來還原對應的JAVA源代碼,因此一旦字節碼結構被打亂(比如說使用混淆器),那么JD-GUI就會失去它的作用,如圖為使用JD-GUI打開Burpsuite時的顯示:

            enter image description here

            顯然,JD-GUI沒能還原JAVA源代碼出來,因為Burpsuite使用了混淆器打亂了字節碼結構 所以,JD-GUI適用于‘沒有使用混淆器’的JAVA字節碼,而缺陷是一旦字節碼結構被打亂,則無法發揮它的作用

            0x02 字節碼分析:


            Java的字節碼并不像普通的二進制代碼在計算機中直接執行,它通過JVM引擎在不同的平臺和計算機中運行。

            enter image description here

            JVM是一個基于棧結構的虛擬計算機,使用的是JVM操作碼(及其助記符),在這一點上和普通二進制反匯編的過程非常相似。 對Java字節碼進行反編譯其實非常簡單,JDK內置的Javap工具即可完成這項任務。

            示例:對Javar.class進行反編

            enter image description here

            注意javap的-c參數是顯示詳細代碼,否則只顯示method,而按照java的老規矩Javar不要加后綴名 同時你也可以使用eclipse的插件Bytecode Visualizer來反編譯字節碼

            enter image description here

            注意右面的流程圖,大家在上程序設計導論課時都畫過吧,現在發現它的用途了吧,一眼就看出是一個if-else結構,前兩句定義i變量,然后取i=2壓棧常數1,比對i和1以后就都java.lang.system.out了,一個輸出wooyun,一個輸出lxj616。

            0x03 老版本的BurpLoader分析:


            隨著Burpsuite的更新,BurpLoader也在跟著進行更新,我們從老版本的BurpLoader入手,簡要分析一下之前老版本的burpsuite破解原理。 本處選用了1.5.01版本的BurpLoader進行分析 首先試著用JD-GUI載入BurpLoader:

            enter image description here

            成功還原了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的計算方法,通過反射把一些環境變量固定成常量了

            0x04 新版本的BurpLoader分析:


            以下用1.6beta版的BurpLoader進行分析: 首先用JD-GUI嘗試打開BurpLoader:

            enter image description here

            看來這個版本的BurpLoader對字節碼使用了混淆,這條路走不通了 于是直接讀字節碼吧!

            enter image description here

            大家可以看到這里的字符串都是混淆過的,每一個都jsr到151去解密

            enter image description here

            這段解密代碼特點非常明顯,一個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

            其實這里解密出字符串沒有什么用處,因為我們已經拿到老版本的源代碼了,不過在別的軟件逆向分析中可能會非常有用

            0x05 總結&POC


            以下為我修改后的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); 
                } 
              } 
            }
            

            其效果如截圖所示

            enter image description here

            其中前8行輸出為之前BurpLoader惡意修改的目標原值(對我的計算機而言),同一臺設備運行多少遍都是不變的,后面的key由于我之前運行過BurpLoader因此是惡意修改后的值(但是由于前8行沒有修改因此不能通過Burpsuite驗證),可見BurpLoader其實是使用了同一個密鑰來注冊所有不同計算機的,只不過修改并固定了某些參與密鑰計算的環境變量而已,這大概就是Burpsuite破解的主要思路了,至于最初能用的license是怎么計算出來的,我們以后再研究

            <span id="7ztzv"></span>
            <sub id="7ztzv"></sub>

            <span id="7ztzv"></span><form id="7ztzv"></form>

            <span id="7ztzv"></span>

                  <address id="7ztzv"></address>

                      亚洲欧美在线