最近遇到一個java後臺管理程序在輸入用戶名和密碼登錄時會判斷是否有加密狗存在,如果無狗則不讓登錄。
首先要確定是哪一個文件中判斷狗的存在,我用了比較笨的方法,就是反編譯出每一個可疑的.class文件,看哪一個文件中是處理登錄的,一般用於登錄的函數都會有login字樣,然後再看登錄程序的處理過程,即可確定到判斷狗的地方。反編譯.class文件我用的是jd-gui.exe程序,綠色小巧,只有六百多K。很快就找到了判斷狗的函數所在,
private boolean key()
{
int[] licHandle = new int[1];
SentinelKeysLicense s = new SentinelKeysLicense();
s.getClass();
s.getClass();
int status = new SentinelKeys().SFNTGetLicense(-525336388L,
s.SOFTWARE_KEY, 4891L, 2080L,
licHandle);
return (status == 0); //關鍵就是這一行的返回值,如果status==0,則證明有狗存在。
}
由程序可知,只要修改返回值即可實現程序的爆破了。可是怎麼修改呢?問了幾個做java的朋友,都說要反編譯,修改後再編譯回去,我覺得太麻煩,還有好多引入包之類的,很有可能編譯不成功,於是想到直接修改二進制文件,只是要通過IDA輔助一下關鍵點的定位。
在IDA中打開該文件,找到該函數所在位置:
met045:00000 met045_begin: ; CODE XREF: login+1P
met045:00000 .line 712
met045:00000 004 iconst_1
met045:00001 188 010 newarray int
met045:00003 076 astore_1 ; met045_slot001
met045:00004 .line 715
met045:00004
met045:00004 met045_4: ; DATA XREF: met045_slot001i
met045:00004 187 002 100 new com/safenet/sentinel/SentinelKeysLicense
met045:00007 089 dup
met045:00008 183 002 102 invokespecial com/safenet/sentinel/SentinelKeysLicense.<init>()V
met045:00011 078 astore_3 ; met045_slot003
met045:00012 .line 716
met045:00012
met045:00012 met045_12: ; DATA XREF: met045_slot003i
met045:00012 187 002 103 new com/safenet/sentinel/SentinelKeys
met045:00015 089 dup
met045:00016 183 002 105 invokespecial com/safenet/sentinel/SentinelKeys.<init>()V
met045:00019 045 aload_3 ; met045_slot003
met045:00020 182 002 106 invokevirtual java/lang/Object.getClass()Ljava/lang/Class;
met045:00023 087 pop
met045:00024 020 002 112 ldc2_w -525336388
met045:00027 .line 717
met045:00027 045 aload_3 ; met045_slot003
met045:00028 180 002 114 getfield com/safenet/sentinel/SentinelKeysLicense.SOFTWARE_KEY [B
met045:00031 045 aload_3 ; met045_slot003
met045:00032 182 002 106 invokevirtual java/lang/Object.getClass()Ljava/lang/Class;
met045:00035 087 pop
met045:00036 020 002 118 ldc2_w 4891
met045:00039 020 002 120 ldc2_w 2080
met045:00042 .line 718
met045:00042 043 aload_1 ; met045_slot001
met045:00043 .line 716
met045:00043 182 002 122 invokevirtual com/safenet/sentinel/SentinelKeys.SFNTGetLicense(J[BJJ[I)I
met045:00046 061 istore_2 ; met045_slot002
met045:00047 .line 719
met045:00047
met045:00047 met045_47: ; DATA XREF: met045_slot002i
met045:00047 028 iload_2 ; met045_slot002
met045:00048 154 000 005 ifne met045_53
met045:00051 004 iconst_1 //關鍵返回點
met045:00052 172 ireturn
met045:00053
met045:00053 met045_53: ; CODE XREF: key+48j
met045:00053 003 .stack use locals
met045:00053 locals Object [I
met045:00053 locals Integer
met045:00053 locals Object com/safenet/sentinel/SentinelKeysLicense
met045:00053 .end stack
met045:00053 iconst_0 //關鍵返回點
met045:00054 172 ireturn
met045:00055 met045_end: ; DATA XREF: met045_slot001i ...
met045:00055
var045:00000 ; ===========================================================================
var045:00000
var045:00001 ;met045_slot001 ; DATA XREF: key+3w ...
var045:00001 ??? .var 1 is licHandle [I from met045_4 to met045_end
var045:00002 ;met045_slot002 ; DATA XREF: key+46w ...
var045:00002 ??? .var 2 is status I from met045_47 to met045_end
var045:00003 ;met045_slot003 ; DATA XREF: key+11w ...
var045:00003 ??? .var 3 is s Lcom/safenet/sentinel/SentinelKeysLicense; from met045_12\
var045:00003 to met045_end
var045:00004 ??? ??? ???+ .end method
如果IDA中顯示的代碼不是如上段代碼的樣式,可以IDA中選擇菜單“選項->常規”,在打開的窗口中選中"行前綴”,在“機器碼字節數”中輸入4(也可輸入其它的數字,過小的話會讓機器碼顯示不完全),如圖所示:
上段代碼中標註“關鍵返回點”的兩處地方就是判斷狗的函數的返回值,有狗則iconst_1返回1,無狗則iconst_0返回0,由此我們便知道,只要把iconst_0改爲iconst_1讓函數一直返回1就可以實現爆破了。
用UE打開該文件,搜索機器碼,機器碼就是上段代碼中第二列的內容,如“028 154 000 005 004 172 003 172”,因爲UE中搜索是十六進制,所以我們需要把機器碼轉化爲十六進制,用計算器轉換一下即可,如"1C 9A 00 05 04 AC 03 AC”,在UE中搜索這段機器碼,找到後將03改成04後保存文件。
然後將修改後的文件替換原文件,重啓web服務即可。