现在很多大学都是用的正方教务管理系统,该系统后台使用的oracle数据库,数据库里存储的密码是经过加密的,如下图所示:
在网站目录下/bin/zjdx.dll 中 zjdx.mmtp 类的 jiemi() 方法负责解密,zjdx.dll是用VB.Net生成的,用 MSIL 反汇编得到如下代码:
- .method public instance string jiemi(string PlainStr,
-
string key) cil managed
-
{
-
// Code size 279 (0x117)
-
.maxstack 3
-
.locals init ([0] int32 i,
-
[1] string jiemi,
-
[2] string KeyChar,
-
[3] string NewStr,
-
[4] int32 Pos,
-
[5] string Side1,
-
[6] string Side2,
-
[7] string strChar,
-
[8] int32 _Vb_t_i4_0)
-
IL_0000: nop
-
IL_0001: ldc.i4.1
-
IL_0002: stloc.s Pos
-
IL_0004: ldarg.1
-
IL_0005: call int32 [Microsoft.VisualBasic]Microsoft.VisualBasic.Strings::Len(string)
-
IL_000a: ldc.i4.2
-
IL_000b: rem
-
IL_000c: ldc.i4.0
-
IL_000d: bne.un.s IL_0062
-
IL_000f: ldarg.1
-
IL_0010: ldarg.1
-
IL_0011: call int32 [Microsoft.VisualBasic]Microsoft.VisualBasic.Strings::Len(string)
-
IL_0016: conv.r8
-
IL_0017: ldc.r8 2.
-
IL_0020: div
-
IL_0021: call float64 [mscorlib]System.Math::Round(float64)
-
IL_0026: conv.ovf.i4
-
IL_0027: call string [Microsoft.VisualBasic]Microsoft.VisualBasic.Strings::Left(string,
-
int32)
-
IL_002c: call string [Microsoft.VisualBasic]Microsoft.VisualBasic.Strings::StrReverse(string)
-
IL_0031: stloc.s Side1
-
IL_0033: ldarg.1
-
IL_0034: ldarg.1
-
IL_0035: call int32 [Microsoft.VisualBasic]Microsoft.VisualBasic.Strings::Len(string)
-
IL_003a: conv.r8
-
IL_003b: ldc.r8 2.
-
IL_0044: div
-
IL_0045: call float64 [mscorlib]System.Math::Round(float64)
-
IL_004a: conv.ovf.i4
-
IL_004b: call string [Microsoft.VisualBasic]Microsoft.VisualBasic.Strings::Right(string,
-
int32)
-
IL_0050: call string [Microsoft.VisualBasic]Microsoft.VisualBasic.Strings::StrReverse(string)
-
IL_0055: stloc.s Side2
-
IL_0057: ldloc.s Side1
-
IL_0059: ldloc.s Side2
-
IL_005b: call string [mscorlib]System.String::Concat(string,
-
string)
-
IL_0060: starg.s PlainStr
-
IL_0062: nop
-
IL_0063: ldc.i4.1
-
IL_0064: ldarg.1
-
IL_0065: call int32 [Microsoft.VisualBasic]Microsoft.VisualBasic.Strings::Len(string)
-
IL_006a: stloc.s _Vb_t_i4_0
-
IL_006c: stloc.0
-
IL_006d: br IL_010b
-
IL_0072: ldarg.1
-
IL_0073: ldloc.0
-
IL_0074: ldc.i4.1
-
IL_0075: call string [Microsoft.VisualBasic]Microsoft.VisualBasic.Strings::Mid(string,
-
int32,
-
int32)
-
IL_007a: stloc.s strChar
-
IL_007c: ldarg.2
-
IL_007d: ldloc.s Pos
-
IL_007f: ldc.i4.1
-
IL_0080: call string [Microsoft.VisualBasic]Microsoft.VisualBasic.Strings::Mid(string,
-
int32,
-
int32)
-
IL_0085: stloc.2
-
IL_0086: ldloc.s strChar
-
IL_0088: call int32 [Microsoft.VisualBasic]Microsoft.VisualBasic.Strings::Asc(string)
-
IL_008d: ldloc.2
-
IL_008e: call int32 [Microsoft.VisualBasic]Microsoft.VisualBasic.Strings::Asc(string)
-
IL_0093: xor
-
IL_0094: ldc.i4.s 32
-
IL_0096: clt
-
IL_0098: ldloc.s strChar
-
IL_009a: call int32 [Microsoft.VisualBasic]Microsoft.VisualBasic.Strings::Asc(string)
-
IL_009f: ldloc.2
-
IL_00a0: call int32 [Microsoft.VisualBasic]Microsoft.VisualBasic.Strings::Asc(string)
-
IL_00a5: xor
-
IL_00a6: ldc.i4.s 126
-
IL_00a8: cgt
-
IL_00aa: or
-
IL_00ab: ldloc.s strChar
-
IL_00ad: call int32 [Microsoft.VisualBasic]Microsoft.VisualBasic.Strings::Asc(string)
-
IL_00b2: ldc.i4.0
-
IL_00b3: clt
-
IL_00b5: or
-
IL_00b6: ldloc.s strChar
-
IL_00b8: call int32 [Microsoft.VisualBasic]Microsoft.VisualBasic.Strings::Asc(string)
-
IL_00bd: ldc.i4 0xff
-
IL_00c2: cgt
-
IL_00c4: or
-
IL_00c5: brfalse.s IL_00d2
-
IL_00c7: ldloc.3
-
IL_00c8: ldloc.s strChar
-
IL_00ca: call string [mscorlib]System.String::Concat(string,
-
string)
-
IL_00cf: stloc.3
-
IL_00d0: br.s IL_00f2
-
IL_00d2: nop
-
IL_00d3: ldloc.3
-
IL_00d4: ldloc.s strChar
-
IL_00d6: call int32 [Microsoft.VisualBasic]Microsoft.VisualBasic.Strings::Asc(string)
-
IL_00db: ldloc.2
-
IL_00dc: call int32 [Microsoft.VisualBasic]Microsoft.VisualBasic.Strings::Asc(string)
-
IL_00e1: xor
-
IL_00e2: call char [Microsoft.VisualBasic]Microsoft.VisualBasic.Strings::Chr(int32)
-
IL_00e7: call string [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.StringType::FromChar(char)
-
IL_00ec: call string [mscorlib]System.String::Concat(string,
-
string)
-
IL_00f1: stloc.3
-
IL_00f2: nop
-
IL_00f3: ldloc.s Pos
-
IL_00f5: ldarg.2
-
IL_00f6: call int32 [Microsoft.VisualBasic]Microsoft.VisualBasic.Strings::Len(string)
-
IL_00fb: bne.un.s IL_0100
-
IL_00fd: ldc.i4.0
-
IL_00fe: stloc.s Pos
-
IL_0100: ldloc.s Pos
-
IL_0102: ldc.i4.1
-
IL_0103: add.ovf
-
IL_0104: stloc.s Pos
-
IL_0106: nop
-
IL_0107: ldloc.0
-
IL_0108: ldc.i4.1
-
IL_0109: add.ovf
-
IL_010a: stloc.0
-
IL_010b: ldloc.0
-
IL_010c: ldloc.s _Vb_t_i4_0
-
IL_010e: ble IL_0072
-
IL_0113: ldloc.3
-
IL_0114: stloc.1
-
IL_0115: ldloc.1
-
IL_0116: ret
-
} // end of method mmtp::jiemi
逆向得到如下C++代码(为保持清晰性,所用到的变量名与原来的一致,如jiemi, Side1, Side2...):
- string ReverseStr(string strFormer)
-
{
-
string strReversed = "";
-
string:: iterator iter = strFormer.end();
-
while(iter != strFormer.begin())
-
{
-
strReversed += *(--iter);
-
}
-
return strReversed;
-
}
-
-
string Decode(string PlainStr, string key)
-
{
-
int i;
-
string jiemi;
-
string KeyChar;
-
string NewStr;
-
int Pos;
-
string Side1;
-
string Side2;
-
string strChar;
-
int _Vb_t_i4_0;
-
-
Pos = 1;
-
if(PlainStr.size()%2 == 0)
-
{
-
Side1 = ReverseStr(PlainStr.substr(0, PlainStr.size()/2));
-
Side2 = ReverseStr(PlainStr.substr(PlainStr.size()/2));
-
PlainStr = Side1 + Side2;
-
}
-
-
_Vb_t_i4_0 = PlainStr.size();
-
int bl_1, bl_2, bl_3, bl_4=0;
-
for(i=1; i<=_Vb_t_i4_0; i++)
-
{
-
strChar = PlainStr.substr(i-1, 1);
-
KeyChar = key.substr(Pos-1, 1);
-
-
bl_1 = (strChar[0] ^ KeyChar[0]) < 32? 1:0;
-
bl_2 = (strChar[0] ^ KeyChar[0]) > 126? 1:0;
-
bl_3 = (strChar[0] < 0? 1:0) | (bl_1 | bl_2);
-
bl_4 = (strChar[0] > 0xFF? 1:0) | bl_3;
-
if(bl_4)
-
{
-
cout << "if" << endl;
-
NewStr += strChar;
-
cout << "strChar :" <<endl;
-
}
-
else
-
{
-
cout << "else" << endl;
-
char ch = strChar[0] ^ KeyChar[0];
-
string str = "";
-
str += ch;
-
NewStr += str;
-
cout << strChar << " xor " << KeyChar << " is " << ch << endl;
-
}
-
if(key.size() == Pos)
-
{
-
cout << "key.size() == Pos" << endl;
-
Pos = 0;
-
}
-
Pos += 1;
-
}
-
jiemi = NewStr;
-
return jiemi;
-
}
要利用上述解密算法进行解密,还需要知道加密所用的密钥(即上述解密函数第二个参数),这里不公开该key, 因为自己也不知道每个学校用的 key 是否相同。其实从上述解密算法看,要逆出该 key 是非常简单的,有需要的人就自己动手吧
。
知道 key 之后就可以对密码进行还原了,,
稍微懂点编程的人大概已经看出来正方教务系统后台程序编程风格就是初学者的水平,变量命名混乱,很多直接用汉语拼音命名。加解密算法毫无强度可言,其实就是简单的异或的基础上作了下处理。数据库中表的命名全部是拼音, 如cxxsmm(查询学生密码),cjb(成绩表),jsxxb(教师信息表),,,,各种无语
。真不知道这样的烂系统是怎么会有1000多所学校还在用。。。
阅读(18618) | 评论(1) | 转发(0) |