Задания для самостоятельной работы



 

Контрольный вопросы


ЛАБОРАТОРНАЯ РАБОТА № 5. ПЕРЕХВАТ СЕТЕВЫХ ПАКЕТОВ

Цель работы;

1. Изучить возможности библиотеки WinPcap

2. Изучить возможности библиотеки SharpPcap

 

Теоретическое введение

Общие сведения

SharpPcap представляет собой библиотеку для захвата пакетов для. NET, основанная на известной библиотеке WinPcap. Целью этой библиотеки является предоставление API для захвата, инъекции, анализа и создания пакета с помощью любого. NET языка, такого как C # и VB.NET.

SharpPcap предоставляет следующие возможности:

· получение подробной информации о физических сетевых интерфейсах на машине с Windows;

· захват сетевых пакетов, проходящих через данный интерфейс;

· анализ пакетов следующих протоколов: Ethernet, ARP, IP, TCP, UDP, ICMP, IGMP;

· инъекция пакетов через заданный сетевой интерфейс;

· сбор статистики по заданному сетевому интерфейсу.

На сайте библиотеки подробной справки нет (разработчики говорят, что лучше всего почитать форум), полезно посмотреть следующие страницы:

· http://www.codeproject.com/KB/IP/sharppcap.aspx - страница библиотеки на www.codeproject.com;

· http://www.tamirgal.com/blog/Page/SharpPcap-tutorial-a-step-by-step-guide-to-using-SharpPcap.aspx - справка к библиотеке на странице разработчика;

· http://www.tamirgal.com/home/SourceView.aspx?Item=SharpPcap – примеры к справке;

· http://sourceforge.net/projects/sharppcap/ - страница библиотеки на sourceforge.net.

5.1.2 Инсталляция драйвера и библиотеки WinPcap:

· установить драйвер WinPcap (WinPcap_X_X_X.exe);

· в реестре в ключе HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Servises\NPF\ значение параметра Start изменить на 2;

· перезагрузить компьютер.

 

По библиотеке WinPcap рекомендуется посмотреть следующие ссылки:

· http://www.winpcap.org/ - сайт библиотеки, там есть много чего полезного, в частности – FAQ, где вы можете найти ответы на вопросы об инсталляции и использовании библиотеки.

Подключение и использование библиотеки SharpPcap

Перед использованием SharpPcap необходимо установить WinPcap, процедура установки приведена выше.

Для того, чтобы использовать SharpPcap, необходимо подключить ссылку на SharpPcap.dll:

В появившемся окне выбираете вкладку Browse, далее с помошью диалога указываете на библиотеку SharpPcap.dll.

Пример простого перехвата пакетов (взят из справки к библиотеке, Example3.BasicCap):

 

Примеры программ для работы с WinPcap и SharpPcap

ПРИМЕР 1

Программа Syn-сканирования портов и обнаружения Syn-сканирования. Экранная форма приложения изображена на рисунке 1.1.

 

 

Используемые элементы управления приведены в таблице 1.1


Таблица 1.1 – Элементы управления для примера 1

Имя Класс Описание
comboBoxDevices comboBox Список сетевых карт
textBoxIP textBox Окно ввода IP адреса
textBoxFromNum textBox Окно ввода номера порта, с которого начинается сканирование
textBoxToNum textBox Окно ввода номера порта, которым заканчивается сканирование
textBox1 textBox Окно лога сканирования
buttonScan Button Кнопка «Scan»
progressBarScan progressBar Бегунок, показывающий процент просканированных портов от общего их количества

Последовательность создания приложения:

1. Подключенные пространства:

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Text;

using System.Windows.Forms;

using System.Runtime.InteropServices;

using System.Net;

using System.Net.NetworkInformation;

using SharpPcap;

using SharpPcap.Packets;

using SharpPcap.Util;

using System.Threading;

2. Процедура инициализации, здесь происходит получение списка сетевых адаптеров:

Примечание: при получении списка адаптеров на Windows 7 есть глюк: не отображается описание адаптера(в коде - d.Description), поэтому добавляем его IP адрес(d.Addresses[0].Addr.ToString()), кроме того, в данной процедуре еще одна ошибка, найдете её сами? А, чуть не забыл - может ошибка и не одна…*злобный смайлик* (Примечание Соколова И.Н.)

