Форум: "Сети";
Текущий архив: 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