Издательский дом ООО "Гейм Лэнд"ЖУРНАЛ ХАКЕР #84, ДЕКАБРЬ 2005 г.

Разводим червей

Ms-Rem (Ms-Rem@yandex.ru)

Хакер, номер #084, стр. 084-118-4


RR-запись выглядит так:

NAME up to 255 bytes + 1 ('\0')

TYPE 2 bytes (UINT)

CLASS 2 bytes (UINT)

TTL 4 bytes (signed 32 bits number - 'long')

RDLENGTH 2 bytes (UINT)

RDATA variable, depend on query

Где NAME - название хоста, к которому относится запись, TYPE - тип представляемой информации (о типах см. выше), CLASS - класс сети (в нашем случае всегда 'IN' (01)), TTL - время хранения информации в секундах, RDLENGTH - длина блока информации в байтах, RDATA - блок представляемой информации.

Самой главной проблемой при декодировании ответа будет разбор возвращаемых имен хостов. Имя хоста состоит из нескольких частей. Перед каждой частью ставится байт, определяющий ее длину. Например, www.microsoft.com будет выглядеть как 03 www 09 microsoft 03 com 00, имя всегда оканчивается нулевым байтом. Но самая главная фича не в этом, а в том, что имя может быть упаковано. Упаковывают имя, используя указатель, он представляет собой два байта, причем первый используется в качестве семафора, два старших бита этого семафора установлены в 1, а остальные не определены. Второй байт является смещением от начала запроса, то есть от первого байта идентификатора. Если байт длины равен $C0, то следующий за ним байт будет указателем (кошмар - прим. gorl'а). Напишем функцию, декодирующую такие имена:

function GetQName(var RecvData; Offset: Integer; var Pt: Pointer): string;

var

ChPt : PChar;

ReadBytes : Byte;

begin

Result := '';

ChPt := @RecvData;

Inc(ChPt, Offset + 1);

while ChPt^ <> '' do

begin

if ChPt^ = #$C0 then

begin

Inc(ChPt);

Result :=Result + GetQName(RecvData, Ord(ChPt^) - 1, Pt);

Break;

end else

begin

ReadBytes := Ord(ChPt^);

while ReadBytes > 0 do

begin

Inc(ChPt);

Result := Result + string(ChPt^);

Dec(ReadBytes);

end;

end;

Inc(ChPt);

if (ChPt^ <> '') then Result := Result + '.';

end;

Pt := ChPt;

end;

Так как объем статьи не позволяет рассмотреть процесс MX-резолвинга целиком, то я рассмотрю здесь только еще один важный момент - получение IP DNS-сервера, через который мы будем слать запросы. В этом нам поможет функция GetNetworkParams из iphlpapi.dll. Эта функция возвращает различную информацию о сетевых адаптерах, в том числе и адреса, связанных с ними DNS.

Назад на стр. 084-118-3  Содержание  Вперед на стр. 084-118-5