public Form1()

   {

       InitializeComponent();

       devices = Pcap.GetAllDevices();

       if (devices == null)

       {

           textBox1.Text += "There no library or network interfaces";

           return;

       }

       foreach(PcapDevice d in devices)

       {

           comboBoxDevices.Items.Add(d.Description+" " + d.Addresses[0].Addr.ToString()); 

       }

       comboBoxDevices.SelectedIndex = 0;

       ap = textBox1.AppendText;

       sv = progressBarScan.Increment;

}

 

3. Необходимо добавить процедуру получение MAC-адреса сетевой карты комьютера, порты которого сканируются:

//получениеMACадреса

[DllImport("iphlpapi.dll")]

Public static externint SendARP(int DestIP, int SrcIP, byte[] pMacAddr, ref int PhyAddrLen);

 

Public static string GetMAC(IPAddress ipAddress)

   {

int intAdr = (int)ipAddress.Address;

byte[] ab = newbyte[6];

int len = ab.Length;

int r = SendARP(intAdr, 0, ab, ref len);

string mac = BitConverter.ToString(ab, 0, 6);

returnmac;

     }

 

4. Объявляем следующие переменные:

List<PcapDevice>devices;//список устройств

public delegate void Append(string s);//необходимо для вывода результатов сканирования

Append ap;

public delegate void SetValue(int i);//н-мо для перевода бегунка

SetValue sv;

PcapDevice dev;

IPAddress dstIP;

Packet ans;

TCPPacket AnsPack;

TCPPacket TcpSynRst;

int NumFrom;

int NumTo;

Thread t;

float d;

string srcMac;

string dstMac;

 

5. Процедура формирования пакета:

public TCPPacket GetTcpPacket(string srcMac, string dstMac,IPAddress srcIP, IPAddress dstIP, int srcPort,

       int dstPort,bool syn,bool rst)

    {

        byte[] bytes = new byte[54];// задаем длину пакета, для сканирования - 54 байта, минимально

        //возмождная

        int len = EthernetFields_Fields.ETH_HEADER_LEN;//задаем длину, с которой будет начинаться пакет

        IPPacket ipp = new IPPacket(len, bytes, IPPacket.IPVersions.IPv4);

 

        ipp.DestinationHwAddress = PhysicalAddress.Parse(dstMac);

        ipp.SourceHwAddress = PhysicalAddress.Parse(srcMac);

        ipp.EthernetProtocol = EthernetPacketType.IpV4;

 

        ipp.DestinationAddress = dstIP;

        ipp.SourceAddress = srcIP;

        ipp.IPProtocol = IPProtocol.IPProtocolType.TCP;

         ipp.TimeToLive = 20;

        ipp.ipv4.Id = 100;

        ipp.IPTotalLength = bytes.Length - len;

        ipp.IPHeaderLength = IPv4Fields_Fields.IP_HEADER_LEN;

            

        TCPPacket TcpSynPacket = new TCPPacket(ipp, srcPort, dstPort, null); 

        TcpSynPacket.Syn=syn;

        TcpSynPacket.Rst = rst;

        TcpSynPacket.WindowSize = 555;

        TcpSynPacket.AcknowledgmentNumber = 10101;

        TcpSynPacket.SequenceNumber = 10101;

 

        TcpSynPacket.ComputeTCPChecksum();

        TcpSynPacket.ComputeIPChecksum();

 

        return TcpSynPacket;           

 

    }

 

6. Процедура последовательного опроса портов и анализа ответов:

