Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 2006.07.09;
Скачать: [xml.tar.bz2];

Вниз

Снифер HTTP-запросов   Найти похожие ветки 

 
Дмитрий_05   (2005-11-22 09:23) [0]

Привет всем. Подскажите пожалуйста как мне выделить HTTP-трафик из TCP-трафика? т.е. мне нужно чтобы моя программа видела по каким сайтам лазиет пользователь, причем любым браузером. В этом примере я определяю только IP-адреса пакетов, но т.к. если зайти на какуюнибудь страничку сайта, пакетов около 150 и больше приходит... как бы мне сделать, чтобы было просто написано, например "forum.vingrad.ru" один раз. Делаю я так:

uses WinSock;

...

type
 USHORT = WORD;

 TIPHeader = packed record
   iph_verlen:   UCHAR;    // версия и длина заголовка
   iph_tos:      UCHAR;    // тип сервиса
   iph_length:   USHORT;   // длина всего пакета
   iph_id:       USHORT;   // Идентификация
   iph_offset:   USHORT;   // флаги и смещения
   iph_ttl:      UCHAR;    // время жизни пакета
   iph_protocol: UCHAR;    // протокол
   iph_xsum:     USHORT;   // контрольная сумма
   iph_src:      ULONG;    // IP-адрес отправителя
   iph_dest:     ULONG;    // IP-адрес назначения
 end;
 PIPHeader = ^TIPHeader;

 TTCPHeader = packed record
   sourcePort: USHORT;       // порт отправителя
   destinationPort: USHORT;  // порт назначения
   sequenceNumber: ULONG;    // номер последовательности
   acknowledgeNumber: ULONG; // номер подтверждения
   dataoffset: UCHAR;        // смещение на область данных
   flags: UCHAR;             // флаги
   windows: USHORT;          // размер окна
   checksum: USHORT;         // контрольная сумма
   urgentPointer: USHORT;    // срочность
 end;
 PTCPHeader = ^TTCPHeader;

 TSnifferThread = class(TThread)
 private
   WSA: TWSAData;
   hSocket: TSocket;
   Addr_in: sockaddr_in;
   Packet: array [0..$10000 - 1] of Byte;
   LogData: string;
   procedure ShowPacket;
 protected
   function InitSocket: Boolean; virtual;
   procedure DeInitSocket(const ExitCode: Integer); virtual;
   procedure Execute; override;
   procedure ParcePacket(const PacketSize: Word); virtual;
 public
   Host: String;
 end;

 TForm1 = class(TForm)
   Edit1: TEdit;
   Button1: TButton;
   Label1: TLabel;
   XPManifest1: TXPManifest;
   Memo1: TMemo;
   procedure FormCreate(Sender: TObject);
   procedure Button1Click(Sender: TObject);
   procedure FormClose(Sender: TObject; var Action: TCloseAction);
 private
   { Private declarations }
   TotalPacketCount: Integer;
   FSnifferThread: TSnifferThread;
 public
   { Public declarations }
 end;

const
 // Размеры используемых структур
 IPHeaderSize = SizeOf(TIPHeader);
 TCPHeaderSize = SizeOf(TTCPHeader);

var
 Form1: TForm1;

implementation

{$R *.dfm}

// узнаем текущий IP
function GetLocalIP: string;
var
 WSAData: TWSAData;
 Host: PHostEnt;
 Buf: array [0..127] of Char;
begin
Result := "";
if WSAStartup($101, WSAData) = 0 then
 begin
 if GetHostName(@Buf, 128) = 0 then
   begin
   Host := GetHostByName(@Buf);
   if Host <> nil then
     Result := iNet_ntoa(PInAddr(Host^.h_addr_list^)^);
   end;
 WSACleanup;
 end;
end;

{TSnifferThread}

function TSnifferThread.InitSocket: Boolean;
var
 PromiscuousMode: Integer;
begin
// инициализируем WinSock
Result := WSAStartup($202, WSA) = NOERROR;
if not Result then
 begin
 LogData := "Ошибка: " + SysErrorMessage(WSAGetLastError);
 Synchronize(ShowPacket);
 Exit;
 end;
// создаем сокет
hSocket := socket(AF_INET, SOCK_RAW, IPPROTO_IP);
if hSocket = INVALID_SOCKET then
 begin
 DeInitSocket(WSAGetLastError);
 Exit;
 end;
FillChar(Addr_in, SizeOf(sockaddr_in), 0);
Addr_in.sin_family:= AF_INET;
// указываем за каким интерфейсом будем следить
Addr_in.sin_addr.s_addr := inet_addr(PChar(Host));
// связываем сокет с локальным адресом
if bind(hSocket, Addr_in, SizeOf(sockaddr_in)) <> 0 then
 begin
 DeInitSocket(WSAGetLastError);
 Exit;
 end;
// Переключаем интерфейс на прием всех пакетов проходящих через интерфейс - promiscuous mode.
PromiscuousMode := 1;
if ioctlsocket(hSocket, $98000001, PromiscuousMode) <> 0 then
 begin
 DeInitSocket(WSAGetLastError);
 Exit;
 end;
Result := True;
end;

procedure TSnifferThread.DeInitSocket(const ExitCode: Integer);
begin
 // Если была ошибка - выводим ее
 if ExitCode <> 0 then
 begin
   LogData := "Ошибка: " + SysErrorMessage(ExitCode);
   Synchronize(ShowPacket);
 end;
 // Закрываем сокет
 if hSocket <> INVALID_SOCKET then closesocket(hSocket);
 // Деинициализируем WinSock
 WSACleanup;
end;

