Довольно часто можно встретить такую реальную ситуацию, что понадобилась статистика по безопасности тачки. С подобным столкнулся и я, а если более конкретно, то меня интересовали открытые порты telnet’а (по стандарту это 23-й порт, кому нужны подробности — см. RFC 1060). Ну не станешь же ты, перец, использовать статистику из газет 🙂 — мало ли откуда её брали. Так что я перешёл к более решительным мерам.

Под рукой был сервер, который работал круглосуточно, с установленным и сконфигурированным Linux’ом. Конечно, можно было использовать готовые сканеры — благо в сети их навалом. Однако куда интереснее и полезнее с точки зрения приобретенных практических навыков написать хоть и простенький сканер, но все же самому.

Выбор языков программирования был вполне достаточный, но памятуя, что простота — залог успеха, я выбрал для написания связку Perl + Expect. Немного обосную для непосвященных: Perl — мощнейшая штука при обработке текста и при этом весьма удобная, а Expect — уже готовый продукт для автоматизации различных задач с заранее известными входными/выходными данными. Думаю, уже понятнее :).

Чтобы хоть немного разобраться с используемыми языками, сделаем следующее: для Expect существует такая утилитка, как autoexpect. С её помощью можно легко наваять простенький скрипт, на основе которого можно понять основные принципы, заложенные в Expect. Допустим, мы хотим добиться, чтобы скрипт «скачал» с ftp-сервера какой-нибудь файл. Для этого выполняем команду: autoexpect ftp ftp.our_ftp_server.com.

Далее мы просто конектимся к серверу, скачиваем нужный файл и закрываем сеанс. Надеюсь, работать с ftp-клиентом все уже умеют :). В результате получаем готовый скрипт, по умолчанию создаётся файл script.exp, но можно и сразу задавать имя файла — autoexpect -f my_script_name ftp ftp.our_ftp_server.com, который делает то, что мы до этого делали вручную. Разумеется, в autoexpect есть куча других полезных фишек, но их вы уже будете изучать самостоятельно. Для более подробной информации советую заглянуть в мануал — man autoexpect.

Изучение кода полученного скрипта в большей части случаев помогает довольно быстро научиться писать свои собственные скрипты. Если кто и после просмотра кода не понял, то догоняю, что этот интерпретатор просто «ожидает» заранее определенного действия или момента времени и выполняет заложенные в него задачи или не выполняет — в зависимости от способностей пишущёго ;)). Для тех, кто в танке, список простейших команд:

  • set    — установить значение переменной;
  • expect    — ждать заранее известное значение(вполне можно задать маской);
  • send    — отправить значение;
  • spawn — породить процесс;
  • close    — завершить процесс;
  • exit    — завершить работу скрипта.

Итак, вооружившись моими советами и собственными мозгами можете попытаться написать свой собственный скрипт. Например, можно попробовать подсоединиться к своей собственной машине с помощью телнета и отправить сообщение самому себе, по мылу, разумеется :). Далеко не всякий сразу же бросится писать свой скрипт — на этот случай привожу уже готовый вариант написанного скрипта:

#!/bin/expect --        #пропишите правильный путь до expect'а
set timeout 60             #устанавливаем период ожидания - в данном случае это можно и не использовать
spawn telnet 127.0.0.1     #все логично - запустили telnet
expect -re "ame"         #ожидаем запроса на ввод логина
{
send -- "your_login r" #отвечаем на запрос(если он пришёл), "/r" - перевод строки.
}
expect -re "assw"        #кто не понял: первая буква может быть и заглавной, смотрим лишь по окончанию.
{
send - "your_password r" #отправляем e-mail в качестве пароля
}
expect -re ">"         #ожидаем приглашения на ввод команд
send - " mail your_login r"
send -- "This is just a test. r"
send - ".r"
expect -re ">"
send -- "exitr"
close                  #посылаем запрос на закрытие сеанса
wait                  #ожидаем закрытия
exit

Проверьте — все должно работать. Теперь слегка усложним скриптик и будем вести log-файл. Тут уж я помогать не буду — пишите сами ;). Для этого юзаем log_file — остальное смотрите в man pages :). После первых удачных опытов можно приступать собственно к написанию самого сканера. Тут возникают некоторые подводные камни: ну, в первую очередь стоит обратить внимание на команду spawn — порождение нового процесса. Что же тут может такого быть?