void ScanPorts()

   {

       srcMac = dev.Interface.MacAddress.ToString();

       dstMac = GetMAC(dstIP);

       dev.Open(true, 1000);           

       for (int i = NumFrom; i <= NumTo; i++)

       {

           dev.SetFilter("tcp dst port 9090 and tcp src port "+ i.ToString());

           TcpSynRst = GetTcpPacket(srcMac,dstMac,IPAddress.Parse(dev.Addresses[0].Addr.ToString()), dstIP,9090, i, true, false);

           dev.SendPacket(TcpSynRst);

           Thread.Sleep(10);

           ans = dev.GetNextPacket();

           {

               if (ans !=null)

               {

                    AnsPack = (TCPPacket)ans;

                   if (AnsPack.Rst)

                   {

                       textBox1.Invoke(ap,"port № " + AnsPack.SourcePort.ToString() + " closed\r\n");

                   }

                   if (AnsPack.Ack && AnsPack.Syn)

                   {

                       textBox1.Invoke(ap, "port № " + AnsPack.SourcePort.ToString() + " open\r\n");

                       TcpSynRst = GetTcpPacket(srcMac, dstMac,IPAddress.Parse(dev.Addresses[0].Addr.ToString()),

              dstIP, 9090, AnsPack.SourcePort, false, true);

                       dev.SendPacket(TcpSynRst);

                      }

 

               }

           }            

           progressBarScan.Invoke(sv, System.Convert.ToInt32((i-NumFrom)*d-progressBarScan.Value));

       }

 

   }

 

7. Процедура OnClick кнопки buttonStart:

private void buttonScan_Click(object sender, EventArgs e)

   {

       if (devices == null)

           return;

       dev = devices[comboBoxDevices.SelectedIndex];

       try

       {

          dstIP = IPAddress.Parse(textBoxIP.Text);

       }

       catch

       {

           MessageBox.Show("Нет IP");

           return;

       }

           

       NumFrom = System.Convert.ToInt32(textBoxFromNum.Text);

       NumTo = System.Convert.ToInt32(textBoxToNum.Text);

       int i = NumTo - NumFrom;

       if (i != 0)

           d = ((float)100) / i;

       else

           d = 100;

       progressBarScan.Value = 0;

       textBox1.Clear();

       srcMac = dev.Interface.MacAddress.ToString();

       dstMac = GetMAC(dstIP);

       ThreadStart ts = new ThreadStart(ScanPorts);

       t = new Thread(ts);

       t.Start();

   }

8. Процедура OnFormClosing формы Form1:

private void Form1_FormClosing(object sender, FormClosingEventArgs e)

   {

if (t != null)

           t.Abort();

}

 

ПРИМЕР 2

Программа обнаружения сканирования: Считаем, что если на разные порты с одного адреса пришло более 10 SYN-пакетов, то компьютер подвергнут сканированию.

Экранная форма приложения изображена на рисунке 1.1.

 

Используемые элементы управления приведены в таблице 1.2.

Таблица 1.2 – Элементы управления для примера 2.

Имя Класс Описание
comboBoxDevices comboBox Список сетевых карт
textBox1 textBox Окно лога сканирования
buttonStart Button Кнопка «Start»
timer1 Timer Таймер проверки, показывает, через какой период проводится проверка

 

Ниже приведен программный код приложения:

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Text;

using System.Windows.Forms;

using SharpPcap.Packets;

using SharpPcap;

using System.Net;

using System.Threading;

 

 

namespace WindowsApplication3

{

public partial class Form1 : Form

{

List<PcapDevice> devices;

delegatevoidAppend(string s);

Append ap;

PcapDevice dev;

staticobject locker = newobject();

Thread t;

 

structTcpInfo

   {

publicIPAddress Ipa;

publicList<int> Ports;

   }

 

staticList<TcpInfo> TcpList = newList<TcpInfo>();

 

public Form1()

   {

       InitializeComponent();

       devices = Pcap.GetAllDevices();

foreach (PcapDevice d in devices)

           comboBoxDevices.Items.Add(d.Description);

       comboBoxDevices.SelectedIndex = 0;

       ap = textBoxLog.AppendText;

   }

 

 

privatevoid CapturePackets(int num)

