Форум АНТИЧАТ

Форум АНТИЧАТ (https://forum.antichat.xyz/index.php)
-   С/С++, C#, Delphi, .NET, Asm (https://forum.antichat.xyz/forumdisplay.php?f=24)
-   -   Еще один вопрос о перехвате пакетов (https://forum.antichat.xyz/showthread.php?t=175463)

Chrome~ 01.02.2010 23:09

Еще один вопрос о перехвате пакетов
 
Еще один вопрос о перехвате пакетов. Раньше уже задавал, но сейчас должен еще раз спросить: как лучше реализовывать перехват входящих и исходящих сетевых пакетов? Можно делать перехват WinSock функций или некоторых внутренних функций браузеров. Какие еще эффективные методы можете посоветовать?

Retimiled 01.02.2010 23:12

WinPCAp (хватает все)
RawSocket (хватает все что открыто на локальном компе)
NDIS (можно повыеживаться но в функционале не догнать WinPCap)
LCP (путь пройденный Comodo)

Chrome~ 01.02.2010 23:14

RawSocket
Это хотелось бы посмотреть. Если у кого то есть инфа по этому материалу, - скиньте ссылку.

Retimiled 01.02.2010 23:32

примерно так .... тут многие говорят с дрожью в голосе о неблокируемых сокетах..... дык вот вам откровение от делимитера 8))
Код:


s = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
  if (s != INVALID_SOCKET)
  {
    addr.sin_family = AF_INET;
    addr.sin_port  = htons(0);
    addr.sin_addr  = ((sockaddr_in*)(*(DWORD*)&addrlist[4]))->sin_addr;
    if (bind(s, (sockaddr*)&addr, sizeof(addr)) != SOCKET_ERROR)
    {
      #define SIO_RCVALL  0x98000001
 
      DWORD optval = 1;
      int  res = WSAIoctl(s, SIO_RCVALL,&optval, sizeof(optval), 0,0,&bytesret,0,0);
      if (res != SOCKET_ERROR)
      {
          int err=WSAAsyncSelect(s,hWnd,TCP_READ,FD_ACCEPT|FD_READ|FD_WRITE|FD_CONNECT);
      }
    }
  }


  {

ну и обработчик события TCP_READ
Код:

  if(WSAGETSELECTERROR(lParam))
      break;
  arg=0;
  ioctlsocket(s,FIONREAD,&arg);
  inquire=new char[arg+2];
  len=recv(s,inquire,arg,0);
  ..... извращаемся
 delete[] inquire;


Chrome~ 02.02.2010 00:14

То есть самое основное здесь, это константа SIO_RCVALL. Раньше немного читал об этом. Можно ли с помощью данного способа перехватывать исходящие пакеты?

Retimiled 02.02.2010 00:16

конечно и входящие и исходящие 8))

обрати внимание на FD_WRITE .... в функии СЕЛЕКТА с помощью ИЛИ "|" перечисляются какие FD события я обьединяю в событие TCP_READ
...
можешь добывить FD_CLOSE 8)) ....
:D как то оно выпало кудато :p сам не паму!

Chrome~ 02.02.2010 00:40

Спасибо! Буду разбираться.
Цитата:

Вы должны добавить репутацию кому-то еще, прежде чем сможете снова добавить ее Retimiled.

Gar|k 02.02.2010 00:47

Код:

/***************************************************************************
"Впервые исходный текст такого сниффера был опубликован в шестом номере журнала #29A,
затем его передрал Z0mnie, переложивший ассемблерный код на интернациональный программистский язык Си++ (странно, а почему не Си?)
и унаследовавший все ляпы оригинала.
Ниже приведен его ключевой фрагмент с моими комментариями,
а полный исходный текст содержится в файле sniffer.с.
Другой источник вдохновления - демонстрационный пример IPHDRINC, входящий в состав Platform SDK 2000. Рекомендую."

(c)Крис Касперски

changed by Gar|k 2010 GNU GPL
***************************************************************************/

#pragma optimize("gsy",on)
#pragma comment(linker, "/MERGE:.data=.text")
#pragma comment(linker, "/MERGE:.rdata=.text")
#pragma comment(linker, "/SECTION:.text,EWR")

#include <stdio.h>
#include <winsock2.h> // Wincosk2.h должен быть раньше windows!
#pragma comment(lib,"Ws2_32.lib")
#include <windows.h>

//#define SIO_ADDRESS_LIST_QUERY _WSAIOR(IOC_WS2,22)

/* во избежании ошибки переполнения 10014 SIO_ADDRESS_LIST_QUERY -- Gar|k
Windows* Sockets 2 / Application Programming Interface  / August 7, 1997
"If output buffer is not large enough to contain the address list,
SOCKET_ERROR is returned as the result of this IOCTL and WSAGetLastError() returns WSAEFAULT." 
*/
struct SSOCKET_ADDRESS_LIST {
        int iAddressCount;
        SOCKET_ADDRESS Address[50];
};

#define MAX_PACKET_SIZE 0x10000

