VR
Virtual Reality On-line   Хакер
Новости   |     Журнал    |    Хаkер   |     Магазин   |   Проекты
[   Вход    ]
[Kарта сайтa]
[ Download  ]
[  Конкурс  ]
[  Анекдоты ]
[  Ссылки   ]
[  Реклама  ]
[ Почтальон ]
[ О проекте ]






TopList
Сканер портов заказывали?:

(Внимание!!! Пример написанный в Kylix прекрасно работает в Delphi6)

Ко мне почти каждый день идут письма с просьбой выслать исходники какой-нибудь сетевой проги. Оно и понятно, потому что сетевой хак интереснее и адреналинистее (любим же мы коверкать русский язык :)). Чаще всего народ просит порт-сканеры, поэтому сегодня я расскажу тебе, как самому создать это чудо природы.

Начнемсссс...:

Постоянные читатели уже должны знать, как самому написать порт-сканер. Год назад, в спец выпуске "Кодинг" я уже рассказывал об этом чуде. Тогда я написал порт сканер с использованием WinAPI. В этом ничего плохого нет, просто в Linux нет WinAPI, поэтому тот пример нельзя так просто перенести на Kylix.

Продвинутые должны знать, что работа с сетью в Linux и Win построена одинаково на использовании сокетов. Но в Linux - это нормальные сокеты, а в Win - это WinSocks. Они не совместимы между собой, хотя и имеют много общего в названиях функций.

Поэтому я решил сегодня написать порт сканер на основе компонентов. Такой сканер скомпилируется в Linux или Win без малейшего изменения исходника. А работать он будет даже быстрее чем синхронные сокеты.

Песни и пляски ...:

Запусти Kylix. Брось на форму одну кнопку (имя по умолчанию Button1), два компонента TLabel (с именами Label1 и Label 2) и два компонента TEdit (c именами Edit1 и Edit2). Теперь у кнопки поменяй свойство Caption на "Scan", у Label1 на "Start Port", а у Label2 на "End Port".
Logo
Рисунок 1. Форма будущего сканера

Если ты все сделал правильно, то у тебя должно получится нечто похожее на рисунок 1. По нажатию кнопки мы будем сканировать порты начиная от номера указанного в Edit1 по номер указанный в Edit2.

Теперь нужно бросить на форму самый важный компонент - TCPClient. В нем дядя Борман уже реализовал для нас все необходимые функции для работы с сокетами и конечно же сканирования.
Logo
Рисунок 2. TCPClient

Прежде чем приступить к кодингу, давай еще немного улучшим форму. Установи у Edit1 свойство Text в "1", а у Edit2 в "2". Этим мы задаем значения по умолчанию для начального и конечного порта. И наконец брось еще TMemo. Желательно растянуть ее на всю оставшуюся свободную часть формы. Здесь мы будет отображать состояние сканирования. В итоге, у тебя должно получится нечто похожее на рисунок 3.

Теперь с оформлением покончено, пора переходить к кодингу. В принципе, код достаточно легкий и помещается всего-то в 8 строчек. Так что скоро ты увидишь свой сканер в действии.
Logo
Рисунок 3. Окончательная форма будущего сканера

Шкодинг:

Для начала создадим событие OnClick для кнопки. Это событие отлавливает сообщение "нажатие на кнопку". Обработчик можно создать двумя способами:

1. Выделить кнопку, перейти в объектный инспектор и дважды щелкнуть по строке OnClick.

2. Просто дважды щелкнуть по кнопке. По умолчанию, двойной клик по компоненту создает для него обработчик события OnClick.

Выбирай то, что тебе по душе и двигаемся дальше.

Как я уже сказал, по нажатию этой пимпы мы будем сканировать порты. Вот и давай напишем сюда этот текст. Перепиши все, что написано во врезке "Обработчик события OnClick". Комментарии переписывать не обязательно, я их вставил для большей ясности происходящего. Как только перепишешь, можешь продолжить читать дальше, я объясню, что здесь происходит.

Теория:

Ну а теперь давай разберемся, как же работает наш сканер. В разделе var я объявил две переменные i типа целое число (intrger) и ipstr типа строка (String). После начала блока кода (после begin), в первой строке я присваиваю переменной ipst значение '127.0.0.1'. Это будет значение по умолчанию для адреса сканируемой машины.

