Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.07.09;
Скачать: CL | DM;

Вниз

Снифер 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;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.044 c
2-1150948586
D@Nger
2006-06-22 07:56
2006.07.09
Установка компонента ZipMaster


4-1144055290
antonn
2006-04-03 13:08
2006.07.09
проблемы с DrawText()


15-1150202201
Prohodil Mimo
2006-06-13 16:36
2006.07.09
как в VB преобразовать число в строку?


15-1149836731
0bsid
2006-06-09 11:05
2006.07.09
PocketPC


2-1150720795
AlexanderMS
2006-06-19 16:39
2006.07.09
Вопросик про шрифт