struct SIPHEADER {
        unsigned char VerLen;
        unsigned char ServiceType;
        unsigned short PacketLength;
        unsigned short Id;
        unsigned short Offset;
        unsigned char TTL;
        unsigned char Protocol;
        unsigned short XSum;
        unsigned char SrcIP[4];
        unsigned char DestIP[4];
};
typedef struct SIPHEADER IPHEADER;

struct SIPPACKET {
        unsigned char Header[sizeof(IPHEADER)];
        unsigned char Data[MAX_PACKET_SIZE];
};
typedef struct SIPPACKET IPPACKET;

int main(void){

        char buf[512];
        SOCKET raw_socket;
        SSOCKET_ADDRESS_LIST addrlist;
        SSOCKET_ADDRESS_LIST *llist=&addrlist;
        SOCKADDR_IN addr;
        unsigned long N,rcv_all_enabled=1;
        int n_addr=0,a,len;
        IPPACKET IPPacket;
        IPHEADER *IPHeader;

        if (WSAStartup(0x202, (WSADATA *)buf))
                return printf("-ERR:WSAStart error %d\n", WSAGetLastError());

        // создаем сырой сокет
        //------------------------------------------------------------------------
        if ((raw_socket = socket(AF_INET, SOCK_RAW, IPPROTO_IP)) == INVALID_SOCKET)
                return printf("-ERR:socket(,SOCK_RAW,) -> %d\n", WSAGetLastError());

        // (не)устанавиваем атрибут IP_HDRINCL (ибо он на фиг не нужен)
        // ------------------------------------------------------------------------
        // if (setsockopt(raw_socket,IPPROTO_IP,IP_HDRINCL,(char*)&rcv_all_enabled,
        // sizeof(optval)) == SOCKET_ERROR) return printf("-ERR:setsockopt(,,IP_"\
        // "HDRINCL) -> %d\n", WSAGetLastError());

        // перечисляем все интерфейсы
        // -----------------------------------------------------------------------
        if (WSAIoctl(raw_socket, SIO_ADDRESS_LIST_QUERY, 0, 0, (LPVOID)&addrlist, sizeof(addrlist), &N, 0, 0) == SOCKET_ERROR)
                return printf("-ERR:WSAIoctl(SIO_ADDRESS_LIST_QUERY) error %d\n", WSAGetLastError());

        // найден хоть один интерфейс?
        if (!(n_addr = llist->iAddressCount)) return printf("-ERR:list is empty\n");

        // распечатываем список имеющихся интерфейсов
        // ------------------------------------------------------------------------
        for (a = 0; a < n_addr; a++)
                printf("IP - %s\n", inet_ntoa(((struct sockaddr_in*)llist->Address[a].lpSockaddr)->sin_addr));

        // биндим последний интерфейс (последний - для простоты понимания)
        addr.sin_family = AF_INET;
        addr.sin_addr = ((struct sockaddr_in*)llist->Address[a - 1].lpSockaddr)->sin_addr;

        if (bind(raw_socket, (struct sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR)
                return printf("-ERR:bind\n");

#define SIO_RCVALL 0x98000001

        // сообщаем системе, что мы хотим получать все IP-пакеты, проходящие мимо
        // ------------------------------------------------------------------------
        if (WSAIoctl(raw_socket, SIO_RCVALL, &rcv_all_enabled, sizeof(rcv_all_enabled), \
                0, 0, &N, 0, 0) == SOCKET_ERROR)
                return printf("-ERR:WSAIoctl(SIO_RCVALL)-->%d\n", WSAGetLastError());

        // получаем все пакеты, приходящие на данный интерфейс
        while(1)
        {
                if ((len = recv(raw_socket, (char *)&IPPacket,sizeof(IPPacket),0)) < 1)
                        return printf("-ERR:recv()->%d,WSAErr=%i\n", len, WSAGetLastError());

                if(len>=sizeof(IPHEADER))
                {
                        IPHeader=(IPHEADER *)&IPPacket.Header;
                        printf("%d.%d.%d.%d -> %d.%d.%d.%d %d %d\n",IPHeader->SrcIP[0],IPHeader->SrcIP[1],IPHeader->SrcIP[2],IPHeader->SrcIP[3],IPHeader->DestIP[0],IPHeader->DestIP[1],IPHeader->DestIP[2],IPHeader->DestIP[3],IPHeader->Protocol,len);

                }
        }

        WSACleanup();
        return 0;
}

как бы вариант на блокирующих сокетах.

Retimiled 02.02.2010 00:47

да лана ... репа это от лукавого!

2 Gar|k
... + .... пример на блокирующих сокетах!


только имя z0mbie (нужно писать правиьно) :D .... передрал его из англоязычного источника с developer-sources!

... читал с удовольствием его рассуждения ! 8)) когда он еще был в A29

slesh 02.02.2010 01:27

Всё бы то хорошо, но вот главный вопрос как получить через сырые сокеты исходящие данные?. Ведь через сырые сокеты можно получать исходящие данные. А также получать события.
Но из событие FD_WRITE ты никак не выдеришь данные исходящие.
Темболее что флаг FD_WRITE не даст тебе толком ничего для получения исходящего трафа.


Время: 14:21