   {

       dev = devices[num];

       dev.OnPacketArrival +=new SharpPcap.Pcap.PacketArrivalEvent( device_PcapOnPacketArrival );

       dev.Open();

       dev.SetFilter("ip and tcp ");

       dev.Capture(SharpPcap.Pcap.INFINITE);

       dev.Close(); 

   }

 

privatevoid buttonStart_Click(object sender, EventArgs e)

{

 

if (devices == null)

       {

MessageBox.Show("Не обнаружена библиотека или нет сетевых интерфейсов");

return;

       }

int num = comboBoxDevices.SelectedIndex;

ThreadStart ts = delegate

       {

           CapturePackets(num);

       };

       t = newThread(ts);

       t.Start();

       timer1.Enabled = true;

 

 

   }

 

privatestaticvoid device_PcapOnPacketArrival(object sender, PcapCaptureEventArgs e)

    {           

            

 

if(e.Packet isTCPPacket)

        {               

            TCPPacket tcp = (TCPPacket)e.Packet;             

 

if (tcp.Syn)

           {

lock (locker)

               {

int num = TcpList.FindIndex(delegate(TcpInfo tcpi)

               { return tcpi.Ipa.Address == tcp.SourceAddress.Address; });

if (num >= 0)

                   {

if (!TcpList[num].Ports.Contains(tcp.DestinationPort))

                             TcpList[num].Ports.Add(tcp.DestinationPort);

                   }

else

                   {

TcpInfo TcpCon = newTcpInfo();

                       TcpCon.Ipa = tcp.SourceAddress;

                       TcpCon.Ports = newList<int>();

                       TcpCon.Ports.Add(tcp.DestinationPort);

                       TcpList.Add(TcpCon);

                   }

               }

           }

 

 

        }

    }

 

privatevoid timer1_Tick(object sender, EventArgs e)

   {

       timer1.Enabled = false;

foreach (TcpInfo tcpi in TcpList)

       {

lock (locker)

           {

if (tcpi.Ports.Count >= 10)

               {

                  textBoxLog.Invoke(ap, "обнаружено сканирование с адреса " + tcpi.Ipa.ToString() + "\r\n");

                  tcpi.Ports.Clear();

 

               }

           }

       }

       timer1.Enabled = true;

   }

 

privatevoid Form1_FormClosing(object sender, FormClosingEventArgs e)

   {

if (t!=null)

           t.Abort();

 

}

}

}

 

ПРИМЕР 3

Приложение выводит список сетевых адаптеров и выводит на экран количество байт, переданных по каждому соединению. Экранная форма приложения приведена на рисунке 5.3.

 


Используемые элементы управления приведены в таблице 5.3.

Таблица 5.3 – Элементы управления для примера программы работы с библиокекой SharpPcap.

Элемент управления Класс Описание
1 2 3
groupBox1 GroupBox Панель «Список сетевых адаптеров»
groupBox2 GroupBox Панель «Аудит сетевого трафика»
comboBox1 ComboBox Содержит раскрывающийся список найденных сетевых адаптеров
dataGridView1 DataGridView Содержит информацию о сетевых соединениях
button1 Button Кнопка «Получить» (получить список сетевых адаптеров)
button2 Button Кнопка «Пуск» (запустить программу аудита)
button3 Button Кнопка «Остановить»
label1 Label Метка используется для вывода сообщения о том, что сетевые адаптеры отсутствуют
timer1 Timer Таймер используется для вывода информации на экран

Последовательность действий по созданию приложения:

1 Установить на ПК библиотеку WinPcap

2 Создать новое приложение подключить к нему библиотеку SharpPcap (Project®Add Reference®Закладка Browse). Если пространства имен не подключатся автоматически, то прописать их вручную:

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;

using SharpPcap;

using PacketDotNet;

using System.Threading;

using System.Collections;

using System.Collections.Generic;

В списке приведены все требуемые библиотеки

 

3 Добавить глобальные переменные:

// Список устройств

public static CaptureDeviceList deviceList;

// Выбранное устройство

   public static ICaptureDevice captureDevice;

// Таблица, в которой будет накапливаться информация о соединениях

   public static Hashtable hash;

 

4  Получение списка сетевых интерфейсов

Для события Click кнопки «Получить» пишем следующий программный код:

private void button1_Click(object sender, EventArgs e)

   {

       // Список сетевых интерфейсов

       // метод для получения списка устройств

       deviceList = CaptureDeviceList.Instance;

       if (deviceList == null)

       {

           label1.Text="Сетевые интерфейсы отсутствуют";

       }

       else

       {

           foreach (ICaptureDevice d in deviceList)

               comboBox1.Items.Add(d.Description + " " + d.Name);

           comboBox1.SelectedIndex = 0;

       }

   }