Оказывается, что иногда (в основном в циклах, рекурсивных структурах и т.д.) процесс просто остаётся и занимает tty — на первых порах я на этом здорово обжёгся. Чтобы этого избежать, во-первых, стоит запускать spawn с ключом -nottycopy, а, во-вторых, не стоит забывать делать wait и close — в циклах это одно из первых правил (в вышеприведенном примере эти команды вполне можно убрать — ничего страшного не случится). Кроме того, не стоит забывать про период ожидания ответа — timeout — подбирайте оптимальное значение в соответствии со своими линиями связи. Например, на плохих линиях я ставил до 3-х минут, хотя есть ли резон сканировать то, до чего практически нельзя добраться? В общем — думайте сами, решайте сами ;).

#!/bin/expect --
set dir "/my_dir"
set timeout 60
set server "[lrange $argv 0 0]"
set index1 "[lrange $argv 1 1]"
match_max 5000000
set telnet_log $dir/telnet.$server
for {set index2 "[lrange $argv 2 2]"} {$index2 < 255} {incr index2} {
    spawn -nottycopy telnet $server.$index1.$index2
    log_file $telnet_log
    send_log "
$server.$index1.$index2"
    log_file
    expect {
    -ex ">"
        {
        log_file $telnet_log
        send_log " - free >r"
        log_file
        }
    -ex "#"
        {
        log_file $telnet_log
        send_log " - free #r"
        log_file
        }
    -ex "$"
        {
        log_file $telnet_log
        send_log " - free $r"
        log_file
        }
    -ex "%"
        {
        log_file $telnet_log
        send_log " - free %r"
        log_file
        }
    -re "ogin|ame"
        {
        log_file $telnet_log
        send_log " - authentification requiredr"
        log_file
        }
    -re "assw"
        {
        log_file $telnet_log
        send_log " - only password requiredr"
        log_file
        }
    -re "route"
        {
        log_file $telnet_log
        send_log " - no route to hostr"
        log_file
        }
    -re "timeout"
        {
        log_file $telnet_log
        send_log " - timeoutr"
        log_file
        }
    -re "timed out"
        {
        log_file $telnet_log
        send_log " - timeoutr"
        log_file
        }
    -re "refuse"
        {
        log_file $telnet_log
        send_log " - connection refusedr"
        log_file
        }
    -re "close"
        {
        log_file $telnet_log
        send_log " - client closed connectionr"
        log_file
        }
    -re "not avail"
        {
        log_file $telnet_log
        send_log " - not availabler"
        log_file
        }
    default
        {
        log_file $telnet_log
        send_log " - defaultr"
        log_file
        }
    }
    close
    wait
    }
exit

Ну а теперь небольшие комментарии :). Как я и предупреждал, это лишь простейший вариант, хотя и вполне работоспособный. Он принимает в качестве параметров 3 аргумента: «A.B», «C» и «D»(без кавычек естественно), где A, B, C – числа из диапазона от 0 до 255, а D – от 0 до 254. Скрипт перебирает все варианты от A.B.C.D до A.B.C.255. Почему не все сразу? Дело в том, что на линии, где я сей скрипт использовал, иногда были обрывы связи, а то и самому скрипт приходилось останавливать.

Вывод — необходимо, чтобы скрипт при запуске сам продолжал сканирование с момента обрыва связи. Все это я реализовал еще в 2-х скриптах — вот тут-то и пригодился Perl. А чтобы это всё работало, само собой я использовал cron (кто не в курсе — см. man cron). Однако я думаю, что вам будет намного полезнее написать все скрипты самим ;). К тому же их можно реализовать и намного проще. И я ни в коем случае никого не призываю сканировать чужие сети с помощью данного скрипта — все может закончиться довольно плачевно :).

Оставить мнение

Check Also

Конкурс хаков: разведка DNS средствами chaosnet txt-записи hostname.bind

Тема information gathering с помощью DNS уже многократно поднималась в специализированных …