Как сделать снифер?

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by nick1000, 18 Feb 2011.

  1. nick1000

    nick1000 New Member

    Joined:
    10 May 2009
    Messages:
    25
    Likes Received:
    2
    Reputations:
    0
    Как сделать сетевой снифер, снифающий трафик в режиме обычного юзера?(в режиме админа и так удалось)

    Вот мой код:

    Code:
    
    procedure TForm1.Button1Click(Sender: TObject);
    var
        inaddrlist: PInAddrList;
        szHostName: array[0..127] of AnsiChar;
        phe:PHostEnt;
        sa:sockaddr_in;
        sock:TSocket;
        flag:Integer;
    
        buffer : Array[0..MaxPacketSize - 1] of byte;
        hdr : PIPHeader;
        outstr,tmpS: AnsiString;
        Len:Word;
        siz,ps:Integer;
    begin
      sock := socket(AF_INET, SOCK_RAW, IPPROTO_IP);
    
    
      if sock = INVALID_SOCKET then exit;
    
      if gethostname(szHostName, sizeof(szHostName)) <> 0 then  Exit;
    
      phe:=gethostbyname(@szHostName);
    
      if phe = Nil then exit;
    
      ZeroMemory(@sa,sizeof(sa));
      inaddrlist:=PInAddrList(phe.h_addr_list);
      // Привязываемся к нашему сокету :)
      sa.sin_family := AF_INET;
      sa.sin_addr.S_addr := inaddrlist^[0].S_addr;
    
      if (bind(sock, sa, sizeof(sa)) = SOCKET_ERROR) then Exit;
    
      flag:=1;
      if ioctlsocket(sock, SIO_RCVALL, flag) = SOCKET_ERROR then exit;
    
      work:=true;
      while work do begin
        // Ждем пакет :)
       siz:=recv(sock, Buffer, sizeof(Buffer), 0);
       if (siz = SOCKET_ERROR) then begin
          // Бывают же глюки :)
         flag := WSAGetLastError; break;
       end;
        // Если пакет имеет размер с заголовок или больше, то это - хорошо :)
       if (siz >= sizeof(TIPHeader)) then begin
    
    
          // Печатаем
    
         tmpS:=ByteToansiString(@Buffer[40],siz-40);
         Memo1.Text:=memo1.Text+tmpS+#13#10;
         Break;
       end;
    
        Application.ProcessMessages;
       end;
      end;
    
      closesocket(sock);
    end;
    
    
    
    Сырые сокеты не хотят создаватся в юзер режиме. Но Http Analyzer как-то же работает.
     
  2. De-visible

    De-visible [NDC] Network develope c0ders

    Joined:
    6 Jan 2008
    Messages:
    916
    Likes Received:
    550
    Reputations:
    66
    если не ошибаюсь он инжектит в процесс.
     
  3. Chrome~

    Chrome~ Elder - Старейшина

    Joined:
    13 Dec 2008
    Messages:
    937
    Likes Received:
    162
    Reputations:
    27
    Да, ты прав. Для 3-ей версии сниффера библиотека называеться HookWinSockV3.dll.
    Важно заметить, что перехват пакетов от Google Chrome входящих и исходящих работает неправильно.
     
  4. nick1000

    nick1000 New Member

    Joined:
    10 May 2009
    Messages:
    25
    Likes Received:
    2
    Reputations:
    0
    Спасибо за ответы. А можно пример как можно проинжектится и получить ответ от сервера?
     
  5. Chrome~

    Chrome~ Elder - Старейшина

    Joined:
    13 Dec 2008
    Messages:
    937
    Likes Received:
    162
    Reputations:
    27
    Прочитай для начала эту статью:
    http://www.codenet.ru/progr/delphi/stat/api-hook.php

    Если хочешь перехватывать траффик с помощью инжектирования своей библиотеки, ты должен перехватывать функции recv, send, WSARecv, WSASend (находяться в Ws2_32.dll).
     
  6. sn0w

    sn0w Статус пользователя:

    Joined:
    26 Jul 2005
    Messages:
    1,021
    Likes Received:
    1,189
    Reputations:
    327
    есть winpcap.org там даже фильтр пакетов со слов компилирует нужный код. попробуй его - единственное что под вопросом - сможешь ли ты к нему OpenFile от юзера осуществить
     
  7. Jingo Bo

    Jingo Bo Member

    Joined:
    25 Oct 2009
    Messages:
    368
    Likes Received:
    51
    Reputations:
    7
    Угу, у меня никогда не запускался, интерфейс Dial-up'а не перехватаывает, сколько не пробовал. А почти все поголовно сниферы через него работают, одно ток спасенье - HttpAnalyzerStd, а он не устраивает тем что только с порта 80 перехватывает HTTP трафик, а бывает что не по 80-ому(HTTP прокси к примеру).
     
    1 person likes this.
  8. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,702
    Likes Received:
    1,223
    Reputations:
    455
    Ставится CommView и без проблем всё снифается на любом типе подключения
    Dial Up/VPN/Lan/WiFi/etc потому что он добавляет свой драйвер везде где только можно.
    Конечно SSL не расшифрует, но gzip на лету умеет распаковывать.
     
    1 person likes this.
  9. Jingo Bo

    Jingo Bo Member

    Joined:
    25 Oct 2009
    Messages:
    368
    Likes Received:
    51
    Reputations:
    7
    slesh, спс, глянем.
     
  10. nick1000

    nick1000 New Member

    Joined:
    10 May 2009
    Messages:
    25
    Likes Received:
    2
    Reputations:
    0
    Не знаю, но у меня все нормально перехватывает.
     
  11. nick1000

    nick1000 New Member

    Joined:
    10 May 2009
    Messages:
    25
    Likes Received:
    2
    Reputations:
    0
    Еще раз спасибо за ответы, он вот не получается у меня инжектирование в Фаерфоксе 2.0 . В 3-ме норм все.
     
  12. GhostOnline

    GhostOnline Active Member

    Joined:
    20 Dec 2008
    Messages:
    723
    Likes Received:
    110
    Reputations:
    22
    А я вообще выбрал радикальное но самое эффективное решение.
    Я поставил логгер - то кто более-менее шарит в кодинге понимает что это такое.
    Я просто логирую входящие и исходящие пакеты в него, там естественно можно сортировать по всем данным. Но самое главное - из множества потоков можно выбрать один и будут показаны запросы только с него. Это оченб удобно, а все остальное ***ня. Пляс я могу отлаживать отдаленно - компилю с помощью условной компиляции 2 экзе один релизный другой дебажный, когда у клиента что-то не работает он запускает дебажную, и мне в реальном времени все видно как работает прога. Есть несколько способов логирования кроме как по сети. В итоге это самый лучший способ найти баг или еще что-то в многопоточной проге, ever.
    Лично я юзаю SmartInspect - вместо того чтобы ебаться отлаживать многопоточную прогу часами я посмотрю в логи 10 минут, исправлю то что нужно и пойду пить пиво )). Есть порты на дельфи, сишарп и еще какие то языки.
     
  13. nick1000

    nick1000 New Member

    Joined:
    10 May 2009
    Messages:
    25
    Likes Received:
    2
    Reputations:
    0
    Как от инжектированной Длл передать главной проге(которая и запускала эту длл) данные?
     
  14. Chrome~

    Chrome~ Elder - Старейшина

    Joined:
    13 Dec 2008
    Messages:
    937
    Likes Received:
    162
    Reputations:
    27
    Межпроцессное взаимодействие:
     
  15. nick1000

    nick1000 New Member

    Joined:
    10 May 2009
    Messages:
    25
    Likes Received:
    2
    Reputations:
    0
    Сначала думал сделать с помощью очереди сообщений, но потом понял что это не получится если приложение будет консольным. Или все же как-то можно? Если нет, то какой технологией лучше всего передавать данные между процессами?
     
  16. greki_hoy

    greki_hoy Member

    Joined:
    4 Mar 2010
    Messages:
    326
    Likes Received:
    57
    Reputations:
    41
    возможный вариант
    ServerSlot находится в вашей программе
    создает слот и ждет сообщений
    ClientSlot находится в библиотеке в другом процессе
    открывает созданный вами слот и пишет в него
    то что награбил вот пример
    Code:
    #define MAX_SLOT_CHUNK 512
    
    DWORD WINAPI ServerSlot(HANDLE hInitCompleted)
    {
    	HANDLE hSlot = CreateMailslot("\\\\.\\mailslot\\sniff", 0,
    		MAILSLOT_WAIT_FOREVER, NULL);
    	SetEvent(hInitCompleted);
    	CHAR buf[MAX_SLOT_CHUNK];
    	DWORD dwReads;
    	while (ReadFile(hSlot, buf, sizeof(buf), &dwReads, NULL))
    	{
    		if (!strcmp(buf, "deadc0de"))
    			break;
    		puts(buf);
    	}
    	CloseHandle(hSlot);
    	return EXIT_SUCCESS;
    }
    
    #define MAX_MESSAGE_COUNT 10
    
    DWORD WINAPI ClientSlot(LPVOID)
    {
    	HANDLE hSlot = CreateFile("\\\\.\\mailslot\\sniff", GENERIC_WRITE,
    		FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
    	CHAR buf[MAX_SLOT_CHUNK];
    	DWORD dwWrites;
    	for (size_t i = 0; i < MAX_MESSAGE_COUNT; i++)
    	{
    		int len = sprintf(buf, "%d", rand());
    		WriteFile(hSlot, buf, len + 1, &dwWrites, NULL);
    		Sleep(rand() % 1000);
    	}
    	WriteFile(hSlot, "deadc0de", 9, &dwWrites, NULL);
    	CloseHandle(hSlot);
    	return EXIT_SUCCESS;
    }
    
    int main()
    {
    	srand(GetTickCount());
    	HANDLE arr[2];
    	HANDLE hInitCompleted = CreateEvent(NULL, FALSE, FALSE, NULL);
    	arr[0] = CreateThread(NULL, 0, ServerSlot, hInitCompleted, 0, NULL);
    	WaitForSingleObject(hInitCompleted, INFINITE);
    	CloseHandle(hInitCompleted);
    	arr[1] = CreateThread(NULL, 0, ClientSlot, NULL, 0, NULL);
    	WaitForMultipleObjects(_countof(arr), arr, TRUE, INFINITE);
    	for_each(arr, arr+_countof(arr), CloseHandle);
    }
    
    еще удобно WM_COPYDATA использовать
     
  17. nick1000

    nick1000 New Member

    Joined:
    10 May 2009
    Messages:
    25
    Likes Received:
    2
    Reputations:
    0
    Не WM_COPYDATA не подайдет, потому что у меня принимающее приложение консольное. А так можно еще и удобно через FileMapping делать.
     
  18. Jingo Bo

    Jingo Bo Member

    Joined:
    25 Oct 2009
    Messages:
    368
    Likes Received:
    51
    Reputations:
    7
    Я недавно решил для себя написать простой снифер...Решил сделать как - при запуске EXE прога определяет список процессов и инжектит в них мельчайшую DLL( что бы быстро), потом загружает свой драйвер который через APC информирует о создание процесса(прога и туда сразу инжектит). А уж потом все процессы присылают нам перехваченные данные, причем в особом формате, который будет в себя включать ID процесса, ID потока, сокет и т.д. Короче в идеале прога наша должна отвечать на эти же данные(что пропускать и что изменять), то есть получится и снифер и как бы прокси. Но это все в идеале, я боюсь что скорость трафика сильно упадет, раз только одна программа будет обрабатывать все соединения.
     
  19. FEV

    FEV Member

    Joined:
    23 Sep 2009
    Messages:
    15
    Likes Received:
    7
    Reputations:
    0
    А еще можно через named pipes или те же сокеты делать
     
  20. greki_hoy

    greki_hoy Member

    Joined:
    4 Mar 2010
    Messages:
    326
    Likes Received:
    57
    Reputations:
    41
    я делал так логировал и ставил таймер скажем на секунду если до истечения
    периода приходили новые данные просто их пропускал если же таймаут прошел
    писал в лог и снова взводил таймер но у меня логика позволяла пропускать
    пакеты нужно было просто видеть активность
     
Loading...