procedure TSnifferThread.Execute;
var
 PacketSize: Integer;
begin
 // Производим инициализацию
 if InitSocket then
 try
   // Крутим поток до упора
   while not Terminated do
   begin
     // Ждем получения пакета (блокирующий режим)
     PacketSize := recv(hSocket, Packet, $10000, 0);
     // Если есть данные - производим их разбор
     if PacketSize > SizeOf(TIPHeader) then ParcePacket(PacketSize);
   end;
 finally
   // В конце освобождаем занятые ресурсы
   DeInitSocket(NO_ERROR);
 end;
end;

procedure TSnifferThread.ParcePacket(const PacketSize: Word);
var
 IPHeader: TIPHeader;
 TCPHeader: TTCPHeader;
 SrcPort, DestPort: Word;
 I, Octets, PartOctets: Integer;
 PacketType, DumpData, ExtendedInfo: String;
 Addr, A, B: TInAddr;
begin
 Move(Packet[0], IPHeader, IPHeaderSize);
 SrcPort := 0;
 DestPort := 0;
 ExtendedInfo := "";
 
 // определяем тип протокола
 if IPHeader.iph_protocol = IPPROTO_TCP then
   begin
     PacketType := "TCP";
       // Читаем ТСР заголовок
     Move(Packet[IPHeaderSize], TCPHeader, TCPHeaderSize);
       // Смотрим порт отправителя и получателя
     SrcPort := TCPHeader.sourcePort;
     DestPort := TCPHeader.destinationPort;

     // Пишем IP адрес отправителя с портом
     Addr.S_addr := IPHeader.iph_src;
     LogData := inet_ntoa(Addr);

     // Выводим все что напарсерили в Memo
     Synchronize(ShowPacket);  
   end;
end;

procedure TSnifferThread.ShowPacket;
begin
 Form1.Memo1.Lines.BeginUpdate;
 Form1.Memo1.Text := Form1.Memo1.Text + FormatDateTime("c", Now) + "   |   " + LogData + sLineBreak;
 SendMessage(Form1.Memo1.Handle, WM_VSCROLL, SB_BOTTOM, 0);
 Form1.Memo1.Lines.EndUpdate;
end;

{TForm1}

procedure TForm1.FormCreate(Sender: TObject);
begin
Edit1.Text := GetLocalIP;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
if FSnifferThread <> nil then
 begin
 FSnifferThread.Terminate;
 FSnifferThread := nil;
 Button1.Caption := ">>> Start >>>";
 end
else
 begin
 FSnifferThread := TSnifferThread.Create(True);
 FSnifferThread.Host := Edit1.Text;
 FSnifferThread.FreeOnTerminate := True;
 FSnifferThread.Resume;
 Button1.Caption := "*** Stop ***";
 end;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if FSnifferThread <> nil then
 begin
 FSnifferThread.Terminate;
 FSnifferThread := nil;
 end;
end;


 
Digitman ©   (2005-11-22 11:26) [1]


> если зайти на какуюнибудь страничку сайта, пакетов около
> 150 и больше приходит


TCP - протокол транспортного уровня, ему безразлично что передавать .. по TCP-соединению передается просто некий поток данных ..

получая в сниффере этот поток (фрагмент за фрагментом) ты анализируешь его содержимое на предмет соответствия получаемых в потоке данных формату , предусмотренному протоколом http (см., например, здесь http://book.itep.ru/4/45/http4561.htm) ... если данные соответствуют формату HTTP GET-запроса, то из заголовка запроса выделяется искомый URL.


 
Дмитрий_05   (2005-11-23 10:48) [2]

проанализировал я содержимое пакетов... почему-то я html-теги видно... а вот слова "GET" в пакетах что-то нету...(((


 
Slym ©   (2005-11-23 11:09) [3]

Если не ошибаюсь... так снифить можно только входящий трафик... а исходящий (GET -в нем) нет.


 
Дмитрий_05   (2005-11-23 11:19) [4]

а как мне тогда этот GET ловить?


 
seeker ©   (2005-11-23 11:31) [5]


> а как мне тогда этот GET ловить?
>

-Свой проксисервер.
-hook.


 
Slym ©   (2005-11-23 11:38) [6]

WinPcap - например


 
umbra ©   (2005-11-23 12:41) [7]

HTTP-сниффер с исходниками

http://www.arsware.org/cms/showpage.php?cid=101&PHPSESSID=77fa03bd7b6139b01280fe6adab1bbe4


 
Дмитрий_05   (2005-11-24 17:40) [8]

umbra, она библиотеку wpcap.dll требует... что это за библиотека?


 
umbra ©   (2005-11-24 18:05) [9]

на том же сайте, откуда ее скачал есть ссылка - http://www.winpcap.org/install/default.htm.


 
FloodaK   (2006-02-27 08:20) [10]

<h1>FloodaK</h1>
<xml>


 
FloodaK   (2006-03-03 12:53) [11]

<center>FloodaK<center>



Страницы: 1 вся ветка

Форум: "Сети";
Текущий архив: 2006.07.09;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.49 MB
Время: 0.01 c
2-1150530227
kilonet
2006-06-17 11:43
2006.07.09
формат файла *.CDS


15-1148747923
Nic
2006-05-27 20:38
2006.07.09
Прибыльный софт?


2-1151048589
zdm
2006-06-23 11:43
2006.07.09
Найти день рождения(MS Access)


2-1150979356
Tonich
2006-06-22 16:29
2006.07.09
Chart (диаграмма)


2-1151059159
alles
2006-06-23 14:39
2006.07.09
Нужен Ваш совет





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский