Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Перехват пакетов  (Прочитано 25464 раз)
0 Пользователей и 6 Гостей смотрят эту тему.
Disasm
Гость
« : 06-06-2006 12:32 » 

Стоит на компе программа, которая является сервером. К ней приходят бинарные данные, причем в конце них стоит контрольная сумма. Моя программа, которая находится на том же компе должна перехватить эти данные сверить контрольную сумму и
1) если контрольная сумма совпала то отдать серверу данные без контрольной суммы
2) если контрольная сумма не совпала - то разорвать соединение.
Следует отметить, что сервер принимает сообщения с трех портов, а моя программа должна обрабатывать сообщения только с двух из них.
Требуемая нагрузка - 30-1000 соединений.
На этапе проверки сверяется контрольная сумма (последние 4 байта пакета) и контрольная сумма данных (полученных). Этот механизм сделан для того, чтобы предотвратить изменение данных сторонними программами, расположенными на клиентских машинах.

Как это сделать?

PS: Если эта тема где-то была поднята и решена, дайте ссылку, plz.
Записан
sss
Специалист

ru
Offline Offline

« Ответ #1 : 07-06-2006 00:19 » 

А что мешает "сторонним" программам изменить данные, пересчитать контрольную сумму и отправить к тебе на проверку? Неизвестный алгоритм расчета?

P.S.: Мне кажется, вопрос задан слишком общий...
Записан

while (8==8)
Disasm
Гость
« Ответ #2 : 07-06-2006 03:47 » 

Алгоритм расчета известен :), зато неизвестен полином, по которому считается контрольная сумма.

Мне нужен метод перехвата данных (методы типа перехвата Native-API функций не предлагать, т.к. они проверены и не работают).
Записан
sss
Специалист

ru
Offline Offline

« Ответ #3 : 07-06-2006 05:52 » 

1. DLL инжектирование (перехват, опять же, но уже в user space).
2. Фильтры брандмауэров ( например, фильтр приложения в ISA).
3. Сетевой посредник NDIS.

Записан

while (8==8)
Артем
Опытный

nz
Offline Offline
Пол: Мужской
Beware the wolf in sheep's clothing.


« Ответ #4 : 07-06-2006 12:27 » 

Под винды есть библиотека -- WinPcap, которая низкоуровневая (у нее даже вроде свой драйвер ставиться) и позволяет перехватывать пакеты.

Большой плюс этой библиотеки -- она неплохо документирована, и работа с ней чем-то похожа на работу с сокетами
Минус-- при установки своей проги, необходимо позаботиться об установки этой библиотеки (меньше мегабайта объему)
« Последнее редактирование: 07-06-2006 12:31 от Артем » Записан
Disasm
Гость
« Ответ #5 : 08-06-2006 02:46 » 

1. DLL инжектирование (перехват, опять же, но уже в user space).
2. Фильтры брандмауэров ( например, фильтр приложения в ISA).
3. Сетевой посредник NDIS.
DLL инжектирование - это и есть подмена API-функций. Метод хорош, но не работает, например, для .NET приложений.
Можете рассказать поподробнее по пунктам 2 и 3?
Под винды есть библиотека -- WinPcap, которая низкоуровневая (у нее даже вроде свой драйвер ставиться) и позволяет перехватывать пакеты.

Большой плюс этой библиотеки -- она неплохо документирована, и работа с ней чем-то похожа на работу с сокетами
Минус-- при установки своей проги, необходимо позаботиться об установки этой библиотеки (меньше мегабайта объему)
Можно ли с помощью нее отслеживать не весь траффик, а только данные, идущие к конкретным портам?

Спасибо.
Записан
sss
Специалист

ru
Offline Offline

« Ответ #6 : 08-06-2006 05:37 » 

Буду описывать только то, что делал сам... И работает.
Все ниже примеры из ISA SDK.
В MSDN - ISA SDK имеется

Фильтры приложения ISA.
----------------------------
1. На компьютере с 2 сетевыми картами устанавливаем Microsoft ISA Server 200x.
2. Загружаем ISA SDK (заголовки, idl)
3. Создаем DLL (используя ATL COM AppWizard).
4. Добавляем файлы заголовков и .idl к проекту
Код:
import "oaidl.idl";      // строка создается мастером 
import "oсidl.idl";      // строка создается мастером
import "wspfwext.idl";   // эту строку добавляешь ты
5. Процесс компиляции создает другие файлы (wspfwext.h и wspfwext_i.c).
6. Добавляем инструкцию include для wspfwext.h в файл заголовка stdafx.h:
Код:
#include "wspfwext.h"
7. Сгенерированный MIDL файл wspfwext_i.c содержит GUIDs для интерфейсов фильтра.
Включи его в один из .cpp файлов.
Код:
include "wspfwext_i.c"
8. Cоздаем объект фильтра реализующего интерфейс IFWXFilter.
Объект фильтра будет контролировать события fwx_AcceptedConnection.
8.a) Вставь новый объект ATL (Simple Object), со следующими свойствами
         •   Интерфейс - IFWXFilter
         •   Атрибуты:
                 Threading model - free
                 Interface - Custom
                 Aggregation - No
8.b) Отредактируй файл project.idl. Поскольку интерфейс IFWXFilter и его GUID уже определены в wspfwext.idl, ты должен удалить код определения IFWXFilter, который генерируется в project.idl
мастером. UUID в этом коде только для примера.
Код:

[
        object,
        uuid(20F10C85-2C5E-11D2-8C3D-006094EB63EF),
        helpstring("IFWXFilter Interface-),
        pointer_default(unique)
]

interface IFWXFilter : IUnknown
{
};

8.c) Добавь объявление методов IFWXFilter. Используй wspfwext.h, чтобы получить прототипы методов IFWXFilter и добавить их в секцию public определения класса project.h. Обрати внимание, что надо удалить = 0 из методов. Вставь следующий код:

Код:
// IFWXFilter
    virtual HRESULT STDMETHODCALLTYPE FilterInit(
    /* [in] */ IFWXFirewall __RPC_FAR *pIFWXFirewall,
    /* [out] */ PFwxFilterHookEvents __RPC_FAR *ppFilterHookEvents);
    virtual HRESULT STDMETHODCALLTYPE FilterShutdown(void);
    virtual HRESULT STDMETHODCALLTYPE AttachToSession(
    /* [in] */ IFWXSession __RPC_FAR *piSession,
    /* [out] */ IFWXSessionFilter __RPC_FAR *__RPC_FAR *piSessionFilter,
    /* [out] */ PFwxFilterHookEvents __RPC_FAR *ppFilterHookEvents);


8.d) Добавь реализацию методов IFWXFilter. Используй wspfwext.h, чтобы получить прототипы методов IFWXFilter и добавить их в SMTPfilter.cpp с реализацией кода.
Начни с простой реализации, например:
return E_NOTIMPL;
Реализованный код  должен выглядеть следующим образом:
Код:
// CSSSFilter
HRESULT STDMETHODCALLTYPE CSSSFilter::FilterInit(
            /* [in] */ IFWXFirewall __RPC_FAR *pIFWXFirewall,
            /* [out] */ PFwxFilterHookEvents __RPC_FAR *ppFilterHookEvents)
{
  return E_NOTIMPL;
}
   
HRESULT STDMETHODCALLTYPE CSSSFilter::FilterShutdown( void)
{
  return E_NOTIMPL;
}
 
 
HRESULT STDMETHODCALLTYPE CSSSFilter::AttachToSession(
        /* [in] */ IFWXSession __RPC_FAR *piSession,
        /* [out] */ IFWXSessionFilter __RPC_FAR *__RPC_FAR *piSessionFilter,
        /* [out] */ PFwxFilterHookEvents __RPC_FAR *ppFilterHookEvents)
{
  return E_NOTIMPL;
}
8.d)   Скомпилируй проект.
8.e)   Добавь код конструктора объекта SSSFilter, и реализуй метод IFWXFilter::FilterInit. Служба брандмауэра вызывает этот метод при старте. В методе IFWXFilter::FilterInit  сохрани указатель на интерфейс IFWXFirewall, который используется позже. Теперь определи набор начальных событий, которые фильтр будет контролировать. Этот пример контролирует события fwx_AcceptedConnection и fwx_Bind_Tcp. Однако, для лучшего быстродействия, лучше контролировать минимальный набор событий на уровне IFWXFilter. Поэтому, наш фильтр будет контролировать событие  fwx_Bind_Tcp для порта 25 и событие fwx_AcceptedConnection. Мы также должны определить порт, с которого хотитм получать события. В этом примере порт 25.
В SSSfilter.h, добавь следующий код:
Код:
private:
    CComPtr<IFWXFirewall>    m_pIFWXFirewall;
    FwxFilterHookEvents      m_FwxFilterHookEvents;
    FwxPortRangeEvents       m_FwxPortRangeEvents;
В SSSfilter.h, определи местонахождение конструктора по умолчанию, удали {}, и добавьте точку с запятой как показано:
CSSSFilter();
{ //удалить
} //удалить
и напиши следующий код конструктора объекта и реализацию FilterInit в SSSFilter.cpp (замени простое выполнение, которое вставил предварительно):
Код:
CSSSFilter::CSSSFilter ()
{
  m_FwxPortRangeEvents.StartPort = 25;
  m_FwxPortRangeEvents.EndPort  = 25;
  m_FwxPortRangeEvents.dwSocketEvents =
            DWORD(FWX_ALL_SOURCES // Источник события клиент NAT и брандмауэра
        | fwx_Bind_Tcp); // Мониторинг привязывается на этот уровнь
 
    m_FwxFilterHookEvents.dwGlobalEvents        = 0;
    m_FwxFilterHookEvents.dwNumPortRanges       = 1;
    m_FwxFilterHookEvents.FwxPortRangeEvents    = &m_FwxPortRangeEvents;
}