Следующей строкой я запрашиваю у юзера ip адрес машины:

if not InputQuery('Atention', 'Enter IP Address', ipstr) then exit;

Здесь я использую функцию InputQuery. Она выводит стандартное окно ввода (ты можешь его увидеть на рисунке 4). Функции передается три параметра:

1. Текст заголовка окна.

2. Текст отображаемый над строкой ввода.

3. Переменная типа строки, куда запишется результат.

Если пользователь ввел значение и нажал ОК, то функция вернет true, иначе вернет false. Поэтому я использую конструкцию:

if not InputQuery(...) then exit;

Которая означает: "Если пользователь не нажал ОК, то выйти".
Logo
Рисунок 4. Результат работы сканера

После этого я запускаю цикл:

for i:=StrToInt(Edit1.Text) to StrToInt(Edit2.Text) do

Эта строка звучит так: "Для переменной i присвоить значение указанное в Edit1 и до значения указанного в Edit2 выполнять следующую строку". Вместо следующей строки у меня идет блок begin ... end, поэтому будет выполнятся код указанный в этом блоке. Чтобы было понятней, давай рассмотрим пример цикла:

for i:=1 to 10 do
begin
 print('ОК');
end;

Строка for i:=1 to 10 do запускает цикл от 1 до 10. Это значит, что код указанный за последующими begin ... end будет выполнятся 10 раз. После каждого выполнения i будет увеличиваться на 1. После первого выполнения print('ОК') переменная i будет равна 2, после второго равна 3 и так держать.

И наконец IntToStr - функция, которой передается строка, а она превращает ее в число. Если ты передашь ей '1', то получишь число 1. Но если передашь 'a24gd', то получишь дулю с маком, потому что здесь не только числа, но и буквы.

Понеслась душа в рай :

Теперь посмотрим на само сканирование, которое находится между begin и end. Первая строка указывает, какой порт мы хотим открыть:

TcpClient1.RemotePort:=IntToStr(i);

Эта строка но русском звучит так: "у компонента TcpClient1 свойство RemotePort установить в значение указанное в переменной "i". Свойство RemotePort является строковым, поэтому я конвертирую число i в строку с помощью IntToStr.

Едем дальше. Следующей строкой я пытаюсь открыть порт: "TcpClient1.Open" После этого произвожу проверку:

if TcpClient1.Connected then

Если компонент TcpClient1 смог законнектиться, то вывожу об этом сообщение "Memo1.Lines.Add(IntToStr(i) + ' open')".

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

Понеслась душа в ад:

Вот и готов первый сканер. В Linux он у меня просканировал 1024 порта за несколько секунд. В Windows сканирование проходило около 5 минут, после чего я его вырубил. Так что под окнами сканируй не более десяти портов. Ты наверно спросишь, а как же тогда другие проги сканируют так быстро? Но это уже совсем другая история, о которой я расскажу в другой раз.

В принципе, сканер рабочий и его вполне реально юзать даже в боевых условиях. Тем более, что сканировать большое количество портов сразу очень опасно. Такие массовые сканы очень легко вычисляются. Желательно еще сканировать не все порты подряд, а в рассыпную. Например: 1, 150, 76, 1654, 756 и так далее. А это уже все в твоих руках.

На этом на сегодня все. Примеры, как всегда можно забрать с моего сайта www.x-c-r.com.

Обработчик события OnClick:
procedure TForm1.Button1Click(Sender: TObject);
var
 i:Integer;
 ipstr:String;
begin
 ipstr:='127.0.0.1';

//Запрашиваю адрес компа.
 if not InputQuery('Atention', 'Enter IP Address', ipstr) then exit;

//Запускаю цикл
 for i:=StrToInt(Edit1.Text) to StrToInt(Edit2.Text) do
  begin
   //Устанавливаю порт
   TcpClient1.RemotePort:=IntToStr(i);
   //Пытаюсь его открыть
   TcpClient1.Open;
   //Если удалось, то сообщаю об этом
   if TcpClient1.Connected then
    Memo1.Lines.Add(IntToStr(i)+' open');
   //Закрываю порт.
   TcpClient1.Close;
  end;
end;

Copyright©: Horrific aka Флёнов Михаил
Design by FMk group©