锐捷客户端密码分析
代码下载地址:http://download.youkuaiyun.com/detail/zerolusta/4072516
前几天下午一个计科的哥们在校内说,锐捷上网密码忘了要去工学部网络中心找回来。
天正大雨赶过去麻烦,但还没来得及跟他说就已经过去了。我想起了大一的时候用某些星号
密码查看工具是能够从内存获取到锐捷登陆框中的密码明文的,前提是你的正确密码被锐捷
保存在电脑中。
武大校园网安装锐捷上网认证客户端的机器还是很多的,只有文理学部一些地方是用的
神州数码。但忘记密码自然是比较麻烦的,虽然可以用校园卡重置,但不如直接找回原来的
密码(口令,准确地说)方便。所以针对锐捷客户端的账号口令在本地的存储和加密算法稍
微做了点分析,总结了几种找回密码的方法(仅限于正确的密码仍通过锐捷保存在机器中的
情况)。
菜鸟有菜鸟的方法,高手有高手的方法,对于我这种介于二者之间的伪技术流,也有折
衷的办法。测试环境为Windows XP sp3,锐捷版本为3.63。我事先将自己的锐捷登陆密码设
置成了testpassword。
(事先声明,这里讲到的所有方法与后面提供下载的小软件都只是为了简单的技术探讨
只用,别拿去做坏事,谁做了坏事与我无关......)
首先最简单的就是使用网上到处可见的所谓查看星号密码的工具,那天下午从荒芜已久
G盘里找出了一个星号密码查看器,然后发现3秒钟就可搞定。

这里将查看器上的放大镜图标按住拖到密码框上,即可在查看器中的结果中看到密码明文。
如果只是说说这样的小软件怎么用,那也太不能证明自己不是菜鸟了。关键在于这类主
流星号密码查看工具的原理。
我们知道,一般用于填写文本和字串的框都属于windows所提供的编辑框这一Common
Control,以MFC框架为例,MFC中所提供的编辑框由CEdit类所描述,它有一个属性表示编
辑框中是不是password,选中了该属性,编辑框在显示的时候就会将当中的字符用星号"*"
代替,从而实现隐藏口令明文的目的。但是这样一个机制的安全性是很差的,因为windows
提供了太多的接口和数据结构可以间接获取到其中的真实内容。这里所使用的方法,核心的
核心就是可以通过控件句柄,向控件发送一个WM_GETTEXT或者EM_GETLINE消息,从而可
将返回的字符串存入预置的缓冲区中。这样一个漏洞的危害是比较大的,关于如何编制安全
的编辑框控件,网上有不少人发过文章,有兴趣的朋友可以参看链接:
http://www.ibiancheng.cn/Article/VCMFCArticle/200804/121.html 。大体思路就是自创一个新
的Edit类,继承自CEdit类,但是重写默认的窗口过程函数,判断收到的消息是不是
WM_GETTEXT或者EM_GETLINE,若是,则拦截,不是则放行。比如腾讯QQ就使用了这种
或者类似这种的方法,不信的朋友可以用前面的查看器试试QQ登陆框,它不会有任何返回
值。另外,我曾经觉得很奇怪为什么所有的这种软件都要做成"拖动某个图标到目标",现
在看来其实是有考虑的,个人猜测,不保证都对。首先发送那两个消息一般是使用
SendMessage()或者PostMessage()两个API函数,其中第一个参数是目标控件的句柄,而实
际使用时潜在的目标控件多种多样,获取句柄有一点麻烦,于是就采用了WindowFromPoint
()这个API返回鼠标位置顶层窗口或控件的句柄。但是如何获得我们想得到的鼠标坐标呢?
那就是响应窗口类的WM_MOUSEMOVE消息了,但是问题在于,鼠标一旦移出了我们的软
件界面,WM_MOUSEMOVE消息就不会再被软件窗口过程截获,怎么办呢?解决方法就是按
住某个图标拖动了,按住鼠标不放使焦点仍处在我们自己的程序上,但同样还能获取到鼠标
的实际坐标,问题便解决了。这段属于题外话,与主题无关: )。如果要自己写一个这样的程
序,不难,几十行代码便可以搞定。
第二种方法,就是分析锐捷客户端在本地机器上存放和读取账号及口令的机制。准确地
说,任何能够在离线状态下记录用户登录口令的软件,都将口令保存在了本地机器。不同点
仅仅在于,在哪个地方,以什么方式。一般认为注册表是首选,另外软件相关目录下的某些
数据文件或者数据库也是不错的选择。而以什么方式,则取决于口令明文到密文的算法,算
法又有可逆和不可逆之分。可逆的算法能够从密文以加密算法的逆操作恢复明文,如锐捷客
户端在每次启动时都会从注册表读取密文解算出明文然后显示在对话框(这也使它的安全性
大打折扣),不可逆算法如linux存储用户登录口令使用的方式:提取口令的某个特征值(像
MD5、哈希值一类的东西)保存起来,每次用户登录的时候将用户输入的字符串做同样的算
法操作,然后对比结果与之前保存的正确口令的特征值,这样的好处在于对于操作系统而言
用户的实际口令是不可见的。计算机学院的大牛彭国军老师曾跟我说起过他一些年前对QQ
的某些版本的密码分析,发现QQ密码在本地存储的文件,并且定位到了该文件的20个字
节用于存放密码加密过的密文,如果将该段数据拷贝到其他机器的相应位置,则同样可以登
陆QQ,显然这时候我们不需要知道这个QQ账号的密码明文,据说这个漏洞直到QQ2005以
后的版本才消失。回到锐捷客户端的问题上来,我在注册表编辑器中以Ruijie为关键字搜索
到了一个可能的信息存放处:HKEY_LOCAL_MACHINE/SOFTWARE/锐捷网络/Ruijie Supplicant,
也就是一个很正规的地方了,SOFTWARE子项中。里面的项名字都很直接,可以肯定就是存
放密码的位置了,截个图:

