服务器维护,服务器代维,安全设置,漏洞扫描,入侵检测服务

dirtysea 发表于 2006-5-18 03:19:02

海洋顶端2006+密码编码分析

<FONT size=2>海洋顶端是很出名的 ASP 木马,我从红粉佳人版本开始就一直用它,也算是它的fans了,今年海洋顶端出了最新版本也是最后一个版本 —— 2006Plus。<BR><BR>身为fans,自然要拿来用用才是,初次使用感觉有了几个变化:界面变了,文件浏览不再是图标形式;所有动作改为POST方式提交;功能增加;……唉呀,赶紧打住,再写就变成广告了^_^<BR><BR>海洋顶端以往的各个版本密码都是明文存放的,这回 2006+ 专门有个 vbs 脚本用于加密密码。这几天闲得无聊,就来尝试分析一下它的加密方式。<BR><BR>加密密码的脚本是在 down 回来的 vbs 目录里面名为Encode.vbs的文件。先看代码,注释是我加的:<BR><BR><BR><BR>&nbsp; &nbsp; &nbsp; Dim theStr<BR><BR>&nbsp; &nbsp; &nbsp; theStr = InputBox("请输入要加密的字串")<BR><BR>&nbsp; &nbsp; &nbsp; If theStr &lt;&gt; "" Then<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Call InputBox("请复制已经加密好的字串",,Encode(theStr))<BR><BR>&nbsp; &nbsp; &nbsp; End If<BR><BR>&nbsp; &nbsp; &nbsp; Function Encode(strPass)<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Dim i, theStr, strTmp<BR><BR>' for循环得到密码各个字符的ascii值,每位值都在0~9<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; For i = 1 To Len(strPass)<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; strTmp = Asc(Mid(strPass, i, 1))<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; theStr = theStr &amp; Abs(strTmp)<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Next<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; strPass = theStr<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; theStr = ""<BR><BR>' 如果前面得到的值位数大于16就进入JoinCutStr函数处理,使之小于16<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Do While Len(strPass) &gt; 16<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; strPass = JoinCutStr(strPass)<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Loop<BR><BR>' 这个for循环处理每个字符,把7、8、9转为C、D、E,其余不变<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; For i = 1 To Len(strPass)<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; strTmp = CInt(Mid(strPass, i, 1))<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; strTmp = IIf(strTmp &gt; 6, Chr(strTmp + 60), strTmp)<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; theStr = theStr &amp; strTmp<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Next<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Encode = theStr<BR><BR>&nbsp; &nbsp; &nbsp; End Function<BR><BR>' JoinCutStr函数把奇数位和偶数位的ascii相加整除2得到新字符,取值在0~9<BR><BR>&nbsp; &nbsp; &nbsp; Function JoinCutStr(str)<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Dim i, theStr<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; For i = 1 To Len(str)<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; If Len(str) - i = 0 Then Exit For<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; theStr = theStr &amp; Chr(CInt((Asc(Mid(str, i, 1)) + Asc(Mid(str, i + 1, 1))) / 2))<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; i = i + 1<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Next<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; JoinCutStr = theStr<BR><BR>&nbsp; &nbsp; &nbsp; End Function<BR><BR>' VB的(a&gt;b)?a:b<BR><BR>&nbsp; &nbsp; &nbsp; Function IIf(var, val1, val2)<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; If var = True Then<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; IIf = val1<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Else<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; IIf = val2<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; End If<BR><BR>&nbsp; &nbsp; &nbsp; End Function<BR><BR><BR><BR><BR><BR>算法不是很复杂,其主要思想是:先依次把每个字符取ascii值,得到的一串数字作为字符对待,如果位数大于16,则折半处理(把奇数位和偶数位的ascii相加整除2得到新字符串,得到的字符串位数为原来的一半),直至小等于16,然后把7、8、9分别替换为C、D、E得到最后结果。<BR><BR>似乎可以逆向,那就试试吧。<BR><BR>我们得到了密文,第一步,我们可以把密文中的C、D、E替换回去,也就是分别替换为7、8、9,然后我们得到一串数字组成的字符串。比如字符lake2编码之后是10DEC10C10150,我们替换之,得到1089710710150,由于字符的ascii在32~127,所以可以很轻松的把字符区分开:108、97、107、101、50,正好是lake2各个字符的ascii值。<BR><BR>千万不要以为这个算法这么简单就破解了,因为上述情况只是若干种情况里面最简单的一种而已。<BR><BR>字符lake2的ascii值位数是11,所以并没有经过JoinCutStr函数处理,如果明文密码是lake2lake2的话,问题就复杂得多了。<BR><BR>JoinCutStr函数把奇数位和偶数位的ascii相加整除2得到新字符串,但这里造成了逆向的困难。因为1234经过处理,得到的是13;1133、1134、1233、1234、1124等等经过处理,得到的仍然是13。即同一个结果对应不同的原因,多数情况下我们不知道到底哪一个才对,只好穷举。但是即使是穷举且排除那些包含不可显示字符的密码,也很难知道哪一个密码才是对的。<BR><BR>我们虽然不知道使用者真正的密码是多少,但是却可以利用得到的任意一个密码登陆,因为它和真正密码加密之后的值是一样的。这个有点像MD5的碰撞,只是这个算法可以根据hash比较容易的构造碰撞,而MD5则很困难。<BR><BR>还有一种比较麻烦的情况:明文密码包含中文。中文的ascii绝对值都很大,要逆向回去还是很麻烦的,所以我们还是构造碰撞吧。<BR><BR>针对最简单的那种情况我们也可以用一个vbs来反编码明文密码,以下代码即实现此功能,copy保存为vbs文件运行即可:<BR><BR><BR><BR>&nbsp; &nbsp; &nbsp; '海洋顶端2006+简单密文反编码 by lake2<BR><BR><BR><BR>&nbsp; &nbsp; &nbsp; theStr = InputBox("输入加密后的字串")<BR><BR>&nbsp; &nbsp; &nbsp; If theStr &lt;&gt; "" Then<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Call InputBox("请复制已经解密的字串",,UnEncode(theStr))<BR><BR>&nbsp; &nbsp; &nbsp; End If<BR><BR>&nbsp; &nbsp; &nbsp; Function UnEncode(str)<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; For i = 1 To Len(str)<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; theStr1 = Mid(str, i, 1)<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; If theStr1 = "C" Then<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; theStr1 = "7"<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ElseIf theStr1 = "D" Then<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; theStr1 = "8"<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ElseIf theStr1 = "E" Then<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; theStr1 = "9"<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; End If<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; StrPass2 = StrPass2 &amp; theStr1<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Next<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; StrPass3 = GetChr(StrPass2)<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; UnEncode = StrPass3<BR><BR>&nbsp; &nbsp; &nbsp; End Function<BR><BR>&nbsp; &nbsp; &nbsp; Function GetChr(str)<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; For i = 1 To Len(str)<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ASCStr = Mid(str, i, 1)<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MyStr = MyStr &amp; ASCStr<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; If MyStr &gt; 32 and MyStr &lt; 127 Then<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; StrResult = StrResult &amp; Chr(MyStr)<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MyStr = ""<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Else<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; If i = Len(str) Then<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetChr = "小虾无能,不能破解"<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; exit function<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; End If<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; End If<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Next<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetChr = StrResult<BR><BR>&nbsp; &nbsp; &nbsp; End Function<BR><BR><BR><BR><BR><BR>试试效果先:<BR><BR>10DEC10C10150 &nbsp; -&gt; &nbsp; lake2<BR><BR>120105EC111106 &nbsp; -&gt; &nbsp; xiaoj (这个是某人的密码哦^_^)<BR><BR><BR><BR>后面两种情况,如果要编程序破解的话感觉比较困难,就不写了。要是阁下写出了程序,可得让我研究研究。<BR><BR>下面让我们通过构造碰撞来破解海洋顶端2006Plus的默认密码。<BR><BR>打开文件,得到它的编码过的密码是02200200251001,我的程序不能恢复,看来是经过JoinCutStr函数处理的。让我们大胆的还原:10 31 22 10 01 22 10 01 22 55 11 10 01 11,整合一下:103 122 100 122 100 122 55 11 100 111,这里有个ascii值11,这个字符也是可以显示的,既然是碰撞,只好将就了。我们得到我们的明文密码:gzdzdz7chr(11)do<BR><BR>因为chr(11)是换行符,格式原因不能显示,你可以把以下代码保存为vbs运行之,得到密码:<BR><BR><BR><BR>Call InputBox("海洋的默认密码碰撞",,"gzdzdz7"&amp;chr(11)&amp;"do")<BR><BR><BR><BR><BR><BR>然后你用它登陆没有改过密码的海洋顶端木马,呵呵,进去了吧。下面再提供一个可以登陆但不同的密码用以证明这是碰撞:<BR><BR><BR><BR>Call InputBox("海洋的默认密码碰撞",,"gqdzdz7ne"&amp;chr(11))<BR><BR><BR><BR><BR><BR>最后,我们来下个结论:在得到海洋顶端2006+编码后的密码之后,就算不能恢复出明文密码,也可以利用碰撞来登陆系统。至于如何得到编码后的密码,呵呵,那就超出本文的范围了。</FONT>
页: [1]
查看完整版本: 海洋顶端2006+密码编码分析