SQL Server
如何存放口令
SQL
Server的口令是通过函数pwdencrypt存放在master.dbo.sysxiogmns表里的,这是我们大家所知道的,但是我们似乎更多关心的是pwdencrypt函数在这个存储过程中的细节,为了明白这个细节,我找了台装有SQL
Server的机器实验了一下,文中将研究这个具体的细节并且说明这个过程具有的缺陷。
SQL
Hash长的什么样
SQL的Hash是怎么样的呢?跟我们熟悉的Windows账户的Hash一样吗?还是有其特殊的规律?带着这些问号,我们来做实验。环境是一台有sa空口令的Wm2k,打了SP4。因为一开始SQL服务器的sa口令是空的,通过查询master.dbo.sysxlogins显示的结果是null,那么我们光把这个默认密码改掉,如何改?这个问题问得也比较多,这里讲一下。我们使用SQL
Server的查询分析器,或者其他的查询工具,执行下面的命令:sp_password null,longker.sa;其中null是原来的空密码,longker是新的密码,sa是登录的账户。显示密码已更改那就成功了,这样我们就把sa的空口令改成了longker。下面我们再来查询下面的命令,就是从sysxiogins表获取sa的密码信息:
Select password form master.dbo.sysxlogins where name='sa'
你应该得到如下的一些东西:
OxO1OOE4056C38CEAC8FBA2C8B4201A2A7C7BFFBBA9A4AD7C6967CD0296F41453742024D5D42AF66EEFOB2266D230B
看起来似乎是杂乱无章的,一长串,但是有其特定的规律的,下面我们就来看看其中的规律。
时间不同加密不同
函数pwdencrypt是SQL Server一个用来加密的函数,我们可以利用它来进行查询输人数据加密后的Hash。下面我们将做一个实验,在不同时刻用pwdencrypt函数查询相同的字符。我们光使用SQL Server的查询分析器,执行下面的查询命令:
select pwdencrypt('longker')
得到的回显结果如下
OxO1OOB60F9D01026E8F16B5E809EICA689CB84A2B3134958AD4062948383411995FDOB6DF991C73FE18BA7B7122C8
但是若干秒以后再次查询,得到的回显结果就不一样了,如下
OxO1OOF1OF5D754F6A9CF6A024199926DC9447E36641A2FC312E074E78FF65B2A4C8B98B3CE7DC8D99F3F465EIDED6
我们可以看到虽然查询的内容是一样的,但是回显的信息却是不一样。这个是为什么呢?对,答案是时间!不同的时刻进行查询,回显却是不一样的,可见时间在口令Hash值产生并且存储的过程中起着十分重要的作用。
大小写加密不同
我们使用SQL
Server的查询分析器,执行下面的查询命令select
pwdencrypt('LONGKER'),这里注意是大写的longker,得到的结果是:
0x01001Dill20C762C83841DEF7D93C684A6F2CFB9DFF930CF9D4D762C83841DEF7D93C684A6F2CFB9DFF930CF9D4D.
看清楚没有?这里存在有两个Hash值,如果你不能看出来,我们可以来比较一下
0x01001D1112OC762C83841DEF7D93C684A6F2CFB9DFF930CF9D4D762C83841DEF7D93C684A6F2CFB9DFF930CF9D4D.
我们可以很快发现最后40个字符是一样的,这跟上面小写的longker是不同的,由此看来大小写也在扮演一个重要的角色。大写的口令是被存储了两次,一次是存储原来的密码,而另一次则是存储后的密码再次存储后的。这样一来,就使得破解SQLServer密码来得简单了。因为只要得到再次存储后的密码信息就可以得到上次存储前的真正密码了,这样就减少了工作量,不用去尝试更多的字符了。
现在我们应该清楚了,由于时间的变化,SQL的Hash也会随着变化;大小写的不同,也会引起Hash的不同。
SQL口令加密规律
我们再回过头来看看那些Hash值:
0x0100
1D11120C
762C83841DEF7D93C684A6F2CFB9DFF930CF9D4D
762C83841DFF7D93C684A6F2CFB9DFF930CF9D4D
是有一定的规律的,前6位是一样的,然后后面的8位则可以看作是密钥,每次查询的时候均是不一样的。我们是不是可以这样认为,密钥是贯穿这个过程的,当密钥产生时,pwdencrypt函数储存一个Hash,然后当密钥快要失效时再产生一个Hash。这样就有了两个Hash,而且当口令是大写时,这两个Hash是相同的。
而它的认证过程是这样的,当用户要登录到SQL
Server时,SQL
Server产生一个8位的密钥,同时产生Hash值,然后这个Hash值会跟数据库中的Hash进行比较,如果符合,则成功通过认证如果不能则登录失败。