注意红框里的东西。对应的数据看似是乱码,实际上就是加密过的账号和口令了。事实上到
这里,我们已经可以像刚刚所说的利用QQ漏洞一样,实现在不知道明文的情况下登陆账户
了,只要将某台机器上的Password和UserName两个项的值复制到另一台上的相应位置,
就能在另一台机器上登陆该账号了。但如果一个有意思的问题只挖掘到这一步,也太浪费了。
既然已经定位到了密文的存放位置,接下来我们说一说密码分析。
正如前面所说,锐捷使用的加密算法属于可逆算法,也就是知道了它的算法原型,我们
就能反推出逆操作从而将加密过的密文还原成明文。但是问题在于我们怎么可以得到算法原
型。刚刚还说了,锐捷的安全性考虑是很差的,所以被我逮到了很多可利用的特点。
首先,它的用户名和密码使用的是同一套加密算法。这样对于我们而言机会在哪里?机
会就在于只要知道了用户名的加密算法就等同于知道了密码的加密算法,从信息安全的角度
看,这也算是木桶原理的实例吧,整体安全性总是由最差的那个环节决定的。举个例子,如
果你要破解QQ密码的加密算法,可以去尝试调试QQ游戏客户端,可以去尝试去抓QQ邮
箱的数据包,千万别去从QQ客户端下手,因为QQ客户端是腾讯的重中之重,安全性的考
虑十分周密(最近奇虎360掀起的针对腾讯QQ的"隐私门",也不得不说有这里的原因)。
既然算法一样,那点子就来了。为了观察一些简单字符加密后的密文,有没有特殊的规律,
我做了一些这样的测试。首先不断地设置用户名为单个字符,然后刷新注册表编辑器看密文
的变化,最后的一些结果是:

看得出其中是有规律的,我翻出了某本书的ASCII码表,发现单个字符的规律就是从
ASCII值为127的字符开始用AQ表示,随ASCII值递减,分别用AA、Aw、Ag表示126、125、
124所代表的字符,每四个为一组,随后为BQ、BA、Bw、Bg,依此类推。
然后做了一些双字符多字符的测试,结果如下:

这样看来也是有一定规律性的,比如它没有使用轮换之类的处理,也就是某一段明文只
与某一段对应的密文有关,前后联系不大。从算法破解的角度看这是有利的。但是这里又并
不是简单的单字符的置换,可能存在分组处理。别的一些特点我也不一一陈述了,如果有对
找规律填数字感兴趣的朋友倒是可以去分析分析:-D。还有一些测试结果:

遥感没有密码学,我也没学过,更没有这方面的经验看不出这是哪种算法的风格,拿它
请教了一下彭国军老师,他说有点像base64编码,但计算发现不是,结论是变异过的base64
编码算法。还说你可以先去研究研究base64算法再做分析,我顿时就汗了,base64在上学
期的计算机网络中学过,但已经不记得了,为了这个而去再学一次?不值,因为我是很懒的。
既然不从算法研究入手,怎么办呢?另一个快捷的方式是动态调试包含了该算法的程
序。提出这个问题的那天晚上在某个QQ群里说了一下,信安的某个哥们表示有兴趣,然后
两人各自拿OD调试了一下锐捷主要的几个exe文件,RuijieSupplicant.exe,8021x.exe,不过
有个麻烦就是锐捷客户端有只允许一个进程实例的限制,方法是创建了互斥对象。所以联网
就不能调试运行,要调试运行就必须断网。这哥们想把这段代码直接JMP掉,未果,锐捷
安全性挺差,但功能上看几个组件的牵扯有点复杂。插个笑话提提神,我们在OllyDgb里搜
索8021x的字串的时候发现了这么一句话,D疼不已,截图有真相:

我估计这个linym是锐捷公司里最风骚的程序员。仅当提神。
动态调试的目的在于定位到我们想知道的"程序领空",从而根据反汇编代码看出程序
进行的计算--也就是我们想研究的那一段算法代码。但是难点在于,一是很难定位,锐捷
读取注册表密文然后反求明文都是后台悄悄完成的,不像破解一般的小软件那样会在输入错
误的注册码后啪地弹出一个框告诉你要注册请联系作者,所以定位很难,二是定位后通过汇
编代码推出算法,这要求破解者很深的汇编功底......我承认曾经看过半本王爽先生的《汇编
语言程序设计》,但那本古老的教材讲得很那个什么通俗易懂,何况只看了半本,N多的语
法于我而言还停留在不懂的阶段。
与这哥们各自弄了一段时间,都没什么明显的结果。于是搁置。
退一步海阔天空,你那套算法我们不要了==。但是如果仅仅只是想要恢复密码,技巧还
有N多可备选则。这里我写了一个小软件,原理是首先从注册表中找到锐捷客户端存放信息
的位置,读取用户名密文和口令密文,而后将口令密文覆盖注册表中的用户名密文,最后启
动或重启锐捷客户端,于是我们就能从它登陆框的用户名框中看到密码明文了。意思就是,
我拿不到你的算法,但是不管怎样你的算法还是包含在你的程序内的,我不能琢磨透你,但
我可以利用你。且把你当做一个黑盒,只与你释放的接口打交道就是了。
主界面,很粗糙......

运行结果,我们可以在用户名框中看到密码了。恢复成功。话说对一个规规矩矩的软件如此
虐待,信安的哥们看不下去了,说,锐捷很萌的,我们还是不要黑他了。......再汗一个。如
有要用这个软件的,我传到了网盘,可以来这里找下载:http://e.ys168.com/?lusta。
事情到这里还没完。还有别的方法。Restorator是一个用户修改可执行程序资源及相关
信息的工具,类似于早期的eXeScope,不过功能应该要更强,毕竟是比较新的软件。有兴趣
的朋友可以去下载玩玩,默认整合到了右键菜单,随时可以将exe文件载入查看菜单图标字
符串对话框等等各种资源,还可以轻松地编辑它们。用Restorator打开8021x.exe,然后找
到登陆框这个对话框,选择密码编辑框,将password属性去掉,保存,OK。
去掉这个勾即可。
这样的结果是再次启动锐捷客户端的时候,密码框中将不再显示星号,而是密码明文。结果
就这个样子,我也不截图了。因为我每截图一次都要断一次网。
最后再说一个思路,还是利用锐捷客户端本身。这有点类似于某些软件注册机的制作方
法,只不过那是从内存获取计算过程,而我这里的方法比较弱智,直接拿人家可执行程序。
同样,用Restorator将8021x.exe做修改(比如修改到只剩两个框分别显示用户名密码,但
虽说只是为了学习研究的目的,随意修改别人的程序还是不厚道的...表示一下歉意),而后
将这个修改过的8021x.exe作为资源导入我刚刚写的那个软件中,恢复密码的过程是:读取
注册表信息,找到锐捷安装目录,将里面原有的8021x.exe更名,释放我们修改过的8021x.exe
到该目录,启动锐捷(实际上启动的8021x.exe就是我们修改过的),从中就能看到密码明文
了。随后软件必须将原有的8021x.exe还原,不然用户就连不上网了。将之前那个程序稍作
修改就行,我没有去写了。
最后还说一种思路,仿照某些软件破解的文件补丁,将用Restorator修改password属
性后的8021x.exe与原来的版本作比较(应该就差几个字节),然后做一个文件补丁,哪天密
码忘了,运行补丁,就可以从锐捷登陆框里看到密码了。这也应该是最厚道的方法了,至少
可以称之为某某补丁,而不是某某破解。
好了,收不住写了四千多字。但这些严格地讲不算密码分析,因为真正涉及到密码学的
那个方法我做不出来。因为我是技术的,不是学术的。自囧...
到这里就把我这几天断断续续得到的结论总结了一下。有对信息安全感兴趣的朋友可以
一起探讨。在此感谢彭国军老师以及信息安全专业的晴岚大猫。
2010-10-17 01:35
6401





