最近遇到一个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服务即可。