5 Для аудита сетевого трафика (событие Click кнопки «Пуск») пишем следующий программный код:

private void button2_Click(object sender, EventArgs e)

   {

       // выбираем устройство в списке

       if (deviceList != null)

           captureDevice = deviceList[comboBox1.SelectedIndex];

       Thread t1 = new Thread(new ThreadStart(ThreadProc));

       t1.Start();

       timer1.Enabled = true;

   }

Аудит будет осуществляться в отдельном потоке t1. Информация о соединениях будет выводиться на экран раз в 1 сек по прерыванию таймера timer1.

 

6 Программируем событие, которое срабатывает, когда приходит новый пакет. Данная программа проверяет есть ли уже информация в таблице о соединении (соединение проверяется по IP-адресам и портам отправителя и получателя). Если нет, то в хеш- таблице созлается новая запись, если – есть, то корректируется количество байт в существующей записи.

static void Program_OnPacketArrival(object sender, CaptureEventArgs e)

   {

       try

       {

           // парсинг всего пакета

           Packet packet = Packet.ParsePacket(e.Packet.LinkLayerType, e.Packet.Data);

           // получение только TCP пакета из всего фрейма

           var tcpPacket = TcpPacket.GetEncapsulated(packet);

           // получение только IP пакета из всего фрейма

           var ipPacket = IpPacket.GetEncapsulated(packet);

           if (tcpPacket != null && ipPacket != null)

           {

               DateTime time = e.Packet.Timeval.Date;

               int len = e.Packet.Data.Length;

 

               // IP адрес отправителя

               var srcIp = ipPacket.SourceAddress.ToString();

               // IP адрес получателя

               var dstIp = ipPacket.DestinationAddress.ToString();

 

               // порт отправителя

               int srcPort = tcpPacket.SourcePort;

 

               // порт получателя

               int dstPort = tcpPacket.DestinationPort;

               // данные пакета

               var data = tcpPacket.PayloadPacket;

 

               string s = dstIp.ToString() + dstPort.ToString() + srcIp.ToString() + srcPort.ToString();

               // Form1.richTextBox4.AppendText

               if (hash[s] == null)

                   hash.Add(s, new PacketView(dstIp.ToString(), dstPort, srcIp.ToString(), srcPort, len));

               else

               {

                   PacketView p = (PacketView)hash[s];

                   p.bytes += len;

 

               }

 

           }

       }

       catch (Exception except)

       {

       }

   }

7 Создаем дополнительный поток для аудита сетевого трафика:

public static void ThreadProc()

   {

       // регистрируем событие, которое срабатывает, когда пришел новый пакет

       captureDevice.OnPacketArrival += new PacketArrivalEventHandler(Program_OnPacketArrival);

       // Создаем коллекцию для хранения информации сетевом трафике

       hash = new Hashtable();

       // открываем в режиме promiscuous, поддерживается также нормальный режим

       captureDevice.Open(DeviceMode.Promiscuous, 1000);

       // начинаем захват пакетов

       captureDevice.Capture();

       //timer1.Enabled = true;

   }

8 Программируем таймер для вывода информации на экран:

private void timer1_Tick(object sender, EventArgs e)

   {

       timer1.Enabled = false;

          dataGridView1.Rows.Clear();

       foreach (PacketView p in hash.Values)

       {

           dataGridView1.Rows.Add(p.destAddr, p.destPort.ToString(), p.sourceAddr, p.sourcePort.ToString(), p.bytes.ToString());

       }

      timer1.Enabled = true;

   }

9 Для прекращения аудита программируем событие Click кнопки «Остановить»

 

private void button3_Click(object sender, EventArgs e)

   {

       // Прекращаем процесс сбора пакетов

       captureDevice.StopCapture();

       //Закрываем pcap устройство

       captureDevice.Close();

       timer1.Enabled = false;

   }

 


Дата добавления: 2018-08-06; просмотров: 294; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!