C#编程让Outlook乖乖交出帐户密码
许多人习惯于让Outlook记住密码,收邮件时便不必每次都输入邮箱密码,一切让Outlook代劳。但时间一长,马虎的人会把自己的邮箱密码忘记,这样就无法重新设置或者登录Web界面收取邮件了。Outlook绝对不会告诉你邮箱的密码是多少,即使你找到了注册表中Outlook存储帐户和密码信息的键值,由于密码信息都是加密存储的,你还是无法提取密码。我们的对策就是针对邮箱服务中安全机制最薄弱的环节采取行动……
众所周知,POP3协议本质上是一种明文协议,也就是说,虽然Outlook本地存储的密码是加密的,但当它连接到POP3服务器准备收取邮件时,必须以明文的形式提供密码。因此,只要我们开发一个POP3服务器(不必是功能完善的POP3服务器,只要骗过Outlook即可),让Outlook从该服务器收取邮件,Outlook就会乖乖地交出加密得严严实实的密码。实际上,这种办法不仅适用于Outlook,而且适用于所有使用POP3的邮件客户程序,如Outlook Express、Foxmail等。
一、构造POP3服务器
下面我们要用VS.NET 2003和C#开发一个“伪”POP3服务器——之所以说它“伪”,那是因为它只有极其有限的功能,只进行到骗出邮箱密码就停止。
启动VS.NET 2003,新建一个C#项目,项目的模板选择“控制台应用程序”,将项目命名为PServer,点击“确定”创建项目,如图1所示:
图1 新建C#项目
VS.NET自动创建PServer名称空间、 Class1类和Main函数骨架。在Class1.cs文件的顶端using System语句之后加入下列三个语句:
using System.Net;
using System.Net.Sockets;
using System.Text;
接下来的任务就是修改Main函数,使它作为一个POP3服务器监听来自Outlook的请求,当Outlook尝试连接这个PServer服务器时,根据POP3协议的要求,我们确认一下Outlook用户提供的帐户名并要求提供密码,Outlook提供密码后,我们在控制台上输出密码,这样就算完成了任务!
在Main函数中,我们的第一个任务是启动一个POP3服务器。为此,我们要用System.Net.Sockets名称空间定义的类创建一个ipEndPoint,让一个TCP服务器监听该端点,接收来自客户端的请求:
// 在127.0.0.1(本地机器)上创建一个TCP服务器,监听
// 110端口的请求(110是POP3服务器的默认端口)
IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"),110);
TcpListener tcpServer = new TcpListener(ipEndPoint);
tcpServer.Start();
// 等待来自POP3客户程序(如Outlook)的连接请求
TcpClient tcpClient = tcpServer.AcceptTcpClient();
当一个POP3客户程序连接该服务器时,服务器必须按照POP3协议的要求对客户程序作出应答。根据POP3协议RFC 1939规范的定义,服务器首先要做的是返回一个欢迎信息:
// 向客户程序返回欢迎信息
NetworkStream ns = tcpClient.GetStream();
byte[] outbytes = Encoding.ASCII.GetBytes("+OK Welcome" + Environment.NewLine);
ns.Write(outbytes,0,outbytes.Length);
客户程序接收到欢迎信息后,同样也会按照POP3协议的要求发送帐户名称。我们把这个帐户名称记录下来以便以后使用,代码如下:
// 接收和记录邮箱帐户名称
byte[] userBytes = new byte[255];
ns.Read(userBytes,0,userBytes.Length);
收到帐户名称信息后,我们要告诉Outlook说这个名称没有问题,客户程序一收到这个信息就会发送密码,然后我们再把密码也记录下来。实现代码是:
// 告诉客户程序帐户名称正确
outbytes = Encoding.ASCII.GetBytes("+OK" + Environment.NewLine);
ns.Write(outbytes,0,outbytes.Length);
// 接收和记录帐户密码
byte[] pwdBytes = new byte[255];
ns.Read(pwdBytes,0,pwdBytes.Length);
接下来要做的就是获取字节数组的内容,将它们转换成字符串,然后输出到控制台:
// 在控制台上显示出帐户名称、密码
Console.WriteLine("帐户名称:" + Encoding.ASCII.GetString(userBytes));
Console.WriteLine("帐户密码:" + Encoding.ASCII.GetString(pwdBytes));
既然已经获得了密码,服务器的任务已经完成了,现在可以关闭它。强行关闭服务器会导致客户程序显示错误信息,不过这里我们并不在乎。关闭服务器的代码是:
// 关闭服务器
ns.Close();
tcpClient.Close();
tcpServer.Stop();
将上面的所有代码依次输入Main函数,编译一下就得到了一个PServer.exe执行文件,它就是我们的伪POP3服务器。PServer.exe体积很小,发行版只有16 KB。
二、获得密码
首先启动PServer.exe,让我们的伪POP3服务器开始监听来自客户程序的请求。
启动Outlook,点击菜单“工具→电子邮件帐户”,选择“查看或更改现有电子邮件帐户”,找到要恢复密码的电子邮件帐户,点击“更改”打开它的属性对话框,如图2,把POP3服务器设置为localhost:
图2 更改Outlook电子邮件帐户
在Outlook中接收一下邮件,如图3所示,Outlook 将报告说服务器中断了连接,不必理睬。
图3 Outlook已经把密码发送到伪POP3服务器了
现在PServer.exe已经得到帐户的密码了,如图4所示,abc帐户的密码原来是abcdefg:
图4 伪POP3服务器返回的用户名和密码
三、利用嗅探工具
基于POP3密码在网络上以明文形式传递这一事实,我们还可以利用嗅探工具分析TCP/IP通信过程获得帐户密码。如果你没有VS.NET开发工具,那么可以用这种办法获得密码。即使你拥有VS.NET,也可以用嗅探工具了解POP3通信的详细情况,加深对POP3通信的理解,这对我们用编程的方式利用POP3协议大有好处。
能够分析TCP/IP通信过程的嗅探工具很多,Ethereal就是一款著名的免费跨平台分析工具。下面我们就以它为例,看看POP3通信步骤和截获POP3密码的过程。
从http://www.ethereal.com/distribution/win32/下载WinPcap驱动程序和Ethereal的Windows版软件包(两者大小分别约300 KB和8.1 MB),安装WinPcap,再安装Ethereal。
启动Ethereal,选择菜单Capture→Start,在图5界面中,Interface栏选择与Internet通信的那块网卡,点击OK。
图5 Ethereal
启动Outlook,用遗忘密码的帐户收一下邮件(不必将帐户的POP3服务器改成localhost),然后在Ethereal中点击Stop按钮。图6显示了一次试验的结果:
图6 嗅探结果
Ethereal的嗅探结果详细地显示了Outlook与服务器通信的过程。正如我们前面介绍的,从No 6(图七最左栏的编号)记录开始,客户程序和服务器之间建立了POP3通信联系:No 6服务器应答说OK,表示服务器运行正常,可以提供服务,No 7客户程序发送一个请求USER ltt,即告知服务器邮箱帐户的名称ltt,No 8是TCP通信数据,在此我们不必理会,No 9记录服务器应答说“+OK”(帐户名称没问题),并要求提供ltt帐户的密码,No 10记录客户程序发送消息“PASS llll”,其中llll就是要寻找的密码,No 11记录服务器回答说OK,No 12记录客户程序发送请求STAT,STAT命令要求服务器以规范的格式返回邮件数量、占用空间,No 13记录服务器回答说邮件数量0、占用空间0,最后,No 14记录客户程序发送QUIT结束会话请求,No 15记录服务器结束会话——这就是一次完整的POP3通信过程。
遇到密码丢失的情况,动动脑筋另辟蹊径,其实你自己就能够把握一切。
源程序可以在 这里 下载。
C#编程让Outlook乖乖交出帐户密码的更多相关文章
- 通过编程为Outlook 2007添加邮件规则
Outlook 所支持的邮件规则相当有用,我们经常需要针对某些特征的邮件做特殊的处理.例如将其移动到某个特定文件夹,或者删除它等等. Outlook所支持的邮件规则主要两大类:收到邮件时和发送邮件时 ...
- 使用 C# 进行 Outlook 2007 编程
原文:使用 C# 进行 Outlook 2007 编程 探讨如何使用 C# 编程语言生成 Outlook 识别的应用程序和 Outlook 外接程序. 请从"Add References&q ...
- 使用 C# 进行 Outlook 2003 编程
原文:使用 C# 进行 Outlook 2003 编程 摘要: 本文介绍了 Microsoft Outlook 2003 对象模型介,并探讨了如何使用 C# 编程语言生成 Outlook 识别的应用程 ...
- Outlook 邮件助手
Outlook 邮件助手 1 Overview 2 C# 编程 3 Outlook 设置 3.1 Outlook 2013 3.2 Outlook 2010 1 Overview 本章将示例如何开发一 ...
- 后端小白的VUE入门笔记, 进阶篇
使用 vue-cli( 脚手架) 搭建项目 基于vue-cli 创建一个模板项目 通过 npm root -g 可以查看vue全局安装目录,进而知道自己有没有安装vue-cli 如果没有安装的话,使用 ...
- NetBIOS名称欺骗和LLMNR欺骗
目录 LLMNR和NetBios 攻击原理 Responder 攻击过程 LLMNR和NetBios 什么是LLMNR和NetBIOS名称服务器广播? 当DNS名称服务器请求失败时,Microsoft ...
- - C#编程大幅提高OUTLOOK的邮件搜索能力!
原文:[原创] - C#编程大幅提高OUTLOOK的邮件搜索能力! 使用OUTLOOK, 你有没有遇到过上图的问题? 多达18419封邮件! 太多了, 每次想找一个邮件都非常耗时, 想办法解决这个问题 ...
- [原创] - C#编程大幅提高OUTLOOK的邮件搜索能力!
使用OUTLOOK, 你有没有遇到过上图的问题? 多达18419封邮件! 太多了, 每次想找一个邮件都非常耗时, 想办法解决这个问题成了一件非常紧迫的事情. 利用MS Search当然可以, 但是它太 ...
- C#中的SMTP配置Outlook.Com SMTP主机
如果你想以编程方式使用 Outlook.com或Gmail帐户作为 SMTP主机 发送电子邮件,也有为了得到这一切工作的几件事情要注意. 使用基本的System.Net.Mail库, ...
随机推荐
- js鼠标及对象坐标控制属性详细解析
对js鼠标及对象坐标控制属性进行了详细的分析介绍. offsetTop获取对象相对于版面或由 offsetParent 属性指定的父坐标的计算顶端位置. offsetLeft获取对象相对于版面或由 ...
- linux配置JDK(转载)
转载自:http://blog.csdn.net/xinxin19881112/article/details/46816385 Linux CentOS 6.6安装JDK1.7 目录 1.下载JDK ...
- SecureCRT上传bash: rz: command not found(转载)
转载自:http://blog.csdn.net/zhangdaiscott/article/details/18141017 -bash: rz: command not found rz命令没找到 ...
- 【BZOJ 1103】 [POI2007]大都市meg
Description 在经济全球化浪潮的影响下,习惯于漫步在清晨的乡间小路的邮递员Blue Mary也开始骑着摩托车传递邮件了.不过,她经常回忆起以前在乡间漫步的情景.昔日,乡下有依次编号为1..n ...
- velocity语法
1.声明变量 #set($var = XXX) 右边可以是以下的内容 Variable reference String literal Property reference Method refer ...
- CLSID {91493441-5A91-11CF-8700-00AA0060263B}错误
最近遇到一个棘手的问题,在C#中处理PPT转HTML的过程中需要用到COM组件,按照往常的设置如下: 1. Start->Run->DCOMCNFG->Component Servi ...
- spoj 338
题意: 无向图 每条边有长度和费用两个属性 求从点1到点n 在花费不超过 k 的情况下的最短路径 BFS 使用优先队列 长度短的优先出列 题解上的方法没看懂 不知道怎么用链表维护 . ...
- ajax请求返回json数据弹出下载框的解决方法
将返回的Content-Type由application/json改为text/html. 在struts2下: <action name="XXXAjax" class=& ...
- Socat
http://www.oschina.net/p/socat/ tcpick https://sourceforge.net/projects/tcpick/
- URAL 1009 K-based numbers(DP递推)
点我看题目 题意 : K进制的N位数,不能有前导零,这N位数不能有连续的两个0在里边,问满足上述条件的数有多少个. 思路 : ch[i]代表着K进制的 i 位数,不含两个连续的0的个数. 当第 i 位 ...