现行能下载的这类程序都只能是在NT 4.0和2K的,xp中的还没有,可能xp中的密码并不是在内存中的原因吧。常见的工具就是showpass和findpass了。showpass和findpass两个程序使用的原理是否一样,这个我不太清楚,因为showpass比findpass大很多,而且运行时间比较长。findpass却是很快就能得到结果,而且还是带有源代码的,会看的可以自己研究一下。下面说说这两个工具的长处和不足: </P><P>Showpass <BR>很有点限制,只能是telnet模式中运行才有机会得到管理员密码,在终端中执行,是得到密码的,一会再讨论为什么它不能得到密码。而且只能得到本地管理员登陆帐号的密码,得不到终端登陆的帐户的密码 </P><P>findpass <BR>在终端中是可以得到所有登陆的帐户的密码,但要使用一些参数,例如winlogon的PID,对应这个winlogon的PID的帐户,以及域名,比较麻烦。如果不加参数的话,只能得到本地登陆管理员帐号的密码。在telnet模式中,findpass是一定要加入参数才会成功的,而且成功率并不高。 </P><P>经过了两天对这两个程序的研究,以及研究过findpass的源代码后,并在好些系统上测试过,终于有所发现。两个程序的原理基本上都是一样的,都是通过winlogon的PID号和正确的域名中,在内存寻找好段加了密的内存块(保存着加密过的登陆密码),然后对它进行解密,这样就能得到明文的密码,但为什么showpass以及findpass会失败呢?特别是showpass,失败率更加高。失败的原因如下: </P><P>1.管理员使用NWGINA模式登陆(就是在hklm\software\microsoft\windows nt\currentversion\winlogon下的Gina是设置为nwgina.dll这时),这样是无法得到密码的,不过不太常见. <BR>2.无法得到正确的域名,winlogon的PID号,以及对应登陆的帐号。 </P><P>findpass是用GetEnvironmentVariableW(L"USERDOMAIN", UserDomain, sizeof(UserDomain))的API对得到域名的,但很不幸,在telnet模式中,这个API是无法得到域名的,只有在本地或终端模式中才能得到域名,这就很清楚为什么findpass在telnet模式不使用参数是无法得到密码了,即使在本地或终端模式中,亦不一定可以得到正确的域名的,有时在本地或终端模式中你在命令行中执行set,亦不一定可以看到有一项是UserDomain的,这样findpass就得到域名了,还有的是,就算能用这方法得到域名,但管理员有可能是从其它域登陆的,这样的话,findpass得到的只是个错误的域名,这样一样会得不到密码.findpass失败原因主要是在于得不到域名或得到不正确的域名,当然不排除得到了错误的帐号,因为它是使用了GetEnvironmentVariableW(L"USERNAME", UserName, sizeof(UserName)) <BR>这个API对得到用户名的,这就和得到域名的方法一样,是很有可能得不到登陆的用户名或一个错误的用户名的。这两个是findpass失败的原因。 </P><P>showpass是用什么方法得到域名和用户名我就不才清楚,毕竟我没有它的源代码。但它在终端模式是会失败的,这是因为在终端模式中,一般有好几个winlogon的PID,我的猜测是它无法分别到哪个winlogon的PID才是正确的,因为一个winlogon的PID只是对应一个帐户的,如果不对应,例如一个winlogon的PID是224,对应的登陆帐户是Admin,但你得到PID号224,但却使用一个Guest的帐户去进行解密,就肯定会失败的了。就算在telnet模式中,如果有几个管理员从不同域中登陆或有其它用户从终端中登陆的话,showpass一样会失败。 </P><P>解决方法: <BR>对于findpass,因为它有源代码,要对其进行修改不是太困难的事,经过研究,修改过代码以及测试后,发现只要对正确得到域名,登陆的帐号以及所有的winlogon的PID,然后进行循环方式对每个域名,每个登陆的帐号和每个不同的winlogon的PID一一进行穷举方式解密,是可以得到所有登陆帐户的密码的. <BR>例如: <BR>1台系统有一个用户自本地登陆,用户名为Admin,winlogon的PID为224.另两个用户从终端登陆,用户名分别为Guest和Test,对应WinLogon的PID假设分别为1111和2222.假设这几个用户登陆到的系统的域名都是aaaaa那么我们首先得到这台系统的域名aaaaa,然后得到所有三个登陆的帐户Admin,Guest和test,然后就是所有winlogon的PID,224,1111和2222因为只是一个域名,所以我们穷举方式只需要进行九次的运算 <BR>第一次:域名aaaaa,用户Admin,PID号224 <BR>第二次:域名aaaaa,用户Admin,PID号1111 <BR>第三次:域名aaaaa,用户Admin,PID号2222 <BR>第四次:域名aaaaa,用户Guest,PID号224 </P><P>第九次:域名aaaaa,用户test,PID号22222 </P><P>但在实际中,其实不需要九次那么多的,因为Admin这个帐号在第一次的运算中能成功得到密码的话,这个帐号是不需要做第二和第三次的运算的,是可以直接跳到第四次运算的,但上面的只是使用到最坏时要进行的运算数。 <BR>到了这里,就可以解决到问题了,虽然方法并不是太高明,毕竟要使用穷举的方法去进行运算,但到底都是一种解决的方法,至于如何在telnet模式和其它模式中得到正确域名,如果枚举所有登陆帐号和枚举所有winlogon的PID号,自己去参考相关的资料. </P><P>在这里要感谢的是 <BR>1.提供findpass原代码的人,因为不知道谁才是原作者(findpass的源代码是从另一个同类的源代码中修改过来的,只是多加了一个功能,就是可以自己加入参数功能,所以使用这种方法用程序去表达出来,并首先发布第一个源代码的作者我不知道是谁,但据闻是国外的人先发布),但还是要感谢发布原代码的那些作者(无论是原创还是修改版的作者) <BR>2.感谢Slackbot一些指导,枚举得到所有winlogon的PID号的方法我是会的,但枚举所有登陆的帐户的方法是使用了他提供的代码. </P><P>上面所写只是本人调试所得,因为水平有限,是否有什么错误的地方,我亦不太清楚,但贴子绝不是从什么地方抄来的(因为论坛中有个混蛋老说我的贴子是抄来的),如果有人说我是抄来的,请说明是从什么地方抄来的,并提供连接,让大家知道我是从哪个"原创"中抄来的<BR> |