HRESULT STDMETHODCALLTYPE CSSSFilter::FilterInit(
    /* [in] */ IFWXFirewall __RPC_FAR *pIFWXFirewall,
    /* [out] */ FwxFilterHookEvents __RPC_FAR *__RPC_FAR *ppFilterHookEvents)
{
    m_pIFWXFirewall = pIFWXFirewall;
    return m_pIFWXFirewall->DuplicateFilterHookEvents (&m_FwxFilterHookEvents,
           ppFilterHookEvents);
}
8.f)   Реализуй метод IFWXFilter::FilterShutdown. Это - запрос на закрытие фильтра. Поскольку этот фильтр не содержит ссылки на любой другой объект, кроме интерфейса брандмауэра, он может просто возвратить S_OK. Это должно быть вставлено в SSSfilter.cpp, вместо предварительно вставленного возврата E_NOTIMPL.
Код:
HRESULT STDMETHODCALLTYPE CSSSFilter::FilterShutdown( void)
{
    return S_OK;
}
8.g)   Скомпилируй проект.

P.S.: Если есть интерес, потом что нибудь добавлю
P.P.S: Смотри ISA SDK. Там все отлично расписано.
Записан

while (8==8)
Артем
Опытный

nz
Offline Offline
Пол: Мужской
Beware the wolf in sheep's clothing.


« Ответ #7 : 08-06-2006 16:33 » 

Можно ли с помощью нее отслеживать не весь траффик, а только данные, идущие к конкретным портам?

Там есть функия pcap_setfilter(), которая используется при открытии доступа к пакетам, но я ее активно не использовал.

По крайней мере, можно "вручную" анализировать поле "номер порта" в заголовке пакета Улыбаюсь

Кстати, есть программка - Ethereal (по-моему)- которая предназначена для отслеживания и фильтрования любых пакетов, так вот она написана с использованием WinPcap. Т.е. я хочу сказать, что по ее возможностям можно судить о возможностях WinPcap
« Последнее редактирование: 08-06-2006 16:38 от Артем » Записан
Disasm
Гость
« Ответ #8 : 09-06-2006 02:50 » 

Можно ли с помощью нее отслеживать не весь траффик, а только данные, идущие к конкретным портам?

Там есть функия pcap_setfilter(), которая используется при открытии доступа к пакетам, но я ее активно не использовал.

По крайней мере, можно "вручную" анализировать поле "номер порта" в заголовке пакета Улыбаюсь

Кстати, есть программка - Ethereal (по-моему)- которая предназначена для отслеживания и фильтрования любых пакетов, так вот она написана с использованием WinPcap. Т.е. я хочу сказать, что по ее возможностям можно судить о возможностях WinPcap

Можете дать тогда формат пакета? Я нашел только такой:
//Структура заголовка IP-пакета
typedef struct IPHeader {
   UCHAR   iph_verlen;   // версия и длина заголовка
   UCHAR   iph_tos;      // тип сервиса
   USHORT  iph_length;   // длина всего пакета
   USHORT  iph_id;       // Идентификация
   USHORT  iph_offset;   // флаги и смещения
   UCHAR   iph_ttl;      // время жизни пакета
   UCHAR   iph_protocol; // протокол
   USHORT  iph_xsum;     // контрольная сумма
   ULONG   iph_src;      // IP-адрес отправителя
   ULONG   iph_dest;     // IP-адрес назначения
}IPHeader;

Как из него узнать порт?

Могу ли я с помощью WinPcap изменять размер пакетов, т.е. получить пакет->изменить длину->отправить пакет дальше?
Записан
Артем
Опытный

nz
Offline Offline
Пол: Мужской
Beware the wolf in sheep's clothing.


« Ответ #9 : 11-06-2006 18:42 » 

Могу ли я с помощью WinPcap изменять размер пакетов, т.е. получить пакет->изменить длину->отправить пакет дальше?

Вообще да. По крайней мере, создать свой новый пакет с нужными параметрами.

 А насчет портов посмотри в яндексе "стек TCP/IP". Если еще надо будет, во вторник могу подробно описать все заголовки.
Записан
Disasm
Гость
« Ответ #10 : 12-06-2006 04:16 » 

Уже не надо. Я другой способ нашел. Спасибо.
Записан
sss
Специалист

ru
Offline Offline

« Ответ #11 : 13-06-2006 07:02 » 

Поделись, какой?
Записан

while (8==8)
Disasm
Гость
« Ответ #12 : 13-06-2006 12:15 » 

Сделал клиент-серверное приложение. Правда мороки куча, особенно со склеиванием пакетов. И для этого способа надо блокировать оригинальные порты сервера фаерволлом.
Все заботает по схеме
                            |
client <->-------------------<->my_prog<->server
                            |
Клиенсткая часть |  Приложения на сервере
                            |
Порты приложения server должны быть защищены фаерволлом, чтобы избежать соединения с сервером "напрямую", и соответственно без защиты.
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines