Kevin Shan

SourceSafe登录密码安全研究

声明:本文仅做研究交流用途。请不要非法利用。SourceSafePasswordRecovery仅用来帮助自己忘记密码的人使用,请不要用作非法用途,否则后果自负。-txhak

最近想重装系统,在备份数据时居然忘记了系统中一年多以前安装的SourceSafe的密码。一时冲动,便分析起SourceSafe的登录密码来。

在SourceSafe安装目录中(我安装的是SourceSafe2005),安装文件并不多,其中ssapi.dll格外惹人注目,使用depends打开ssapi.dll文件一看,果然有登录密码相关的API。

ssapi   

使用OllyDbg打开SourceSafe客户端文件ssexp.exe一路跟踪,果然在ssapi模块的5C491F75处,发现密码Hash算法。

ollydbg1

这段汇编代码用C#表示如下:

Code

 

在OllyDbg中还可以发现,在 SourceSafe目录\data\um.dat文件中存储了用户名和Hash值。具体格式可以参照我附上的工具。

原来SourceSafe将密码存储存储为(16bit,2byte)长的hash值。密码长度最长是15位,而且不区分大小写。想想这种加密方式就知道太简单了。现在MD5都被王小云教授找出碰撞的规律了。这个Hash算法岂不更容易产生Hash碰撞?带着这样的疑问,以及如何产生Hash碰撞的好奇,开始了我的分析之旅。

1, 16bit存储的Hash值共有65536种可能。

2,15位长度,不区分大小写的密码组合共有3119376532692091019651167124种可能。因为合法的密码字符为"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ~!@#$%^&*()_+`-=[]\\;',./{}|:\"<>?"。共68个。共有681 + 682 + 683 + … + 6815 =

 = 3119376532692091019651167124种。

3,所以每个Hash值至少对应3119376532692091019651167124/65536 = 47597908518861252130907.701477051种密码。可见这种Hash算法产生冲突的几率是多高。(实际的冲突比例比这个数更高,因为总共只产生了10305种哈希值)。

有这么高的Hash冲突几率。要找回忘记的密码还是很难的,3119376532692091019651167124种密码可能性,穷举尝试估计得上万年了吧。但是要找到一个可用的密码那就简单多了。 

 现在的问题实际上就是求解一个已知Hash值所对应的一个可用密码就可以了。当然,要找回你原始密码,应该不太可能了。一是高Hash冲突率使得一个Hash值会对应很多个解,你不一定知道原始密码是哪个。二是穷举所有可能性的话,现在家用的计算机还没这么快。不过找到可用解也就解决我们的问题了。要找到可用解,还是需要穷举所有密码,计算密码的Hash值,如果该密码计算出来的Hash值与已知的Hash值相等,那么这个密码就是一个可用解。这种穷举在一般情况下应该可以算出解来,不过如果是一些特殊解,可能很长时间也算不出来。我们可以用密码破解中RainbowTable的概念,通过空间换时间,在只需要一次性计算好所有Hash值对应的一个可用密码表。就可以每次查表得到已知Hash值的一个可以密码。由于Hash值一共才65536种可能,因此存储空间也不大。

:)其他方法就当我抛砖引玉,留个大家了。

我使用RainbowTable实现了这个求解的算法,优化后发现生成所有Hash值的RainbowTable都只需要30ms左右。因此相当快,每次自动生成这个RainbowTable都可以,不用事先计算好。:)

 

Code

 

附上我写的SourceSafePasswordRecovery工具

 

 

 

 

 

posted on 2009-03-12 17:50  Kevin Shan  阅读(2886)  评论(19编辑  收藏  举报